Repository navigation
feat: agent-fleet ergonomics (PROJ-958: 959, 960, 961, 962) - #386
Merged
Merged
Conversation
…J-959) add_comment and friends only took a UUID and answered "Issue not found" for a ref, costing agents a get_issue round trip (38 failed calls across 22 sessions). - services/issue-ref.ts: the ref resolver moves out of issues.ts (re-exported there) so comments/leases/file-claims can use it without an import cycle; adds a batched resolver for move_issues_to_sprint (one chunked query per project key) and a scope canonicaliser so "issue:PROJ-42" and "issue:<uuid>" are the same message channel. - schemas accept IssueIdOrRefSchema instead of .uuid(); services resolve at their entry point, so REST and MCP behave identically. - Covers comments (4), claim/release/list leases, claim/release/list file claims, register_agent, start_work, finish_work, list_active_agents, post/list_messages, move_issues_to_sprint, list/create attachments. Tool descriptions say "UUID or ref". - List filters and attachment reads return empty for an unknown ref rather than 404, so they can't be used to probe which refs exist in projects the caller can't see. - Tests: one MCP test per tool, unknown-ref and visibility cases. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EiHvwofTMQZrWW9oPQWuqq
…sues (PROJ-960)
Agents scope cohorts ("all bugs found during X") by label but had no way to list by one:
list_issues rejected `labels`, and search_issues for the exact label text returned
nothing even though 28 issues carried it (issues_fts indexes title and body only).
- list_issues: `labels` (array over MCP, comma-separated over REST) with all-of
semantics by default and `labelsMode: "any"`. Exact, case-sensitive match via
json_each; a row with malformed label JSON reads as no labels instead of 500ing the
list. Paginates and counts like every other filter.
- search_issues: an issue whose label equals the whole query (case-insensitive) is a
hit and leads the results, merged and de-duplicated with the FTS hits; `labels` /
`labelsMode` narrow keyword hits. No FTS migration needed. Visibility and project
scoping apply to both sources. Tool description points cohorts at list_issues, since
search is capped at 50 and has no cursor.
- Tests: all-of/any, exactness, pagination, MCP + REST shapes, malformed JSON, project
visibility, merge/dedupe/limit.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EiHvwofTMQZrWW9oPQWuqq
…ROJ-959/960 review) Refs no longer widen project visibility: hidden refs answer like unknown ones. Label search guards (length, json_type), repeated labels params, tests. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EiHvwofTMQZrWW9oPQWuqq
…PROJ-961) Adds follows_from link type (migration 0068), follow-up issue under the same parent/labels returned as followUp.ref from update_issue/finish_work, and a 'Partially done -> PROJ-n' relation in the issue view. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EiHvwofTMQZrWW9oPQWuqq
…es (PROJ-962)
Per-project epicAutoClose setting (migration 0069, default off). update_issue and
finish_work return parentReadyToClose:{ref} or parentClosed:{ref}; cancelled
children count; an open remainder follow-up keeps the epic open.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EiHvwofTMQZrWW9oPQWuqq
- epic check only on a real transition into done/cancelled (not re-saves) - parentReadyToClose/parentClosed respect project visibility and write access - auto-close failure degrades to the hint instead of failing the child's close - remainder follow-up failure is reported as followUpError, not thrown - epicAutoClose settable via update_project only; web label handles legacy done key Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EiHvwofTMQZrWW9oPQWuqq
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EiHvwofTMQZrWW9oPQWuqq
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Epic PROJ-958: agent-fleet ergonomics
PROJ-42; refs resolve visibility-aware, so a hidden ref answers exactly like an unknown one.list_issues/search_issuestakelabels(all-of by default,labelsMode: "any");search_issuesalso matches exact label text.completionReport.remainderon done creates afollows_from-linked follow-up (same parent + labels) and returnsfollowUp.ref; issue view shows "Partially done → PROJ-n". Migration 0068.epicAutoClose(default off): last child done/cancelled returnsparentReadyToClose:{ref}or auto-closes (parentClosed). Migration 0069.Two opus adversarial reviews; all confirmed findings fixed with tests.
Verification
gen:docs no diff, biome clean, turbo type-check, db tests, API suite (1863), web build, docs build. Web suite: 913 pass;
font-subset.test.tsfails here for lack of thebrotlipython module (fails identically on main).🤖 Generated with Claude Code
https://claude.ai/code/session_01EiHvwofTMQZrWW9oPQWuqq
Generated by Claude Code