fix(gemini-cli): emit SessionStart as structured JSON, not plaintext (#299)#314
fix(gemini-cli): emit SessionStart as structured JSON, not plaintext (#299)#314ousamabenyounes wants to merge 1 commit intomksglu:nextfrom
Conversation
…ksglu#299) The Gemini CLI SessionStart hook concatenated the full ~10 KB routing block into a plain-text string prefixed with "SessionStart:compact hook success". Gemini CLI surfaced that string verbatim as user-visible startup noise, per mksglu#299 ("the message is too verbose"). The Claude Code and VS Code Copilot SessionStart hooks already use structured JSON (`{ hookSpecificOutput: { hookEventName, additionalContext } }`) which Gemini CLI treats as hook metadata and does not render to the user. This PR brings the Gemini hook in line — same contract, no new config flag needed, hidden by default. - hooks/gemini-cli/sessionstart.mjs: JSON.stringify output instead of the plaintext concatenation. - tests/hooks/gemini-hooks.test.ts: two regression tests — one parses stdout and asserts the expected shape, one greps the source to lock in the JSON path (mirrors the existing vscode-copilot source check). Tests: - npx vitest run tests/hooks/gemini-hooks.test.ts → 13/13 pass - npm test → 1597 pass, 23 skipped, 0 fail - npm run typecheck → clean Co-Authored-By: Claude <noreply@anthropic.com>
|
Hi @ousamabenyounes! Did you test on local env for that? Did you repro and fixed? |
|
Tested with Gemini CLI 0.38.2 and reproduced the issue end-to-end in interactive TUI mode (which is where the visible bug lives; Before — current
|
What
hooks/gemini-cli/sessionstart.mjsconcatenated the full ~10 KB routing block into a plain-text string prefixed with"SessionStart:compact hook success: Success"and wrote it to stdout. Gemini CLI surfaces that text verbatim in the UI, which is exactly the startup noise reported in #299 ("the message is too verbose").The Claude Code and VS Code Copilot SessionStart hooks already use structured JSON (
{ hookSpecificOutput: { hookEventName, additionalContext } }) and are rendered as hook metadata rather than user-visible output. This PR brings the Gemini hook in line — no new config flag needed, hidden by default as the reporter suggested.Fixes #299.
Why just this
An in-repo source contract for the VS Code Copilot hook already exists (
tests/hooks/vscode-hooks.test.ts:279) that forbids\"SessionStart:compact hook success\"in that hook's source and requires JSON.stringify. The Gemini hook is the one remaining SessionStart hook that hadn't been migrated. No config / new env var / new feature flag was considered necessary — the issue is effectively a missed parity cleanup.No code path other than the final stdout emission changes, so session-lifecycle behavior (startup / compact / resume / clear) is untouched.
Changes
hooks/gemini-cli/sessionstart.mjsconst output = ...; process.stdout.write(output);) with the sameconsole.log(JSON.stringify({ hookSpecificOutput: { hookEventName: \"SessionStart\", additionalContext } }))form Claude Code / VS Code Copilot already use.tests/hooks/gemini-hooks.test.ts— two regression cases added to the existingsessionstart.mjsdescribe block (per CONTRIBUTING's "add to existing domain file" rule):sessionstart outputs structured JSON (hidden from user in Gemini CLI)— parses stdout as JSON, assertshookSpecificOutput.hookEventName === \"SessionStart\"and thatadditionalContextis a string containing "context-mode". Also asserts the old plaintext markers (\"SessionStart:compact hook success\",\"SessionStart hook additional context:\") are not present.sessionstart source uses JSON.stringify, not plaintext output (#299)— reads the hook source and pins the JSON path in place (symmetric with the existing vscode-copilot source check attests/hooks/vscode-hooks.test.ts:279).Test plan
npx vitest run tests/hooks/gemini-hooks.test.ts→ 13/13 pass (2 new, 11 existing)npm test→ 1597 pass, 23 skipped, 0 failuresnpm run typecheck→ cleanOutput quality (before / after)
Before — Gemini CLI user sees on session start:
After:
The routing block is still injected into the agent's context on every session start — nothing changes semantically. Only the Gemini CLI UI rendering changes.
Generated by Claude Code
Vibe coded by ousamabenyounes