feat(subagents): accept @server.tool / server.tool / bare id in subagent tools[]#120
Merged
Conversation
…ent tools[] Until now subagents[].tools required a bare local tool id, while skills' requires[] used the @-prefixed qualified form. Users who learned `requires` syntax first would write `@dbx.sql_read_only` under a subagent, hit the new unknown-tool warning, and conclude capa is broken. Add `resolveSubagentToolRef(ref, tools)` that accepts all three equivalent forms — `@server.tool`, `server.tool`, and `tool_id` — and route the three consumers through it: - MCP handler filtered endpoint (mcp-handler.ts) - Subagent file renderer (handlers.ts resolveTool) - Install-time validator (collectSubagentRefWarnings) Update the capabilities-manager skill's schema reference to document all three forms and the new validation. New unit tests cover the resolver and the mixed-form path through the warning collector. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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.
Summary
Follow-up to #118 and #119.
Until now
subagents[].toolsrequired the bare local tool id, whileskills[].def.requiresused the @-prefixed qualified form:Users who learned
requiresfirst wrote@dbx.sql_read_onlyunder a subagent, hit the new unknown-tool warning from #119, and concluded capa is broken — when in fact they'd just used the wrong dialect. The warning made the asymmetry more visible, not less.This PR adds a resolver that accepts all three equivalent forms for the same tool and routes the three consumers through it:
All three resolve to the same
Tool. Pick whichever reads best in context.Changes
src/types/capabilities.ts— newresolveSubagentToolRef(ref, tools)next togetQualifiedToolName. Tries qualified-name match first (handles@server.tool/server.tool/ ungrouped command tools), then falls back to bare-id match.src/server/mcp-handler.ts:260— filtered MCP endpoint uses the resolver instead oftools.find(t => t.id === toolId), so subagents with@-prefixed refs can actually call their tools.src/shared/providers/handlers.ts(resolveTool) — renderer uses the resolver so all three input forms produce the same canonical<group>.<tool>bullet.src/cli/commands/install-tasks/helpers/tool-warnings.ts(collectSubagentRefWarnings) — validator uses the resolver and the warning copy now lists the three accepted forms.skills/capabilities-manager/references/capabilities-schema.md— documents all three forms with examples and notes the install-time validation.Tests
src/types/__tests__/resolveSubagentToolRef.test.ts(new) — 7 cases covering MCP tool, grouped/ungrouped command tools, and unresolved refs in all three input shapes.src/cli/commands/install-tasks/helpers/__tests__/tool-warnings.test.ts— new cases: mixed-form happy path produces no warnings;@-prefixed ref that doesn't resolve still warns with the original ref intact.Test plan
bun test— 1095/1095 pass (8 new)sql_read_only,dbx.poll_sql_result, and@dbx.sqlall rendered the same canonical bullet; only an unresolvable@dbx.does_not_existproduced a warningcapabilities-manager— that's the surface external users learn from