Skip to content

Commit 9933d86

Browse files
rohans0509claude
andcommitted
refactor: restyle jobs viewer as editorial logbook
The original jobs UI shipped as a dashboard — 4-cell run-ledger, twin Settings/Outcome panels of monospaced key/value tiles, redundant 3-cell impact grids on every row. The viewer everywhere else is editorial: Palatino serif, paper cream, navy accent, ornaments, quiet page rows. The jobs surface now matches that register. List view: hero kicker + prose deck replaces the stat ledger; runs group under day labels (Today / Yesterday / weekday / Month D) with an HH:MM time gutter; each entry is one row — kicker, serif title, two-line summary, status dot + composed tally. No more right-side impact panel. Detail view: dual Settings/Outcome panels collapse into a single two-column colophon (small-caps dt / serif dd); failure gets a left- border callout; ornament divides metadata from transcript. Status is a sage/navy/burgundy dot, not a pill chip. Transcript internals (tool cards, chat bubbles, parsers) are unchanged — only the surrounding chrome moved. Decision log + open questions for reviewer: docs/plans/2026-05-10-jobs-ui-redesign.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 7d2e704 commit 9933d86

4 files changed

Lines changed: 589 additions & 323 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# Jobs viewer redesign — decision log
2+
3+
Started 2026-05-10. Owner: Claude (Opus 4.7).
4+
5+
## Why
6+
7+
The jobs UI shipped in commits `42b2ef9``7d2e704` was functional but felt
8+
out of place in the viewer. The rest of the viewer is **editorial**: Palatino
9+
serif, cream paper, navy accent, dingbat ornaments, hero-with-kicker, quiet
10+
page rows with chips. Jobs shipped as a **dashboard**: 4-cell run-ledger,
11+
twin Settings/Outcome panels of monospaced key/value tiles, a redundant
12+
3-cell "impact" grid pinned to every row.
13+
14+
The information was right; the visual register was wrong. This redesign keeps
15+
the data, swaps the register.
16+
17+
## Design principles (held while redesigning)
18+
19+
1. **Match the viewer's existing register.** Hero kicker + serif title +
20+
muted prose deck. Ornament where a section break needs weight. Chips for
21+
taxonomy, not for state.
22+
2. **One representation per fact.** The old detail page showed
23+
created/updated/archived in three places — strip, settings panel, outcome
24+
panel. Pick one.
25+
3. **Prose over grids.** "147 runs recorded — 3 active, 142 completed"
26+
reads better than a 4-tile stat grid, and matches the
27+
"{N} pages and {M} topics indexed" line on the overview page.
28+
4. **Group by day.** A run history is a logbook. Group rows under
29+
"Today / Yesterday / Mar 8" labels — that gives the page rhythm without
30+
filter chrome.
31+
5. **State as a dot, not a pill.** Pills are loud. A `` glyph in
32+
sage/navy/burgundy + the word reads like an editorial mark.
33+
6. **Don't touch transcript internals.** The tool-card and chat-bubble work
34+
is fine; only the surrounding chrome (avatar, section heading) changes.
35+
36+
## Concrete shape
37+
38+
### List page
39+
40+
```
41+
[kicker] LEDGER
42+
[title] Run history
43+
[deck] 147 runs recorded in .almanac/runs —
44+
3 active, 142 completed, 2 need attention.
45+
46+
──────── Today ────────
47+
14:32 absorb · claude / sonnet-4
48+
{displayTitle}
49+
{displaySubtitle}
50+
● Completed · +3 created, 2 updated · 3m 24s
51+
52+
09:14 garden · claude / sonnet-4
53+
...
54+
55+
──────── Yesterday ────────
56+
...
57+
```
58+
59+
- Time column: `HH:MM` in mono, fixed width, left.
60+
- Kicker: `operation · provider / model` — small caps, accent color.
61+
- Title: serif, 18px.
62+
- Summary: muted, two-line clamp.
63+
- Tally line: dot + status word + impact (only non-zero counts) + elapsed.
64+
No chips here; chips are for taxonomy elsewhere.
65+
66+
### Detail page
67+
68+
```
69+
[kicker] ABSORB
70+
[title] {displayTitle}
71+
[deck] {displaySubtitle}
72+
[chips] ● Completed claude · sonnet-4 3m 24s absorb-target
73+
74+
───────────── colophon ─────────────
75+
Started 2026-05-10 14:32 Created 3
76+
Finished 2026-05-10 14:35 Updated 2
77+
Provider claude / sonnet-4 Archived 0
78+
Turns 4 Tokens 12,432
79+
Cost $0.18 Log .almanac/runs/...
80+
Session {providerSessionId}
81+
82+
[if failure]
83+
Failure — {message}
84+
Fix — {fix}
85+
86+
[if targets]
87+
Targets
88+
{chips of paths}
89+
90+
91+
92+
Transcript · {N} events
93+
...
94+
```
95+
96+
- Colophon: one `<dl>`, two columns on wide screens, one column on narrow.
97+
Small-caps `dt`, serif `dd`, mono only when the value is a path/hash.
98+
- Failure: standalone callout with left border in accent; not a fact row.
99+
- Targets: chip row, separate section so it doesn't get lost in the dl.
100+
- Ornament `` divides above-fold metadata from the transcript, matching
101+
page header treatment elsewhere.
102+
103+
## What I deliberately did NOT change
104+
105+
- `jobs-transcript.js` parser and `buildTranscript` / `getToolCardModel`.
106+
- Tool card open/close, fact grid inside tool cards, code blocks.
107+
- API shape — pure frontend redesign.
108+
- Status taxonomy (queued / running / done / failed / cancelled / stale).
109+
- Color tokens. The dots reuse existing `--ca-accent`, `--ca-sage`, and a
110+
derived burgundy for failure.
111+
112+
## Open questions for reviewer
113+
114+
1. Is "LEDGER" the right kicker for the list page? Alternatives: "RUNS",
115+
"JOBS LOG". I chose "Ledger" because the viewer already uses words like
116+
"almanac" — "ledger" carries the same archival feel.
117+
2. The colophon two-column layout on the detail page — should it instead
118+
be a flowing definition list (one column, all the way down) for easier
119+
scanning? I picked two-column because the metadata count is high (10+
120+
fields) and a single column scrolls past the fold.
121+
3. Day grouping uses **local time** of the user's browser. If a run
122+
crosses midnight UTC, the label is whatever the viewer's clock says.
123+
Acceptable for a local viewer; flagging in case it's not.
124+
125+
## After-thoughts (filled in as work progresses)
126+
127+
- _(to be appended)_

