Skip to content

[twarp 07b] Claude Code panel: panel shell + ported transcript#69

Merged
timomak merged 2 commits into
masterfrom
twarp-07b-port
Jun 2, 2026
Merged

[twarp 07b] Claude Code panel: panel shell + ported transcript#69
timomak merged 2 commits into
masterfrom
twarp-07b-port

Conversation

@timomak
Copy link
Copy Markdown
Owner

@timomak timomak commented Jun 2, 2026

twarp 07b — Claude Code panel: panel shell + ported transcript

Sub-phase 7b of feature 07. Brings back the rendering layer of Warp's Agent Mode as a left-panel tab, by porting the deleted ai_assistant transcript renderer and reparenting it onto the thin claude_code::Transcript model. No live claude process yet — 7b is fed by a synthetic event source so the ported renderer is testable end-to-end; the live driver lands in 7c.

This is a rendering-layer-only revival. Feature 02 removed Warp's AI service (accounts, LLM clients, billing, cloud conversation storage); none of that comes back here. twarp adds no account, no LLM client, no cloud sync — the panel only ever renders a transcript, and (from 7c on) talks solely to the local claude CLI the user already runs.

Why a port, not a rebuild

PR #67 rebuilt the panel from Flex/Container/Link primitives and was abandoned for it (TECH.md §Postmortem). This PR follows the re-spec's per-file decision matrix:

  • Ported ai_assistant::transcript::render_message's markdown body → render_markdown_body (FormattedTextElement for prose, a bordered monospace box for fenced code).
  • Ported the AI-agnostic splitter translate_formatted_text_into_markdown_segmentssplit_markdown_segments.
  • Reused feature 03's live markdown stack (parse_markdownFormattedTextElement) for §18.
  • Assistant text renders as themed markdown (headings, lists, inline code, fenced code blocks, links) — not the plain spans [twarp 07b] Claude Code panel: resurrect view + event model #67 shipped.

Kept from #67 (correct, decoupled)

  • crates/claude_code driver crate (Transcript/TranscriptEvent/TranscriptItem + driver + sessions) — 19 unit tests pass.
  • Registration scaffolding: ToolPanelView::ClaudeCode, LeftPanelDisplayedTab::ClaudeCode, toolbelt button, render arm, compute_left_panel_views push, and the ⌘⌥K binding via custom_tag_to_keystroke (not with_key_binding — the feature-06 lesson).

Discarded from #67

  • The entire primitive claude_code_panel/mod.rs body (rebuilt as a port).
  • The WorkspaceAction::ClaudeCodePanel(...) forwarder and its Workspace::handle_action arm. The panel now dispatches its own ClaudeCodePanelAction the GlobalSearchView way — it is a TypedActionView with an on_left_mouse_down focus-grab, so in-panel clicks land without a forwarder.

Behavior delivered (PRODUCT §1–§7, §16–§20, §60)

  • Claude Code toolbelt entry + ⌘⌥K toggle (remappable).
  • Panel resizes/persists width with the rest of the left panel.
  • Zero state when empty; unavailable state (named binary + install hint) when claude is off PATH, replacing the panel.
  • Opening the panel starts no subprocess.
  • Submitting a message renders a user turn + a representative markdown assistant reply via the ported renderer (synthetic; 7c wires the real driver).

Feature flag decision

Always-on (no flag) — acceptable on a personal fork; the panel degrades cleanly to the unavailable state when claude is absent (§6). Recorded in STATUS.md / TECH.md §Feature flag & rollout.

Testing

  • cargo test -p claude_code → 19 passed.
  • cargo check -p warp → clean.
  • ./script/presubmit is not fully runnable on the owner's Mac (see project notes); relied on cargo check/clippy/fmt + the crate tests.

Smoke test (7b section of PRODUCT.md): steps 1–5 (toolbelt entry, ⌘⌥K toggle, width persistence, zero state + no subprocess, unavailable state) plus the acceptance gate — a submitted message renders in Agent-Mode markdown shape (prose + themed fenced code block), not plain text.

