feat(tower): retrieve_work_item_by_identifier — UUID lookup by 'PROJECT-N'#21
Conversation
…CT-N' Counterpart to pickup_issue for interactive use when the operator has only the canonical identifier (e.g. from a Plane browse URL or comment reference) and no UUID. SDLC-pipeline agents continue to use pickup_issue — they receive UUIDs in the spawn prompt. Identifier parsing is strict (^[A-Z][A-Z0-9]*-\d+$, case-insensitive), workspace auto-resolves via project_identifier when registered. Underlying PlaneClient.retrieve_issue_by_sequence_id walks list_issues and short-circuits on first match, since Plane v1 silently ignores ?sequence_id= as a query filter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (5)
WalkthroughThis PR adds an identifier-based work item lookup system. PlaneClient gains a ChangesWork item identifier lookup
Sequence DiagramsequenceDiagram
participant Caller
participant MCPTool as retrieve_work_item_by_identifier
participant PlaneClient
participant PlaneAPI as Plane API
Caller->>MCPTool: identifier, optional workspace
MCPTool->>MCPTool: validate format against _IDENTIFIER_RE
MCPTool->>MCPTool: parse project_identifier and sequence_id
MCPTool->>MCPTool: resolve workspace (explicit or via registry)
MCPTool->>PlaneClient: retrieve_issue_by_sequence_id(project_id, sequence_id)
PlaneClient->>PlaneAPI: list_issues(project_id)
PlaneAPI-->>PlaneClient: issues array
PlaneClient->>PlaneClient: iterate and find first matching sequence_id
PlaneClient-->>MCPTool: issue record or None
alt issue found
MCPTool->>MCPTool: format response with canonical identifier
MCPTool-->>Caller: issue dict with identifier field
else issue not found
MCPTool-->>Caller: ValueError: not found
end
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
mcp__plane-tower__retrieve_work_item_by_identifier— resolves a human-readable identifier (<PROJECT_IDENTIFIER>-<N>, e.g.COINEX-72) to its full work-item record with UUID.pickup_issuefor interactive use when the operator has only the canonical identifier (from a Plane browse URL or comment) and no UUID. SDLC-pipeline agents continue to usepickup_issue— they receive UUIDs via the spawn prompt.PlaneClient.retrieve_issue_by_sequence_idwalkslist_issuesand short-circuits on first match, since Plane v1 silently ignores?sequence_id=as a query filter (same category as?parent=).project_identifierregistry when the prefix is registered; can be overridden via explicitworkspace=arg.Motivation
Interactive users (operators in chat, ad-hoc tower calls) routinely have only the
COINEX-72-style identifier, never the UUID — Plane's/browse/URL doesn't even expose UUID. Until this PR, the only path waslist_sub_issues(root_uuid)which itself needs a UUID, or a raw REST call outside MCP.Test plan
tests/test_plane_client.py::test_retrieve_issue_by_sequence_id_finds_match— short-circuit on matchtests/test_plane_client.py::test_retrieve_issue_by_sequence_id_returns_none_when_missing— None on absent sequencetests/test_mcp_tower.py::test_retrieve_work_item_by_identifier_happy_path— full resolve via prefixtests/test_mcp_tower.py::test_retrieve_work_item_by_identifier_case_insensitive—test-42acceptedtests/test_mcp_tower.py::test_retrieve_work_item_by_identifier_malformed_raises— strict shape contracttests/test_mcp_tower.py::test_retrieve_work_item_by_identifier_not_found_raises— clear errorruff check+ruff formatclean🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
PROJECT-123format, case-insensitive)Tests