docs: document __SPECKIT_COMMAND_ token for portable cross-command references#3503
Conversation
the development guide's 'Body (Markdown)' section listed $ARGUMENTS and
{SCRIPT} but never mentioned __SPECKIT_COMMAND_<NAME>__, the agent-neutral
token that resolve_command_refs() renders into each agent's invocation
syntax. with no signal the token exists, an author naturally hard-codes a
literal like /speckit.my-ext.prepare — correct for one agent, broken on the
rest (the root cause behind github#3451).
added it to the placeholder list plus a 'Referencing other commands'
subsection: why a literal isn't portable, the name->token encoding, and a
worked example showing the same token render as /speckit.bug.fix for a
slash agent and /speckit-bug-fix for a skills agent. examples verified
against resolve_command_refs and the first-party bug/git extensions.
phase 1 of the plan in github#3474; addresses the discoverability gap for github#3451.
There was a problem hiding this comment.
Pull request overview
Documents the portable __SPECKIT_COMMAND_<NAME>__ placeholder in the extension development guide so extension authors can reference other commands without hard-coding agent-specific invocation syntax.
Changes:
- Adds
__SPECKIT_COMMAND_<NAME>__to the command-body placeholder list. - Introduces a “Referencing other commands” subsection explaining the token’s purpose, encoding rules, and an example.
- Notes a naming limitation around underscores/hyphens in command-name segments.
Show a summary per file
| File | Description |
|---|---|
| extensions/EXTENSION-DEVELOPMENT-GUIDE.md | Documents the cross-command reference token, its encoding, and provides usage guidance/examples for extension authors. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 1/1 changed files
- Comments generated: 1
- Review effort level: Low
|
Can you please address Copilot feedback. We will should tackle the documentation change for skill rendering once that lands. Thanks! |
Copilot flagged (and mnriem asked me to address) that the section implied __SPECKIT_COMMAND_<NAME>__ always resolves to each agent's native invocation, including $speckit-* for Codex/ZCode. the resolver (resolve_command_refs) only emits /speckit<separator>... based on the active integration's invoke_separator; the $ and /skill: prefixes come from later skills-output post-processing, not the token resolver itself. reworded both the placeholder-list entry and the two explanatory paragraphs to describe separator-based rendering, and moved the prefix-in-skills-mode detail to a parenthetical example rather than stating it as the token's guaranteed output.
|
addressed in 8fb401a. you're right resolve_command_refs only emits /speckit... based on the active integration's invoke_separator; the $ and /skill: prefixes come from later skills-output post-processing, not the token resolver itself. reworded the placeholder-list entry and both paragraphs to describe separator-based rendering, and moved the skills-mode prefix detail (Kimi /skill:, Codex/ZCode $) into a parenthetical example rather than stating it as the token's guaranteed output. @mnriem agreed on holding the fuller skill-rendering docs until that work lands happy to follow up with it then. |
mnriem
left a comment
There was a problem hiding this comment.
Please address Copilot feedback
Copilot correctly noted the __SPECKIT_COMMAND_<NAME>__ token is not yet resolved for extension-generated skills: _register_extension_skills() calls resolve_skill_placeholders() and post_process_skill_content() but never resolve_command_refs(), so the token reaches Codex/ZCode/Kimi verbatim in skills mode. Token resolution only runs in the command-file rendering path (CommandRegistrar). Add an explicit limitation note so the guidance no longer implies universal portability.
|
Addressed in fc72805. You're right — I verified that Rather than overstate portability, I added an explicit "Current limitation — skills mode" note right after the example: the token is safe for command-file extensions today, and authors should avoid relying on it inside skill bodies destined for skills-based agents until that rendering step lands. Happy to swap the note for the resolver wiring instead if you'd prefer to close the gap in this PR. |
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (2)
extensions/EXTENSION-DEVELOPMENT-GUIDE.md:293
- This example promises that an extension token renders for skills-based agents and “stays portable,” but the skills registration path currently leaves the token verbatim, as the following limitation correctly explains. Please qualify these outputs as command-file rendering and avoid presenting
/speckit-bug-fixas current extension-skill behavior.
This renders as `/speckit.bug.fix slug=<slug>` for a slash-based agent, `/speckit-bug-fix slug=<slug>` for a skills-based agent, and so on — the author writes it once and it stays portable. The first-party `bug` and `git` extensions use this token exclusively; see `extensions/bug/commands/` for working examples.
extensions/EXTENSION-DEVELOPMENT-GUIDE.md:273
- “Exactly one agent” is inaccurate because multiple integrations share each invocation style. The portability issue is that the literal is tied to one syntax and fails for agents using a different syntax.
A command body is a *template* that Spec Kit renders once per agent. Different agents invoke commands with different surface syntax — for example `/speckit.plan` (dot separator) or `/speckit-plan` (hyphen separator). Some agents also use different prefixes in skills mode (e.g. Kimi `/skill:speckit-plan`, Codex/ZCode `$speckit-plan`). So when you reference a sibling command from a body, **do not hard-code a literal invocation** like `/speckit.my-ext.prepare`. A literal is correct for exactly one agent and breaks on the rest.
- Files reviewed: 1/1 changed files
- Comments generated: 0 new
- Review effort level: Medium
phase 1 of the plan @mnriem laid out in #3474: document the
__SPECKIT_COMMAND_<NAME>__token so extension authors have a signal it exists.why
the development guide's "Body (Markdown)" section listed
$ARGUMENTSand{SCRIPT}but never mentioned__SPECKIT_COMMAND_<NAME>__— the agent-neutral token thatresolve_command_refs()(integrations/base.py) renders into each agent's own invocation syntax. with no mention of it, an author naturally hard-codes a literal like/speckit.my-ext.prepare, which is correct for one agent and breaks on the rest. that literal-instead-of-token mistake is the root cause behind #3451.what
docs-only, in EXTENSION-DEVELOPMENT-GUIDE.md:
speckit.prefix dropped, dotted segments -> underscores), and a worked example_back to the agent separator, so a token can't carry a hyphen inside a name segmentverification
every rendered example in the docs was checked against
resolve_command_refsdirectly — e.g.__SPECKIT_COMMAND_BUG_FIX__->/speckit.bug.fix(slash) and/speckit-bug-fix(skills). the token names match the first-partybugandgitextensions, which use this token exclusively.scope: this is the independent, shippable docs increment. phases 2 (wire token resolution into the skill render path) and 3 (codex
$speckit-override) from the #3474 plan are separate.