Repository navigation
Conversation
Codex agents each kept their own `codex app-server` (~300-400 MB with its MCP children) until the agent stopped running. With agents now running in every joined community, that cost grew with every Codex agent used. Everything agent-specific already travels with the thread: cwd, developer instructions and dynamic tools go in thread/start, and tool calls carry their threadId. So the runtime now owns one server, opened on first use in ~/.buzz, and finds a tool call's agent by thread and turn across all agents. Entries keep their conversations and saved bindings but no longer own a process. A stopped agent can no longer take its process down with it, so it interrupts its own turns, then cleans the background shells its threads left (a dev server from a finished turn, say). Starting the same agent again waits for that, so it never resumes a thread mid-teardown. The server ends with the last Codex agent, on dispose, or on a crash (the next mention reopens it). live.mjs passed the relay as an object since the per-agent relay change; it now passes a function, expands ~ like the desktop host, and checks two agents on one real server. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
`bin/node scripts/session-debug.mjs '<thread>'` serves a loopback page that follows a Codex or Claude Code transcript as it is written. The left rail is a vertical wall-time chart: inference, tool waits and their overlap, gaps nobody is accounted for, and idle time between runs, with each call's new tokens marked beside it. A grey band shows which part of the session is on screen. The conversation shows one harness/model/effort line, compact tool rows, and messages posted to Buzz as cards, so text the agent never sent stands out. Claude Code's zero-usage `<synthetic>` resume replies and queue bookkeeping no longer count as activity, which had been inflating inference time. The standalone exporters pick up the same tool rows and posted-message cards. Started by codex00; chart and conversation design by claude00. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Squashed-from: baxen/session-debug Squashed-head: 84d70727ddf9db15c352f070634ab47f7adb682f Signed-off-by: Bradley Axen <baxen@squareup.com>
The session page hid every instructions entry, so even Codex's recorded base instructions and dynamic tools never appeared. Model-visible context now shows as quiet collapsed rows where it was recorded, without a proxy: - Claude: the system prompt and tool schemas from Claude Code's `prompt_snapshot` records, one disclosure per tool. Each snapshot pair counts as one, and repeats only show when the prompt or tools change. Every injected reminder (environment, skills, CLAUDE.md, hook context) is shown with its rendered text and role. - Codex: base instructions, dynamic tools per tool, run settings from `turn_context` whenever they change, and developer/AGENTS.md context named by its tag. A one-line reminder also shows inline, such as the token count. Request framing, Claude's deferred tool schemas and Codex's native tool schemas are not recorded, and the page says so. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Squashed-from: baxen/session-debug Squashed-head: d7e8a3c248cdbbb693fdba2ef4c9262e412f21d8 Signed-off-by: Bradley Axen <baxen@squareup.com>
…page Browser fixtures scan every HTML file under the repo root, and scripts/session-debug.html imported "client.js", which only the inspector's own server maps to a real file. The scan failed, Vite skipped pre-bundling and re-optimized mid-test, and the reloads broke browser journeys across both engines. The page now names its files as they are on disk and the server serves them under those names, so the vite.config.ts exclusion (which fixture servers never read) goes away. Co-authored-by: claude00 <fb8b76a01257932b8ca35060862c29bd09b2137638573731c2d5074fc02c5385@buzz.block.builderlab.xyz> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Bradley Axen <baxen@squareup.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 430392dd1e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const calls = [ | ||
| ...text(input).matchAll( | ||
| /tools\.([A-Za-z0-9_]+)\(\s*(?:\{\s*"?text"?\s*:\s*("(?:[^"\\]|\\.)*"))?/g, | ||
| ), |
There was a problem hiding this comment.
Derive posted messages from completed tool records
This regex treats any tools.buzz__send(...) text in an exec program as a successfully posted message, even when it is in a comment, an untaken branch, or after an earlier statement that throws. It also misses non-Code-Mode calls where item.name === "buzz__send", which the Codex session documentation explicitly identifies as a supported call shape. As a result, the diagnostic can both invent and omit Buzz replies; derive these entries from recorded completed tool-call events/results rather than matching JavaScript source.
Useful? React with 👍 / 👎.
| return ( | ||
| new RegExp(`^Thread root: ${id}\\s*$`, "m").test(body) || | ||
| new RegExp(`^Event ID: ${id}\\s*$`, "m").test(body) | ||
| ); |
There was a problem hiding this comment.
Restrict fallback matches to Buzz envelope sections
For Claude transcripts, these fallback regexes scan the entire user message rather than the <context> or current <buzz-event> section. If quoted history or the current request text contains a standalone Thread root: or Event ID: line for the requested ID, that unrelated session becomes a candidate and may be selected by default, contrary to the documented promise that discovery ignores quoted history. Parse the semantic prompt sections and match only the routing context or current event metadata.
Useful? React with 👍 / 👎.
| }, | ||
| turns, | ||
| timing: wallTiming(records, turns, provider), | ||
| raw: records.map(publicRecord), |
There was a problem hiding this comment.
Stop returning unused raw transcripts on every poll
Every one-second /state poll includes a recursively copied version of the complete transcript here, although session-debug-client.js never reads state.raw; the browser still parses it and then stringifies the entire response again for change detection. For long-lived sessions this needlessly transfers and processes potentially tens of megabytes each second, making the live viewer increasingly unresponsive. Omit raw from the polling response or load it only through an explicit on-demand endpoint.
Useful? React with 👍 / 👎.
wesbillman
left a comment
There was a problem hiding this comment.
Three new P2s inline: Claude sends displayed as posted without confirmation, live refresh dropping chart focus, and keyboard activation failing to jump from timing segments. I also corroborated the existing Codex send-parsing, thread-discovery, and stopped-agent cleanup findings; linked rather than duplicated.
Star Lord automated source review via Wes’s account. Head 430392dd1e5dcc23adaf5343e0cac8bb02a96ab4; base 10ddcc861ee20ab75c9537aacaac44ecde277a31. Source-only: no tests, viewer/app execution, or CI verification; rendered/browser and native acceptance remain unverified.
| /(^|__)buzz__send$/.test(block.name) && | ||
| typeof block.input?.text === "string" | ||
| ) { | ||
| entries.push(entry.sent(timestamp, block.input.text)); |
There was a problem hiding this comment.
[P2] Confirm Claude delivery before rendering a send as posted
This branch replaces every buzz__send invocation with a “posted to Buzz” card without consulting the results map. If publication is rejected, the recorded tool_result.is_error and its explanation are therefore discarded; a still-pending send is also shown as delivered. That makes the diagnostic viewer report success precisely when someone is investigating a missing reply. Preserve the pending/failed tool row and show a posted card only when the recorded result confirms success. The analogous Codex-side issue is already covered in this finding.
| if (force || chartHtml !== html) { | ||
| $("timeline").innerHTML = html; | ||
| chartHtml = html; |
There was a problem hiding this comment.
[P2] Preserve chart focus across live refreshes
While an explicit turn is running, wallTiming() extends its end to the current time on every poll. The resulting duration/geometry changes this HTML every second, so this assignment destroys all chart buttons, including the one a keyboard user has focused. The focus restoration in render() only handles descendants of details, not these buttons, so focus drops out of the chart during normal live use. Reconcile chart controls by stable activity identity, or restore the focused chart control without stealing focus, and cover a refresh while a chart button is focused.
| $("timeline").addEventListener("click", (event) => { | ||
| const target = targetAt(event); | ||
| if (target) jumpTo(target); |
There was a problem hiding this comment.
[P2] Use the activated chart button for keyboard clicks
Enter/Space activation of a focused segment button produces a click with no meaningful pointer coordinates (normally 0,0). targetAt() handles marks directly, but for segments it instead checks clientX against the bar position; at the normal positive left offset this returns closest(".idle-break"), which is null for a segment. Consequently keyboard users can focus a timing segment and see its details but cannot jump to its record. Prefer the clicked [data-seg]/[data-mark] button, using coordinate hit-testing only for the enlarged pointer target.
Adds a local live viewer for Claude Code and Codex sessions: inference/tool timing, posted messages, recorded prompts, tools, and injected context. Run
bin/node scripts/session-debug.mjs '<Buzz thread ID or link>'to follow a session in a loopback browser view. Recorded context is distinguished from fields the harness does not record.Restacked from the existing session-debug and session-debug-context integration commits without source conflicts. The 54 tooling tests (including session viewer/context) and required model-tip push checks pass; native/human acceptance of the combined stack is pending. Kept draft for that testing. No raw session files are included.