Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@ and enabled groups union.
- `get_change` — one change in review-relevant detail: status, owner, labels with votes, current revision, messages.
- `list_change_files` — files touched by a revision, with per-file change stats.
- `get_file_diff` — the diff of one file in a revision.
- `get_change_comments` — comment threads on a change, with resolution state and comment ids.
- `get_change_comments` — comment threads on a change, with resolution state and comment ids. Returns unresolved
threads only by default; `status=all` fetches the full history, `status=resolved` the settled threads.
- `post_comments` — publish a review in one call: optional top-level message plus inline, range, file-level, and
reply comments; replies anchor to comment ids from `get_change_comments`; `resolved` toggles the thread state.
- `set_vote` — set a label vote (e.g. `Code-Review`) with an optional message; value `0` clears an own vote.
Expand Down
22 changes: 14 additions & 8 deletions internal/tools/get-change-comments.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ var errInvalidStatus = e.New("invalid status filter, expected all, resolved, or

type getChangeCommentsInput struct {
Change string `json:"change" jsonschema:"Change identifier: change number (123), project~number (myproject~123), or Change-Id (I8473b95...)"`
Status string `json:"status,omitempty" jsonschema:"Thread filter: all, resolved, or unresolved; default all"`
Status string `json:"status,omitempty" jsonschema:"Thread filter: all, resolved, or unresolved; default unresolved"`
}

func getChangeComments(c *gerritclient.Client) Tool {
Expand All @@ -38,16 +38,22 @@ func getChangeComments(c *gerritclient.Client) Tool {
Description: "List a Gerrit change's inline review comments — the code discussion " +
"anchored to files and lines, distinct from the change messages get_change " +
"shows — grouped by file and reconstructed into threads with their resolved " +
"state. The calling account's unpublished draft comments are included, marked " +
"draft=\"true\" and invisible to anyone else; thread state accounts for them, " +
"matching what this account's Gerrit UI shows. Unresolved threads render " +
"before resolved ones; threads follow their latest activity and comments " +
"their history. Comment ids are the reply anchors for post_comments; filter " +
"status=unresolved to see what still needs action.",
"state. By default only unresolved threads return: the discussion still " +
"needing action. status=all adds the settled history — on long reviews that " +
"can be very large, so reach for it only when the resolved context matters; " +
"status=resolved lists the settled threads alone. The calling account's " +
"unpublished draft comments are included, marked draft=\"true\" and invisible " +
"to anyone else; thread state accounts for them, matching what this account's " +
"Gerrit UI shows. Unresolved threads render before resolved ones; threads " +
"follow their latest activity and comments their history. Comment ids are the " +
"reply anchors for post_comments.",
}, func(ctx context.Context, _ *mcp.CallToolRequest, in getChangeCommentsInput,
) (*mcp.CallToolResult, any, error) {
// Unresolved is the default: it is the actionable subset, and
// the full history of a long review can dwarf the context it
// lands in.
if in.Status == "" {
in.Status = statusAll
in.Status = statusUnresolved
}

if in.Status != statusAll && in.Status != statusResolved && in.Status != statusUnresolved {
Expand Down
21 changes: 16 additions & 5 deletions internal/tools/read-tools_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,11 +160,22 @@ func Test_GetChangeComments(t *testing.T) {

cs := commentsSession(t, fixture, emptyDraftsJSON)

out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123"})
out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123", "status": "all"})

golden(t, "change-comments-all", out)
})

t.Run("default returns only unresolved threads", func(t *testing.T) {
t.Parallel()

cs := commentsSession(t, fixture, emptyDraftsJSON)

out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123"})

// Same golden as the explicit filter: the default IS unresolved.
golden(t, "change-comments-unresolved", out)
})

t.Run("unresolved filter drops resolved threads", func(t *testing.T) {
t.Parallel()

Expand Down Expand Up @@ -241,7 +252,7 @@ func Test_GetChangeComments(t *testing.T) {

cs := commentsSession(t, published, emptyDraftsJSON)

out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123"})
out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123", "status": "all"})

golden(t, "change-comments-renamed", out)
})
Expand Down Expand Up @@ -273,7 +284,7 @@ func Test_GetChangeComments(t *testing.T) {

cs := commentsSession(t, published, emptyDraftsJSON)

out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123"})
out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123", "status": "all"})

golden(t, "change-comments-ui-fork", out)
})
Expand Down Expand Up @@ -301,7 +312,7 @@ func Test_GetChangeComments(t *testing.T) {

cs := commentsSession(t, published, emptyDraftsJSON)

out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123"})
out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123", "status": "all"})

golden(t, "change-comments-latest-order", out)
})
Expand Down Expand Up @@ -329,7 +340,7 @@ func Test_GetChangeComments(t *testing.T) {

cs := commentsSession(t, published, emptyDraftsJSON)

out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123"})
out := callTool(t, cs, "get_change_comments", map[string]any{"change": "123", "status": "all"})

golden(t, "change-comments-tiebreak", out)
})
Expand Down