Skip to content

fix(#172): eliminate shell() calls in audit-workspace and session-handoff#204

Closed
TerminalGravity wants to merge 3 commits intomainfrom
fix/172-shell-cleanup-remaining
Closed

fix(#172): eliminate shell() calls in audit-workspace and session-handoff#204
TerminalGravity wants to merge 3 commits intomainfrom
fix/172-shell-cleanup-remaining

Conversation

@TerminalGravity
Copy link
Collaborator

Closes the remaining items from #172 for audit-workspace and session-handoff.

Changes

  • audit-workspace: Replace shell('find tests ...') with recursive readdirSync — pure Node.js, no shell needed
  • session-handoff: Replace shell('command -v ...') with execFileSync('which', [cmd]) — no shell injection surface
  • session-handoff: Replace shell('gh pr list ...') with execFileSync('gh', [...]) — proper arg array

All tests pass. Build clean.

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
Copy link
Collaborator Author

@TerminalGravity TerminalGravity left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 with countTestFiles() using readdirSync — do the same in clarify-intent
  • pnpm 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.

@TerminalGravity
Copy link
Collaborator Author

Closing — fix already landed on main via 3b855be

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant