Files
buzz/desktop
Taylor HoandCarl 33ede155c6 feat(composer): stable turn-start pill order and persistent action labels
Calm the working-agent pill strip while multiple agents stream: position
now encodes identity (stable for a whole turn), liveness stays on the
per-pill label tickers, and positional motion is reserved for membership
changes (an agent starting or finishing) — the transitions a builder
actually needs to notice. Grounded in the work-visibility and
completion-awareness JTBDs: transcript-recency ordering shuffled pills on
every agent event (cry-wolf motion) and buried quiet/stuck agents at the
scrolled-off end of the strip.

- composerLiveActivity.ts: replace deriveAgentActivityOrder (transcript
  recency, newest first) with deriveAgentWorkingOrder — sorts by
  channel-scoped turn anchorAt ascending (earliest worker left-most, new
  agents append right), quantized to whole seconds so retroactive
  clock-offset refinements cannot reorder the strip, stable roster-order
  tiebreak, no-anchor agents keep roster order at the end
- composerLiveActivity.ts: remove the 6s label decay
  (ACTIVITY_PILL_STALE_MS and the now/staleAfterMs params) — the last
  real action now persists through quiet stretches; the generic
  "<name> is working…" label only shows before the first action lands,
  since the last action is more informative than a placeholder while a
  turn is in progress
- BotActivityBar.tsx: order snapshot subscribes to agentWorkingSignal
  (turn anchors) instead of the observer store's transcript scan; drop
  the per-pill useNow(1000) staleness tick so pills no longer re-render
  every second; hover-freeze machinery (order/membership/width hold)
  unchanged and still guards membership changes under the cursor
- composerLiveActivity.test.mjs: six anchor-ordering tests (earliest
  first, append-on-later-start, channel scoping, unscoped
  earliest-across-channels, roster fallback, sub-second-shift stability);
  decay tests replaced with a headline-persists-regardless-of-age test
- channels.spec.ts: retarget the two hover-freeze e2e tests from recency
  flips to membership changes — a third agent (lyra) starting a turn
  mid-hover appends only after the hold releases, and a turn completing
  mid-bar-hover exits only after release
- e2eBridge.ts: __BUZZ_E2E_SEED_ACTIVE_TURNS__ accepts an explicit atMs
  so tests seed well-separated turn-start anchors deterministically
- channels.spec.ts: seedPillActivityMessage now takes the matching
  turnId — the old hardcoded id resurrected a phantom sibling turn that
  would have kept a completed agent "working" forever
- debugAgentHarness.ts / debug README: update decay-era comments to the
  hold-last-headline behavior

Verified: 3652 unit tests pass; 12 pill/activity/typing e2e tests pass
against a fresh build:e2e.

Co-authored-by: Taylor Ho <taylorkmho@gmail.com>
Signed-off-by: Taylor Ho <taylorkmho@gmail.com>
2026-08-05 16:41:59 -07:00
..
2026-08-03 21:51:17 -04:00
…

Buzz

Desktop chat shell with:

  • Tauri + React + TypeScript + Vite
  • Tailwind CSS
  • shadcn/ui-ready shared components
  • Biome (lint/format/check)
  • Feature-driven frontend structure

Scripts

  • pnpm dev - run the web frontend
  • pnpm tauri dev - run the desktop app
  • pnpm build - typecheck and build frontend
  • pnpm typecheck - TypeScript checks
  • pnpm lint - Biome lint
  • pnpm format - Biome format (write)
  • pnpm check - Biome check

Structure

  • src/shared - reusable app-wide code (ui, lib, styles)
  • src/features - feature modules (vertical slices)
  • src/app - top-level app composition