Files
buzz/desktop
Matt Toohey d77611dd08 feat(desktop): let users resize Project Canvas widgets
Widgets could be dragged and nudged but their footprint stayed fixed by
the package, so a dense reviews list or cramped tasks card could not be
adjusted without editing data/*.json. Resize is the same kind of direct
manipulation as drag, so it follows the same host-persisted,
revision-independent layout contract.

- `canvas.layout` gains an optional `sizes` map alongside `widgets`,
  validated like positions: bounded dimensions (16 to 100 000), the
  widget-id charset as keys, at most 256 entries, inside the existing
  64 KiB port cap. Optional keeps packages that predate size persistence
  valid — malformed layout messages count toward frame teardown.
- Size overrides persist and replay independently of positions:
  resizing a widget must not pin its position and vice versa, so a later
  package revision can still move a resized widget (and resize a moved
  one). `projectCanvasLayout.ts` sanitizes stored sizes like points,
  pruning malformed entries and folding them into the record caps.
- The template gets a per-widget resize handle: a focusable button
  (aria-label "Resize {title} widget", the label's single owner) that
  drags with the pointer and resizes with arrow keys (24px steps, 48px
  with Shift), snapping to the 24px grid and clamping at 192x144 so a
  widget cannot shrink out of reach. Saves go through the SDK's
  debounced `layout.save`, which now clamps dimensions into the accepted
  range so a save can never emit an invalid port message.
- Reset restores package sizes and clears stored overrides. The e2e mock
  package grew a resize control and had to slim its shell comment: the
  descriptor `url` data-URL cap is 8192 characters and the first version
  exceeded it by 12, failing every canvas frame activation.
- Also updates the template-harness avatar assertion broken by
  3ed98a804: with both a pubkey and a data URL the SDK now prefers the
  `./__buzz/avatar/` route, per projectCanvasSdkAvatar.test.mjs.

The base-prompt/nest-skill documentation for `layout.save({..., sizes})`
landed with 3ed98a804's doc edits; this change binds those strings in
the buzz-acp doc test.

Verified: canvas unit suites 75 passing (size sanitization, corrupt
records, `__proto__` safety, override independence, keyboard resize and
clamp, reset — bound to the real template + SDK in jsdom), buzz-acp
doc-binding test, tsc --noEmit, biome, and all 9 project-canvas
Playwright e2e tests including the extended resize/reload/reset flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Matt Toohey <contact@matttoohey.com>
2026-09-02 15:08:28 +10: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