test/viewer-ui-assets.test.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,10 @@ describe("viewer UI assets", () => {
5151
expect(jobsJs).toContain("export function createJobsView");
5252
expect(jobsJs).toContain('from "./jobs-transcript.js"');
5353
expect(jobsJs).toContain("transcriptEntry");
54-
expect(jobsJs).toContain("runOutcomeStrip");
55-
expect(jobsJs).toContain("jobImpact");
54+
expect(jobsJs).toContain("colophonEntries");
55+
expect(jobsJs).toContain("groupByDay");
56+
expect(jobsJs).toContain("logEntry");
57+
expect(jobsJs).toContain("statusMark");
5658
expect(jobsJs).toContain("cleanSummary");
5759
expect(jobsJs).toContain("displayTitle");
5860
expect(jobsJs).toContain("displaySubtitle");
@@ -79,19 +81,24 @@ describe("viewer UI assets", () => {
7981
expect(appCss).toContain("brightness(0.68)");
8082
expect(appCss).toContain(".ca-left .ca-link-button.is-active");
8183
expect(appCss).toContain(".ca-shell.is-rail-hidden");
82-
expect(appCss).not.toContain(".ca-job-row");
83-
expect(jobsCss).toContain(".ca-job-row");
84-
expect(jobsCss).toContain(".ca-job-impact");
85-
expect(jobsCss).toContain(".ca-job-stream");
86-
expect(jobsCss).toContain(".ca-run-ledger");
84+
expect(appCss).not.toContain(".ca-log-entry");
85+
expect(jobsCss).toContain(".ca-log-entry");
86+
expect(jobsCss).toContain(".ca-logbook");
87+
expect(jobsCss).toContain(".ca-log-day");
88+
expect(jobsCss).toContain(".ca-colophon");
89+
expect(jobsCss).toContain(".ca-transcript-section");
8790
expect(jobsCss).toContain(".ca-transcript");
8891
expect(jobsCss).toContain(".ca-chat-bubble");
8992
expect(jobsCss).toContain(".ca-tool-step");
9093
expect(jobsCss).toContain(".ca-tool-card");
9194
expect(jobsCss).toContain(".ca-tool-summary");
9295
expect(jobsCss).toContain(".ca-tool-facts");
9396
expect(jobsCss).not.toContain(".ca-event-row");
94-
expect(jobsCss).toContain(".ca-status-running");
97+
expect(jobsCss).not.toContain(".ca-job-impact");
98+
expect(jobsCss).not.toContain(".ca-run-ledger");
99+
expect(jobsCss).toContain(".ca-status-tone-active");
100+
expect(jobsCss).toContain(".ca-status-tone-done");
101+
expect(jobsCss).toContain(".ca-status-tone-alert");
95102
expect(appCss).toContain(".ca-suggest");
96103
expect(appCss).toContain(".ca-suggest-item");
97104
expect(appCss).toContain("overflow-wrap: anywhere");

0 commit comments

Comments
 (0)