From 864342726c5e01546fcd83557833e60f34d41667 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Sat, 25 Apr 2026 08:44:01 -0700 Subject: [PATCH] Fix Claude diff temp file handling --- CHANGELOG.md | 1 + claude/SKILL.md.tmpl | 11 ++++++----- test/gen-skill-docs.test.ts | 2 ++ 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d54e9830..f201dfaf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ This release adds the reverse of `/codex`: external hosts can now ask Claude for - `hosts/claude.ts`: excludes the Claude outside-voice skill from Claude-host generation. - `test/brain-sync.test.ts`: the `GSTACK_HOME` isolation test now snapshots and preserves the real config file instead of assuming local machine state. - `model-overlays/opus-4-7.md`: restores the fanout nudge expected by the Opus overlay regression test. +- `claude/SKILL.md.tmpl`: uses `mktemp` for diff capture in review/challenge mode instead of a `$$`-based temp path, avoiding collisions across concurrent invocations. ### Changed diff --git a/claude/SKILL.md.tmpl b/claude/SKILL.md.tmpl index 3944807d..94552cbe 100644 --- a/claude/SKILL.md.tmpl +++ b/claude/SKILL.md.tmpl @@ -151,8 +151,9 @@ Review the current branch diff with nested Claude in tool-less mode. ```bash _REPO_ROOT=$(git rev-parse --show-toplevel) || { echo "ERROR: not in a git repo" >&2; exit 1; } cd "$_REPO_ROOT" +DIFF_FILE=$(mktemp /tmp/gstack-claude-diff-XXXXXX.patch) git fetch origin --quiet 2>/dev/null || true -git diff "origin/" > /tmp/gstack-claude-diff-$$.patch 2>/dev/null || git diff "" > /tmp/gstack-claude-diff-$$.patch +git diff "origin/" > "$DIFF_FILE" 2>/dev/null || git diff "" > "$DIFF_FILE" ``` If the diff file is empty, stop and say: @@ -171,7 +172,7 @@ Additional user instructions, if any: DIFF: EOF -cat /tmp/gstack-claude-diff-$$.patch >> "$PROMPT_FILE" +cat "$DIFF_FILE" >> "$PROMPT_FILE" ``` 3. Run Claude: @@ -192,7 +193,7 @@ CLAUDE SAYS (code review): 5. Cleanup: ```bash -rm -f /tmp/gstack-claude-diff-$$.patch "$PROMPT_FILE" "$RESP_FILE" "$ERR_FILE" +rm -f "$DIFF_FILE" "$PROMPT_FILE" "$RESP_FILE" "$ERR_FILE" ``` --- @@ -217,7 +218,7 @@ Focus area, if any: DIFF: EOF -cat /tmp/gstack-claude-diff-$$.patch >> "$PROMPT_FILE" +cat "$DIFF_FILE" >> "$PROMPT_FILE" ``` 3. Run Claude: @@ -238,7 +239,7 @@ CLAUDE SAYS (adversarial challenge): 5. Cleanup: ```bash -rm -f /tmp/gstack-claude-diff-$$.patch "$PROMPT_FILE" "$RESP_FILE" "$ERR_FILE" +rm -f "$DIFF_FILE" "$PROMPT_FILE" "$RESP_FILE" "$ERR_FILE" ``` --- diff --git a/test/gen-skill-docs.test.ts b/test/gen-skill-docs.test.ts index f6c541cc..726a5115 100644 --- a/test/gen-skill-docs.test.ts +++ b/test/gen-skill-docs.test.ts @@ -1615,6 +1615,8 @@ describe('Codex generation (--host codex)', () => { const content = fs.readFileSync(path.join(AGENTS_DIR, 'gstack-claude', 'SKILL.md'), 'utf-8'); expect(content).toContain('claude -p'); expect(content).toContain('mktemp /tmp/gstack-claude-prompt-'); + expect(content).toContain('mktemp /tmp/gstack-claude-diff-'); + expect(content).not.toContain('/tmp/gstack-claude-diff-$$'); expect(content).toContain('cat "$PROMPT_FILE" | claude -p'); expect(content).toContain('--disable-slash-commands'); expect(content).toContain('--tools ""');