Files
pad/web
xarmian ffaba632cf test(web): pin attachment open-set mutation contracts (TASK-2513)
PLAN-2392 phase 3c-iii U4. Pin the open-set mutation contracts DR-15
style — assert the chosen behavior, don't assume it.

- Upload-during-open: a new REAL end-to-end test mounts the strip + the
  AttachmentSurfaceHost, opens the surface on a 2-image set, fires the
  upload bus, and asserts the open surface's set is unchanged (counter
  stays 1/2) while the strip's own tile list DOES gain the row. The two
  legs are independent: a dead upload bus fails the strip leg, a
  live-following surface fails the surface leg — neither masks the other.
  It pins the no-live-follow half; the in-place-mutation half stays pinned
  by events.test.ts's deep-snapshot test.

- Rename/metadata-change: no channel exists to exercise it (api.attachments
  has no rename/update-in-place op; transform mints a new peer row; metadata
  is immutable), so the contract is WRITTEN DOWN in the events.ts
  deep-snapshot doc rather than tested, and the future channel is routed to
  IDEA-2515.

Codex-reviewed (3 rounds): tightened the doc to scope claims to the event
channel, correct the api.attachments surface, and account for deletion
reconciliation + downstream metadata completion.

Claude-Session: https://claude.ai/code/session_01WFBYxdBuSZs2tjipATxAZu
2026-08-11 03:13:33 +00:00
..
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00
2026-03-26 01:52:36 +00:00

Pad Web UI

SvelteKit 2 + Svelte 5 frontend for Pad, compiled to static files and embedded into the Go binary.

Development

npm install
npm run dev          # Dev server at localhost:5173 (proxies API to localhost:7777)
npm run build        # Production build to build/
npm run check        # Type checking with svelte-check

When developing, run the Go backend separately with make dev from the project root.

Building for Production

Do not build in isolation. Always use make build from the project root — this builds the web frontend, then compiles the Go binary with the build output embedded via //go:embed.

Stack

  • Svelte 5 with runes ($state, $derived, $effect)
  • SvelteKit 2 with adapter-static (SPA mode)
  • Tiptap block editor with markdown round-trip
  • svelte-dnd-action for drag-and-drop in board/list views
  • SSE for real-time updates
  • TypeScript throughout

Structure

src/
  routes/                    SvelteKit pages
    +layout.svelte           App shell (sidebar + main)
    +page.svelte             Landing/redirect
    [workspace]/
      +page.svelte           Dashboard (collections, phases, activity)
      +layout.svelte         SSE connection per workspace
      [collection]/
        +page.svelte         Collection view (board/list)
      [collection]/[item]/
        +page.svelte         Item detail + editor
      conventions/            Purpose-built conventions page
      playbooks/              Purpose-built playbooks page
      settings/               Workspace settings
  lib/
    api/client.ts            HTTP API client
    components/
      layout/                Sidebar, navigation
      editor/                Tiptap editor, raw markdown editor
      fields/                FieldEditor, relation picker
      items/                 ItemCard, ItemDetail
      collections/           BoardView, ListView
      common/                StatusBadge, badges, modals
      search/                CommandPalette
      activity/              ActivityFeed
    stores/                  Svelte 5 reactive stores
      workspace.svelte.ts    Workspace state
      collections.svelte.ts  Collection + item state
      ui.svelte.ts           Sidebar, mobile state
    types/index.ts           TypeScript types and constants
  app.css                    Global styles and design tokens