Skip to content

allow hyphen in command ref token names - #4356

Open
HuzaifaChaudary wants to merge 3 commits into
github:mainfrom
HuzaifaChaudary:fix/command-ref-token-hyphen
Open

allow hyphen in command ref token names#4356
HuzaifaChaudary wants to merge 3 commits into
github:mainfrom
HuzaifaChaudary:fix/command-ref-token-hyphen

Conversation

@HuzaifaChaudary

@HuzaifaChaudary HuzaifaChaudary commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

problem

the command ref token can not hold a command name that has a hyphen in it. the pattern is

__SPECKIT_COMMAND_([A-Z][A-Z0-9_]*)__

the bundled command speckit.agent-context.update has a hyphen in the middle segment so there is no way to write a token for it. the text SPECKIT_COMMAND_AGENT-CONTEXT_UPDATE matches nothing and it stays in the generated file as plain text. the agent then reads a raw token instead of a real command.

fix

allow a literal hyphen in the character class in the two places that resolve the token

  • src/specify_cli/integrations/base.py in resolve_command_refs
  • src/specify_cli/extensions/__init__.py in the extension skills resolver

no decode change is needed. the existing replace call already leaves a hyphen untouched. so AGENT-CONTEXT_UPDATE becomes agent-context.update with the dot separator and agent-context-update with the hyphen separator.

this is option 2 from the review on #4204 which is the direction that was asked for there.

tests

i added 4 tests

  • hyphenated name with the dot separator
  • hyphenated name with the hyphen separator
  • a leading hyphen still does not match because the first character is still [A-Z]
  • extension skill registration resolves a hyphenated token

all 4 fail before the change and pass after it.

full suite after the change is 7139 passed and 9 failed. the same 9 fail on main without my change so they are not from this. they are the python parity template tests.

ruff 0.15.0 check src tests passes which is what the workflow runs.

ai disclosure

i used an ai assistant to help me read the code and write the tests. i reviewed the change myself and ran the suite locally.

Fixes #4198

the token pattern was matching only A-Z 0-9 and underscore so a command
name like speckit.agent-context.update can not be written as a token and
the token stays in the output as plain text

now the character class allows a hyphen also in both places that resolve
the token
Copilot AI balanced review requested due to automatic review settings August 27, 2026 20:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The extension authoring guide still explicitly contradicts the newly supported syntax.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment on lines +639 to +641
A hyphen belongs to the segment it sits in rather than separating
segments, so ``__SPECKIT_COMMAND_AGENT-CONTEXT_UPDATE__`` resolves to
``/speckit.agent-context.update``.
the guide still said the token scheme does not carry hyphens, which is the
opposite of what this branch does. added the real bundled command as the
example since speckit.agent-context.update is the one that was unreachable
before this.
@mnriem

mnriem commented Sep 1, 2026

Copy link
Copy Markdown
Collaborator

This is now the canonical implementation for #4198. We selected this PR because it applies the requested option 2 with the smallest backward-compatible code change. Please address the existing focused documentation feedback so the authoring guide reflects the newly supported literal-hyphen syntax; no broader refactor is requested. #4204, #4361, and duplicate issue #4328 are being closed to consolidate the work here.

Posted on behalf of @mnriem by GitHub Copilot (model: GPT-5.6 Sol).

@HuzaifaChaudary

Copy link
Copy Markdown
Contributor Author

documentation feedback is addressed in a40b2bf2, and nothing else changed.

extensions/EXTENSION-DEVELOPMENT-GUIDE.md had the opposite of this behaviour written into it:

the token scheme rebuilds those dots and does not carry hyphens within a segment

that line is gone. the encoding rule now says a hyphen inside a segment is kept, and the table has a hyphenated row using the real bundled command rather than a made up one:

Command file Token
speckit.agent-context.update.md __SPECKIT_COMMAND_AGENT-CONTEXT_UPDATE__

i used speckit.agent-context.update on purpose. it ships in extensions/agent-context/commands/ and it is the command that was unreachable before this change, so the example is the actual case rather than an illustration.

the sentence after the table now states the rule both ways, since a hyphen and an underscore doing different jobs in the same token is the part that is easy to get wrong:

