|
@@ -143,6 +143,27 @@ for (const forbiddenText of forbiddenTexts) {
|
|
|
|
|
|
|
|
echo "SessionStart hook output tests"
|
|
echo "SessionStart hook output tests"
|
|
|
|
|
|
|
|
|
|
+# Registration shape: the hook must declare shell:"bash" so Claude Code on
|
|
|
|
|
+# Windows dispatches via Git Bash (or fails with an actionable error) instead
|
|
|
|
|
+# of PowerShell/cmd.exe, whose parsers break on the quoted command string
|
|
|
|
|
+# (PowerShell ParserError; cmd.exe quote-stripping on paths with metacharacters).
|
|
|
|
|
+if node -e '
|
|
|
|
|
+const hooks = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
|
|
|
|
|
+const entry = hooks.hooks.SessionStart[0].hooks[0];
|
|
|
|
|
+if (entry.shell !== "bash") {
|
|
|
|
|
+ console.error(`SessionStart hook shell is ${JSON.stringify(entry.shell)}, expected "bash"`);
|
|
|
|
|
+ process.exit(1);
|
|
|
|
|
+}
|
|
|
|
|
+if (!/run-hook\.cmd" session-start$/.test(entry.command)) {
|
|
|
|
|
+ console.error(`unexpected SessionStart command shape: ${entry.command}`);
|
|
|
|
|
+ process.exit(1);
|
|
|
|
|
+}
|
|
|
|
|
+' "$REPO_ROOT/hooks/hooks.json"; then
|
|
|
|
|
+ pass "hooks.json registers SessionStart with shell:bash dispatch"
|
|
|
|
|
+else
|
|
|
|
|
+ fail "hooks.json registers SessionStart with shell:bash dispatch"
|
|
|
|
|
+fi
|
|
|
|
|
+
|
|
|
claude_home="$(make_home claude-code)"
|
|
claude_home="$(make_home claude-code)"
|
|
|
assert_command_output \
|
|
assert_command_output \
|
|
|
"Claude Code emits nested SessionStart additionalContext" \
|
|
"Claude Code emits nested SessionStart additionalContext" \
|