Skip to content

fix(widgets): lifecycle + UX round — apps:changed refresh, ⋯ size presets, keyboard move/resize, typed bridge queries (F-380/382/383/384)#94

Merged
th3-br41n merged 1 commit into
mainfrom
fix/widgets-lifecycle-ux
Jul 3, 2026
Merged

fix(widgets): lifecycle + UX round — apps:changed refresh, ⋯ size presets, keyboard move/resize, typed bridge queries (F-380/382/383/384)#94
th3-br41n merged 1 commit into
mainfrom
fix/widgets-lifecycle-ux

Conversation

@th3-br41n

Copy link
Copy Markdown
Contributor

Fixes four findings from dogfood session 375 (harness PR #24). Companion PR with the new widgets + empty-state CTAs follows.

F-380 — app reinstall orphans live widgets

An app (re)install raced three one-shot dashboard reads (widget titles, iframe entry, icon cache) which then never healed — slug-titled placeholder cards + initials icons until restart (the dogfood harness hit this every boot).

  • new apps/apps-changed.ts: payload-free apps:changed push to the dashboard, broadcast from the installer chokepoints (install / update / uninstall / refreshRegistrations)
  • preload apps.onChanged; widgets layer re-fetches titles + re-resolves entries (an update's new bundle sha live-reloads the iframe); icons layer re-lists into the icon cache
  • tests: broadcast module unit tests, installer integration (fires on success paths, not failures), and a jsdom layer test that mounts mid-"reinstall" and watches the slug title heal

F-382 — ⋯ menu was Remove-only

Size → Small / Medium / Large (via widgetFootprint, current footprint checked) + Open app; Remove stays last per the object-menu convention.

F-383 — no keyboard move/resize

Both grips are focusable (role=button, accent focus ring; the hover-revealed resize grip reveals on focus too) and nudge on the 8px grid with arrow keys, Shift = 4 cells, persisting through the same optimistic-pending path as pointer gestures. Grip-local arrow handling (the app-grid combobox-bridge precedent), not global chords.

F-384 — bridge ships the full vault to every widget

vaultEntities.list() accepts optional {types, limit} (sdk-types VaultEntitiesListQuery), threaded iframe shim → parent proxy → preload → handler. Validation + filtering are pure (ipc/widget-list-query.ts, unit-tested); limit implies live-only newest-first. Capability upgrade: a scoped-read app (Books holds only per-type grants) is now admitted through a typed query covering exactly its grants — the old handler flatly demanded entities.read:*. useVaultEntities gains an optional query passthrough.

Verification

  • bun --bun vitest run: installer 30/30 · widgets-layer 2/2 · widget-list-query 8/8 · react-yjs 95/95 (244 across the affected set)
  • bun run typecheck + bun run lint green

🤖 Generated with Claude Code

…presets, keyboard move/resize, typed bridge queries (F-380/382/383/384)

F-380: app (re)installs now push a payload-free apps:changed signal to the
dashboard (installer chokepoint -> preload subscription). The widgets layer
re-fetches titles and re-resolves iframe entries (a reinstall's new bundle
sha reloads the iframe live), and the icon cache re-lists — the one-shot
reads no longer race the installer and stick broken until restart.

F-382: the widget ... menu grows Size presets (Small/Medium/Large via
widgetFootprint, current one checked) and Open app; Remove stays last.

F-383: the move grip and resize grip are focusable (role=button, accent
focus ring) and nudge on the 8px grid with arrow keys (Shift = 4 cells),
persisting through the same optimistic-pending path as pointer gestures.

F-384: vaultEntities.list() accepts an optional {types, limit} query,
threaded shim -> parent proxy -> preload -> handler; filtering is pure
(widget-list-query.ts) and limit implies live-only newest-first. A
scoped-read app (Books) is admitted through a typed query covering its
grants — previously the bridge demanded entities.read:* outright.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@th3-br41n th3-br41n merged commit 340a134 into main Jul 3, 2026
3 checks passed
@th3-br41n th3-br41n deleted the fix/widgets-lifecycle-ux branch July 3, 2026 22:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant