Skip to content

[Bug]: Codex skills show /speckit-… in hook "To execute" lines instead of $speckit-… #4954

Open

Description

@codegeek

Summary

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

  1. specify integration install codex --script py in a project with the git extension.
  2. Open .agents/skills/speckit-specify/SKILL.md.
  3. 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.

Activity

  1. github-actions commented on Oct 14, 2026

    @github-actions
    Contributor

    Bug assessment — codex-hook-prefix: Valid · severity medium


    Bug Assessment: Codex skills show slash-prefixed hook invocations

    Report (summarized)

    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

    1. In a project with the git extension, run specify integration install codex --script py.
    2. Open .agents/skills/speckit-specify/SKILL.md.
    3. Run $speckit-specify in Codex and inspect the generated hook report.
    4. 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?]

    Generated by 🐛 Assess Bug from Labeled Issue for #4954 · copilot · gpt52codex · 2.83 AIC · ⌖ 0.658 AIC · ⊞ 22.2K · ◷

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions