From b804abf1636c68d4051870a7ec30b7827ab733a6 Mon Sep 17 00:00:00 2001 From: Garry Tan Date: Tue, 28 Apr 2026 00:31:41 -0700 Subject: [PATCH] fix(test): clear USERPROFILE alongside HOME (Git Bash auto-populates HOME) Final Windows fix. 29/31 pass; 2 fail in gstack-paths HOME-unset tests: (fail) CWD fallback when HOME also unset (container env) (fail) PLAN_ROOT chain: GSTACK_PLAN_DIR > CLAUDE_PLANS_DIR > HOME > CWD Root cause: Git Bash on Windows auto-populates `HOME` from `USERPROFILE` at shell startup if HOME is empty/unset. Passing `HOME: ''` to spawnSync does set HOME='' for the child, but Git Bash overwrites it from USERPROFILE during init, so the script sees `${HOME:-}` as non-empty (C:\\Users\\runneradmin) and never reaches the CWD-fallback branch. Fix: clear USERPROFILE='' too. On Linux/Mac it's a no-op (env var doesn't exist in normal env); on Windows Git Bash it stops the HOME auto-populate. Co-Authored-By: Claude Opus 4.7 (1M context) --- test/gstack-paths.test.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/gstack-paths.test.ts b/test/gstack-paths.test.ts index 987897e0..d0b367da 100644 --- a/test/gstack-paths.test.ts +++ b/test/gstack-paths.test.ts @@ -10,9 +10,14 @@ const BIN = path.join(ROOT, 'bin', 'gstack-paths'); // doesn't parse `#!/usr/bin/env bash`. Production usage always sources the // helper from inside a bash block (`eval "$(~/.claude/skills/gstack/bin/gstack-paths)"`) // so bash is always the executor — this matches that contract. +// +// USERPROFILE: '' is a Windows-specific override. Git Bash auto-populates +// HOME from USERPROFILE at shell startup if HOME is unset/empty, which +// silently breaks the "HOME unset" test scenarios. Clearing USERPROFILE +// alongside HOME prevents that auto-population on Windows runners. function run(env: Record): Record { const result = spawnSync('bash', [BIN], { - env: { PATH: process.env.PATH, ...env } as Record, + env: { PATH: process.env.PATH, USERPROFILE: '', ...env } as Record, encoding: 'utf-8', }); if (result.status !== 0) { @@ -76,7 +81,7 @@ describe('gstack-paths', () => { test('output is shell-evalable: only KEY=VALUE lines, no extra prose', () => { const result = spawnSync('bash', [BIN], { - env: { PATH: process.env.PATH, HOME: '/tmp/h' } as Record, + env: { PATH: process.env.PATH, USERPROFILE: '', HOME: '/tmp/h' } as Record, encoding: 'utf-8', }); const lines = result.stdout.split('\n').filter(Boolean);