fix(hooks): bun-runner.js parses on pre-ES2020 Node (closes #2791) (#2801)

The Stop hook crashes every session with 'SyntaxError: Unexpected token .'
when a host invokes bun-runner.js under a bundled pre-ES2020 Node whose ESM
loader rejects optional chaining (?.). Replace the only ?. site with explicit
guards and add a build-time guard forbidding ?. / ?? in this launcher so it
can't regress.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Alex Newman
2026-06-05 20:36:18 -07:00
committed by GitHub
parent cf450cec00
commit 9efb04da84
2 changed files with 22 additions and 1 deletions
+9 -1
View File
@@ -66,7 +66,15 @@ function isPluginDisabledInClaudeSettings() {
const settingsPath = join(configDir, 'settings.json');
if (!existsSync(settingsPath)) return false;
const settings = JSON.parse(readFileSync(settingsPath, 'utf-8'));
return settings?.enabledPlugins?.['claude-mem@thedotmack'] === false;
// No optional chaining (?.) here: this launcher must parse on the oldest
// Node that any host might invoke it with. Some Claude Code installs run
// hooks under a bundled pre-ES2020 Node whose ESM loader throws
// "SyntaxError: Unexpected token '.'" on `?.` (issue #2791).
return Boolean(
settings &&
settings.enabledPlugins &&
settings.enabledPlugins['claude-mem@thedotmack'] === false
);
} catch {
return false;
}
+13
View File
@@ -175,6 +175,19 @@ async function verifyShellTemplateCanonical() {
);
}
// Parser-compat guard (issue #2791): bun-runner.js is invoked by hosts that
// may run a pre-ES2020 Node whose ESM loader throws on optional chaining.
// Strip comments, then forbid `?.` / `??` in executable code.
const bunRunnerCode = bunRunner
.replace(/\/\*[\s\S]*?\*\//g, '')
.replace(/(^|[^:])\/\/.*$/gm, '$1');
if (/\?\.|\?\?/.test(bunRunnerCode)) {
throw new Error(
'plugin/scripts/bun-runner.js uses optional chaining (?.) or nullish coalescing (??) — ' +
'this launcher must parse on pre-ES2020 Node (issue #2791). Rewrite with explicit guards.'
);
}
console.log('✓ Rule A shell templates match the canonical generator');
}