mirror of
https://github.com/PerpetualSoftware/pad.git
synced 2026-10-25 22:10:25 +00:00
6f8cb6c2da
* fix(pane): pane Back restores as near as the body reaches while late text is still arriving, instead of leaving the reader at the top (BUG-3251) The restore waited until the pane could scroll to the saved position before applying it. Under write load, text typed just before leaving an item reaches the reopened connection after its replay, seconds later (BUG-3253), so the body rendered one to four lines short and the wait ran out the cap: the reader landed at the top. The restore now clamps at once and holds, so late growth inside the cap walks the reader to the target, and growth after it leaves them near it. Measured on the trail: the typed-then-Back probe at 8 workers failed 19/100, 13 of 14 no-apply runs having a fully rendered but short body. Claude-Session: https://claude.ai/code/session_01NidgPePY7UvHcEJCMkD2Qz * fix(pane): a scrollbar press ends the pane Back restore, so a drag in the same frame as late growth is not overridden (BUG-3251 codex round 1) The hold tells the reader's scroll from its own by whether scrollHeight held still. A scrollbar drag that lands in the same frame as late growth arrives with the height already changed, reads as a clamp, and the next resize re-applied the target over it: 3/3 overridden by 908px. A press on the scrollbar is a pointerdown on the pane, which now ends the restore. The short-body leg also checks that the position stays put once the body grows after the cap, which a stick-to-bottom mechanism would not do. Claude-Session: https://claude.ai/code/session_01NidgPePY7UvHcEJCMkD2Qz
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