An underscore separates segments and a hyphen belongs to the segment it sits in, so AGENT-CONTEXT_UPDATE is the two segments agent-context and update rather than three.

markdownlint clean, 0 issues. no code changed in this commit, the regex is still the one character [A-Z0-9_-] widening from the first commit.

Copilot AI review requested due to automatic review settings September 1, 2026 14:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The development guide retains a contradictory, obsolete skills-mode limitation.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Balanced

Comment thread extensions/EXTENSION-DEVELOPMENT-GUIDE.md

@mnriem mnriem left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please address Copilot feedback

the callout said a command ref token reaches codex zcode and kimi verbatim.
it does not. _resolve_command_ref_tokens inside _register_extension_skills
resolves the same token shape against the active skill style. the callout was
right that resolve_command_refs is never called there and wrong about what
follows from it.
@HuzaifaChaudary

Copy link
Copy Markdown
Contributor Author

addressed in fd8ed36e. the finding was right, and it is worth being precise about which half of it was.

the callout said this:

_register_extension_skills resolves placeholders and post-processes content but never calls resolve_command_refs, so a __SPECKIT_COMMAND_<NAME>__ token reaches agents such as Codex, ZCode, and Kimi verbatim in that mode

the first half is still literally true. resolve_command_refs is never called there. the conclusion drawn from it is not, because _resolve_command_ref_tokens in the same function does its own substitution over the same token shape and handles exactly the agents the callout named:

if is_dollar_skills_agent(selected_ai, ai_skills_enabled):
    return "$" + command_name.replace("speckit.", "speckit-").replace(".", "-")
if is_slash_skills_agent(selected_ai, ai_skills_enabled):
    return "/" + command_name.replace("speckit.", "speckit-").replace(".", "-")

so a token becomes $speckit-bug-fix for codex or zcode and /speckit-bug-fix for kimi rather than arriving verbatim.

i ran it rather than take my own reading of it:

tests/test_extension_skills.py  8 passed

that includes test_skill_registration_resolves_hyphenated_command_ref_tokens, which registers an extension as skills for a skills agent and asserts the hyphenated token comes out resolved.

one thing worth flagging since it changes who owns the wording. the callout was already wrong before this branch. the skills side substitution and its re.sub were both there, and all this branch did to that line was widen the character class by one character to allow -. so this is not a limitation my change lifted, it is one the guide had been describing incorrectly for a while, and i noticed it because copilot pointed at the paragraph next to the one i was editing.

the replacement says what both paths do rather than claiming a limitation either way. markdownlint 0 issues.

Copilot AI review requested due to automatic review settings September 1, 2026 14:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The updated guide incorrectly documents Kimi’s final command invocation syntax.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Balanced

> (`CommandRegistrar`). Skill bodies go through `_resolve_command_ref_tokens` in
> `_register_extension_skills`, which resolves the same token shape against the
> active skill style: `$speckit-bug-fix` for a dollar-prefixed agent such as
> Codex or ZCode, `/speckit-bug-fix` for a slash-prefixed one such as Kimi, and
@HuzaifaChaudary

Copy link
Copy Markdown
Contributor Author

the red on Test & Lint Python is a cancelled macos runner rather than a test failure, in case it reads as one.

run 33519638199, 6 of 7 jobs green:

success    ruff
success    pytest (ubuntu-latest, 3.13)
success    pytest (ubuntu-latest, 3.14)
success    pytest (windows-latest, 3.13)
success    pytest (windows-latest, 3.14)
success    pytest (macos-latest, 3.13)
cancelled  pytest (macos-latest, 3.14)

the cancelled one ran 14:28:48 to 14:43:56 and reports no step conclusions at all, so it never got to a result. macos 3.13 passed and both 3.14 cells on the other two platforms passed, so it is not the python version and not the platform.

the workflow conclusion is failure because a job was cancelled, not because anything asserted false. a re-run should clear it, and i cannot trigger one from here.

Lint, CodeQL and Security Audit are all green on the same commit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: __SPECKIT_COMMAND_*__ tokens can't reference commands whose names contain hyphens

3 participants