Specs: PRODUCT.md / TECH.md merged in #66 and re-spec #68. Scope here is 7b only; 7c–7h follow.

🤖 Generated with Claude Code

timomak and others added 2 commits June 2, 2026 11:07
Sub-phase 7b of feature 07. Brings back Warp Agent Mode's rendering layer as
a left-panel tab by PORTING the deleted ai_assistant transcript renderer onto
the thin claude_code::Transcript model, fed by a synthetic event source (no
live driver yet — that lands in 7c).

Rendering layer only: no AI service, LLM client, billing, or cloud sync comes
back (feature 02's removals stay removed). From 7c on, the panel talks solely
to the local `claude` CLI the user already runs.

Kept from #67 (correct, decoupled):
- crates/claude_code driver crate (Transcript/TranscriptEvent/TranscriptItem
  + driver + sessions) — 19 unit tests pass.
- Registration scaffolding: ToolPanelView::ClaudeCode, the toolbelt button,
  render arm, compute_left_panel_views push, and the remappable ⌘⌥K binding
  via custom_tag_to_keystroke (not with_key_binding — the feature-06 lesson).

Discarded from #67:
- The primitive Flex/Container/Link panel body (rebuilt as a port).
- The WorkspaceAction::ClaudeCodePanel forwarder + its handler arm. The panel
  now self-dispatches ClaudeCodePanelAction the GlobalSearchView way (it is a
  TypedActionView with an on_left_mouse_down focus-grab).

The port:
- render_markdown_body ports render_message's markdown body (FormattedTextElement
  for prose, a bordered monospace box for fenced code).
- split_markdown_segments ports the AI-agnostic markdown splitter.
- Reuses feature 03's parse_markdown -> FormattedTextElement stack (§18), so
  assistant text renders as themed markdown, not plain spans.
- Transcript renders in a UniformList; zero state + claude-unavailable state;
  always-on (no feature flag — degrades cleanly when claude is off PATH, §6).

cargo test -p claude_code (19 passed), cargo check -p warp, cargo clippy, and
cargo fmt all clean. Scope is 7b only; 7c–7h follow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reconcile after re-spec #68 merged: phase spec-in-review -> impl-in-review.
Tick 7b, record the 7b decisions (always-on, no feature flag) and PR #69.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
timomak added a commit that referenced this pull request Jun 2, 2026
STATUS.md rewritten for the terminal-triggered main-pane direction; sub-phases
re-derived around the pane host; placement open-decision reversed (sidebar →
main-content pane). ROADMAP row notes the main-pane re-spec PR and the
superseded 7b sidebar PR. Phase stays spec-in-review pending #70.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@timomak timomak merged commit 9b6b9a8 into master Jun 2, 2026
5 of 16 checks passed
timomak added a commit that referenced this pull request Jun 2, 2026
#69 (the sidebar 7b build) was merged to master, bringing in
crates/claude_code + the ported renderer (in a sidebar host). Merge
master into the main-pane re-spec branch; the only conflicts were the
two roadmap docs, resolved to git reality:

- #69 relabeled from "superseded / to-close" -> "merged": it landed the
  placement-agnostic core; the sidebar host is now obsolete.
- 7b re-scoped from "re-introduce crates/claude_code" -> "relocate the
  merged sidebar surface into a main-content pane (delete sidebar host)".
- Phase stays spec-in-review (gating spec PR #70 still open).

Docs-only resolution; #69's code merged cleanly (17 files, claude_code
crate + app wiring).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
timomak added a commit that referenced this pull request Jun 2, 2026
…bar) (#70)

* [twarp 07] re-spec: terminal-triggered main-pane chat (supersede sidebar)

The 7b sidebar build (PR #69) was rejected on sight: wrong placement. Re-spec
PRODUCT.md + TECH.md for the corrected, owner-confirmed direction:

- Trigger: running `claude` in a terminal is intercepted at submit and opens a
  dedicated Claude Code MAIN-CONTENT pane (a tab like an editor/terminal), not
  a left-sidebar toolbelt button / ⌘⌥K.
- Surface: the chat is a first-class pane (IPaneType::ClaudeCode, modeled on
  CodePane) — resizable, splittable, closeable.
- Sidebar: repurposed to a read-only past-sessions list, shown only when any
  sessions exist.
- Visual bar: match Anthropic's Claude desktop / Claude Code app.

Kept (placement-agnostic): the headless claude_code driver crate (19 tests) and
the ported markdown renderer from #69. Dropped: the left-panel placement + ⌘⌥K.
TECH.md adds the terminal-interception hook (terminal/input.rs) and the pane
host (pane_group / IPaneType) integration points from a codebase audit, keeps
the rendering per-file matrix, and re-derives 7b–7h. Specs only; no code here.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* [twarp 07] roadmap: record main-pane re-spec (#70); mark #69 superseded

STATUS.md rewritten for the terminal-triggered main-pane direction; sub-phases
re-derived around the pane host; placement open-decision reversed (sidebar →
main-content pane). ROADMAP row notes the main-pane re-spec PR and the
superseded 7b sidebar PR. Phase stays spec-in-review pending #70.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
timomak added a commit that referenced this pull request Jun 5, 2026
…ger (#71)

* [twarp 07b] Claude Code panel: main-pane host + claude-at-submit trigger

Relocate the transcript renderer #69 landed in the rejected left sidebar into
a first-class main-content pane (IPaneType::ClaudeCode), add the conservative
`claude`-at-submit terminal trigger that opens it, and delete the #69 sidebar
host. Per the main-pane re-spec (#70).

- ClaudeCodeView (BackingView) is the git-mv'd #69 renderer; transcript + docked
  composer are the pane body, the "Claude Code" + cwd header moves to
  render_header_content. All render leaves + the synthetic source are unchanged.
- ClaudeCodePane (PaneContent) mirrors NetworkLogPane; LeafContents::ClaudeCode
  is non-persisted (no transcript store; resume via `claude --resume`, 7h).
- Trigger mirrors the OpenCodeInWarp chain: Input intercepts a bare top-level
  `claude` (tokenized via warp_completer; pipes/chains/paths/off-PATH run raw),
  emits OpenClaudeCodePane through input::Event -> view::Event -> pane_group
  -> Workspace::open_claude_code_pane. Intercepted block shows a brief toast.
- Sidebar host removed: ToolPanelView::ClaudeCode, toolbelt button,
  LeftPanelDisplayedTab persistence, ToggleClaudeCodePanel action + the cmd-alt-K
  binding.

cargo check/clippy/fmt clean; claude_code 19/19 tests pass.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* [twarp 07b] roadmap: advance 07 to impl-in-review; tick 7b (PR #71); mark #70 merged

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* [twarp 07b] fix claude trigger under shell aliases + transcript truncation

Two fixes found testing #71 on a real build:

1. Alias-aware trigger. Warp expands shell aliases at submit, so a user's
   `alias claude='command claude --flags'` reached the interceptor already
   expanded as `command claude …`; `top_level_command` then read `command`
   (the builtin) and the trigger never fired. `claude_pane_trigger` now peels
   leading env-var assignments and the `command`/`builtin`/`exec` run-a-program
   wrappers to recover the real program token, and forwards only a leading
   positional as the first turn (alias-injected flags are not a prompt).

2. Transcript no longer truncates. The ported `UniformList` clips every row to
   one measured height, so multi-paragraph assistant replies rendered as a
   single line. Render transcript items at their natural height in a
   `ClippedScrollable` column instead (a variable-height virtualized list can
   return later if very large sessions need it, PRODUCT §14).

cargo check/clippy/fmt clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant