Files
pad/web
xarmian 7aef246dcd feat(web): comments move under the item content; Activity keeps changes (IDEA-2843)
GitHub #1228. Reviewing an agent-written doc meant many small comments, and
every one cost a trip to the Activity tab and back. TASK-2294's own spec put
an activity preview on the Details panel; it never shipped, and the comments
being tab-only is the half that was left. Dave ruled the full move.

One component cannot render in two DOM locations, so ItemTimeline stays the
SINGLE owner — one fetch, one SSE subscription, one composer — mounted under
the content on Details rendering comments, and mirrors its feed out through a
new bindable `feed` prop. The Activity and Versions panels render that same
feed through a second TimelineEntryList.

- The mirror publishes the WHOLE feed, not the owner's rendered slice. The
  owner renders comments only, so publishing `visibleEntries` would leave
  both tabs permanently empty with nothing to report. Tested, and the
  one-word mutation fails it.
- `loadMore` rides in the mirror: pagination is a property of the ONE feed,
  and a tab that can show older entries but not ask for them is a dead end.
- The kind partition is three shared constants with an exhaustiveness check,
  not literals at the mount sites. A kind in none of them renders NOWHERE —
  which is how note/decision shipped invisible the first time (BUG-2301).
  Adding a kind to TimelineEntry without routing it is now a build error or
  a failing test rather than a silent hole.
- The comments section carries its own {#key itemSlug}: it left the block
  that used to provide that remount, and dropping the guard would have been
  invisible. It wraps only the timeline — the collab editor must never be
  keyed.

Five e2e specs asserted comments behind the Activity tab and are updated.
attachment-lifecycle's tab round-trip is preserved deliberately: its claim is
that the panel is CSS-hidden rather than unmounted, so it now goes out to
Activity and BACK rather than asserting against a hidden panel.

Gates: 117 files / 1987 tests pass, svelte-check 0 errors. Both new
properties have negative controls — publishing the rendered slice fails 1,
unrouting a kind fails 2.

Claude-Session: https://claude.ai/code/session_011Q4b1iHtJtSyMs7BA2ySxo
2026-09-02 19:42:50 +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
    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