fix: prevent shell injection and broken commands in run() callers#289
Open
TerminalGravity wants to merge 5 commits intomainfrom
Open
fix: prevent shell injection and broken commands in run() callers#289TerminalGravity wants to merge 5 commits intomainfrom
TerminalGravity wants to merge 5 commits intomainfrom
Conversation
Adds a ready-to-use CLAUDE.md template that makes Claude Code automatically run preflight_check on prompts. Users can copy it into their project to get preflight working without manual tool calls. Referenced from Quick Start in README and examples/README.
- CLI now responds to --help/-h with usage info, profiles, and links - CLI now responds to --version/-v with package version - Previously, any flag just launched the interactive wizard - Fixed README badge from Node 18+ to Node 20+ (matches engines field)
Adds a new 'export_timeline' MCP tool that generates markdown reports from timeline data with: - Summary stats table (events by type, correction rate, commits/prompt) - ASCII activity chart grouped by day - Recent commits log - Correction insights - Error summary - Configurable period (day/week/month) with offset - Optional save to ~/.preflight/reports/ Includes tests (2 passing). Closes #5
Adds 10 tests covering: - Trivial prompt pass-through - force_level=skip bypass - Ambiguous prompt detection (vague pronouns, short prompts, vague verbs) - Multi-step execution plan generation - Git state inclusion in clarification - Triage confidence/reasons display - Pattern match triage boosting - Risk level assignment in execution plans Brings test count from 45 to 55.
Several tools were passing shell syntax (pipes, redirects, || chains) and non-git commands (cat, find, pnpm, gh) to run(), which uses execFileSync without a shell. This caused silent failures: - Shell redirections (2>/dev/null) passed as literal git args - Pipe chains (| grep, | tail) passed as literal git args - 'git' prefix doubled (run already prepends 'git') - Non-git commands (find, gh, pnpm) routed through git execFileSync Fix: - Add shell() helper using execSync for commands needing shell features - Harden run() string parsing to strip leading 'git' and shell syntax - Migrate 10 call sites across 8 tools to use shell() or proper arrays - Add 13 tests covering run() cleanup and shell() behavior Affected tools: audit-workspace, clarify-intent, enrich-agent-task, sequence-tasks, session-handoff, session-health, verify-completion
TerminalGravity
commented
Mar 19, 2026
Collaborator
Author
TerminalGravity
left a comment
There was a problem hiding this comment.
Solid fix. The shell() function with execSync is the right escape hatch for callers that genuinely need pipes/redirects, while run() stays injection-safe with execFileSync. Tests cover the important edge cases. One thought: might want to add a comment on shell() noting it should only be used for trusted command strings (never user input).
TerminalGravity
commented
Mar 20, 2026
Collaborator
Author
TerminalGravity
left a comment
There was a problem hiding this comment.
Solid fix. The shell() utility is the right call — execFileSync cannot handle pipes or redirects, and callers were passing shell syntax that would break silently. The regex stripping in run() is good backward-compat. LGTM, ready to merge.
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.
Problem
Several tools were passing shell syntax to
run(), which usesexecFileSync(no shell). This caused silent failures in production:2>/dev/null) passed as literal git args → git errors| grep,| tail) passed as literal git args → wrong outputgitprefix doubled (run("git diff ...")→execFileSync("git", ["git", "diff", ...]))find,gh,pnpm) routed throughexecFileSync("git", ...)Fix
shell()helper — new export fromgit.tsusingexecSyncfor commands that need shell features (pipes, redirects, non-git commands)run()hardened — string parsing now strips leadinggit, removes2>/dev/null, strips pipe/fallback chainsshell()or proper array syntaxrun()cleanup logic andshell()behaviorAffected tools
audit-workspace, clarify-intent, enrich-agent-task, sequence-tasks, session-handoff, session-health, verify-completion
Tests
68 passing (was 55) — all green.