Skip to content

[Bug]: Extension materialization rewrites extension-local script paths to .specify/scripts/, breaking installed extensions #3358

Description

@rolland97

Bug Description

When an extension is installed, its command files are materialized into agent skills. During materialization, CommandRegistrar.rewrite_project_relative_paths() (called via _adjust_script_paths()) rewrites every project-relative scripts/ reference to .specify/scripts/:

# src/specify_cli/agents.py:190
text = re.sub(r'(^|[\s`"\'(])(?:\.?/)?scripts/', r"\1.specify/scripts/", text)

But extension helper scripts are installed under .specify/extensions/<extension_id>/scripts/, not .specify/scripts/. The extension's own command sources use paths like scripts/bash/resolve-skill.sh, which are correct relative to the extension root — the rewrite converts them into references to a directory that does not exist.

Result: every installed extension whose commands invoke helper scripts fails at first hook execution with e.g.:

bash: .specify/scripts/bash/resolve-skill.sh: No such file or directory

Observed with the Superpowers Bridge extension (specify extension add superb), whose materialized skills reference resolve-skill.sh / ensure-skills.sh at the wrong location. This affects any catalog extension that ships scripts.

Steps to Reproduce

  1. specify init a project (spec-kit v0.12.4, Claude Code agent)
  2. specify extension add superb
  3. Inspect a materialized skill, e.g. .claude/skills/speckit-superb-check/SKILL.md — script references point at .specify/scripts/bash/…
  4. ls .specify/scripts/bash/ → scripts are absent (they live in .specify/extensions/superb/scripts/bash/)
  5. Run any speckit command that fires a bridge hook → No such file or directory

Expected Behavior

Script references in materialized extension commands resolve to the extension's own scripts directory: .specify/extensions/<extension_id>/scripts/…

Actual Behavior

References are rewritten to .specify/scripts/…, which only contains spec-kit core scripts (create-new-feature.sh, check-prerequisites.sh, …), never extension scripts.

Environment

  • Specify CLI: v0.12.4
  • OS: Linux (WSL2)
  • Agent: Claude Code
  • Extension: Superpowers Bridge v1.8.0 (also reproducible with current catalog version)

Additional Context

  • Root-cause analysis by the extension maintainer: Wrong script pathts? RbBtSn0w/spec-kit-extensions#16 (closed there as unfixable in the extension repo — the rewrite happens in spec-kit core; the issue was to be flagged upstream, but I could not find a corresponding spec-kit issue, hence this report).
  • Suggested fix from that analysis: pass an extension_id through _adjust_script_paths() / rewrite_project_relative_paths() and resolve scripts/ to .specify/extensions/{extension_id}/scripts/ when materializing extension commands (extension materialization lives in src/specify_cli/extensions/__init__.py); keep the current .specify/scripts/ rewrite for core commands only.
  • Related but distinct: Extension scripts need an absolute project root for reliable path resolution #3308 proposes an absolute __PROJECT_ROOT__ for CWD-independence. This report is about the rewrite targeting the wrong directory even when CWD is the project root.
  • Workaround we use today: commit symlinks in .specify/scripts/bash/ pointing into .specify/extensions/superb/scripts/bash/.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions