Bug Description
Component: Skill — ce-compound
Summary: Invoking /ce-compound from inside a git repo fails immediately because the pre-resolved "Repo name" command pipes git rev-parse into sed. Claude Code's permission system treats piped commands as multiple operations and refuses to auto-approve, so the substitution never runs and the skill aborts before Phase 1.
This is not the same issue as #730 (which was about being outside a git repo / missing || true). I'm in a normal git worktree with broad git permissions allowlisted; the failure is the multi-op check, not exit-code handling.
Environment
- Plugin Version: compound-engineering 3.3.2 (from every-marketplace)
- Agent Platform: Claude Code
- OS: Darwin 24.6.0 (macOS, arm64)
- Working dir: inside a git worktree (
git rev-parse would succeed)
What Happened
Error: Shell command permission check failed for pattern
"!`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`":
This Bash command contains multiple operations. The following parts require approval:
git rev-parse --path-format=absolute --git-common-dir
sed -E 's|/\.git/?$||; s|.*/||'
Skill never executes. The other pre-resolved line (git rev-parse --abbrev-ref HEAD) works fine — it's the | sed chain that trips the check.
Root Cause
plugins/compound-engineering/skills/ce-compound/SKILL.md (around line 25):
**Repo name (pre-resolved):** !`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`
Claude Code's bash permission layer splits piped commands and requires each segment to be individually allowlisted. Even with Bash(git rev-parse:*) permitted, the sed segment isn't, so the whole !...`` substitution is blocked rather than executed.
Suggested Fixes
Pick whichever fits the skill's defensive style; any of these avoids the pipe:
Option A — let git produce the basename directly (no second tool):
-**Repo name (pre-resolved):** !`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`
+**Repo name (pre-resolved):** !`basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo '__REPO_UNRESOLVED__'`
(Still two commands, but basename is usually allowlisted; if not, swap for option B.)
Option B — emit the toplevel path and let the agent take the basename:
-**Repo name (pre-resolved):** !`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`
+**Repo toplevel (pre-resolved):** !`git rev-parse --show-toplevel 2>/dev/null || echo '__REPO_UNRESOLVED__'`
Then update the "If the lines above resolved..." instruction to tell the dispatcher to take the basename of the path.
Option C — bundle into a single shell invocation (still one command from the permission system's perspective if wrapped):
-**Repo name (pre-resolved):** !`git rev-parse --path-format=absolute --git-common-dir 2>/dev/null | sed -E 's|/\.git/?$||; s|.*/||'`
+**Repo name (pre-resolved):** !`sh -c 'd=$(git rev-parse --show-toplevel 2>/dev/null) && printf "%s" "${d##*/}"' 2>/dev/null || echo '__REPO_UNRESOLVED__'`
(Permission-fragile — depends on whether sh -c is allowlisted in a given environment.)
I'd recommend B — it's the simplest, matches the existing __*_UNRESOLVED__ sentinel pattern used in ce-commit/ce-commit-push-pr, and shifts the trivial string manipulation to the agent where it belongs.
Repro
- Open Claude Code in any git worktree.
- Run
/ce-compound.
- Observe
Shell command permission check failed ... contains multiple operations before any phase begins.
Additional Context
The companion line right below (git rev-parse --abbrev-ref HEAD) does not use a pipe and works correctly, which confirms the trigger is the | sed chain, not git itself.
Bug Description
Component: Skill —
ce-compoundSummary: Invoking
/ce-compoundfrom inside a git repo fails immediately because the pre-resolved "Repo name" command pipesgit rev-parseintosed. Claude Code's permission system treats piped commands as multiple operations and refuses to auto-approve, so the substitution never runs and the skill aborts before Phase 1.This is not the same issue as #730 (which was about being outside a git repo / missing
|| true). I'm in a normal git worktree with broad git permissions allowlisted; the failure is the multi-op check, not exit-code handling.Environment
git rev-parsewould succeed)What Happened
Skill never executes. The other pre-resolved line (
git rev-parse --abbrev-ref HEAD) works fine — it's the| sedchain that trips the check.Root Cause
plugins/compound-engineering/skills/ce-compound/SKILL.md(around line 25):Claude Code's bash permission layer splits piped commands and requires each segment to be individually allowlisted. Even with
Bash(git rev-parse:*)permitted, thesedsegment isn't, so the whole!...`` substitution is blocked rather than executed.Suggested Fixes
Pick whichever fits the skill's defensive style; any of these avoids the pipe:
Option A — let git produce the basename directly (no second tool):
(Still two commands, but
basenameis usually allowlisted; if not, swap for option B.)Option B — emit the toplevel path and let the agent take the basename:
Then update the "If the lines above resolved..." instruction to tell the dispatcher to take the basename of the path.
Option C — bundle into a single shell invocation (still one command from the permission system's perspective if wrapped):
(Permission-fragile — depends on whether
sh -cis allowlisted in a given environment.)I'd recommend B — it's the simplest, matches the existing
__*_UNRESOLVED__sentinel pattern used ince-commit/ce-commit-push-pr, and shifts the trivial string manipulation to the agent where it belongs.Repro
/ce-compound.Shell command permission check failed ... contains multiple operationsbefore any phase begins.Additional Context
The companion line right below (
git rev-parse --abbrev-ref HEAD) does not use a pipe and works correctly, which confirms the trigger is the| sedchain, not git itself.