feat(ui): workspace hero-layout redesign + portfolio pass#100
feat(ui): workspace hero-layout redesign + portfolio pass#100
Conversation
Introduces a drop-in renderer for the Draft (Workspace) tab that lifts the AI-drafted answer into a dedicated hero column, with a sticky composer on top and a consolidated triage rail (workflow, signals, alternatives, feedback, context, model) on the right. Answer prose is set at 16px / 1.65 / 70ch for multi-paragraph readability; citation pills remain click-through to the cited source. All rules scoped under `.wsx` so nothing collides with existing `.cdw` Claude Design styles. No new tokens — reuses `--as-*` palette / accent / glass surfaces. Includes a smoke test covering the empty state, the grounded-response render, the thumbs-up feedback flow, and the disabled-generate title. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a new revamp feature flag defaulting off. When enabled, DraftTab renders the Workspace (Draft) tab via the new WorkspaceHeroLayout; when off, the existing ClaudeDesignWorkspace renderer stays in place. Prop shape is shared across the two renderers so flipping the flag requires no other change. Env key `VITE_ASSISTSUPPORT_REVAMP_WORKSPACE_HERO` and localStorage override `assistsupport.flag.ASSISTSUPPORT_REVAMP_WORKSPACE_HERO` both work for local rehearsal. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Documents the Workspace hero-layout redesign as a Claude Code handoff package: README overview, SPEC with grid geometry + typography table + a11y contract, INTEGRATION guide for the DraftTab swap and test steps, and an ACCEPTANCE checklist. Intended as the reviewer's companion to the feat(ui) component + flag commits — the SPEC describes what's intended, the ACCEPTANCE checklist is what reviewers verify. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a negation so portfolio screenshot PNGs under docs/screenshots/out/ ship with the repo even though the generic `out/` ignore rule is still in force for Tauri/Vite build outputs. Excludes the LinkedIn Live PPTX (above the 2MB large-files guard — regenerate via `cd docs/deck && npm run build`) and the LibreOffice thumbs/ intermediate artifacts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds six self-contained HTML mockups under docs/screenshots/panels/ (workspace in action, triage queue, ML intent, KB gap analysis, ops surface, eval harness) and a Node/Playwright capture script that renders each to a 2880×1800 PNG plus a 2×3 contact sheet. The mockups reuse the same `--as-*` token set as the live app via a shell.css subset, so portfolio visuals stay in sync with the app's design system. Outputs land under docs/screenshots/renders/ (renamed from `out/` so the repo's generated-artifact guard allows them through). CAPTIONS.md carries one-to-two-sentence copy per panel. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Produces a single-page 11in × 8.5in landscape PDF tying together the portfolio positioning: tagline "Your support team's second brain", five feature pillars (ML intent · hybrid search · trust-gated · feedback loop · local-first), and a three-column impact-stats strip (25% deflection · sub-25ms hybrid search · 3,500+ KB articles). Source is a self-contained HTML file consuming the same `--as-*` tokens as the live app; generate.mjs uses Playwright's page.pdf() for vector output plus a 2× PNG preview for web embeds. The hero image is pulled from docs/screenshots/renders/01-workspace.png so any workspace redesign re-syncs through on the next build. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A 16:9 editable deck for the LinkedIn Live titled "Running a local-first support agent on a Mac": title + problem + thesis + architecture + workspace demo + ML intent + hybrid search + trust gating + feedback loop + ops + lessons + Q&A. Slides use native text boxes, shapes, and embedded portfolio screenshots (not image backgrounds), so the speaker can edit copy in PowerPoint / Keynote / Slides before the Live. build.mjs runs pptxgenjs; the dep is pinned in a local package.json so the app's root package.json isn't polluted. The .pptx itself is gitignored (above the 2MB large-file guard) — the committed PDF is a LibreOffice render for preview; rebuild the .pptx via `cd docs/deck && npm run build`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Single entry point under docs/portfolio/README.md that ties the four portfolio artifacts together (workspace redesign, screenshot set, one-pager, LinkedIn Live deck) and documents how they share one design system sourced from src/styles/revamp/tokens.css. Includes a regeneration-commands section so any artifact can be re-synced after a token or workspace change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5acf9c9923
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const [rating, setRating] = useState<"up" | "down" | null>(null); | ||
| const handleRate = (value: "up" | "down") => { | ||
| setRating((prev) => (prev === value ? null : value)); | ||
| if (onRateResponse) onRateResponse(value); |
There was a problem hiding this comment.
Propagate rating clear events to onRateResponse
Clicking an already-selected thumb clears local UI state (setRating toggles to null), but the callback always sends the original value. In any integration that persists response ratings, this leaves backend/app state stuck at up/down while the UI shows the vote as cleared. Either emit the post-toggle state or remove toggle-off behavior so UI and callback semantics stay consistent.
Useful? React with 👍 / 👎.
|
|
||
| const claudeDesignWorkspacePanel = | ||
| workspaceFlags.ASSISTSUPPORT_REVAMP_WORKSPACE_HERO ? ( | ||
| <WorkspaceHeroLayout {...workspacePanelProps} /> |
There was a problem hiding this comment.
Pass feedback callbacks into WorkspaceHeroLayout
When the hero flag is enabled, this render path only spreads workspacePanelProps, which does not include onRateResponse, onFlagKbGap, or retrievalLatencyMs. That makes thumbs-up/down purely local UI toggles and leaves “Flag as KB gap” permanently disabled in the new layout, so the feedback surface cannot drive app-level workflows. Wire the callbacks (or conditionally hide these controls) before enabling this variant.
Useful? React with 👍 / 👎.
Adds docs/screenshots/live-capture.mjs — starts `pnpm dev` on port 1422 with VITE_E2E_MOCK_TAURI=1, primes localStorage with the workspace-hero + admin-tabs flags, drives the composer so a grounded draft renders on the Workspace tab, then walks through Queue, Analytics, and Operations capturing each at 1440×900 / 2× DPR. The shell's draft-tab rail is temporarily hidden via an injected stylesheet for a cleaner hero frame — no app code is changed. Panels 3 (ML intent drilldown) and 6 (eval harness) intentionally stay as the HTML mockups — OpsTab.tsx explicitly notes eval tooling is out of the active UI in this wave, and the ML-intent drilldown has no dedicated page. Also adds rebuild-contact-sheet.mjs (re-stitch the 2×3 sheet after mixing live captures and mockups) and fixes capture.mjs's src path regex for the renders/ rename. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Panels 1 (Workspace), 2 (Queue), 4 (KB gap / Analytics), and 5 (Operations / Deployment) are now rendered from the real running app via live-capture.mjs instead of the HTML mockups. Panel 1 shows the hero layout carrying a grounded draft with 86% confidence, inline citations, and the triage rail — all real component output flowing through the mocked Tauri IPC layer. Panels 3 (ML intent) and 6 (Eval harness) stay as HTML mockups because neither has a dedicated UI in the current wave. README + CAPTIONS now document the live-vs-mockup split per panel. Contact sheet regenerated from the new mix. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
WorkspaceHeroLayout ships its own self-contained triage rail (workflow, signals, alternatives, feedback, context, model footer), but the revamp shell was still rendering its draft-tab rail (WorkspaceQueueContext + Response playbook + AI status) on top. Two rails competed for right-column real estate and the hero never reached its intended full-width design in the real app. When REVAMP_WORKSPACE_HERO is on and activeTab === "draft", the shell now hides its rail and collapses .as-shell__content to a single column via the `as-shell__content--solo` modifier. Other tabs keep the two-column layout with diagnostics on the right. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Expands the dev-server mock IPC layer so running `VITE_E2E_MOCK_TAURI=1 pnpm dev` shows populated screens instead of sparse empty states. Improves the live portfolio captures and day-to-day dev work against the mock. Adds: - 3 deployment artifacts (v1.2.0 stable · v1.1.4 stable · v1.1.5-rc canary) - 4 deployment runs covering succeeded / paused / rolled_back cases - 3 eval runs with realistic grounding/faithfulness/intent F1 numbers - 5 triage clusters with real-sounding IT-support scenarios - 5 KB gap candidates with occurrences, low-confidence, ungrounded counts - `get_kb_gap_candidates` + `update_kb_gap_status` IPC handlers Shape matches src/types/insights.ts KbGapCandidate exactly; no existing Playwright / Vitest test depends on the previous sparse mock data. Re-captures the four live portfolio panels + contact sheet against the richer mock so the shipped PNGs show populated triage queue, KB gap dashboard, and deployment artifact lifecycle. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two companion docs for the deck: - REHEARSAL.md — 40-minute budget (30-min talk + 10-min Q&A), slide-by-slide cues with pivots per audience (IT leaders / ML eng / platform devs), an anticipated-questions matrix with short-form answers, three opening-line and three closing-line options, and a dry-run checklist. - DEMO-VIDEO.md — 7-shot storyboard for a 90-second async demo reel with verbatim narration per shot, pre-flight setup commands, timing table, voice notes, and a distribution checklist for LinkedIn / portfolio embeds. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds docs/case-study.md — an engineering-professional writeup of the three load-bearing architectural choices that cut against the industry default in 2026: logreg over embeddings for intent classification, hybrid TF-IDF + cross-encoder over pure ANN for retrieval, and trust-gated answer/clarify/abstain over optimistic generation. Each section explains the tradeoff, the concrete numbers (latency, model size, NDCG@5, calibrated hit rate), and what breaks in the default path. Designed to sit next to the one-pager on a portfolio site as evergreen writing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
fix(ui): stylelint cleanups post-#100 merge
Summary
Two things in one PR — kept together because each session's docs /
assets reference each other and should land as a coherent drop.
1. Workspace hero-layout redesign (3 commits, behind a flag):
WorkspaceHeroLayout.tsx— a 3-region renderer (stickycomposer on top, KB-grounded answer hero in the middle with
citations at 16px / 1.65 / 70ch, triage rail on the right) that
consolidates confidence, grounded claims, alternatives, feedback
controls, and context into one column.
.wsx— no new tokens, all--as-*reuse.ASSISTSUPPORT_REVAMP_WORKSPACE_HEROflag (default off);DraftTab.tsxbranches on it so the existingClaudeDesignWorkspacelayout stays reachable for A/B or rollback.flow, and disabled-generate title.
docs/redesign/(SPEC + INTEGRATION +ACCEPTANCE + README).
2. Portfolio pass (5 commits, all under
docs/):docs/screenshots/— six 2880×1800 PNG panels + 2×3 contactsheet + captions + Playwright capture pipeline.
docs/one-pager/— 11in × 8.5in landscape PDF with tagline,five feature pillars, and the 25% / <25ms / 3,500+ impact strip.
docs/deck/— 12-slide LinkedIn Live deck ("Running a local-firstsupport agent on a Mac"), built with pptxgenjs. The PPTX itself is
gitignored (above the 2MB large-file guard) — rebuild via
cd docs/deck && npm run build. Committed PDF is a LibreOfficerender for preview.
docs/portfolio/README.md— top-level index tying the fourartifacts together.
Verification
pnpm ui:typecheckcleanpnpm lintcleanpnpm test— 266/266 pass, including 4 newWorkspaceHeroLayout.test.tsxcases--as-*token set fromsrc/styles/revamp/tokens.cssVITE_ASSISTSUPPORT_REVAMP_WORKSPACE_HERO/ the localStorage overrideClaudeDesignWorkspace.tsxuntouched; rollback = flip the flagTest plan
pnpm dev, confirm the Draft tab still renders viaClaudeDesignWorkspace(flag off).ASSISTSUPPORT_REVAMP_WORKSPACE_HEROtotruein localStorage (or setVITE_ASSISTSUPPORT_REVAMP_WORKSPACE_HERO=1) and reload — confirm the 3-region hero layout renders, composer sticks to the top, answer prose sits at the centered 70ch column, and the triage rail shows workflow + signals + alternatives + feedback + context + model footer.[n]citation in a grounded draft and confirm it invokesonNavigateToSourcewith the source title.aria-pressedtoggles, then click again to clear.node docs/screenshots/capture.mjsand verify all six PNGs + the contact sheet regenerate.docs/one-pager/AssistSupport-one-pager.pdfanddocs/deck/AssistSupport-LinkedIn-Live.pdf— confirm they render cohesively in the same design system.Rollback
Set
VITE_ASSISTSUPPORT_REVAMP_WORKSPACE_HERO=0(already the default). No code revert needed.🤖 Generated with Claude Code
Lockfile rationale
This PR adds a scoped
docs/deck/package-lock.json— not a change to the rootpnpm-lock.yaml. The root workspace is unaffected.docs/deck/is built withpptxgenjs. To keep that dependency fully isolated from the app's rootpackage.json, the deck has its own tinypackage.json(installed via plain npm, not pnpm). Thepackage-lock.jsonis npm's pin file for that isolated sub-package and exists only socd docs/deck && npm run buildproduces a deterministic output.pnpm-lock.yaml.docs/deck/removes it entirely. The deck's role is documented, not load-bearing on the app.