Skip to content

connect: image-phase steps, transcript metadata column, and startup-block polish - #74

Merged
hbrooks merged 13 commits into
mainfrom
connect-image-steps
Jul 23, 2026
Merged

connect: image-phase steps, transcript metadata column, and startup-block polish#74
hbrooks merged 13 commits into
mainfrom
connect-image-steps

Conversation

@hbrooks

@hbrooks hbrooks commented Jul 23, 2026

Copy link
Copy Markdown
Member

Context

ellipsis-dev/ellipsis#5943 (merged, deployed) split the sandbox image provisioning phase into build/container/smoke steps on the existing open step vocabulary, with build output streaming live. This PR renders those nicely, then iterates on the whole agent session connect startup and transcript presentation (each change verified live against the deployed backend).

Startup block

  • Image steps: labeled as sentences (Building image / Starting container / Smoke check) and nested one level under "Preparing image". The nesting rule is generic (a phase:step entry indents under its bare-phase sibling when one exists); hook steps have no bare-phase sibling (verified against the backend's _PhaseTracker) and render unchanged, as do old feeds. The sandbox_ready total still sums phase_timings only, never the step durations.
  • Live log tail: a running step shows its last 5 log lines as a dim indented tail beneath it (was: latest line inlined to the right), headed by a … +N earlier lines row on its own line.
  • Persistent trace: the startup tree no longer collapses once the session is ready; it stays as the all-✓ record of how the session came up, logs hidden behind the → panel.
  • Opener + headline: the app opens with a bold ✦ Connected to ellipsis.dev line, and the settled "Session ready!" headline reads bold instead of dim.

Transcript

  • Metadata column: assistant messages keep to the left 80% of the row; the right 20% carries right-aligned metadata. A turn's closing summary moves there as (4s) · $0.10 (the "turn complete" label dropped), with the cost now the step's own increment rather than Claude Code's cumulative total (tracked across the whole feed so --no-records subtracts hidden history; a lower total means a fresh process after a wake). Error summaries keep their own red line.
  • Live lines: Working / Generating / Running-tool readouts ((2m 31s · ↓ 9 tokens)) sit in the right column; pending sends show (sending…) / (queued…) there too.
  • Ordering fix: accepted sends (delivered, echo record lagging) render above the live activity lines, fixing the flash where "Generating…" appeared above the message it was answering (diagnosed from a screen recording).
  • One duration format: parenthesized human-readable durations everywhere — (428ms), (1.2s) under 5s, (10s), (1m 2s), (1h 3m 30s).
  • Icons: user ◆ cyan (unchanged), assistant prose ● (default foreground; tool calls stay green+bold), system/notice lines ✦ dim.
  • Footer: status · $total · model · session id · config · version, dropping the Last-step cost.

Verification

  • 260 tests pass (vitest), tsc --noEmit clean, CI green.
  • New unit coverage: image-step labels/nesting, live-output attachment, phase-timings-only total, reshapeTranscript (meta attachment, incremental/reset/hidden-history cost math, error and orphan summaries), humanDuration precision tiers.
  • Exercised live against the deployed backend throughout (fresh --rebuild --connect runs); the ordering-flash fix confirmed against the recording's frames.

Boundaries

  • No release tag (v* tags trigger the Homebrew pipeline).

hbrooks added 13 commits July 23, 2026 11:27
Backend PR ellipsis#5943 splits the sandbox image phase into three
sub-steps on the existing open step vocabulary (sandbox_phase records
with step build/container/smoke, build output streaming live). The CLI
already rendered them generically; this labels them as sentences
(Building image / Starting container / Smoke check) and indents a
phase:step entry one level under its bare-phase sibling when one
exists, so the startup block reads as a hierarchy under Preparing
image. Hook steps have no bare-phase sibling and render unchanged, as
do old feeds without step transitions. The sandbox_ready total still
sums phase_timings only; step durations ride each record's duration_ms
and are never added to it.
The startup block inlined a running step's latest log line to the
right of its label (Running setup… · Installing termcolor), while the
RUNNING_TAIL_LINES tail only appeared after drilling into the panel.
Now every running step shows its live tail as dim lines under the step
line; the inline latest-line form is gone, and finished steps' logs
stay behind the panel toggle. sandboxBlockRows counts the tails so the
viewport budget stays honest.
The block used to collapse to the single ✓ Session ready! headline
once done, with the hierarchy behind →. Now the config line, sandbox
summary, and step trace stay on screen as all-✓ lines — the durable
record of how the session came up. Logs stay hidden once nothing is
running (a running step's live tail requires a running step; finished
logs stay behind the → panel).
The tail sat flush with the step's label text; nudging it two columns
right makes it read as the step's child.
It was prefixed onto the tail's first log line; now it heads the tail
as its own dim line, and sandboxBlockRows counts the extra row.
The turn-complete summary rendered as its own full-width line under
the assistant message, showing Claude Code's cumulative session total.
Now each turn's closing assistant message keeps to the left 80% of the
row and its metadata (duration · step cost) renders right-aligned in
the remaining 20%, with the turn complete label dropped. The cost is
the step's own: result totals are tracked across the whole feed
(--no-records still subtracts hidden history; a lower total is a fresh
process after a wake, costing the new total itself). Error summaries
keep their label and their own red line, as does a summary with no
assistant message to hang on. Live streamed prose wraps in the same
80% column so nothing jumps when the turn commits.
Session ready! (and the idle parking line) now reads bold in the
default foreground instead of dim, standing out over the dim all-done
trace beneath it. While starting, the ticking headline stays dim.
status · total · model · session id · config · version, dropping the
Last step cost (each step's cost now rides the transcript's metadata
column) and the config: prefix.
… a dim star

Sender icons after review: user stays the cyan filled diamond, the
assistant's prose moves from the media-style circle to the smaller
filled circle (default foreground; the tool-call circle stays green
and bold so they never read the same), and system/notice lines gain a
dim four-point star instead of no icon.
…ating flash

- Durations read as parenthesized human components everywhere: (3s),
  (1m 2s), (1h 3m 30s), with ms kept below one second. One formatter
  (humanDuration) replaces the SDK formatDuration and the decimal
  msLabel styles ('42.0s', '1m 0s').
- A pending send's state moves off the message text into the
  right-hand metadata column as (sending…) / (queued…).
- The Working fallback line drops the esc-to-interrupt hint and sinks
  its elapsed time to the right column.
- Accepted sends (delivered, echo record in flight) render ABOVE the
  live activity lines: the running turn is the response to that
  message, so Generating no longer flashes in above it during the echo
  gap.
humanDuration scales precision with size: under 1s reads as
milliseconds (428ms), under 5s keeps one decimal (1.2s, trimming a
trailing .0), and longer durations stay whole h/m/s components.
- The app opens with a dim '✦ Connected to ellipsis.dev' line above
  the startup story, the name hyperlinking to this session's dashboard
  page.
- The Generating and Running-tool lines move their parenthesized
  readouts (elapsed, token count) to the right-hand metadata column
  like the Working line, dropping the esc-to-interrupt hint with them.
The OSC 8 hyperlink got broken by ink's wrapping and swallowed the
label; the opener is now plain 'Connected to ellipsis.dev' in bold,
and the clickable dashboard link stays in the footer.
@hbrooks hbrooks changed the title connect: nest and label the image phase's build/container/smoke steps connect: image-phase steps, transcript metadata column, and startup-block polish Jul 23, 2026
@hbrooks
hbrooks merged commit 94a0210 into main Jul 23, 2026
1 check passed
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