feat(run): minimalist narration-style output for roar run#66
Merged
TrevorBasinger merged 14 commits intomainfrom Apr 21, 2026
Merged
feat(run): minimalist narration-style output for roar run#66TrevorBasinger merged 14 commits intomainfrom
TrevorBasinger merged 14 commits intomainfrom
Conversation
… summary Replaces the old boxed "ROAR Run Complete" summary with a streamed lifecycle of brief, prefixed lines followed by a three-column inputs / job / outputs block. Lifecycle (TTY, emoji-capable): 🦖 tracing with preload (proxy off) [user command output streams here] 🦖 trace done · 0.9s · exit 0 🦖 hashing (3 artifacts) 🕐 🦖 lineage captured · Inputs (1) Job 4bce5669 Outputs (2) · input.txt → 9 pip pkgs → input.txt · 10 dpkg pkgs output.json · 2 env vars · · roar show --job 4bce5669 roar dag 🦖 done · 1.4s (trace 0.9s + post 0.5s) Design points: * 🦖 prefix on lifecycle lines (roar: fallback without emoji) — reading down the left margin shows exactly what roar did. * Middle-dot · prefix on summary lines (quieter than 🦖 on every line) keeps the block visually grouped. * Arrow between columns only on the first data row — flow direction shown once, not on every row. * Trace duration and post-processing duration reported separately so roar's overhead is visible. * All lifecycle output goes to stderr; user command stdout stays clean for piping. * Three modes: - Rich (TTY + emoji): full output with color, spinner, emoji - Plain (TTY, no emoji): same but with `roar:` prefix and braille spinner - Pipe (no TTY): single `roar: done · ... (exit 0)` line only Respects NO_COLOR env var. Plumbs new data through RunResult: backend, post_duration, proxy_active, pip_count, dpkg_count, env_count. TracerResult gains `backend`. Supplemental changes: * roar/presenters/terminal.py (new): centralized TTY/color/emoji/width detection, replacing ad-hoc checks scattered across presenters. * roar/presenters/spinner.py: clock-emoji frame set + optional total count, with braille fallback. (Live counter advance plumbed but not yet wired end-to-end — current label shows the static total honestly.) Test plan: 16 new unit tests cover all three modes, interrupted runs (suggest `roar pop`), summary column layout, truncation, and the legacy one-shot show_report path. Full suite 646 passed. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds thin vertical rules (│, | without UTF-8) between the three columns so the Inputs/Job/Outputs grouping is unmistakable. Previously the columns relied on whitespace alone, which made subsequent rows look disconnected from their headers. Also splits the "next steps" line into two: `roar show --job <id>` on one line, `roar dag` (or `roar pop` for interrupted runs) on the next. Easier to pick out and copy. The vertical rules are dim, so they anchor visually without competing with the content. The first-row arrow (→ or >) sits just past the rule on its way into the destination column. Gutter width grew from 4 to 5 chars to accommodate the rule. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Major iteration on the run output design per user feedback: Lifecycle changes: - trace_starting shows tracer/proxy/sync params in compact format - New "hashed N artifacts · XX.XMB/s" throughput line after hashing - "lineage captured:" with colon (introduces the block below) - "done" omits total time, shows only "(trace Xs + post Ys)" Summary block redesign: - Removed vertical rule column separators; use color instead (job UID in yellow/bold to distinguish from input/output columns) - Added [Parent] sub-column to inputs showing producing job UID (currently shows "--" placeholder — parent lookup not yet plumbed) - Added "git:" line showing branch @ short-commit + clean/dirty - Added "env:" compact summary (N pip • N dpkg • N vars) - Added "Inspect:" section with blue commands + dim "#" comments - roar show and roar dag on separate lines under "Inspect:" label Data plumbing: - RunResult gains: git_branch, git_short_commit, git_clean, total_hash_bytes, hash_duration - Coordinator collects git info via subprocess (best-effort) - Coordinator computes hash throughput from output sizes + timing Stubs/follow-ups: - Parent job UID lookup (needs DB query per input artifact) - DAG summary line (needs session-level aggregate query) - Live m/n hashing counter (needs hook into record_job) - sync: always "off" (future capability) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds two missing pieces to the run summary block: 1. Short artifact hashes — each input and output now shows its primary hash digest (blake3:a1b2c3d4…) on a dim sub-line beneath the path. 2. DAG summary line — "DAG: N jobs • M artifacts • depth D" computed from the session's dependency graph via DagDataBuilder. Depth is the longest root-to-leaf chain. Best-effort; never fails the run. Plumbs dag_jobs, dag_artifacts, dag_depth through RunResult. Coordinator computes them after job recording using an additional read-only DB context. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary block changes per review: - Hashes on same line as filename (8-char digest, no algorithm prefix) - No brackets on Parent column - Color-coded columns: inputs=cyan, job=yellow, outputs=green, parent=dim gray. Headers use same color as their column but dim. Hashes and job UIDs are dim, not bright. - Parent job UID now populated from DB: each input artifact's producing job is looked up via artifacts.get_jobs(). Shows "--" when no producing job is found. - Filenames always shown (truncated with … when needed). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Implements the layout from roar_run_output_redesign.md: - Five distinct sections (Inputs, Job, Outputs, DAG, Inspect) with bold green headers and indented data rows, replacing the three-column table. - Emoji progression: 🦖 → 🦖 → → 🧬 for the lifecycle phases. - exit code appears before duration in the trace-done line. - Color tokens: status_green (256-color #35), command_blue (#74), dim, bold. No raw ANSI codes outside terminal.py. - Hashes carry no hue — weight only: bold (current job), regular (artifact digests), dim (source-job hashes). - "Source Job" replaces "Parent" in Inputs section. - Job section is key-value: id (bold), git, env. - Singular/plural: "1 artifact", "1 job", "1 var", etc. - 2-space section indent, 4-space row indent. - Column headers on section-header line, dim, aligned with data. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The trace_starting line shows the requested mode (often "auto"). The trace_ended line now appends the actual backend that was used in dim brackets: `🦖 trace done [preload] exit 0 · 0.9s`. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Status-line values (tracer:auto, MB/s, etc.) now start at the same column as the Hash column in Inputs/Outputs sections. - Path column is variable-width: sized to the longest filename in each section (min 14, max 30, default 20). Short filenames no longer waste space; long ones get room. - Section column headers (Hash, Source Job) aligned with data below. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All three zones now start at the same column (_VALUE_COL = 24): - Status-line values (tracer:auto, MB/s, timing) - Section column headers (Hash, Source Job) - Data-row hashes Previously the section headers used a path_w-relative offset that drifted from the status-line padding. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use 🦖 for all status lines. Drops (Emoji 15.1, 2024 — broken in tmux and older terminals) and 🧬. Consistent branding, no compat issues. - Account for emoji being 2 display cells in padding calculation so status values align correctly regardless of emoji/non-emoji mode. - Align # comments in Inspect section at the same column by padding commands to uniform width. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replaces the section-based layout with a compact, git-like narration
where every line is voiced by 🦖 or prefixed with · (detail block).
Format:
🦖 tracing · tracer:preload proxy:off sync:off
🦖 trace done [preload] · 0.9s · exit 0
🦖 hashed 5 artifacts · 204.9 MB/s
🦖 lineage captured:
· i/o 2 inputs ← 1 prior job · 3 outputs
· job 32156d79
· git master @ efc9a23 · clean
· env 9 pip · 10 dpkg · 2 vars
· dag 1 job · 3 artifacts · depth 1
·
· $ roar show --job 32156d79 # details
🦖 done · trace 0.9s + post 0.6s
Key changes from v7:
- No section headers, column headers, or per-artifact rows
- Summary is counts only: i/o (with prior-job count), job (bold),
git, env, dag — each on a · detail line with 3-char label
- Hashing spinner is transient (skipped for < 5 artifacts)
- Suggested command uses $ prefix ("paste this")
- pip/dpkg stay uncountable ("9 pip" not "9 pips")
- warn_amber (256 #172) for dirty git and non-zero exit
- · (middle dot U+00B7) as sole separator everywhere
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Resolve the actual tracer backend (preload/ebpf/ptrace) before execution by calling _get_tracer_candidates() early. The trace_starting line now shows the real backend instead of "auto". - Remove [backend] suffix from trace_done line — redundant now that trace_starting already shows it. - Remove "← N prior jobs" from the i/o detail line. Just show input and output counts. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The early backend resolution was hardcoding "auto" when no CLI --tracer flag was given, ignoring the config's tracer.default setting. Now mirrors execute()'s resolution: config default → CLI override → auto fallback. `roar tracer ptrace` followed by `roar run` now correctly shows tracer:ptrace. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove unused symbols left over from the v5→v8 iteration: - _HASH_W, _pad, _visible_len, format_size (run_report.py) - Unused `re` and `os` imports - Duplicate total_hash_bytes / hash_duration computation in coordinator (computed once now, used for both the hashed line and RunResult) No behavior change. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
TrevorBasinger
approved these changes
Apr 17, 2026
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
Replaces the boxed "ROAR Run Complete" summary with a compact, narration-style output where every status line is voiced by 🦖 and lineage details follow in a
·-prefixed block.Before:
After:
Key design decisions
tracer.default, shows actual backend (preload/ebpf/ptrace) not "auto".i/o,job,git,env,dag) for scanability.roar:prefix), pipe (no TTY → single done line to stderr).terminal.py:status_green(refactor: Restructure to support multiple backends and integrations #35),warn_amber(#172),command_blue(#74),dim,bold. No raw ANSI outside the style module.1 artifact,1 job,1 var).Files changed (9)
roar/presenters/run_report.pyroar/presenters/terminal.pyroar/presenters/spinner.pyroar/core/models/run.pyroar/execution/runtime/coordinator.pyroar/execution/runtime/tracer.pybackendfield on TracerResultroar/application/run/execution.pytests/unit/test_run_report.pytests/unit/test_terminal_caps.pyTest plan
ruff check+ruff format)roar tracer ptrace→roar runshowstracer:ptrace🤖 Generated with Claude Code