You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[Bug]: Codex skills show /speckit-… in hook "To execute" lines instead of $speckit-… #4954
For integrations that invoke skills with $ (for example Codex), the generated skills still tell the user to run hooks with a / prefix. The dot-to-hyphen note in the same skill correctly uses $, so the two lines contradict each other.
Environment
specify-cli 1.2.0 (latest release); same code on main
Integrations: claude (default) and codex, script type py
Extension: git 1.0.1
Steps to reproduce
specify integration install codex --script py in a project with the git extension.
Open .agents/skills/speckit-specify/SKILL.md.
Run $speckit-specify <description> in Codex.
Expected
Hook invocations use Codex's prefix: To execute: `$speckit-git-commit`.
Actual
The generated SKILL.md contains both:
- When constructing command invocations from hook command names, replace dots (`.`) with hyphens (`-`). For example, `speckit.git.commit` → `$speckit-git-commit`.
...
To execute: `/{command}`
Codex then prints To execute: `/speckit-git-commit` in its hook report, which is not a valid Codex invocation.
Cause
templates/commands/*.md (and bundled extension commands such as extensions/bug/commands/speckit.bug.fix.md) hard-code To execute: `/{command}`. SkillsIntegration._inject_hook_command_note in src/specify_cli/integrations/base.py adapts only the injected note's example to the agent's invocation prefix (get_invocation_prefix). It doesn't rewrite the template's /{command} lines.
Possible fix
Replace the literal / in those templates with a prefix placeholder that is resolved at install time, the same way __SPECKIT_COMMAND_*__ placeholders are. Alternatively, have post_process_skill_content rewrite `/{command}` to `{prefix}{command}` when invocation_prefix != "/".
Searched before filing
There are no matching open or closed issues or PRs for "To execute", Codex hook prefix, or $speckit hook invocation.
The reporter states that with specify-cli 1.2.0/main, the codex skills integration, Python scripts, and the git extension, generated .agents/skills/speckit-specify/SKILL.md contains a correct $speckit-git-commit example in the dot-to-hyphen note but still emits hook instructions such as To execute: /speckit-git-commit``. Codex treats the slash-prefixed form as invalid. No additional comments were present.
Symptom
Codex skills are generated with contradictory hook guidance: the shared note documents $ invocations while the hook blocks copied from command templates retain / literals. When the agent follows the generated To execute instruction, it can produce an invocation that is not valid for Codex; the expected output is $speckit-<hyphenated-command>.
Reproduction
In a project with the git extension, run specify integration install codex --script py.
Open .agents/skills/speckit-specify/SKILL.md.
Run $speckit-specify in Codex and inspect the generated hook report.
Observe hook guidance containing /speckit-git-commit where Codex requires $speckit-git-commit.
The report does not specify whether every Codex hook execution fails identically or whether the behavior varies by Codex version: [NEEDS CLARIFICATION: confirm the exact Codex error/result for each hook block].
Suspected Code Paths
src/specify_cli/_invocation_style.py:11-12,62-74 — declares Codex as a dollar-skills agent and returns $ as its skills invocation prefix.
src/specify_cli/integrations/base.py:40-42 — defines the shared injected example with a hard-coded slash prefix before the integration-specific replacement is applied.
src/specify_cli/integrations/base.py:1729-1784 — _inject_hook_command_note() only adapts the injected note's example, while post_process_skill_content() passes the Codex prefix into that note injection; it does not rewrite / literals already present in the skill body.
templates/commands/specify.md:37-49,251-268 — generated hook examples use literal /{command} in optional and mandatory hook blocks. The same pattern is present across the shared command templates, including templates/commands/plan.md and templates/commands/tasks.md.
extensions/bug/commands/speckit.bug.fix.md:58-72,156-172 — bundled extension command content repeats the literal slash-prefixed hook examples, demonstrating that extension-provided commands are affected too.
src/specify_cli/extensions/__init__.py:5663-5684,6155-6181 — runtime hook rendering already computes agent-native invocations and formats display_invocation, so the inconsistency is in generated skill prose rather than the runtime invocation resolver.
tests/integrations/test_integration_codex.py:89-101 — verifies that Codex receives the dot-to-hyphen note, but does not assert that hook blocks in the generated skill use $.
tests/test_extensions.py:8379-8398 — covers Codex runtime hook execution resolving to $speckit-tasks, which supports that the desired runtime prefix is already established.
Root Cause Hypothesis
Confidence: high. Codex's native prefix is correctly centralized and used by runtime hook rendering and by the injected dot-to-hyphen example. However, hook instructions are embedded as literal / text in shared and bundled command markdown. post_process_skill_content() does not transform those existing template lines, so generated Codex skills retain invalid slash-prefixed instructions even though the runtime path knows to use $.
Proposed Remediation
Preferred: Make hook invocation examples in generated skill content resolve through the same agent-native invocation mechanism as runtime hooks. The safest design is to introduce a dedicated invocation placeholder for hook command display text (or an equivalent structured token) and resolve it during skill generation using get_invocation_prefix() plus the existing dotted-to-hyphen command conversion. Apply this to all optional and mandatory hook display lines in shared command templates and bundled extension command templates, while leaving EXECUTE_COMMAND as the underlying dotted command identifier.
A narrower alternative is to update SkillsIntegration.post_process_skill_content() (or a shared helper it calls) to rewrite only hook-display forms such as `/{command}` and concrete slash-prefixed hook invocations in generated hook blocks when the integration prefix is not /. This should be constrained to the known hook block structure so ordinary slash-command documentation is not rewritten accidentally.
Files likely to change:
src/specify_cli/integrations/base.py
src/specify_cli/extensions/__init__.py (only if the shared hook formatter/placeholder resolution is extended there)
templates/commands/*.md
Bundled extension command files containing hook blocks, including extensions/bug/commands/speckit.bug.fix.md
tests/integrations/test_integration_codex.py
tests/test_extensions.py or a focused skills-generation test module
Tests to add or update:
Generate a Codex skill containing an optional hook and assert its Command and To execute lines use $speckit-..., not /speckit-....
Generate a Codex skill containing a mandatory hook and assert its Executing line uses $speckit-... while EXECUTE_COMMAND remains the dotted command id.
Cover a bundled extension command (for example the git hook content) so extension-generated skills cannot regress independently of core templates.
Preserve existing slash behavior for Claude/default slash integrations and /skill: behavior for Kimi.
Retain the existing runtime test that verifies Codex hook execution resolves to $speckit-tasks.
Risks & Considerations
A broad string replacement could alter legitimate prose or documentation; limit rewriting to structured hook blocks or use an explicit placeholder.
The transformation must preserve dotted-to-hyphen conversion and the distinction between display invocation and the underlying EXECUTE_COMMAND value.
All skill-generation routes (core, preset, and extension) need the same post-processing behavior; fixing only templates/commands/*.md would leave bundled extension commands inconsistent.
Existing generated projects will not be corrected until users reinstall/regenerate their skills; document or otherwise preserve the normal upgrade path if applicable.
No security or data-integrity impact is indicated; the primary impact is failed or confusing hook execution for Codex users.
Open Questions
[NEEDS CLARIFICATION: Which Codex release/version emits the quoted hook report and exact error behavior?]
[NEEDS CLARIFICATION: Should the fix update only generated skill output, or also revise static extension API/user documentation that intentionally demonstrates slash syntax for slash-based agents?]
Activity
github-actions commentedon Oct 14, 2026
Bug assessment — codex-hook-prefix: Valid · severity medium
Bug Assessment: Codex skills show slash-prefixed hook invocations
/speckit-…in hook "To execute" lines instead of$speckit-…#4954Report (summarized)
The reporter states that with specify-cli 1.2.0/main, the
codexskills integration, Python scripts, and thegitextension, generated.agents/skills/speckit-specify/SKILL.mdcontains a correct$speckit-git-commitexample in the dot-to-hyphen note but still emits hook instructions such asTo execute:/speckit-git-commit``. Codex treats the slash-prefixed form as invalid. No additional comments were present.Symptom
Codex skills are generated with contradictory hook guidance: the shared note documents
$invocations while the hook blocks copied from command templates retain/literals. When the agent follows the generatedTo executeinstruction, it can produce an invocation that is not valid for Codex; the expected output is$speckit-<hyphenated-command>.Reproduction
gitextension, runspecify integration install codex --script py..agents/skills/speckit-specify/SKILL.md.$speckit-specifyin Codex and inspect the generated hook report./speckit-git-commitwhere Codex requires$speckit-git-commit.The report does not specify whether every Codex hook execution fails identically or whether the behavior varies by Codex version: [NEEDS CLARIFICATION: confirm the exact Codex error/result for each hook block].
Suspected Code Paths
src/specify_cli/_invocation_style.py:11-12,62-74— declares Codex as a dollar-skills agent and returns$as its skills invocation prefix.src/specify_cli/integrations/base.py:40-42— defines the shared injected example with a hard-coded slash prefix before the integration-specific replacement is applied.src/specify_cli/integrations/base.py:1729-1784—_inject_hook_command_note()only adapts the injected note's example, whilepost_process_skill_content()passes the Codex prefix into that note injection; it does not rewrite/literals already present in the skill body.templates/commands/specify.md:37-49,251-268— generated hook examples use literal/{command}in optional and mandatory hook blocks. The same pattern is present across the shared command templates, includingtemplates/commands/plan.mdandtemplates/commands/tasks.md.extensions/bug/commands/speckit.bug.fix.md:58-72,156-172— bundled extension command content repeats the literal slash-prefixed hook examples, demonstrating that extension-provided commands are affected too.src/specify_cli/extensions/__init__.py:5663-5684,6155-6181— runtime hook rendering already computes agent-native invocations and formatsdisplay_invocation, so the inconsistency is in generated skill prose rather than the runtime invocation resolver.tests/integrations/test_integration_codex.py:89-101— verifies that Codex receives the dot-to-hyphen note, but does not assert that hook blocks in the generated skill use$.tests/test_extensions.py:8379-8398— covers Codex runtime hook execution resolving to$speckit-tasks, which supports that the desired runtime prefix is already established.Root Cause Hypothesis
Confidence: high. Codex's native prefix is correctly centralized and used by runtime hook rendering and by the injected dot-to-hyphen example. However, hook instructions are embedded as literal
/text in shared and bundled command markdown.post_process_skill_content()does not transform those existing template lines, so generated Codex skills retain invalid slash-prefixed instructions even though the runtime path knows to use$.Proposed Remediation
Preferred: Make hook invocation examples in generated skill content resolve through the same agent-native invocation mechanism as runtime hooks. The safest design is to introduce a dedicated invocation placeholder for hook command display text (or an equivalent structured token) and resolve it during skill generation using
get_invocation_prefix()plus the existing dotted-to-hyphen command conversion. Apply this to all optional and mandatory hook display lines in shared command templates and bundled extension command templates, while leavingEXECUTE_COMMANDas the underlying dotted command identifier.A narrower alternative is to update
SkillsIntegration.post_process_skill_content()(or a shared helper it calls) to rewrite only hook-display forms such as`/{command}`and concrete slash-prefixed hook invocations in generated hook blocks when the integration prefix is not/. This should be constrained to the known hook block structure so ordinary slash-command documentation is not rewritten accidentally.Files likely to change:
src/specify_cli/integrations/base.pysrc/specify_cli/extensions/__init__.py(only if the shared hook formatter/placeholder resolution is extended there)templates/commands/*.mdextensions/bug/commands/speckit.bug.fix.mdtests/integrations/test_integration_codex.pytests/test_extensions.pyor a focused skills-generation test moduleTests to add or update:
CommandandTo executelines use$speckit-..., not/speckit-....Executingline uses$speckit-...whileEXECUTE_COMMANDremains the dotted command id.githook content) so extension-generated skills cannot regress independently of core templates./skill:behavior for Kimi.$speckit-tasks.Risks & Considerations
EXECUTE_COMMANDvalue.templates/commands/*.mdwould leave bundled extension commands inconsistent.Open Questions