From 1a7ab3f2c6c349b43f6a674f0347ab1f8f9658cb Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 18 May 2026 22:33:40 +0000 Subject: [PATCH 1/4] feat(ui): D.2 migrate SamplePlayback to ui/ primitives MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR 3 of 16 in the UI consistency overhaul. Worst-drift fix: kills every raw zinc-* / amber-* / emerald-* / rounded-lg instance in SamplePlayback.tsx (was 13 occurrences, now 0). Stacked on top of PR #65 (D.1 primitives). Will be rebased onto main once PR #65 merges. Migration: - Outer
. Rack status reflects panel state — error tone on failure, active tone while generating, success tone once a manifest is rendered. - Original

id-based labelling replaced by aria-label on the DeviceRack; the title strip carries the visible name. - Regenerate - )} - - - {!measurementCompleted && ( -

- Measurements still running — audition samples become available once Phase 1 - completes. + + ) + } + > +

+

+ Short clips derived from Phase 1 measurements (and Phase 2 context when + available) so you can ear-check the measurement chain. These are not + Ableton-accurate reconstructions — follow Phase 2 in Live for the + production character.

- )} - {measurementCompleted && !manifest && status.kind !== 'generating' && ( - - )} + {!measurementCompleted && ( +

+ Measurements still running — audition samples become available once + Phase 1 completes. +

+ )} - {status.kind === 'generating' && ( -

Rendering audition clips…

- )} + {measurementCompleted && !manifest && status.kind !== 'generating' && ( + + )} - {status.kind === 'error' && ( -

- {status.message} -

- )} + {status.kind === 'generating' && ( +

+ Rendering audition clips… +

+ )} - {manifest && groupedSamples.length > 0 && ( -
- - {groupedSamples.map(([category, samples]) => ( - - - - ))} -
- )} -

