feat: Claude Code's warm thinking-spinner shimmer (CLFY-27) #57

Merged
owlburtoe merged 1 commit from clfy-27-spinner-shimmer into master 2026-07-17 15:23:56 -04:00
Owner

What

Replicates Claude Code's spinner "wave" captured in CLFY-26. The spinner verb and glyph now, keyed to the spell's elapsed time:

  • Warm hue escalation (the reporter's "orange→red→yellow"): salmon #D78787 → tan → orange #FFAF5F (bold at ~17s) → gold #FFD700 at ~20s, then plateaus. One-way, no cycle-back.
  • Sweep highlight: a ~3-char window (#FFAF87) sweeping right→left across the verb during the first ~15s, then uniform.

Emits CC's exact 256-color indices for fidelity.

The capture's open question — resolved

CLFY-26 flagged: can pi's render loop even repaint the spinner mid-stream at ~5 Hz? Yes. ui.setWorkingMessageLoader.setMessageupdateDisplayrequestRender runs synchronously (pi-tui components/loader.js), so refreshing the working message at the sweep cadence repaints immediately, independent of the 500ms glyph timer. A fast-refresh window (200ms), bounded to the ~20s escalation, drives the animation; past the plateau the color is constant and the existing text-equality guard throttles re-renders.

Scope / gating

  • New spinnerShimmer setting (Spinner section, default on). Chasing CC's look is claudify's whole point, so it's on by default.
  • Suppressed when a custom spinnerColor is set — the shimmer imposes CC's fixed warm palette, so a user's static color choice wins.
  • Applied uniformly to verb + glyph via shared elapsed anchor; the ✻ Worked for … completion line is never shimmered.

Tests + smoke

  • bun run test — 15/15 green. Pure functions (shimmerBase/shimmerSweep/colorizeShimmerVerb/shimmerGlyphAnsi) unit-tested through the gold+bold plateau and the moving sweep window.
  • tsc --strict clean.
  • Live-smoked (pi 0.80.10, checkout, Anthropic Opus): shimmer activates on default color, verb renders salmon + a right→left moving sweep highlight, glyph rotates, no overflow / no crash — the many per-char SGR codes (the main 2.3.0-class width risk) render cleanly. Gate verified: a custom spinnerColor suppressed the shimmer entirely.
  • Not caught live: the >13s gold/bold plateau — thinking spells stayed under 13s and a longer run hit the account's Anthropic usage limit. It's unit-tested and uses the identical render path; \x1b[1m is zero-width so it can't overflow.

Note: this mutates pi's spinner render, so re-run the live smoke before the next npm publish (ideally catching the gold plateau).

Closes CLFY-27

## What Replicates Claude Code's spinner "wave" captured in CLFY-26. The spinner verb **and** glyph now, keyed to the spell's elapsed time: - **Warm hue escalation** (the reporter's "orange→red→yellow"): salmon `#D78787` → tan → orange `#FFAF5F` (**bold** at ~17s) → gold `#FFD700` at ~20s, then plateaus. One-way, no cycle-back. - **Sweep highlight**: a ~3-char window (`#FFAF87`) sweeping right→left across the verb during the first ~15s, then uniform. Emits CC's exact 256-color indices for fidelity. ## The capture's open question — resolved CLFY-26 flagged: *can pi's render loop even repaint the spinner mid-stream at ~5 Hz?* **Yes.** `ui.setWorkingMessage` → `Loader.setMessage` → `updateDisplay` → `requestRender` runs synchronously (pi-tui `components/loader.js`), so refreshing the working message at the sweep cadence repaints immediately, independent of the 500ms glyph timer. A fast-refresh window (200ms), **bounded to the ~20s escalation**, drives the animation; past the plateau the color is constant and the existing text-equality guard throttles re-renders. ## Scope / gating - New **`spinnerShimmer`** setting (Spinner section, **default on**). Chasing CC's look is claudify's whole point, so it's on by default. - **Suppressed when a custom `spinnerColor` is set** — the shimmer imposes CC's fixed warm palette, so a user's static color choice wins. - Applied uniformly to verb + glyph via shared elapsed anchor; the `✻ Worked for …` completion line is never shimmered. ## Tests + smoke - [x] `bun run test` — 15/15 green. Pure functions (`shimmerBase`/`shimmerSweep`/`colorizeShimmerVerb`/`shimmerGlyphAnsi`) unit-tested through the **gold+bold plateau** and the moving sweep window. - [x] `tsc --strict` clean. - [x] **Live-smoked** (pi 0.80.10, checkout, Anthropic Opus): shimmer activates on default color, verb renders **salmon + a right→left moving sweep highlight**, glyph rotates, **no overflow / no crash** — the many per-char SGR codes (the main 2.3.0-class width risk) render cleanly. Gate verified: a custom `spinnerColor` suppressed the shimmer entirely. - [ ] **Not caught live:** the >13s **gold/bold plateau** — thinking spells stayed under 13s and a longer run hit the account's Anthropic usage limit. It's unit-tested and uses the identical render path; `\x1b[1m` is zero-width so it can't overflow. **Note:** this mutates pi's spinner render, so re-run the live smoke before the next `npm publish` (ideally catching the gold plateau). Closes CLFY-27
feat: Claude Code's warm thinking-spinner shimmer
All checks were successful
Plane Sync / Close referenced Plane work items (pull_request) Successful in 2s
810ba95126
CLFY-27. Replicates CC's spinner 'wave' captured in CLFY-26: the verb and glyph
warm one-way salmon -> gold (turning bold, then plateauing) keyed to the spell's
elapsed time, plus a ~3-char highlight sweeping right->left across the verb in
the first ~15s. Emits CC's 256-color indices for fidelity.

Resolves the capture's open question about pi repaint cadence: setWorkingMessage
-> Loader.setMessage -> updateDisplay -> requestRender is synchronous, so a fast
refresh window (200ms, bounded to the ~20s escalation) animates the sweep
independent of the 500ms glyph timer.

Gated behind a spinnerShimmer setting (default on, in the Spinner section) and
suppressed when a custom spinnerColor is set, since the shimmer imposes CC's
fixed palette. Pure functions (shimmerBase/shimmerSweep/colorizeShimmerVerb)
are unit-tested through the gold+bold plateau. Live-smoked on pi 0.80.10: salmon
base + moving sweep render cleanly, no overflow (the per-char SGR width was the
main 2.3.0-class risk); the >13s gold plateau is unit-tested (spells stayed
under 13s live).

Closes CLFY-27
owlburtoe merged commit b36523983e into master 2026-07-17 15:23:56 -04:00
owlburtoe deleted branch clfy-27-spinner-shimmer 2026-07-17 15:23:56 -04:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
owlburtoe/pi-claudify!57
No description provided.