fix(gemini): sync TUI↔chat and restore session titles#194
Open
fix(gemini): sync TUI↔chat and restore session titles#194
Conversation
- persistGeminiSessionMetadata now writes null instead of the "Untitled
Session" placeholder; buildGeminiSessionsIndex treats legacy rows with
that placeholder as empty so firstMessageText fallback can run.
- Same placeholder fix for nano-claude-code's "Nano Claude Code Session".
- Resolve Gemini session UUID → --list-sessions index before passing to
`gemini --resume` (the CLI doesn't accept UUIDs).
- Ingest ~/.gemini/tmp/{hash}/chats/session-*.json (live TUI state);
getSessionMessages prefers this blob when newer than the committed
jsonl so chat mirrors what the TUI is displaying.
- New gemini-tmp chokidar watcher resolves tmp/chats changes back to a
session UUID and bypasses the identical-snapshot shortcut so the chat
page's existing {uuid}.jsonl refetch gate still fires.
- Relax the useProjectsState gate that required a 2-part changedFile
path, unblocking Gemini refetch triggers.
- Shell renders a yellow advisory banner when resuming a Gemini session,
since the TUI can't ingest chat-originated writes without re-resume.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
| } | ||
| if (Array.isArray(m.toolCalls)) { | ||
| for (const tc of m.toolCalls) { | ||
| let toolInput = '{}'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes two user-reported Gemini session bugs and adds a shell-side advisory banner for a Gemini CLI limitation.
Bug #1 — Gemini sessions always showed "Untitled Session" in the sidebar, even after the user sent their first message. Three-pronged fix:
server/gemini-cli.js:persistGeminiSessionMetadatanow writesnullinstead of the hardcoded placeholder, soupsertSessionFromSource'sincoming || existingpattern stops clobbering real titles.server/projects.js(buildGeminiSessionsIndex): treat the legacy"Untitled Session"placeholder as empty so the existingfirstMessageTextfallback can run for rows seeded by older builds.server/nano-claude-code.jsfor its"Nano Claude Code Session"placeholder.Bug #2 — Shell↔chat desync on the same session. Root causes turned out to span three layers:
gemini --resumeaccepts"latest"or a numeric index from--list-sessions, not the UUID.server/index.jsnow resolves UUID → index viaexecFile('gemini', ['--list-sessions'])before spawning the shell.useProjectsState.tshad achangedFileParts.length >= 2gate that excluded Gemini's single-segment path ({uuid}.jsonl), blocking chat refetch on file changes. Relaxed to use the basename directly.~/.gemini/tmp/{projectHash}/chats/session-*.jsonon every turn but only flushes~/.gemini/sessions/{uuid}.jsonlperiodically. The chat page was only reading the committed jsonl, so TUI activity was invisible for minutes. Now:server/projects.js(readGeminiTmpChatSessionId,findGeminiTmpChatFile,convertGeminiTmpChatsToMessages) ingest the tmp/chats blob and map its{type: "user"|"gemini", content, toolCalls}shape into the downstream message format (includingtool_use/tool_resultentries).getSessionMessagesprefers tmp/chats when its mtime ≥ the jsonl's.gemini-tmpchokidar watcher on~/.gemini/tmpresolves change events back to the session UUID and synthesizes a{uuid}.jsonlbroadcast so the frontend's existing refetch gate fires without any client-side changes. The identical-snapshot dedup shortcut is bypassed for these events since tmp/chats churn doesn't change the project index.Advisory banner. The reverse direction (chat → TUI) is inherently one-way: the running Gemini TUI keeps conversation state in memory and never re-reads its session file.
src/components/Shell.jsxnow writes a yellow\x1b[33mbanner when resuming a Gemini session: "Gemini TUI won't see messages sent from the chat page until you exit and re-resume this session".Test plan
sqlite3 ~/.dr-claw/auth.db "SELECT id, display_name FROM session_metadata WHERE provider='gemini';"showsNULLfor new rows.gemini --resume {index}actually attaches to the same session (no new session created).🤖 Generated with Claude Code