Repository navigation
feat(feed): render Compacting placeholder for /compact turns - #74
Merged
Merged
Conversation
Previously, when Claude Code's `/compact` ran (manual or auto), the streaming assistant turn that synthesises the summary leaked its raw output into the feed for as long as it took to run — typically tens of seconds, sometimes >90s on large contexts. The output is `<analysis>...</analysis><summary>...</summary>` XML that's meant to be consumed by Claude Code itself, not rendered to the user. Native Claude Code TUI hides this entirely; cc-shell rendered it raw. The cleanest place to detect this turn is the proxy layer where the request body is already in memory — that's claude-code-headless#8 (submodule bump in this PR). The renderer just consumes the new `isCompactionSynthesis` bit on `turn_started`: * `SemanticLiveTurn.isCompactionSynthesis`: new optional flag, populated once at `turn_started` and preserved across same-turn refresh events. Defaults missing/false everywhere — codex, screen fallback, and pre-2026-05-11 proxy adapters never set it. * `StreamingTurn.tsx`: early-return a "Compacting conversation…" MarkerRow placeholder when the flag is set, mirroring the existing `CompactBoundaryRow` styling so live and committed states share visual language. Placed AFTER existing hooks to keep Rules of Hooks happy. The post-compaction user-facing artefacts (`compact_boundary` system entry, `isCompactSummary: true` user entry) land via JSONL after the synthesis turn ends and already have working renderers (`CompactBoundaryRow`, `CompactSummaryRow`). The placeholder only covers the streaming window where the bug was visible. Bumps claude-code-headless to b237c88 (PR #8) for the proxy-side flag plumbing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
/compactruns (manual or auto), the synthesis turn streams<analysis>...</analysis><summary>...</summary>XML to the model. Native TUI hides it; cc-shell rendered it raw in the feed for the entire ~10–90s the model spends summarising.compact_boundary+isCompactSummary: trueuser entry) already had working renderers (CompactBoundaryRow,CompactSummaryRow). This PR only covers the streaming window where the XML leaked.Architecture
All hops carry the flag as an optional, truthy-only field — non-Claude sources and older proxy adapters keep their event payloads byte-identical, and the renderer fails closed (legacy XML-leak behaviour) on a missing flag rather than over-hiding turns.
Files touched
mitmAddon.py,ClaudeProxyAdapter.ts,SemanticChannel.ts,channels/types.tssrc/renderer/src/workspace/workspaceState.tsisCompactionSynthesis?: booleantoSemanticLiveTurnsrc/renderer/src/workspace/semantic/foldEvent.tsturn_startedsrc/renderer/src/features/feed/ui/semantic/StreamingTurn.tsxWhy detect at the proxy and not in the renderer
A renderer-side heuristic (e.g. "if
textSoFarstarts with<analysis>") would render a flash of raw XML before the heuristic engages. The request body is the earliest layer where the signal is unambiguous — Claude Code's compaction prompt is a fixed preamble invendor/claude-code-src/full/services/compact/prompt.ts(BASE_COMPACT_PROMPT,PARTIAL_COMPACT_PROMPT,PARTIAL_COMPACT_UP_TO_PROMPTall open with"Your task is to create a detailed summary"). The mitm addon already parses these bodies for sidecar detection, so the cost is one new regex + one new bool field.Test plan
tsc) passes ✅ (verified locally).npm run build) passes ✅ (verified locally)./compact(or wait for auto-compaction in a 600k+ context session). Expect "Compacting conversation…" placeholder in feed during the synthesis, then thecompact_boundarydivider +Conversation Summarycard fromCompactSummaryRowonce JSONL catches up.turn_startedevents withisCompactionSynthesis: true(and only on compaction turns).Risk
Dependencies
b237c88).🤖 Generated with Claude Code