fix: extract preamble cleanup into bin scripts to avoid damage-control hook collision#1008
Open
wojtekszkutnik wants to merge 1 commit intogarrytan:mainfrom
Open
Conversation
…l hook collision The preamble's inline `rm -f` triggers claude-code-damage-control's regex (`rm\s+(-[rfR]+|--recursive|--force)\s.*(/|~|\$HOME)`), blocking every gstack skill on launch. Extract session cleanup and pending-telemetry finalization into standalone bin scripts — hooks scan command text, not script contents. Keeps POSIX `-exec rm` (not `-delete`) per prior compatibility decision.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The preamble bash block runs as a single Bash tool call at session start. Users of claude-code-damage-control — a popular PreToolUse hook — get every gstack skill blocked on launch.
The hook's regex
rm\s+(-[rfR]+|--recursive|--force)\s.*(/|~|\$HOME)scans the full command text and matches the inlinerm -f "$_PF" 2>/dev/null(the-fflag triggers the force group,/dev/nullprovides the/). The entire preamble is hard-blocked before any of it executes.We considered replacing
-exec rm {} +withfind -delete, but the project intentionally moved away from-deletebecause Safety Net and other non-GNU environments don't support it. Extracting into scripts preserves the POSIX-exec rmwhile hiding it from hook text scanning.This PR extracts two cleanup operations from the inline preamble into standalone bin scripts, following the same pattern as
gstack-update-checkand other existing bin utilities:bin/gstack-session-cleanup— removes stale session tracking files (>120 min). Keeps POSIX-exec rmfor compatibility.bin/gstack-pending-finalize— flushes and removes pending telemetry marker files. Preserves the existing zsh-safefindapproach.Hooks scan command text, not script contents. Moving
rmandfind -exec rminto scripts makes them invisible to the hook while keeping identical behavior.Note on the telemetry epilogue
The "Telemetry (run last)" bash block (
preamble.ts:493) also containsrm -f ~/.gstack/analytics/.pending-"$_SESSION_ID"which matches the same regex. We are not changing it here because: (1) the epilogue runs as a separate Bash tool call after the skill completes, so impact is lower, and (2) the.pending-*marker creation is not yet implemented in the codebase — this line is currently a no-op that appears to be infrastructure for a future feature. We don't want to remove or relocate code whose design intent we don't fully understand.What changed
scripts/resolvers/preamble.ts— replaced 12 lines of inline cleanup with two script callsbin/gstack-session-cleanup— new (15 lines)bin/gstack-pending-finalize— new (30 lines)test/gen-skill-docs.test.ts— updated two assertions for new script names--host all), 4 golden fixtures re-syncedTest plan
bun test— 654 pass, 1 pre-existing fail (package.json version mismatch)