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
Skill instructions tell agents to invoke helper scripts as bare commands (e.g., Run `resolve-frontmatter.sh --skill orchestrate --interactive false` via Bash), but the scripts are installed under ~/.claude/scripts/ (or ~/.codex/scripts/, etc.) and that directory is not on PATH. Only the launcher set (check-project-staleness.sh, claude.sh, rovo.sh) is symlinked into /usr/local/bin by scripts/install-launchers.sh.
When an agent shells out, the bare command does not resolve. The agent then guesses a path. The _data/ subtree under skills/ is a plausible-but-wrong guess because it does hold shared skill artifacts (artifact-conventions.md, pr-resolution.md, etc.), so the model conflates "shared skill data" with "skill-adjacent scripts." Each wasted attempt costs at least one tool round trip plus permission overhead.
Observed example (orchestrate-dev run):
Bash(/Users/william/.claude/skills/_data/resolve-frontmatter.sh --skill orchestrate --interactive false)
Error: Exit code 127 — no such file or directory
Bash(/Users/william/.claude/scripts/resolve-frontmatter.sh --skill orchestrate --interactive false)
---
provenance:
skill: orchestrate
...
Context
Affected scripts: resolve-frontmatter.sh, describe-change.sh, get-ticket-id.sh, resolve-merge-options.sh, resolve-reviewer-context.sh (everything in packages/agents/content/scripts/ that ends up at ~/{platform_home}/scripts/).
25 sites across skill and subagent files invoke these scripts as bare commands. Sample sites: packages/agents/content/skills/orchestrate/SKILL.md:718, packages/agents/content/subagents/orchestrated-architect.md:118, and the rest under packages/agents/content/skills/**/SKILL.md and packages/agents/content/subagents/*.md.
One additional site, packages/agents/content/skills/orchestrate/modules/review-cycle.md:62, invokes resolve-reviewer-context.sh via {repo-root}/packages/agents/content/scripts/... rather than as a bare command. This invocation is broken in the same way (it assumes the user's working repo is the codeassembly repo) and is included in scope.
packages/agents/src/lib/path-rewriter.ts already supports a {platform_home_dir} template variable that the install pipeline expands to ~/.claude (or ~/.codex, ~/.opencode, etc.) per target platform.
Skill content already uses {platform_home_dir} for cross-platform Markdown link targets; bare-command script invocations bypass it.
Considerations
Alternatives considered:
Symlink ~/.claude/scripts/*.sh into /usr/local/bin from install-launchers.sh. Rejected: pollutes a global bin directory with names that could collide with user scripts, and only helps after the launcher install has run.
Leave as-is. Rejected: drift is observable in every orchestrated run.
Cross-platform: the template var already expands per platform, so the change works for .claude, .codex, .opencode, etc., without further changes.
Backward compatibility: rewriting bare invocations is purely additive. The resulting command is an absolute path that resolves whether or not the script is also on PATH.
Out of scope: changing how scripts are installed or distributed; rewriting pure-prose mentions of script names (these are not executed and do not need a prefix).
Proposed solution
Rewrite bare-command script invocations in skill and subagent content to use the existing {platform_home_dir} template variable, so the install-time path rewriter produces an explicit, platform-correct absolute path:
Before:
Run `resolve-frontmatter.sh --skill orchestrate --interactive false` via Bash.
After:
Run `{platform_home_dir}/scripts/resolve-frontmatter.sh --skill orchestrate --interactive false` via Bash.
At install time this becomes Run ~/.claude/scripts/resolve-frontmatter.sh ... on the Claude target, ~/.codex/scripts/... on the Codex target, and so on.
Apply the same treatment to every bare-command invocation of the affected scripts across packages/agents/content/skills/**/*.md and packages/agents/content/subagents/*.md.
For the one related site in packages/agents/content/skills/orchestrate/modules/review-cycle.md:62, replace {repo-root}/packages/agents/content/scripts/resolve-reviewer-context.sh with {platform_home_dir}/scripts/resolve-reviewer-context.sh so it resolves to the installed location instead of the user's working repository.
Add a regression test to catch future drift. The test walks packages/agents/content/skills/**/*.md and packages/agents/content/subagents/*.md and, for each known helper script name, scans for occurrences immediately followed by CLI-argument syntax ( --, \, "$@", etc.). Any such occurrence not immediately preceded by {platform_home_dir}/scripts/ is reported as a violation with the offending file:line.
Add a short packages/agents/content/scripts/README.md documenting the convention for maintainers (this file is not loaded by agents, so it does not impose token cost on agent invocations).
Acceptance criteria
Must have
Every bare-command invocation of resolve-frontmatter.sh, describe-change.sh, get-ticket-id.sh, resolve-merge-options.sh, and resolve-reviewer-context.sh in packages/agents/content/skills/**/*.md and packages/agents/content/subagents/*.md is prefixed with {platform_home_dir}/scripts/.
The {repo-root}/packages/agents/content/scripts/resolve-reviewer-context.sh invocation in packages/agents/content/skills/orchestrate/modules/review-cycle.md:62 is replaced with {platform_home_dir}/scripts/resolve-reviewer-context.sh.
After running the install pipeline, the rendered skill/subagent files under ~/.claude/skills/ and ~/.claude/agents/ contain explicit absolute paths (e.g., ~/.claude/scripts/resolve-frontmatter.sh ...) at every previously-bare invocation site.
The same rendering works for at least one non-Claude platform target (e.g., ~/.codex/scripts/... on a Codex install) without manual fixup.
A regression test at packages/agents/src/__tests__/script-invocation-conventions.test.ts walks the skill and subagent trees, detects bare-command invocations of any known helper script, and fails listing each offending file:line.
All existing tests pass, including packages/agents/src/lib/__tests__/path-rewriter.test.ts.
Should have
A short packages/agents/content/scripts/README.md documents the {platform_home_dir}/scripts/ invocation convention, the list of helper scripts it applies to, and a pointer to the regression test that enforces it.
Nice to have
(No additional work identified. The audit during design confirmed the five scripts in packages/agents/content/scripts/ are the complete set of helper scripts referenced as bare commands.)
Description
Skill instructions tell agents to invoke helper scripts as bare commands (e.g.,
Run `resolve-frontmatter.sh --skill orchestrate --interactive false` via Bash), but the scripts are installed under~/.claude/scripts/(or~/.codex/scripts/, etc.) and that directory is not onPATH. Only the launcher set (check-project-staleness.sh,claude.sh,rovo.sh) is symlinked into/usr/local/binbyscripts/install-launchers.sh.When an agent shells out, the bare command does not resolve. The agent then guesses a path. The
_data/subtree underskills/is a plausible-but-wrong guess because it does hold shared skill artifacts (artifact-conventions.md,pr-resolution.md, etc.), so the model conflates "shared skill data" with "skill-adjacent scripts." Each wasted attempt costs at least one tool round trip plus permission overhead.Observed example (orchestrate-dev run):
Context
resolve-frontmatter.sh,describe-change.sh,get-ticket-id.sh,resolve-merge-options.sh,resolve-reviewer-context.sh(everything inpackages/agents/content/scripts/that ends up at~/{platform_home}/scripts/).packages/agents/content/skills/orchestrate/SKILL.md:718,packages/agents/content/subagents/orchestrated-architect.md:118, and the rest underpackages/agents/content/skills/**/SKILL.mdandpackages/agents/content/subagents/*.md.packages/agents/content/skills/orchestrate/modules/review-cycle.md:62, invokesresolve-reviewer-context.shvia{repo-root}/packages/agents/content/scripts/...rather than as a bare command. This invocation is broken in the same way (it assumes the user's working repo is the codeassembly repo) and is included in scope.packages/agents/src/lib/path-rewriter.tsalready supports a{platform_home_dir}template variable that the install pipeline expands to~/.claude(or~/.codex,~/.opencode, etc.) per target platform.{platform_home_dir}for cross-platform Markdown link targets; bare-command script invocations bypass it.Considerations
~/.claude/scripts/*.shinto/usr/local/binfrominstall-launchers.sh. Rejected: pollutes a global bin directory with names that could collide with user scripts, and only helps after the launcher install has run..claude,.codex,.opencode, etc., without further changes.PATH.Proposed solution
Rewrite bare-command script invocations in skill and subagent content to use the existing
{platform_home_dir}template variable, so the install-time path rewriter produces an explicit, platform-correct absolute path:Before:
After:
At install time this becomes
Run ~/.claude/scripts/resolve-frontmatter.sh ...on the Claude target,~/.codex/scripts/...on the Codex target, and so on.Apply the same treatment to every bare-command invocation of the affected scripts across
packages/agents/content/skills/**/*.mdandpackages/agents/content/subagents/*.md.For the one related site in
packages/agents/content/skills/orchestrate/modules/review-cycle.md:62, replace{repo-root}/packages/agents/content/scripts/resolve-reviewer-context.shwith{platform_home_dir}/scripts/resolve-reviewer-context.shso it resolves to the installed location instead of the user's working repository.Add a regression test to catch future drift. The test walks
packages/agents/content/skills/**/*.mdandpackages/agents/content/subagents/*.mdand, for each known helper script name, scans for occurrences immediately followed by CLI-argument syntax (--,\,"$@", etc.). Any such occurrence not immediately preceded by{platform_home_dir}/scripts/is reported as a violation with the offendingfile:line.Add a short
packages/agents/content/scripts/README.mddocumenting the convention for maintainers (this file is not loaded by agents, so it does not impose token cost on agent invocations).Acceptance criteria
Must have
resolve-frontmatter.sh,describe-change.sh,get-ticket-id.sh,resolve-merge-options.sh, andresolve-reviewer-context.shinpackages/agents/content/skills/**/*.mdandpackages/agents/content/subagents/*.mdis prefixed with{platform_home_dir}/scripts/.{repo-root}/packages/agents/content/scripts/resolve-reviewer-context.shinvocation inpackages/agents/content/skills/orchestrate/modules/review-cycle.md:62is replaced with{platform_home_dir}/scripts/resolve-reviewer-context.sh.~/.claude/skills/and~/.claude/agents/contain explicit absolute paths (e.g.,~/.claude/scripts/resolve-frontmatter.sh ...) at every previously-bare invocation site.~/.codex/scripts/...on a Codex install) without manual fixup.packages/agents/src/__tests__/script-invocation-conventions.test.tswalks the skill and subagent trees, detects bare-command invocations of any known helper script, and fails listing each offendingfile:line.packages/agents/src/lib/__tests__/path-rewriter.test.ts.Should have
packages/agents/content/scripts/README.mddocuments the{platform_home_dir}/scripts/invocation convention, the list of helper scripts it applies to, and a pointer to the regression test that enforces it.Nice to have
(No additional work identified. The audit during design confirmed the five scripts in
packages/agents/content/scripts/are the complete set of helper scripts referenced as bare commands.)