From 18da9b8e638fbb3d4d145858587a004ae3875ed1 Mon Sep 17 00:00:00 2001 From: Boaz Reicher <44614829+boazreicher@users.noreply.github.com> Date: Tue, 26 May 2026 07:53:24 +0000 Subject: [PATCH 1/3] Adding suggest bool flag to suggest type changes to an issue --- .../__toolsnaps__/update_issue_type.snap | 4 ++ pkg/github/granular_tools_test.go | 65 +++++++++++++++++++ pkg/github/issues_granular.go | 27 ++++++++ 3 files changed, 96 insertions(+) diff --git a/pkg/github/__toolsnaps__/update_issue_type.snap b/pkg/github/__toolsnaps__/update_issue_type.snap index 237603a6ed..ab33c4ddf7 100644 --- a/pkg/github/__toolsnaps__/update_issue_type.snap +++ b/pkg/github/__toolsnaps__/update_issue_type.snap @@ -28,6 +28,10 @@ "repo": { "description": "Repository name", "type": "string" + }, + "suggest": { + "description": "If true, propose the issue type change instead of applying it. Defaults to false, which applies the change to the issue.", + "type": "boolean" } }, "required": [ diff --git a/pkg/github/granular_tools_test.go b/pkg/github/granular_tools_test.go index 59eb478224..88bd560b4f 100644 --- a/pkg/github/granular_tools_test.go +++ b/pkg/github/granular_tools_test.go @@ -2,6 +2,7 @@ package github import ( "context" + "encoding/json" "net/http" "strings" "testing" @@ -458,6 +459,70 @@ func TestGranularUpdateIssueType(t *testing.T) { } } +func TestGranularUpdateIssueTypeSuggest(t *testing.T) { + tests := []struct { + name string + requestArgs map[string]any + expected map[string]any + }{ + { + name: "suggest without rationale", + requestArgs: map[string]any{ + "owner": "owner", + "repo": "repo", + "issue_number": float64(1), + "issue_type": "bug", + "suggest": true, + }, + expected: map[string]any{ + "owner": "owner", + "repo": "repo", + "issue_number": float64(1), + "issue_type": "bug", + "suggested": true, + }, + }, + { + name: "suggest with rationale", + requestArgs: map[string]any{ + "owner": "owner", + "repo": "repo", + "issue_number": float64(1), + "issue_type": "feature", + "rationale": " Asks for dark mode support ", + "suggest": true, + }, + expected: map[string]any{ + "owner": "owner", + "repo": "repo", + "issue_number": float64(1), + "issue_type": "feature", + "rationale": "Asks for dark mode support", + "suggested": true, + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + // No HTTP handler registered: any API call would fail the test. + deps := BaseDeps{Client: mustNewGHClient(t, MockHTTPClientWithHandlers(nil))} + serverTool := GranularUpdateIssueType(translations.NullTranslationHelper) + handler := serverTool.Handler(deps) + + request := createMCPRequest(tc.requestArgs) + result, err := handler(ContextWithDeps(context.Background(), deps), &request) + require.NoError(t, err) + require.False(t, result.IsError) + + textContent := getTextResult(t, result) + var got map[string]any + require.NoError(t, json.Unmarshal([]byte(textContent.Text), &got)) + assert.Equal(t, tc.expected, got) + }) + } +} + func TestGranularUpdateIssueTypeInvalidRationale(t *testing.T) { tests := []struct { name string diff --git a/pkg/github/issues_granular.go b/pkg/github/issues_granular.go index 400a22f5c2..931ed973b9 100644 --- a/pkg/github/issues_granular.go +++ b/pkg/github/issues_granular.go @@ -512,6 +512,11 @@ func GranularUpdateIssueType(t translations.TranslationHelperFunc) inventory.Ser "State the concrete signal (e.g. 'Reports a crash when saving' → bug, 'Asks for dark mode support' → feature).", MaxLength: jsonschema.Ptr(280), }, + "suggest": { + Type: "boolean", + Description: "If true, propose the issue type change instead of applying it. " + + "Defaults to false, which applies the change to the issue.", + }, }, Required: []string{"owner", "repo", "issue_number", "issue_type"}, }, @@ -542,6 +547,28 @@ func GranularUpdateIssueType(t translations.TranslationHelperFunc) inventory.Ser if len([]rune(rationale)) > 280 { return utils.NewToolResultError("parameter rationale must be 280 characters or less"), nil, nil } + suggest, err := OptionalParam[bool](args, "suggest") + if err != nil { + return utils.NewToolResultError(err.Error()), nil, nil + } + + if suggest { + suggestion := map[string]any{ + "owner": owner, + "repo": repo, + "issue_number": issueNumber, + "issue_type": issueType, + "suggested": true, + } + if rationale != "" { + suggestion["rationale"] = rationale + } + r, err := json.Marshal(suggestion) + if err != nil { + return utils.NewToolResultErrorFromErr("failed to marshal suggestion", err), nil, nil + } + return utils.NewToolResultText(string(r)), nil, nil + } client, err := deps.GetClient(ctx) if err != nil { From e1d687b192f4daffd9a0be415684d6080b86411d Mon Sep 17 00:00:00 2001 From: Boaz Reicher <44614829+boazreicher@users.noreply.github.com> Date: Tue, 26 May 2026 06:18:30 -0700 Subject: [PATCH 2/3] Update pkg/github/issues_granular.go Co-authored-by: Sam Morrow --- pkg/github/issues_granular.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/github/issues_granular.go b/pkg/github/issues_granular.go index 931ed973b9..9e789c6d16 100644 --- a/pkg/github/issues_granular.go +++ b/pkg/github/issues_granular.go @@ -512,7 +512,7 @@ func GranularUpdateIssueType(t translations.TranslationHelperFunc) inventory.Ser "State the concrete signal (e.g. 'Reports a crash when saving' → bug, 'Asks for dark mode support' → feature).", MaxLength: jsonschema.Ptr(280), }, - "suggest": { + "is_suggestion": { Type: "boolean", Description: "If true, propose the issue type change instead of applying it. " + "Defaults to false, which applies the change to the issue.", From 771036e533c3b2fa1ee01796a26b596369e1254b Mon Sep 17 00:00:00 2001 From: Boaz Reicher <44614829+boazreicher@users.noreply.github.com> Date: Tue, 26 May 2026 14:30:39 +0000 Subject: [PATCH 3/3] fixed snaps --- pkg/github/__toolsnaps__/update_issue_type.snap | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/github/__toolsnaps__/update_issue_type.snap b/pkg/github/__toolsnaps__/update_issue_type.snap index ab33c4ddf7..7fb5fde894 100644 --- a/pkg/github/__toolsnaps__/update_issue_type.snap +++ b/pkg/github/__toolsnaps__/update_issue_type.snap @@ -7,6 +7,10 @@ "description": "Update the type of an existing issue (e.g. 'bug', 'feature').", "inputSchema": { "properties": { + "is_suggestion": { + "description": "If true, propose the issue type change instead of applying it. Defaults to false, which applies the change to the issue.", + "type": "boolean" + }, "issue_number": { "description": "The issue number to update", "minimum": 1, @@ -28,10 +32,6 @@ "repo": { "description": "Repository name", "type": "string" - }, - "suggest": { - "description": "If true, propose the issue type change instead of applying it. Defaults to false, which applies the change to the issue.", - "type": "boolean" } }, "required": [