Tasks: nesting work items and their PRs in the sidebar
Phase 3 of 3. Small, verifiable tasks; each
_Test:_names a row oftesting-plan.md.
Task list
[x] 1.
sessionTreegains the two fields a row needsui/src/api/model.ts:SessionNode.label(prRepo ? shortRef : "#" + number) andSessionNode.lastActivity(endpoint.lastEventAt ?? ""), set for both the outer node and each inner one. The doc comments stop naming the retired Sessions screen.- No new "this item's PRs" derivation anywhere else (R5.2).
- Depends on: none
- Requirements: R2.1, R2.2, R2.3, R5.2
- Test:
T1 — bun run test -- src/api/model.test.ts
[x] 2. The sidebar renders the tree
ui/src/views/Work.tsx:sessionTree(sorted); each item wrapped in.lp-side-itemwith a named<ul className="lp-side-prs">ofPullRequestRows when it has any;activeRefresolves the hash (or the newest-item fallback) once, and drivesselectedon both levels plusowneron the parent.- Depends on: 1
- Requirements: R1.1, R1.2, R1.3, R1.4, R1.5, R2.4, R3.3, R3.4
- Test:
T2, T6 — bun run test -- src/App.test.tsx
[x] 3. The route owns the viewed trace
ui/src/views/WorkItemDetail.tsx:initialTraceRef+useState→ atraceRefprop and a derivedviewed, with the ownership guard; the transcript fetch, the caption's session, the event-fallback filter and the chat bar's target all readviewed; the trace tabs become links onhrefFor({ name: "work", ref }).- Security-relevant (abuse cases A1, A2): the guard is the whole of R4.3, and one resolved value is the whole of A2.
- Depends on: 2
- Requirements: R3.1, R3.2, R4.1, R4.2, R4.3, R4.4
- Test:
T2, T7, T11 — bun run test -- src/App.test.tsx src/components/Transcript.test.tsx
[x] 4. The nesting's styling
ui/src/styles/app.css:.lp-side-item,.lp-side-prs,.lp-side-pr(indent + per-row gutter hairline + smaller ref) and.lp-side-row.owner.- Depends on: 2
- Requirements: R1.1, R2.4, R3.4
- Test:
T5 — Chromium screenshots over the production build
[x] 5. Tests
ui/src/api/model.test.ts: the existingsessionTreeexpectation updated to the new shape, plus the foreign-repo label /lastActivitycase.ui/src/App.test.tsx: the nested-list case, the PR-row-opens-its-session case, and the trace tabs re-asserted as links.- Depends on: 1, 2, 3
- Requirements: all
- Test:
T1, T2, T6, T7
[x] 6. Verification and evidence
- Lint (at the lockfile's oxlint), the full vitest suite,
tsc --noEmit+ production build; Chromium screenshots of the sidebar and of a selected PR, against the demo fixture. Results inevidence/verification.md. - Depends on: 5
- Requirements: R5.1
- Test:
T5, T8
- Lint (at the lockfile's oxlint), the full vitest suite,
[x] 7. Docs in the same PR
docs/capabilities/control-plane.md: the sidebar behaviour bullet and a history row.ui/README.md: the screen description and the layout note.- Depends on: 6
- Requirements: —
- Test:
markdownlint