fix(#172): eliminate shell() calls in audit-workspace and session-handoff#204
fix(#172): eliminate shell() calls in audit-workspace and session-handoff#204TerminalGravity wants to merge 3 commits intomainfrom
Conversation
run() uses execFileSync (no shell), so pipes, redirects, and non-git commands were silently broken. Fixed all 8 remaining tools: - verify-completion: use readFileSync for package.json, shell() for tsc/tests/build - token-audit: use readFileSync/statSync for line counting and file sizes, openSync/readSync for tail-reading large files - session-handoff: use shell() for command -v and gh pr list - audit-workspace: use array args for git commands, shell() for find|wc - sharpen-followup: use array args for git diff/status - scope-work: use array args, do grep/filter in JS - enrich-agent-task: use array args, readFileSync, JS filtering - sequence-tasks: use array args, slice in JS Added shell() helper to lib/git.ts for commands that genuinely need shell interpretation (non-git CLIs with pipes/redirects).
Fixes remaining broken run() calls in 4 tools: - clarify-intent: use shell() for pnpm/find commands with pipes - session-health: use array args + JS .pop() instead of pipe to tail - what-changed: use array args with JS fallback instead of || operator - checkpoint: use array args for add/commit/reset instead of string interpolation Part of #172
…ession-handoff
- audit-workspace: replace shell('find ...') with recursive fs.readdirSync
- session-handoff: replace shell('command -v') with execFileSync('which')
- session-handoff: replace shell('gh pr list ...') with execFileSync('gh', [...])
- Remove shell import from audit-workspace (no longer needed)
- All changes eliminate shell interpretation for safer, cross-platform execution
TerminalGravity
left a comment
There was a problem hiding this comment.
Good progress on #172, but I have a concern about the approach:
The new shell() helper is a step backward. The whole point of #172 is to eliminate shell interpretation risks. Adding execSync(cmd) as a convenience function just moves the problem — now clarify-intent.ts calls shell("pnpm tsc --noEmit 2>&1 | grep -c 'error TS' || echo '0'") which has the same injection surface we're trying to close.
Instead of shell(), these should use proper Node APIs:
find tests -name '*.spec.ts'→ you already did this right withcountTestFiles()usingreaddirSync— do the same in clarify-intentpnpm tsc --noEmit | grep -c 'error TS'→execFileSync('pnpm', ['tsc', '--noEmit'])then count matches in JS
Also, this PR mixes two concerns — the shell fixes AND the examples directory. Split the examples into #201 and keep this focused on the #172 fix.
The actual run() → array conversion in audit-workspace, checkpoint, session-handoff looks solid 👍. Just need to remove the shell() escape hatch and this is ready.
|
Closing — fix already landed on main via 3b855be |
Closes the remaining items from #172 for audit-workspace and session-handoff.
Changes
shell('find tests ...')with recursivereaddirSync— pure Node.js, no shell neededshell('command -v ...')withexecFileSync('which', [cmd])— no shell injection surfaceshell('gh pr list ...')withexecFileSync('gh', [...])— proper arg arrayAll tests pass. Build clean.