Summary
tests/brainstorm-server/lifecycle.test.js spawns bash -lc (login shell) in three helper functions and captures all of stdout, assuming the only output is the command's own result. On any machine whose login profile prints anything to stdout (fastfetch/neofetch banners, motd scripts, etc.), the helpers return polluted garbage and tests fail even though nothing is wrong with the server code.
This is the same class of bug as #292 (-l flag in run-hook.cmd breaking Windows startup), just in the test suite instead of a hook.
Affected code
tests/brainstorm-server/lifecycle.test.js, three spots:
// line 104-106
function makeShellTempDir(prefix) {
return execFileSync('bash', ['-lc', `mktemp -d "\${TMPDIR:-/tmp}/${prefix}-XXXXXX"`], { encoding: 'utf8' }).trim();
}
// line 108-110
function removeShellPath(p) {
execFileSync('bash', ['-lc', 'rm -rf "$1"', 'bash', p], { stdio: 'ignore' });
}
// line 112-117
function newestSessionDir(projectDir) {
const sessionDir = execFileSync('bash', [
'-lc',
'find "$1/.superpowers/brainstorm" ...',
None of these need a login shell: they only run mktemp, rm, and find.
Repro
On Linux with a login profile that prints a banner to stdout (e.g. fastfetch invoked from ~/.bash_profile, a very common setup):
git clone https://github.com/obra/superpowers && cd superpowers/tests/brainstorm-server
npm ci
node --test
Result: start-server.sh --idle-timeout-minutes sets the timeout fails, plus cleanup errors like:
mkdir: cannot create directory '.',;::::;,'. honey@fedora\n .';:ccccccc...': File name too long
.../start-server.sh: line 141: <banner text>: File name too long
Command failed: bash -lc rm -rf "$1" bash <banner text>
The banner output gets captured as the "temp dir path", then leaks into --project-dir, $SERVER_ID_FILE, and cleanup commands.
Root cause
bash -l sources /etc/profile and ~/.bash_profile, so anything those scripts echo lands in the captured stdout before the actual command output. .trim() only removes surrounding whitespace, it cannot separate a multi-line banner from the payload.
Suggested fix
Drop -l; plain -c is sufficient since no login environment is needed:
- return execFileSync('bash', ['-lc', `mktemp -d "\${TMPDIR:-/tmp}/${prefix}-XXXXXX"`], { encoding: 'utf8' }).trim();
+ return execFileSync('bash', ['-c', `mktemp -d "\${TMPDIR:-/tmp}/${prefix}-XXXXXX"`], { encoding: 'utf8' }).trim();
Same change at lines 109 and 114. I verified locally on an affected machine (Fedora 44, fastfetch in the login profile): with -lc the file reports 1 failing test, after switching the three occurrences to -c all 13 lifecycle tests pass.
A more defensive alternative (or addition) is taking only the last non-empty line of captured stdout in makeShellTempDir/newestSessionDir, but removing -l alone fixes every case where the pollution comes from the login profile.
Environment
- OS: Fedora Linux 44, bash 5.3.9
- Node: v22.x
- superpowers @ main (b36e082), v6.3.0
Summary
tests/brainstorm-server/lifecycle.test.jsspawnsbash -lc(login shell) in three helper functions and captures all of stdout, assuming the only output is the command's own result. On any machine whose login profile prints anything to stdout (fastfetch/neofetch banners, motd scripts, etc.), the helpers return polluted garbage and tests fail even though nothing is wrong with the server code.This is the same class of bug as #292 (
-lflag inrun-hook.cmdbreaking Windows startup), just in the test suite instead of a hook.Affected code
tests/brainstorm-server/lifecycle.test.js, three spots:None of these need a login shell: they only run
mktemp,rm, andfind.Repro
On Linux with a login profile that prints a banner to stdout (e.g. fastfetch invoked from
~/.bash_profile, a very common setup):Result:
start-server.sh --idle-timeout-minutes sets the timeoutfails, plus cleanup errors like:The banner output gets captured as the "temp dir path", then leaks into
--project-dir,$SERVER_ID_FILE, and cleanup commands.Root cause
bash -lsources/etc/profileand~/.bash_profile, so anything those scripts echo lands in the captured stdout before the actual command output..trim()only removes surrounding whitespace, it cannot separate a multi-line banner from the payload.Suggested fix
Drop
-l; plain-cis sufficient since no login environment is needed:Same change at lines 109 and 114. I verified locally on an affected machine (Fedora 44, fastfetch in the login profile): with
-lcthe file reports 1 failing test, after switching the three occurrences to-call 13 lifecycle tests pass.A more defensive alternative (or addition) is taking only the last non-empty line of captured stdout in
makeShellTempDir/newestSessionDir, but removing-lalone fixes every case where the pollution comes from the login profile.Environment