feat: search cost, recovery confirmation, TUI scroll, and session directories - #4
Merged
Merged
Conversation
Web search runs on a separate Responses API call whose token usage was written into the tool artifact but never counted, so knownSessionCost under-reported searching sessions. Record the usage durably on the web_search tool result (an optional searchUsage field on tool_result_committed, present only for successful searches) and have the cost projector price it with the same flash price book into the session and lineage cost. The usage is cost-only: it stays out of the chat-prefix cache metrics.
Recovery can reach a pending tool call whose result was never committed. Executing it silently would run a command the operator never approved, so add an explicit operator gate: interactive terminals are asked y/N, and non-interactive invocations require the --confirm-execute flag. Declining stops the recovery fail-closed and records a not_executed_denied reconciliation resolution, which replays as a static permission-denied result instead of a fabricated or bypassed effect.
Add a scroll offset to the TUI base and a history viewport to the main-screen renderer: wheel (via SGR mouse reports), PageUp/PageDown, Home and End move a window over the rendered content without touching the terminal's own scrollback. Enable SGR button-event tracking (1002 + 1006) only inside tmux so the wheel reaches the Screen layer, and disable it on exit; outside tmux the terminal keeps owning the mouse and its scrollback.
Resolve the durable cwd fact during the fast JSONL scan (no second log read) and in the verified fallback, then append the workspace path to both the plain sessions output and the interactive session picker.
Add a compatibility test that writes a web_search result without the searchUsage field and verifies the journal still replays and projects cost correctly, matching the schema's backward-compatible read.
The fast session list parses log.jsonl lines for a read-only projection, the recovery confirmation parses a tool call's arguments only to disclose the command, and the screen probes TMUX for the mouse hint. All three are display/read-only paths, not credential or invariant mutations.
- The tmux mouse hint was the only Chinese string in the CLI; make it English. - Shorten the workspace path to ~ for home and ellipsize long paths so the session rows stay within the terminal instead of wrapping. - Show local times in both the plain sessions output and the picker; the raw ISO timestamp with T/Z only appeared in the plain output before.
A crash or SIGTERM left the terminal in raw mode with mouse tracking, bracketed paste and Kitty protocol enabled. Register a best-effort process exit handler in start() that writes the disable sequences and restores raw mode, and remove it in stop() once the normal path has already cleaned up. SIGKILL still cannot be helped.
Each session summary reads independent files, so wait for them together instead of one at a time. The result set and sort order are still decided after the awaits.
Inside tmux the mouse now selects text within the rendered window: left press anchors, drag extends with reverse-video highlight, and release copies the plain text to the system clipboard via OSC 52. Wheel scrolling still works, and the selection never lets raw mouse bytes reach the editor.
…tmux mouse - Selection rows were indexed into the full rendered content as if row 0 were the top of the screen; add previousViewportTop so dragging selects the row under the cursor after the window has scrolled or resized. - Enable tmux mouse mode for the current window and set-clipboard for the current session at startup instead of asking the operator to edit their tmux.conf. Both are scoped (window/session), not global.
Uh oh!
There was an error while loading. Please reload this page.
Owen718
commented
Aug 12, 2026
Owner
Merged and released in v0.1.0-rc.7. Verified before merging:
Two edits on top of the merge:
Thanks — the search-cost gap had been on the list unfixed for two days. |
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 freeto 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.
What
This branch carries several related fixes and features on top of the search-cost work:
1. Price web search usage into the session cost
Web search runs on a separate Responses API call whose token usage was parsed into the tool artifact but never counted, so
knownSessionCostunder-reported searching sessions. The usage is now recorded durably on theweb_searchtool result (an optionalsearchUsagefield ontool_result_committed, present only for successful searches) and priced with the same flash price book into the session and lineage cost. The usage stays out of the chat-prefix cache metrics.2. Require confirmation before recovery executes pending tool calls
Recovery can reach a pending tool call whose result was never committed. Executing it silently would run a command the operator never approved. This adds an explicit operator gate:
y/Nbefore execution--confirm-executeflagnot_executed_deniedreconciliation resolution, which replays as a static permission-denied result instead of a fabricated or bypassed effect3. Scroll rendered history with wheel, PageUp/PageDown, Home/End
The TUI base gains a scroll offset and the main-screen renderer gains a history viewport. Inside tmux, SGR button-event tracking (
1002+1006) is enabled so the wheel reaches the Screen layer and scrolls the internal history; it is disabled on exit. Outside tmux the terminal keeps owning the mouse and its own scrollback, so native selection and scrolling are unchanged.4. Click-drag text selection with OSC 52 copy (tmux)
Inside tmux, left-button drag selects text within the rendered window with reverse-video highlight, and release copies the plain text to the system clipboard via OSC 52. Selection rows are mapped through the viewport top so the highlight stays under the cursor after scrolling or resizing. tmux
mouse(window) andset-clipboard(session) are enabled automatically at startup, so no manual tmux.conf changes are needed.5. Show each session's workspace directory in the session list
The session list resolves the durable
cwdfact during the fast JSONL scan (no second log read) and in the verified fallback, then appends a shortened workspace path to both the plainflashcoder sessionsoutput and the interactive session picker. Sessions are summarized concurrently.6. Polish and hardening
stop()path.~paths, and local session times.recover/inspectreport "no such session in this workspace" instead of a bootstrap internals error when the session belongs to another directory.searchUsagefield existed.Tests
All suites pass locally: