Commit Graph

22 Commits

Author SHA1 Message Date
Jonas H
ba6b18e7d9 Lane server tools, lift task notes, parse ANSI
Three streams of data were being lost or mangled in the feed.

WebSearch is not purely client-side: it issues a nested /v1/messages that
declares Anthropic's hosted web_search under the parent session id and with
no agent-id header. Read as a turn start it pushed a fake user prompt,
clobbered the main lane's system/tools signatures and downgraded a [1m]
session to the short window on the next resume. Requests are now classified
three ways (Turn / ServerTool / Side) from the tools array shape alone, and a
nested call gets its own lane, readable only in the A popup. Its result and
citations arrive complete in the stream and are echoed back in no later
request body, so they are attached as the stream delivers them.

An Agent call returns its tool_result immediately ("async agent launched"),
so the real completion is a <task-notification> injected into the parent's
next user turn. Those are lifted out of the prompt: the report moves onto the
Agent entry it answers, the usage totals onto the lane, and the status
becomes one glyph-led note line. A finished agent used to keep reading as
running.

Tool output we do not control carries SGR codes. A self-contained parser maps
them to styles instead of leaving [1m as literal text; filled blocks keep
their own colours and take only the attributes.

Also: a non-2xx upstream response now surfaces as an error entry instead of a
silent stall, tool renderers cover the file/shell/task/prompt/web families,
and the fake upstream answers the nested hosted-tool request so both search
paths run offline.
2026-08-27 10:24:05 +02:00
Jonas H
c7eddf3bde subagent handling + 1m context resume 2026-08-26 11:17:43 +02:00
Jonas H
a7d7940be3 auto resume 2026-08-17 07:47:47 +02:00
Jonas H
fc9c05ce97 fake upstream
+1
2026-08-17 07:47:35 +02:00
Jonas H
b56ea650ab claude expand fixes and line numbers 2026-07-09 08:49:53 +02:00
Jonas H
27b0f791aa table markdown rendering improvement 2026-06-29 07:24:20 +02:00
Jonas H
9c5356c6ba new session fixes 2026-06-26 13:10:10 +02:00
Jonas H
5669d30c27 dynamic prompt framing 2026-06-26 10:31:56 +02:00
Jonas H
f97828d7d1 less filter 2026-06-19 12:14:31 +02:00
Jonas H
f0e5c202f5 UX improvements 2026-06-17 12:53:18 +02:00
Jonas H
8ffd258341 multiline paste and cursor fix 2026-06-16 11:45:26 +02:00
Jonas H
10279a49a4 ui updates 2026-06-16 11:04:50 +02:00
Jonas H
a72eafc42a claude cloak rename 2026-06-15 10:31:35 +02:00
Jonas H
37cf183377 Add session history browser, turn-tree branching, model picker, mouse capture, and feed cache
Sessions panel now shows on-disk JSONL history for the current directory
(background scanner, ~1/s, deduped against live sessions). space/→ expands
a session into a lazygit-style turn tree; j/k walks sessions and turns; v
anchors a visual range; b materialises a new fully-decoupled branch file.
ctrl-↓ is the commit point for attach/resume/spawn; live external sessions
get a 3-second liveness guard (past_embeds skips the guard for sessions we
killed ourselves).

n opens a model-picker popup and spawns a fresh --session-id session;
model aliases are auto-discovered by scanning the installed claude binary
(no API call, no exec). ctrl-f toggles fullscreen for the embedded pane.

Mouse is now captured: wheel always scrolls the feed, left-drag selects
screen text copied on release via OSC 52 (like Claude Code). Native
selection needs shift held.

FeedCache stores per-entry rendered lines + wrapped heights, rebuilt only
when the content fingerprint changes — work while holding the app mutex is
proportional to what changed, and feed scroll now works past u16::MAX lines.
Kind::User entries (deep-blue ❯ prefix) surface user prompts from request
bodies via record_user_prompt.

src/markdown.rs added: GFM table rendering (box-drawing, width-fitted
columns) and heading # marker stripping, compensating tui-markdown 0.3.5
gaps without upgrading.

The proxy tap now runs on a dedicated tokio task via a bounded mpsc channel
(try_send; drop-on-full) so it never delays forwarded bytes. Listener is
bound before the TUI starts so multi-instance port coexistence works from
launch; CT_UPSTREAM added for fully offline testing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-12 11:27:34 +02:00
Jonas H
d34496da0b Document embedded terminal module in CLAUDE.md
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 09:11:00 +02:00
Jonas H
255c67de3f Fix session key extraction for Claude Code 2.1.x user_id format
metadata.user_id is now a JSON-ish blob containing "session_id":"<uuid>"
(verified against the 2.1.173 binary: user_id is built from an object
with device_id/account_uuid/session_id). split("session_") was matching
inside "session_id":" and producing mangled keys like `id":"a78…`,
which broke the embed-session match — so the pane never grew for
interactive prompts. New session_key() handles both the JSON blob and
the legacy user_…_session_<uuid> format, with tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 09:08:28 +02:00
Jonas H
ee429be917 Crop claude chrome rows; size ask-tool pane from option count
Render window is now content-anchored instead of the raw screen top:
ends BOTTOM_CROP(2) rows above the last non-blank row (hides the
"? for shortcuts"/mode hint rows) and starts no higher than row 2
(hides "✻ Worked for 1s"; the streaming spinner stays visible since it
sits next to the input box). The PTY gets PTY_PAD(4) extra rows so
Claude Code still has room to draw what we crop. Compact pane shrinks
12 → 8 rows.

AskUserQuestion pane height is now estimated from the tool input
(max over questions of: question text + 2 rows per option incl. the
implicit "Other" + submit/hint rows + tab header), replacing the flat
75% — which remains the fallback for ExitPlanMode/parse failures.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 09:04:19 +02:00
Jonas H
b05706a51e Keep the claude pane prompt-only: compact height + auto transcript wipe
The pane was showing Claude Code's own transcript (tool calls, diffs) —
redundant with the feed above. Two measures:

- Default pane height is now compact (12 rows): room for the input box
  and status, (almost) none for transcript. Interactive grow to 75% is
  unchanged.
- When a turn of the embedded session finishes streaming (Tap drop),
  schedule a ctrl-l into the PTY 400ms later: Claude Code clears the
  screen but keeps the conversation, leaving just the prompt UI.

Residual: while a response is streaming, a few transcript rows can
still scroll through the compact pane until the turn-end wipe fires.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 08:52:30 +02:00
Jonas H
a770052673 Grow interactive prompt pane to 75% of the screen
Claude Code clips AskUserQuestion option lists to the rows available;
60% was still cutting options off. Also relax the upper clamp so small
terminals give the prompt as much as possible (6 rows reserved).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 08:44:26 +02:00
Jonas H
4f9331e274 Replace alt-key scheme with directional focus (ctrl-arrows + F2)
Alt-modified keys never reach the app on keyboard layouts where Alt
composes characters (e.g. dk_mac_fixed: alt-c = ©, alt-q = @), so the
modifier-split model was unusable. New scheme, layout-proof:

- F2          show/hide the claude pane
- ctrl-down   focus the claude pane (spawns/shows it if hidden)
- ctrl-up     focus the feed
- claude focused: every other key goes to claude (bold cyan border)
- feed focused: original plain keybindings unchanged
- CT_DEBUG_KEYS=1 surfaces raw key events in the status bar

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 08:36:47 +02:00
Jonas H
60df921dbb Add embedded claude pane (option B spike): PTY + wezterm-term module
- src/term.rs: self-contained module spawning `claude --session-id <uuid>`
  with ANTHROPIC_BASE_URL pointed at our proxy, inside a portable-pty;
  wezterm-term models the screen (and answers terminal queries), a small
  renderer paints cells into the ratatui buffer.
- Toggle with alt-c; off by default, hiding keeps the session alive.
- Modifier-split input: plain keys go to claude, alt-keys drive the feed
  (alt-q quit, alt-j/k scroll, alt-f filter, alt-n/p session).
- Dynamic pane height: the tap flags AskUserQuestion/ExitPlanMode in the
  embedded session (matched via --session-id) before Claude Code renders
  the prompt → pane grows 35%→60%; shrinks when the tool_result echoes
  back in the next request.
- wezterm-term isn't on crates.io: pinned git rev of the monorepo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 08:16:53 +02:00
Jonas H
3f49e11b21 Initial commit: pass-through proxy TUI for Claude Code streams
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-11 07:59:05 +02:00