Commit graph

62 commits

Author SHA1 Message Date
Shay
2d850c8d9b fix(workbench): preserve command section focus indices 2026-06-12 09:06:52 -07:00
Shay
94a122ba6e fix(workbench): guard recent-item persistence 2026-06-12 09:06:22 -07:00
Shay
2746655bb4 feat(workbench): evidence context, inspector drawer & command registry (Wave 1A/1B)
Brief 4 of the Wave 1 evidence spine — wire the evidence-context architecture
so every route can project into one shared evidence manifold.

Command registry (1A):
- commandRegistry.ts: useSyncExternalStore-backed command store with a cached
  snapshot (referentially stable to avoid render loops); useCommands /
  useCommandRegistry; recent-items in localStorage (last 10).
- CommandPalette.tsx: reads from the registry; all ten routes are navigation
  commands (was Chat/Proposals/Evals hardcoded); fuzzy filter, recent section,
  shortcut badges; Router/Fallback split preserved.
- useGlobalKeyboard.ts: Cmd+K palette, Cmd+I inspector, Cmd+1-0 routes, ? help.

Evidence drawer (1B):
- evidenceContext.tsx: EvidenceSubject union (turn|proposal|artifact|
  eval_result|none) + useEvidenceSubject hook + EvidenceProvider above the
  router Outlet so inspector state persists across route transitions.
- RightInspector.tsx: five evidence projections (was a null stub); reuses the
  Brief 2 primitives (MetadataTable, DigestBadge, Timestamp, badges).
- Shell.tsx: visibility driven by inspectorOpen (collapsed by default); no more
  hardcoded collapsed=true.
- KeyboardHelp.tsx: shortcut reference dialog.
- TopBar.tsx: palette open state lifted to Shell via props.

Tests: evidenceContext + RightInspector specs added; CommandPalette keyboard
contract updated for the ten-command navigation set (clamp at both ends).

Deferred (noted in spine doc): per-route register()/setSubject call sites,
action-commands (run eval / copy hash), resizable inspector width.

Verified: tsc -b + vite build green; affected specs pass per-file.
2026-06-12 07:44:19 -07:00
Shay
af8d4f75da fix(workbench-ui): guard SplitPane storage access
Handle environments where localStorage is unavailable and provide the Vitest browser-storage shim expected by SplitPane tests.
2026-06-12 07:08:22 -07:00
Shay
5b68e78ed2 feat(workbench): six evidence primitives (Wave 1C)
SplitPane, TabBar, MetadataTable, DigestBadge, Timestamp, SearchInput.
All token-driven, keyboard-navigable, ARIA-accessible, dark theme,
motion-respectful. No new dependencies — TabBar uses native ARIA
semantics instead of @radix-ui/react-tabs.

PreviewPage updated with all six components in representative states.
Section 1C checked off in wave-1-evidence-spine.md.
2026-06-12 06:45:20 -07:00
Shay
6d1f6bba0c feat: implement CORE Workbench W3 Ratification Corridor 2026-06-03 20:13:36 -07:00
Shay
30972e184e
feat(workbench/W-029): proposal queue (#329) 2026-05-26 21:08:36 -07:00
Shay
19506e9f60
feat(workbench/W-031): replay theater (ADR-0160 §Phase 6, deterministic-evidence UX) (#328) 2026-05-26 20:56:31 -07:00
Shay
00f5056209
feat(workbench/W-030): eval center (safe lanes only, ADR-0160 §Phase 5) (#327) 2026-05-26 20:39:30 -07:00
Shay
a612038d41
feat(W-028): chat surface + trace drawer (#303) 2026-05-26 13:22:11 -07:00
Shay
cdead696ed
feat(W-027): Workbench frontend shell — five-region grid + ten empty routes + live StatusFooter (ADR-0160 / ADR-0162) (#299)
- Five-region CSS grid shell (TopBar, LeftNav, Main, StatusFooter; Inspector collapsed)
- Ten placeholder routes with EmptyState cli/string variants and ApiErrorBoundary
- Extended EmptyState API: nextAction accepts string (button) | { kind: "cli", command }
- Updated CommandPalette: real fuzzy search over three commands (Chat, Proposals, Evals)
  with ↑/↓/Enter keyboard nav and useInRouterContext degradation for Branch 1 preview
- TanStack Query hooks for all W-026 endpoints; 30s polling on runtime/status
- TypeScript mirror of workbench/schemas.py at src/types/api.ts
- StatusFooter: mutation_mode badge, git_revision (copy on click), checkpoint_revision
  with amber warning + ADR-0157/ADR-0158 expansion note
- TopBar: CORE Workbench wordmark, ⌘K palette trigger, connection pill
- ApiErrorBoundary (class component) catches WorkbenchApiError → ErrorState
- scripts/dump-api-schemas.py: AST-based Python dataclass field extractor
- workbench-ui/api-schema-snapshot.json: checked-in drift sentinel
- 51 tests across 10 files (0 failures); enum-coverage 4/4; clean vite build
2026-05-26 12:09:12 -07:00
Shay
e89463a975
feat(workbench-ui): design system v1 scaffold (ADR-0162 Branch 1) (#295)
* feat(workbench-ui): design system v1 scaffold

* fix(workbench): close R1 (GroundingSource enum coverage) + R4 (digest test)

R1 — Promote GroundingSource to a typed Literal in core/epistemic_state.py
so it has the same single-source-of-truth shape as ReviewState.  The
existing epistemic_state_for_grounding_source() function already
enumerates the six labels (pack, teaching, vault, partial, oov, none);
this codifies them.

scripts/dump-enums.py now snapshots GroundingSource via the existing
literal_values helper.  workbench-ui's enumCoverage.test.ts gains a
fourth assertion that the badge mapping matches the Python source
1:1.  Adding a grounding-source value on the Python side without
updating the badge fails the build-time test loud — same discipline
as the other three enums.

R4 — Add an explicit DigestBadge test to StableJsonViewer.test.tsx:
asserts the badge text matches the SHA-256 prefix of the source bytes,
and clicking the badge copies the FULL digest (not the truncated
prefix).  Recomputes the expected digest via crypto.subtle to avoid
hard-coding a hex string that could drift.

R2 (component-level reduced-motion enforcement), R3 (EmptyState
copy-CLI affordance), and R5 (`uv run core` packaging paper cut) are
deferred — R2/R3 become meaningful with W-027/W-029, R5 is a
packaging-layer concern outside this PR's scope.

Validation:
- pnpm test: 19 passed (was 17, +1 enum coverage, +1 digest test)
- pnpm build: clean
- pnpm test:enum-coverage: 4 passed
- core test --suite smoke -q: 67 passed
2026-05-26 11:33:27 -07:00