mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-25 22:10:25 +00:00
5fe478b7d0
expected_seq guards the row, and a browser tab's typing is not in the row until the tab flushes. So a content PATCH carrying a current token replaced those edits: through the applier's setContent with a tab open, and with no tab open the direct path's PruneItemOpLogTx deleted them, and they existed nowhere else. A content write that carries expected_seq or expected_updated_at is now refused with 409 content_pending_flush while content-bearing op-log rows sit above the flush watermark. The check is composed into the existing precheck, so the direct, applier and collab-disabled paths all inherit it, and runs in the write's own tx after the token check (a stale token still answers update_conflict). It has its own code because re-reading returns the same row and seq. overwrite_pending_edits lifts it on the API, the CLI (--overwrite-pending-edits; item edit --force sets it on the save) and MCP on both transports, with a shared hint that does not say re-read and retry. A tokenless write is unchanged, except that a direct write now reports warnings.pruned_pending_edits when its prune deleted such rows (the CLI prints it to stderr). MCP ToolSurfaceVersion 0.39: a behavior bump with one additive param. Claude-Session: https://claude.ai/code/session_01X4uYKs5ZPF28eCWfm8VPvE
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