+ {status.kind === 'error' && ( +

+ {status.message} +

+ )} + + {manifest && groupedSamples.length > 0 && ( +
+ + {groupedSamples.map(([category, samples]) => ( + + + + ))} +
+ )} + + ); } @@ -184,13 +209,9 @@ function ManifestMeta({ manifest }: { manifest: SamplesManifest }) { ? 'PyTheory' : 'Pure-Python theory fallback'; return ( -
- - Music theory: {theoryLabel} - - - Synthesis: {synthesisLabel} - +
+ Music theory: {theoryLabel} + Synthesis: {synthesisLabel}
); } @@ -204,15 +225,18 @@ interface SampleGroupProps { function SampleGroup({ category, samples, runId, apiBaseUrl }: SampleGroupProps) { return ( -
-

- {CATEGORY_LABELS[category]} -

-
From bb1d557ef5069f80c2e989874db9470a5a86321f Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 18 May 2026 22:37:43 +0000 Subject: [PATCH 3/4] =?UTF-8?q?feat(ui):=20D.3=20AnalysisStatusPanel=20?= =?UTF-8?q?=E2=86=92=20SignalChain=20(marquee=20transformation)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR 4 of 16 in the UI consistency overhaul. The visual hook reviewers will remember: the analysis pipeline literally renders as a horizontal Live 12 device chain. Stacked on PR #66 (D.2 SamplePlayback + DeviceRack rail fix). Branch already includes the rail fix needed for the all-3-slots layout this PR exercises. Migration: - Outer
. Status maps progress tone + isActive to idle/active/success/error. - Stop button → + ) : ( + nonRetryableHint + ); + + return { + key: stage.key, + name: STAGE_LABELS[stage.key], + status: toSignalStatus(stage.status), + statusLabel: statusLabel(stage.status), + action, + }; + }); + + const rackStatus = rackStatusFromProgress(progress, isActive); + const subtitle = run ? `· ${run.runId.slice(-8)}` : undefined; + const railTone: SignalTone = + progress.tone === 'success' ? 'success' : progress.tone === 'failed' ? 'idle' : 'active'; + + const railProgressLabel = progress.indeterminate + ? 'estimating' + : `${Math.round(progress.percent)}%`; + return ( -
- {/* Header row */} -
-
- Analysis Run - {run && ( - - {run.runId} - - )} -
-
-
-
- {formatElapsed(elapsedMs)} -
+ } + onClick={onStopAnalysis} + title="Stop analysis" + aria-label="Stop analysis" + > + Stop + + ) : undefined + } + signalIn={railTone} + signalOut={progress.tone === 'success' ? 'success' : 'idle'} + railContent={ + + + {formatElapsed(elapsedMs)} + {estimate && ( - - est {formatEstimateRange(estimate)} - + est {formatEstimateRange(estimate)} )} - {onStopAnalysis && isActive && ( - + {railProgressLabel} + + } + > +
+ {/* Audit Finding #6: primary readout. The stage diagnostic message + used to render at `text-[9px] text-secondary/50` below the percent + — sized as background fluff. During a 4–5 minute Phase 2 wait the + producer would tab away and miss any actual signal about what's + happening. Now it sits at the top of the device body as the visual + focus, with the active stage label as a mono eyebrow above it. The + SignalChain below becomes the secondary "which stage is which" + landmark. */} + + {progress.activeStageKey && ( +

+ {STAGE_LABELS[progress.activeStageKey]} + {progress.tone === 'failed' ? ' · failure' : null} +

)} -
-
- - {/* Audit Finding #6: primary readout. The stage diagnostic message used - to render at `text-[9px] text-secondary/50` below the percent — sized - as background fluff. During a 4–5 minute Phase 2 wait the producer - would tab away and miss any actual signal about what's happening. - Now it sits between the header and the stage chips as the visual - focus, with the active stage label as a mono eyebrow above it. The - chips below become the secondary "which stage is which" landmark. */} -
- {progress.activeStageKey && ( -

- {STAGE_LABELS[progress.activeStageKey]} - {progress.tone === 'failed' ? ' · failure' : null} +

+ {progress.message}

- )} -

- {progress.message} -

-
+ - {/* Stage pipeline */} -
- {stages.map((stage, i) => { - // A retry button only makes sense when (a) the parent provided a - // handler, (b) the stage is in a retryable state, and (c) the - // backend hasn't explicitly marked the error as non-retryable - // (e.g. GEMINI_NOT_CONFIGURED: clicking RETRY won't fix a missing - // env var). Audit N1 sibling: previously the button rendered for - // every failed stage regardless of error.retryable. - const errorMarkedNonRetryable = stage.error?.retryable === false; - const isRetryable = - stage.onRetry && - (stage.status === 'failed' || stage.status === 'interrupted' || stage.status === 'ready') && - !errorMarkedNonRetryable; - return ( -
-
- - {STAGE_LABELS[stage.key]} - -
-
-
- - {statusLabel(stage.status)} - - {isRetryable ? ( - - ) : errorMarkedNonRetryable && stage.error?.code ? ( - // Audit N1 sibling: a non-retryable failure (e.g. - // GEMINI_NOT_CONFIGURED) used to render FAILED with no - // actionable feedback. Surface the error code so the user - // knows where to look; full message goes in the tooltip. - - {stage.error.code} - - ) : null} -
-
- ); - })} -
- - {/* Progress bar */} -
-
- {progress.indeterminate ? ( -
- ) : ( -
= 95 && progress.tone === 'running' ? 'animate-pulse' : '' - }`} - style={{ width: `${progress.percent}%` }} - /> - )} -
-
- - {progress.indeterminate ? 'estimating' : `${Math.round(progress.percent)}%`} - -
- {/* Audit Finding #6: the duplicate small `progress.message` that used - to render here was removed — the primary readout above is the - single source for "what's happening". Keeping it here would have - been visual noise repeating the same sentence twice. */} +
-
+ ); } From cc9509510a7e6e768c60e4582aa2af6c1a431fdf Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 18 May 2026 22:42:15 +0000 Subject: [PATCH 4/4] chore(ui): normalize package-lock.json optional dep dev flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit npm install during PR review pass dropped "dev": true from optional rollup platform-binary entries — cosmetic lockfile normalization, no functional change. https://claude.ai/code/session_01MWRh46jPZ7YbFq4SkPFEwU --- apps/ui/package-lock.json | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/apps/ui/package-lock.json b/apps/ui/package-lock.json index 52cc0bcb..1edabd73 100644 --- a/apps/ui/package-lock.json +++ b/apps/ui/package-lock.json @@ -362,7 +362,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -379,7 +378,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -396,7 +394,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -413,7 +410,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -430,7 +426,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -447,7 +442,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -464,7 +458,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -481,7 +474,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -498,7 +490,6 @@ "cpu": [ "arm" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -515,7 +506,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -532,7 +522,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -549,7 +538,6 @@ "cpu": [ "loong64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -566,7 +554,6 @@ "cpu": [ "mips64el" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -583,7 +570,6 @@ "cpu": [ "ppc64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -600,7 +586,6 @@ "cpu": [ "riscv64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -617,7 +602,6 @@ "cpu": [ "s390x" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -634,7 +618,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -651,7 +634,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -668,7 +650,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -685,7 +666,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -702,7 +682,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -719,7 +698,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -736,7 +714,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -753,7 +730,6 @@ "cpu": [ "arm64" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -770,7 +746,6 @@ "cpu": [ "ia32" ], - "dev": true, "license": "MIT", "optional": true, "os": [ @@ -787,7 +762,6 @@ "cpu": [ "x64" ], - "dev": true, "license": "MIT", "optional": true, "os": [