Problem
Extension commands that invoke helper scripts need a reliable absolute path to those scripts at runtime. The project-relative paths that rewrite_project_relative_paths() produces (e.g., .specify/extensions/spex/scripts/foo.sh) only work when the agent's working directory is the project root. In practice, CWD shifts during a session and the relative paths break.
The most common scenario where this happens is git worktrees. When an agent creates a worktree for isolated feature development, the working directory changes to the worktree root, which is a different filesystem location from the main repo. Subagent spawning can also reset CWD, as can explicit cd commands in multi-step workflows. Any of these cause a relative script path to resolve against the wrong directory.
What we're doing today
In our extension (cc-spex), we currently work around this by using the Claude Code plugin system. Our scripts live in the plugin cache directory (~/.claude/plugins/cache/spex-plugin/spex/5.8.0/scripts/), and a context hook injects the absolute plugin root path into every prompt. Commands reference scripts as <PLUGIN_ROOT>/scripts/foo.sh, which always resolves correctly regardless of CWD.
This works, but it's entirely Claude Code-specific. The plugin cache, the context hook, the <plugin-root> injection are all Claude Code infrastructure. None of it exists on other agents, so the approach doesn't generalize.
The git rev-parse workaround
The agent-agnostic fallback is:
REPO_ROOT=$(git rev-parse --show-toplevel)
"$REPO_ROOT/.specify/extensions/spex/scripts/foo.sh"
This works from any CWD within the repo, including worktrees (--show-toplevel returns the worktree root, not the main repo root). But it requires a git invocation every time a command references a script, and it assumes the project is a git repository.
Proposal
A __PROJECT_ROOT__ template variable, resolved at install time to the absolute project path, would solve this cleanly. It fits the existing pattern of __AGENT__ and __SPECKIT_COMMAND_*__ substitutions in the template pipeline, and it would give extension authors a reliable way to reference their own scripts from any working directory.
Commands would reference scripts as:
__PROJECT_ROOT__/.specify/extensions/spex/scripts/foo.sh
This stays materialized (the absolute path is baked into the installed command file), project-local, and agent-agnostic.
One tradeoff: the resolved path becomes stale if the project directory moves. But that's the same tradeoff __AGENT__ already makes (agent name is baked in at install time), and specify init --refresh would re-resolve it.
Related: #3303 (extension portability discussion, where the maintainer suggested using extension-local paths for script discovery).
Problem
Extension commands that invoke helper scripts need a reliable absolute path to those scripts at runtime. The project-relative paths that
rewrite_project_relative_paths()produces (e.g.,.specify/extensions/spex/scripts/foo.sh) only work when the agent's working directory is the project root. In practice, CWD shifts during a session and the relative paths break.The most common scenario where this happens is git worktrees. When an agent creates a worktree for isolated feature development, the working directory changes to the worktree root, which is a different filesystem location from the main repo. Subagent spawning can also reset CWD, as can explicit
cdcommands in multi-step workflows. Any of these cause a relative script path to resolve against the wrong directory.What we're doing today
In our extension (cc-spex), we currently work around this by using the Claude Code plugin system. Our scripts live in the plugin cache directory (
~/.claude/plugins/cache/spex-plugin/spex/5.8.0/scripts/), and a context hook injects the absolute plugin root path into every prompt. Commands reference scripts as<PLUGIN_ROOT>/scripts/foo.sh, which always resolves correctly regardless of CWD.This works, but it's entirely Claude Code-specific. The plugin cache, the context hook, the
<plugin-root>injection are all Claude Code infrastructure. None of it exists on other agents, so the approach doesn't generalize.The
git rev-parseworkaroundThe agent-agnostic fallback is:
This works from any CWD within the repo, including worktrees (
--show-toplevelreturns the worktree root, not the main repo root). But it requires a git invocation every time a command references a script, and it assumes the project is a git repository.Proposal
A
__PROJECT_ROOT__template variable, resolved at install time to the absolute project path, would solve this cleanly. It fits the existing pattern of__AGENT__and__SPECKIT_COMMAND_*__substitutions in the template pipeline, and it would give extension authors a reliable way to reference their own scripts from any working directory.Commands would reference scripts as:
This stays materialized (the absolute path is baked into the installed command file), project-local, and agent-agnostic.
One tradeoff: the resolved path becomes stale if the project directory moves. But that's the same tradeoff
__AGENT__already makes (agent name is baked in at install time), andspecify init --refreshwould re-resolve it.Related: #3303 (extension portability discussion, where the maintainer suggested using extension-local paths for script discovery).