tests: add UI primitive stories and fix design-sync previews#3626
Conversation
- Fix design-sync preview clipping: MuxPreviewShell resets the html/body 100vh lock from globals.css so the Claude Design gallery sizes cards to content instead of clamping documentElement.scrollHeight. - Add Storybook stories for 8 core UI primitives (Button, Input, Checkbox, Switch, Select, Dialog, Tooltip, Popover) under Components/. - Extend design-sync to bundle, grade, and upload the primitives: export compound subcomponents from gen-barrel, exclude the chat composer by path so the Input primitive keeps its name, add owned previews and overrides (cardMode single for overlays, skip Select's play-driven Open). - Refresh conventions header (agent-mode token accuracy) and NOTES. Change-Id: Icc840f38d910a641f77fa76468786f314045449f Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 71328d15f6
ℹ️ 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".
Address Codex review: the synced Dialog primitive exposed content/header/ footer parts but omitted DialogTrigger and DialogClose, so a design agent could only use it defaultOpen or fully controlled. Export both so consumers can declaratively open the dialog and make footer buttons close it. Change-Id: I9728a80625405c4698c609fc77f6a0d2443e51b5 Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review Addressed the Dialog parts finding: |
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
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". |
## Summary Long-lived auto-cleanup PR maintained by the **Auto-Cleanup Agent**. Each pass lands at most one extremely low-risk, behavior-preserving cleanup drawn from recently merged `main` activity, then advances the checkpoint below. Auto-cleanup checkpoint: 620c2a6 This PR currently contains six accumulated cleanups against `main`: 1. `src/node/services/taskService.ts` — dedupe queued-message foreground backgrounding into a private helper. 2. `src/node/services/workflows/workflowScriptResolver.ts` — reuse the `SKILL_SCRIPT_PATH_PREFIX` constant for canonical-path construction. 3. `src/node/services/workflows/WorkflowTaskServiceAdapter.ts` — extract the duplicated agent-task creation arg shape into a shared `WorkflowTaskCreateArgs` type. 4. `src/constants/workspaceTags.ts` (new) — centralize the workspace-turn task tag keys, removing the cross-layer `"mux.taskHandleId"` string duplication. 5. `src/node/services/tools/workflowProgress.ts` — extract the duplicated "latest phase" lookup into a shared `getLatestPhaseEvent` helper. 6. `src/browser/features/RightSidebar/Workflows/WorkflowBadges.tsx` — map workflow run-status glyphs through an exhaustive `Record<WorkflowRunStatus, LucideIcon>` instead of a repeated `if`-chain. ## This pass Rebased the branch onto the latest `origin/main` (clean) and considered the three new commits since the prior checkpoint: - coder#3624 (`feat: add Workflows right-sidebar tab with live run streaming`) - coder#3626 (`tests: add UI primitive stories and fix design-sync previews`) - coder#3627 (`feat: return workflow plan agent results`) coder#3624 added `WorkflowBadges.tsx`, whose `WorkflowStatusIcon` selected a glyph through a four-branch `if`-chain that re-spelled the identical `className="h-3 w-3 shrink-0"` + `style={{ color }}` props in every branch and fell back to a default `<Circle>` for unmatched statuses. Replaced that with a module-level `WORKFLOW_STATUS_ICON: Record<WorkflowRunStatus, LucideIcon>` map (mirroring the existing `WORKFLOW_STATUS_META` / `WORKFLOW_TONE_VAR` records in the same feature) and render the looked-up icon once. Behavior-preserving: the map reproduces the prior mapping exactly (`pending`/`running` → `Circle`, `backgrounded`/`interrupted` → `Pause`, `completed` → `Check`, `failed` → `X`), and using a `Record` makes the mapping exhaustive so a newly added run status is a compile error here rather than a silent fall-through. coder#3626 (Storybook/design-sync, test-only) and coder#3627 (already extracts its own `__muxAgentReturnValue` runtime helper) offered no additional low-risk dedup. <details> <summary>Prior pass — workflowProgress getLatestPhaseEvent helper</summary> coder#3623 added `src/node/services/tools/workflowProgress.ts`, in which both `buildWorkflowProgressSummary` and `formatWorkflowProgressNote` independently re-spelled the same `run.events.findLast((event) => event.type === "phase")` expression to find the latest phase event. Extracted that into a single private `getLatestPhaseEvent(run)` helper and referenced it from both functions, giving the "latest phase" definition one source of truth so the summary builder and the note formatter can't drift. Behavior-preserving: the helper's body and inferred return type are identical to the inline expression, so both call sites compute exactly the same value. </details> <details> <summary>Prior pass — checkpoint-only advance for coder#3621 (Claude Design integration)</summary> coder#3621 is purely additive and lives entirely under `.design-sync/` (plus one `.gitignore` entry); it contains zero production (`src/`) code. `.design-sync/**` is outside both the ESLint scope (`src/**`) and the TypeScript `include`, so `make static-check` cannot validate the behavior-preservation of any refactor there. That pass advanced the checkpoint without a code change. </details> <details> <summary>Prior pass — workspace-turn task tag keys centralization</summary> The workspace-turn task tag key `"mux.taskHandleId"` is **written** by `TaskService.createWorkspaceTurn` (node, coder#3617/coder#3619) and **read** by `findWorkspaceForTaskTarget` in `TaskToolCall.tsx` (browser, coder#3613) — the same magic string duplicated across the node/browser boundary. Extracted the three workspace-turn task tag keys (`handle`, `ownerWorkspaceId`, `turn`) into a new `@/constants/workspaceTags` module and referenced `WORKSPACE_TURN_TASK_TAGS` from both the node write site and the browser read site. Behavior-preserving: the extracted values are byte-identical to the previous literals, so the persisted tag keys and all lookups are unchanged. </details> <details> <summary>Prior pass — WorkflowTaskServiceAdapter WorkflowTaskCreateArgs type</summary> `WorkflowTaskServiceLike` (in `WorkflowTaskServiceAdapter.ts`) declared the agent-task creation argument object **twice** — once inline in `create(args: { ... })` and again inside `createMany?(args: Array<{ ... }>)` — as byte-identical 10-field shapes. Extracted a named `WorkflowTaskCreateArgs` interface and referenced it from both `create` and `createMany`. Behavior-preserving: structurally identical interface, signatures unchanged. </details> <details> <summary>Prior pass — workflowScriptResolver SKILL_SCRIPT_PATH_PREFIX reuse</summary> In `workflowScriptResolver.ts`, the `skill://` prefix is named by the module-level constant `SKILL_SCRIPT_PATH_PREFIX`, but the two canonical-path builders re-spelled the literal `` `skill://${...}` `` instead of reusing the constant. Both builders now interpolate `${SKILL_SCRIPT_PATH_PREFIX}`. Behavior-preserving: `SKILL_SCRIPT_PATH_PREFIX` is exactly `"skill://"`, so the interpolation is byte-identical. </details> <details> <summary>Prior pass — taskService queued-message dedup</summary> Considered coder#3605 (`fix: background foreground waits for prequeued messages`), which open-coded the same queued-message guard at two `TaskService` wait-registration sites. Both sites now delegate to a single private helper `backgroundForegroundWaitIfQueued(shouldBackgroundOnQueuedMessage, requestingWorkspaceId)`. Behavior-preserving: the helper folds in the `requestingWorkspaceId` truthiness guard and the pushed call is unchanged. </details> ## Validation - `make static-check` is green for the touched code (ESLint, `tsconfig` + `tsconfig.main.json`, Prettier). (`fmt-shell-check` is the only non-passing step, solely because the `shfmt` binary is absent in this environment; no shell files are touched.) - Targeted tests pass: `bun test src/browser/features/RightSidebar/Workflows/workflowDisplay.test.ts src/browser/features/RightSidebar/Workflows/projectWorkflowRun.test.ts` (32 tests) cover the same Workflows feature module the change lives in. ## Risks Minimal. All accumulated changes are pure local extractions / constant reuse; no logic, types, or call semantics change. --- _Generated with `mux` • Model: `anthropic:claude-opus-4-8` • Thinking: `xhigh`_ <!-- mux-attribution: model=anthropic:claude-opus-4-8 thinking=xhigh --> --------- Co-authored-by: mux-bot[bot] <264182336+mux-bot[bot]@users.noreply.github.com>
Summary
Adds Storybook stories for 8 core Mux UI primitives and syncs them into the Claude Design design system, and fixes the design-sync preview rendering so component cards show their content on the gallery's main page.
Background
The design-system sync previously shipped only app-level feature components (tool-call cards, settings sections, banners) — none of Mux's foundational primitives (
Button,Input,Select, …) were storied, so the sync (which only covers storied components) had no building blocks for the design agent to compose with. Separately, design-sync preview cards rendered as empty dark boxes on the gallery main page; the component was only visible after clicking "Edit".Implementation
globals.csspinshtml,body,#root,#storybook-rootto100vh, which clampsdocumentElement.scrollHeightinside the gallery's auto-sizing iframe so cards never grow to fit content.MuxPreviewShellnow injects aheight:autoreset so the gallery measures the true content height. No-op for fixed-overlay previews (theirscrollHeightalready floors at the viewport).Components/<Name>stories (Button, Input, Checkbox, Switch, Select, Dialog, Tooltip, Popover) using the lightweight isolated meta.gen-barrel.mjsnow exports the compound subcomponents (Dialog/Tooltip/Popover parts) ontowindow.Mux, and excludes the chat composer by path so theInputprimitive keeps the canonical name without a title-segment collision. Adds owned previews and config overrides (cardMode: singlefor overlays; skip Select's play-drivenOpen). Bundle stays at 4.48 MB (under the 5 MB cap); render-check is 33/33 clean.Validation
make typecheck,make lint, prettier: clean.matchagainst their storybook reference; uploaded and verified on the design-system project.Risks
Low — no app/product behavior changes. The only
src/additions are new Storybook story files; everything else is.design-sync/tooling. Chromatic will show 8 new stories (new baselines to accept).