ohm: migrate orphaned subagent transcripts (0019.x, 0026.x) + renumber dup 0046.0 -> 0073
Backfills transcripts that existed only locally in ohm-infra: - 0019.1/.2/.3 - UX-polish wave subagent transcripts (driver 0019.0 never finalized) - 0026.1-.9 - security-audit-0026 subagent transcripts (driver abandoned/closed-out by 0068; audit drove published 0030 remediation) - 0073.0 - PPE/progressive-delivery + engineering-handbook session, originally drafted as a duplicate 0046.0; reassigned next free number (0072 taken by a concurrent session) sessions.json: add 0019/0073 titles, update 0026 title. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,158 @@
|
||||
# SESSION-0019.1 — App.css + index.css token sweep
|
||||
|
||||
Parent: SESSION-0019.0-TRANSCRIPT-… (UX-polish wave, rfc-app v0.21.0, roadmap item #31)
|
||||
|
||||
## Goal
|
||||
|
||||
Sweep `frontend/src/App.css` (2434 lines) and `frontend/src/index.css`
|
||||
onto the design-token system established in `frontend/src/styles/tokens.css`:
|
||||
hardcoded hex → nearest semantic/primitive token, font-size literals →
|
||||
`--text-*` scale, border-radius literals → `--radius-*` scale, safe
|
||||
spacing where it maps cleanly, a coherent transition vocabulary + a
|
||||
consistent `:focus-visible` ring, and base rules pointed at semantic
|
||||
tokens. Hard constraint: never rename/remove a selector (parallel
|
||||
siblings reference these class names); values + additive rules only.
|
||||
|
||||
## Pre-state
|
||||
|
||||
- Worktree: `/Users/benstull/git/rfc-app-v0.21.0-appcss`
|
||||
- Branch `feature/v0.21.0-appcss-sweep`, based on `5be2c48` (token-module
|
||||
foundation).
|
||||
- index.css used literal `#1a1a1a` / `#fafaf8` / inline font stack.
|
||||
- App.css had ~98 distinct hex (66× `#fff`, 51× `#1a1a1a`, plus a long
|
||||
tail of near-duplicate grays: #888/#999/#777/#666/#555 etc.), 16
|
||||
distinct font-size px values, 12 distinct radius px values.
|
||||
|
||||
## Turn-by-turn arc
|
||||
|
||||
1. Read tokens.css (the foundation) + both target files in full
|
||||
(App.css needed two reads — 2434 lines). Confirmed branch/base.
|
||||
2. Extracted the full distinct-hex inventory via grep+uniq across both
|
||||
files to build the mapping deterministically rather than guessing.
|
||||
3. Round-1 script (`/tmp/sweep.py`): regex word-boundary,
|
||||
case-insensitive, longest-key-first replacement of all hex that map
|
||||
cleanly to a ramp step or status/accent token. 615 replacements.
|
||||
- One dict-key collision worth noting: `#ddd` appears as both a
|
||||
gray-300 candidate and an on-dark-muted candidate. Resolved to
|
||||
`--c-gray-300` (the consolidation target); the header user-name
|
||||
`#ddd`-on-dark shifts imperceptibly to #d1d5db.
|
||||
4. Re-grepped remainder; 35 distinct hex left — all genuinely off-token
|
||||
(true blues, violet tints/shades, functional state dots, deep
|
||||
diff-contrast shades, warm oranges with no token).
|
||||
5. Round-2 script (`/tmp/sweep2.py`): conservative — only the 7 hex that
|
||||
are unambiguously the same ROLE as an existing token and visually
|
||||
near it (light-red error bgs/borders → danger-bg/-border, warm soft
|
||||
bgs → warning-bg-soft). 15 replacements. Left everything else.
|
||||
6. index.css base `:root` → `var(--font-sans)`, `var(--color-text)`,
|
||||
`var(--color-bg)`.
|
||||
7. Round-3 script (`/tmp/sweep3.py`): font-size px → `--text-*` (280),
|
||||
border-radius px → `--radius-*` (128), `rgba(255,255,255,.15/.25)` →
|
||||
`--color-on-dark-soft/-hover` (5), the three 48px header-band values
|
||||
→ `--header-height` (3). Note: script rewrite invalidated an Edit I
|
||||
had queued for `.app-header`; re-read + re-applied.
|
||||
8. Promoted `.app-header` to semantic `--color-header-bg` /
|
||||
`--color-text-inverse`.
|
||||
9. Appended (not interleaved) the interaction-polish layer: a
|
||||
transition vocab on hover-reactive selectors + one `:focus-visible`
|
||||
ring using `--color-focus-ring`. Additive only — no resting-state
|
||||
change, reduced-motion handled by the token module's media query.
|
||||
10. Build: first attempt failed on `VITE_APP_NAME is required` (env
|
||||
gate, not CSS). Re-ran with `VITE_APP_NAME=OHM` → built in 249ms,
|
||||
only the expected ~500kB chunk-size warning. CSS is sound.
|
||||
11. Committed; wrote this transcript.
|
||||
|
||||
## Hex → token MAPPING TABLE
|
||||
|
||||
Grays (→ neutral ramp):
|
||||
| literal(s) | token | note |
|
||||
|---|---|---|
|
||||
| #ffffff, #fff | --c-white | |
|
||||
| #fafafa, #fafaf8, #fafaf9, #fafbfc, #f9f9f9, #f9fafb | --c-gray-50 | |
|
||||
| #f3f4f6, #f5f5f5, #f6f6f4, #f7f7f5, #f7f6f0 | --c-gray-100 | |
|
||||
| #f0f0ee, #fcfcfb | --c-gray-150 | warm canvas |
|
||||
| #e5e5e5, #e5e7eb, #e5e5e0, #e7e5e4, #eee | --c-gray-200 | |
|
||||
| #d1d5db, #d4d4d4, #ddd, #ccc | --c-gray-300 | **#ccc→#d1d5db slightly lighter; #ddd→#d1d5db imperceptible** |
|
||||
| #9ca3af, #aaa, #b0b0b0, #94a3b8 | --c-gray-400 | #94a3b8 is slightly cooler→neutral, minor |
|
||||
| #6b7280, #888, #999, #777, #666, #555 | --c-gray-500 | **#555→#6b7280 and #999→#6b7280 are the most noticeable gray shifts (the desired consolidation)** |
|
||||
| #4b5563, #444, #475569 | --c-gray-600 | **#444→#4b5563 noticeable; #475569→#4b5563 slightly warmer** |
|
||||
| #374151, #333 | --c-gray-700 | **#333→#374151 slightly cooler, noticeable** |
|
||||
| #1f2937, #222 | --c-gray-800 | **#222→#1f2937 noticeable** |
|
||||
| #111 | --c-gray-900 | |
|
||||
| #1a1a1a | --c-ink (header→--color-header-bg, base text→--color-text) | |
|
||||
|
||||
Accent / status (→ family tokens):
|
||||
| literal | token |
|
||||
|---|---|
|
||||
| #5b5bd6 | --c-accent |
|
||||
| #4338ca | --c-accent-strong |
|
||||
| #7c3aed | --c-violet |
|
||||
| #166534 | --c-success-fg |
|
||||
| #dcfce7 | --c-success-bg |
|
||||
| #991b1b | --c-danger-fg |
|
||||
| #b91c1c | --c-danger-fg-strong |
|
||||
| #fef2f2, #fff5f5 | --c-danger-bg |
|
||||
| #fecaca, #fca5a5, #fcc | --c-danger-border |
|
||||
| #fee2e2, #fee | --c-danger-bg (light red error bg; **slightly pinker→#fef2f2**) |
|
||||
| #92400e | --c-warning-fg |
|
||||
| #b45309 | --c-warning-accent |
|
||||
| #fef3c7 | --c-warning-bg |
|
||||
| #fffbeb, #fff7ed, #fff8e0 | --c-warning-bg-soft (**#fff7ed warm→#fffbeb, minor**) |
|
||||
|
||||
Font-size (→ --text-* scale; round-to-nearest flagged):
|
||||
10→2xs · 11→xs · 12→sm · 13→base · 14→md · **15→lg(16)** ·
|
||||
16→lg · **17→xl(18)** · 18→xl · **19→xl(18)** · 22→2xl ·
|
||||
**24→2xl(22)** · **26→3xl(28)** · 28→3xl. 9px left as literal
|
||||
(below the 10px scale floor — the .beta-chip micro-tag).
|
||||
|
||||
Border-radius (→ --radius-* scale):
|
||||
2→xs · **3→sm(4)** · 4→sm · **5→md(6)** · 6→md · 8→lg ·
|
||||
**10→xl(12)** · 12→xl · **14→xl(12)** · **20→pill** (model-pill,
|
||||
already pill-shaped at its height) · 99→pill · 999→pill. `50%`
|
||||
(circle dots) left untouched.
|
||||
|
||||
On-dark + layout:
|
||||
rgba(255,255,255,0.15)→--color-on-dark-soft;
|
||||
rgba(255,255,255,0.25)→--color-on-dark-hover;
|
||||
48px header band (×3)→--header-height.
|
||||
rgba(255,255,255,0.08) (header link hover) LEFT — no token.
|
||||
|
||||
Left as literals (no clean token, intentional): blues #3b82f6 #2563eb
|
||||
#1e40af #dbeafe #bfdbfe #eff6ff #eef2ff #c7d2fe; violet tints/shades
|
||||
#c4b5fd #ede9fe #ddd6fe #faf5ff #4c1d95 #3737a0 #3730a3; status dots /
|
||||
functional #ef4444 #dc2626 #fbbf24 #f59e0b #d97706 #10b981; deep
|
||||
diff-contrast #14532d #7f1d1d #78350f #bbf7d0 #f0fdf4; warm/misc
|
||||
#9a3412 #c2410c #4a3f00 #cb6a6a #cfc8a8 #e6dca0 #fde68a #fdba74
|
||||
#fed7aa #f1f5f9. Spacing (--space-*) left untouched this pass —
|
||||
prioritized color/type/radius per the brief; no spacing literal was
|
||||
both clearly mappable and zero-layout-risk enough to be worth it.
|
||||
|
||||
## Cut state
|
||||
|
||||
- Branch: `feature/v0.21.0-appcss-sweep`
|
||||
- Final commit: `cbf02d5507f91cc5bf16a68b3f8a8b6b52990849`
|
||||
- Files changed: `frontend/src/App.css`, `frontend/src/index.css` (only).
|
||||
- Replacements: ~630 color, 280 font-size, 128 radius, 5 on-dark, 3
|
||||
header-height. Build green (`VITE_APP_NAME=OHM npm run build`, 249ms,
|
||||
expected chunk-size warning only).
|
||||
|
||||
## What the driver needs to know
|
||||
|
||||
- No selector renamed/removed — safe for parallel sibling subagents.
|
||||
- Gray consolidation deliberately shifts a handful of mid-grays by a
|
||||
visually-noticeable amount (#555/#999→gray-500, #444→gray-600,
|
||||
#333→gray-700, #222→gray-800). This IS the intended polish; operator
|
||||
should eyeball muted-text and secondary-button text before deploy.
|
||||
- 15px reading-body → 16px (lg): markdown/entry/landing body text gets
|
||||
1px larger. Intentional rounding; check it reads well.
|
||||
- The appended polish layer adds a global `:focus-visible` ring and
|
||||
transitions to broad element selectors (button/a/input/…). Low risk
|
||||
(focus-visible never fires on pointer), but it is the one place that
|
||||
touches elements beyond the named classes.
|
||||
|
||||
## §19.2 candidates
|
||||
|
||||
- The on-dark translucent-white pattern (`--color-on-dark-soft/-hover`)
|
||||
and the focus-ring/transition vocabulary are deployment-agnostic and
|
||||
would belong in a future `flotilla-core`-adjacent shared UI layer if
|
||||
rfc-app's frontend ever extracts one — but that's an rfc-app concern,
|
||||
not flotilla. No flotilla-side extraction implied by this work.
|
||||
@@ -0,0 +1,96 @@
|
||||
# SESSION-0019.2 — header rename + inbox icon + light inbox UX
|
||||
|
||||
Parent: SESSION-0019.0-TRANSCRIPT-… (UX-polish wave, rfc-app v0.21.0)
|
||||
Subsession: 0019.2
|
||||
Window: 2026-05-28T11-27 → 2026-05-28T11-31 (PST)
|
||||
|
||||
## Goal
|
||||
|
||||
Roadmap #24 (rename), #25 (inbox icon + light inbox UX), and the
|
||||
header's share of #31 polish — confined to the App.jsx header region,
|
||||
Inbox.jsx, and a new Inbox.css. No version/changelog/tag/merge/push.
|
||||
|
||||
## Pre-state
|
||||
|
||||
- Branch `feature/v0.21.0-header-inbox` at the foundation commit (token
|
||||
module `frontend/src/styles/tokens.css` present).
|
||||
- Header link text was "About" (already routing to /philosophy).
|
||||
- Inbox trigger used a 📮 emoji with title "Notifications inbox (§15.2)".
|
||||
- Inbox.jsx: working panel; row click marks-read + navigates; one
|
||||
"Mark all read (under filter)" button; terse empty copy; no per-row
|
||||
mark-read; unread indicated only by `.inbox-row.unread` bg tint.
|
||||
- No Amplitude `track()` calls inside Inbox.jsx (only api.js calls:
|
||||
listNotifications, markNotificationRead, markNotificationsReadByFilter).
|
||||
So "preserve §15 tracking" = don't break the data path; nothing to add.
|
||||
|
||||
## Turn-by-turn arc (honest)
|
||||
|
||||
1. Read tokens.css, the App.jsx header block (~150–238), Inbox.jsx full,
|
||||
and the §15 inbox block of App.css (1573–1641) to learn existing class
|
||||
names + property values before touching anything.
|
||||
2. #24: one-word change "About" → "Philosophy" (kept the title attr).
|
||||
3. #25 icon: replaced `<span>📮</span>` with a hand-rolled inline SVG
|
||||
envelope (18×18, viewBox 0 0 24 24, stroke=currentColor, ~1.75 stroke,
|
||||
rounded). Set `aria-label="Inbox"`, retitled "Inbox (§15.2)". Badge
|
||||
block untouched.
|
||||
4. #25 UX: refactored Inbox.jsx. Extracted `markOneRead(item)` (used by
|
||||
both row-click and the new per-row affordance) which also decrements
|
||||
the local unreadCount. Added an `inbox-unread-dot` span + `read`/`unread`
|
||||
row class, a per-row "Mark as read" button (inline check SVG) that sits
|
||||
OUTSIDE the Link and `preventDefault/stopPropagation`s so it marks
|
||||
without navigating, shown only for unread rows. Simplified the
|
||||
mark-all label to "Mark all read" with an explanatory title. Replaced
|
||||
empty copy with a "You're all caught up." state that branches on
|
||||
whether filters are active.
|
||||
5. Wrote Inbox.css (tokenized). Discovered via import order that Inbox.jsx
|
||||
is imported at App.jsx line 6, BEFORE App.css at line 30 — so under
|
||||
ESM depth-first eval Inbox.css injects FIRST and App.css wins ties.
|
||||
Wrote override rules one notch more specific (`.inbox-list .inbox-row…`)
|
||||
and `.inbox-empty .muted` to beat global `.muted`. New classes need no
|
||||
guard. All values via var(--space/-text/-color/-radius/-motion/-ease).
|
||||
6. Build: first `npm run build` failed — VITE_APP_NAME required (config
|
||||
guard, unrelated to my change; no .env in worktree). Re-ran with
|
||||
`VITE_APP_NAME="OHM RFC" npm run build` → green (expected ~971kB
|
||||
chunk warning only).
|
||||
7. Verified `git status` shows only App.jsx + Inbox.jsx modified and
|
||||
Inbox.css new (node_modules symlink left untracked). Committed exactly
|
||||
those three.
|
||||
|
||||
## Cut state
|
||||
|
||||
- Branch: `feature/v0.21.0-header-inbox`
|
||||
- Final commit: 317738ed7998a7af5abe0b64769941cb11808ab2
|
||||
- Files changed: frontend/src/App.jsx (header region only),
|
||||
frontend/src/components/Inbox.jsx, frontend/src/components/Inbox.css (new)
|
||||
- Build: green (chunk-size warning only).
|
||||
|
||||
## What the driver needs to know (inbox UX review pointers)
|
||||
|
||||
The inbox pass is LIGHT — same layout, panel, filters, bundle toggle,
|
||||
deep-links, and API calls as before. Exactly what changed for review:
|
||||
|
||||
- Unread/read: unread rows now get an accent left-bar (inset box-shadow)
|
||||
+ warm tint + a filled accent dot + medium-weight summary; read rows
|
||||
drop the dot (space reserved, stays aligned) and mute the summary.
|
||||
- Per-row affordance: a check-icon button appears on row hover/focus
|
||||
(always visible on touch via `@media (hover:none)`) that marks the row
|
||||
read without navigating. Uses the same markOneRead path.
|
||||
- Mark-all: relabeled "Mark all read" (+ title clarifying it's
|
||||
filter-scoped). Same `markNotificationsReadByFilter` call, same
|
||||
disabled-when-all-read guard.
|
||||
- Empty state: "You're all caught up." with filter-aware sub-copy.
|
||||
- Behavior preserved: row-click still marks-read then navigates +
|
||||
closes; unreadCount now also decremented locally on single marks (was
|
||||
only reset to 0 on mark-all before — minor, improves badge accuracy,
|
||||
SSE still authoritative per §15.3).
|
||||
|
||||
## §19.2 candidates
|
||||
|
||||
- Full inbox redesign deferred to a #25-followup: the operator's
|
||||
reference screenshot did not transmit, so this stayed a polish pass
|
||||
within the existing structure rather than a re-layout. Revisit with
|
||||
the screenshot.
|
||||
- The inbox-trigger / inbox-* base rules still live in App.css with
|
||||
hardcoded hex (a sibling is tokenizing App.css this wave). If that
|
||||
sweep lands, the few overrides in Inbox.css could shed their
|
||||
extra-specificity guards once import order is normalized.
|
||||
@@ -0,0 +1,141 @@
|
||||
# Session 0019.3 — Transcript
|
||||
|
||||
Parent: SESSION-0019.0-TRANSCRIPT-… (UX-polish wave, rfc-app v0.21.0)
|
||||
Subagent ordinal: .3 — roadmap item #32 (session/transcript page
|
||||
polish) + the /docs surfaces' share of #31.
|
||||
|
||||
## Goal
|
||||
|
||||
In the isolated worktree `/Users/benstull/git/rfc-app-v0.21.0-docs`
|
||||
on branch `feature/v0.21.0-docs-32`:
|
||||
|
||||
(a) Collapse single-transcript session roots — render the transcript
|
||||
inline at `/docs/sessions/:nnnn` instead of a dead-end placeholder;
|
||||
multi-transcript sessions inline the `.0` driver transcript and
|
||||
list the siblings.
|
||||
(b) Add a transcript metadata header (title, started/ended parsed from
|
||||
the filename ISO segments, derived duration, optional `tldr` from
|
||||
the manifest, external view-source link).
|
||||
(c) Docs-surface token polish + consistent loading/empty/error states +
|
||||
aria-labels on icon-only controls.
|
||||
|
||||
## Pre-state
|
||||
|
||||
- Foundation commit carried `frontend/src/styles/tokens.css` (the #31
|
||||
design-token module). Build requires `VITE_APP_NAME` (no default).
|
||||
- `/docs/sessions/:nnnn` (DocsSessionIndex.jsx) rendered a
|
||||
`.docs-session-overview` placeholder: "N transcript(s) in this
|
||||
session. Select one from the navigation."
|
||||
- DocsSessionTranscript.jsx rendered body via MarkdownPreview with a
|
||||
breadcrumb but no metadata header.
|
||||
- Backend `/api/docs/sessions/manifest` (api.py:177-178) returns
|
||||
`result["manifest"]` verbatim — the full `sessions.json` object —
|
||||
so arbitrary per-entry fields already reach the frontend.
|
||||
|
||||
## Turn-by-turn arc (honest)
|
||||
|
||||
1. Read tokens.css, SESSION-PROTOCOL.md (§1 naming + the 0017.0
|
||||
folder-layout amendment + the sessions.json shape), all seven owned
|
||||
docs components, api.js docs helpers, docs_sessions.py, and the
|
||||
api.py manifest route.
|
||||
2. Confirmed the manifest endpoint is a pass-through → **no backend
|
||||
change needed** for `tldr`. The decision branch in the task was
|
||||
resolved in favor of "already passes through".
|
||||
3. Read the existing docs CSS block in App.css (read-only) to learn
|
||||
which classes a sibling owns (.docs-article, .docs-empty,
|
||||
.docs-error, .docs-source-link, .docs-session-overview, etc.) so
|
||||
Docs.css would not collide.
|
||||
4. Rewrote DocsSessionTranscript.jsx: exported `gitSourceUrl`,
|
||||
`transcriptOrdinal`, `parseTranscriptMeta`, and `TranscriptMetaHeader`;
|
||||
added a manifest fetch for title+tldr; rendered the header above the
|
||||
body.
|
||||
5. Rewrote DocsSessionIndex.jsx to inline-render the primary transcript
|
||||
(driver `.0` preferred, else `files[0]`) and list siblings; reused
|
||||
the imported header + ordinal helpers.
|
||||
6. Created Docs.css (new classes only, all token-valued).
|
||||
7. Brought DocsUserGuide's bare `<p className="error">` onto the shared
|
||||
`.docs-error` + retry convention.
|
||||
8. Build failed first run (VITE_APP_NAME unset — env requirement, not
|
||||
my change); re-ran with `VITE_APP_NAME="OHM Verify" npm run build`
|
||||
→ green (974 kB index chunk; >500 kB warning expected/benign).
|
||||
9. Staged the four files explicitly (avoided the `frontend/node_modules`
|
||||
symlink), committed.
|
||||
|
||||
## Design decisions
|
||||
|
||||
**Inline-collapse (a).** URL stays stable to the session number — the
|
||||
session root fetches the index, picks a primary file, fetches its body,
|
||||
and renders the same `TranscriptMetaHeader` + `philosophy-body` the
|
||||
standalone route uses. No `<Navigate>`, no 301. Primary selection:
|
||||
`SESSION-NNNN.0-TRANSCRIPT…` if present, else `files[0]` (backend
|
||||
returns the list pre-sorted). For multi-transcript sessions, a
|
||||
`.docs-session-siblings` strip lists every transcript ordinal — the
|
||||
primary marked "(shown below)" with `aria-current`, the rest linking to
|
||||
`/docs/sessions/:nnnn/:filename`. No empty placeholder remains on any
|
||||
path that has at least one transcript.
|
||||
|
||||
**Metadata header (b).** `parseTranscriptMeta` regexes the
|
||||
`-TRANSCRIPT-<start>--<end>.md` ISO segment (`YYYY-MM-DDTHH-MM` x2,
|
||||
colons-as-dashes per protocol). Times are built as **local** Dates and
|
||||
rendered as wall-clock via `toLocaleString` — the filename encodes no
|
||||
timezone (PST implied), and duration is a difference of two same-basis
|
||||
Dates so the implied-TZ ambiguity cancels. Legacy renamed-letter
|
||||
transcripts (no segment) → all derived fields null → header shows just
|
||||
the title + source link (graceful degrade). Duration omitted when
|
||||
start==end or unparseable.
|
||||
|
||||
**tldr schema (b).** Consumed as a **string** field named `tldr` on the
|
||||
per-session entry of `sessions.json`, i.e. keyed by the 4-digit session
|
||||
number alongside `title`:
|
||||
```json
|
||||
{ "0019": { "title": "UX-polish wave …", "tldr": "One-line summary." } }
|
||||
```
|
||||
Read via `getSessionsManifest()` → `payload[nnnn].tldr`; rendered only
|
||||
when `typeof === 'string'` and truthy. Absent ⇒ no TL;DR line.
|
||||
|
||||
**Polish (c).** Docs.css styles ONLY the two new element families
|
||||
(`.docs-transcript-meta*`, `.docs-session-siblings*`), every value a
|
||||
tokens.css custom property, to avoid racing the #31 App.css sweep for
|
||||
the pre-existing docs selectors. DocsUserGuide normalized to the shared
|
||||
error convention. All icon-only controls already carried aria-labels
|
||||
(verified the drawer toggle `☰`, scrim) — no aria gaps found in owned
|
||||
files.
|
||||
|
||||
## Cut state
|
||||
|
||||
- Branch: `feature/v0.21.0-docs-32`
|
||||
- Final commit SHA: `adb5d2571532ad5992900791d295ef214ddfba0d`
|
||||
- Files changed (4):
|
||||
- `frontend/src/components/DocsSessionIndex.jsx` (rewrite — inline collapse)
|
||||
- `frontend/src/components/DocsSessionTranscript.jsx` (rewrite — meta header + exports)
|
||||
- `frontend/src/components/DocsUserGuide.jsx` (error-state normalize)
|
||||
- `frontend/src/components/Docs.css` (new)
|
||||
- **Backend: NOT changed.** docs_sessions.py untouched — manifest
|
||||
pass-through already exposes `tldr`. (No py_compile needed.)
|
||||
- Build: GREEN (`VITE_APP_NAME=… npm run build`; 974 kB chunk warning benign).
|
||||
|
||||
## What the driver needs to know
|
||||
|
||||
- **No backend coordination required** for this item — frontend renders
|
||||
`tldr` when present; the field's value-backfill is the documented
|
||||
out-of-scope follow-up.
|
||||
- **sessions.json `tldr` schema to backfill** (driver/operator task in
|
||||
`wiggleverse/ohm-session-history`): add an optional `"tldr": "<one
|
||||
line>"` string to any per-session entry next to `"title"`. The
|
||||
frontend already consumes it on both the inline session-root view and
|
||||
the standalone transcript view. Absent ⇒ no-op.
|
||||
- Inline-collapse changes the `/docs/sessions/:nnnn` semantics: it is no
|
||||
longer nav-only. The left-nav transcript rows + sibling links still
|
||||
point at the standalone `/docs/sessions/:nnnn/:filename` route, which
|
||||
is unchanged and now also carries the metadata header.
|
||||
- Build needs `VITE_APP_NAME` set (env requirement, not from this item).
|
||||
|
||||
## §19.2 candidates
|
||||
|
||||
- `parseTranscriptMeta` / `transcriptOrdinal` are filename-shape logic
|
||||
that mirrors the backend `_TRANSCRIPT_FILENAME_RE` and the nav's own
|
||||
`transcriptOrdinal` in DocsLayout.jsx — there are now two frontend
|
||||
copies of the ordinal regex (DocsLayout owns one; I export one). A
|
||||
future consolidation could lift a single `lib/transcripts.js` and have
|
||||
DocsLayout import it (DocsLayout is sibling-owned, so I did not touch
|
||||
it). Worth flagging for a follow-up de-dup.
|
||||
Reference in New Issue
Block a user