diff options
| author | Adam Malczewski <[email protected]> | 2026-09-07 11:47:18 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-09-07 11:47:18 +0900 |
| commit | 754450b539818f9ad94c9586888973b0edd74b68 (patch) | |
| tree | d852f9a8910f223e15a5e11ad04868b0d0a29804 /GLOSSARY.md | |
| parent | 719f0038dbb09f0fe9b073c3dc8e4f403815223d (diff) | |
| download | dispatch-web-754450b539818f9ad94c9586888973b0edd74b68.tar.gz dispatch-web-754450b539818f9ad94c9586888973b0edd74b68.zip | |
feat(workspaces): Win8 Start-style tile-grid home page
Rebuild the workspace home as a Windows 8 Start-screen-style tile grid,
replacing the max-w-3xl vertical card list.
Pure core (zero DOM/Svelte/fetch, fully unit-tested):
- logic/tile-layout.ts — geometryFor(width, height) resolves WIDE (4 fixed
~120px rows, column-wise flow, 4x2 span cap) or TALL (2 fixed columns,
row-wise flow, 2x2 cap); pack() is the ONLY order->coordinates transform
(greedy first-fit in fill order, hole-free, render-clamped per geometry);
firstEmptySlot/insertAtFirstEmptySlot/mergeLayout/resizeTile/moveTile/
sortByRecentActivity/sanitizeLayout. Persisted data is
orientation-independent {version:1, tiles:[{id,colSpan,rowSpan,order}]} —
order + spans only, never positions; the same data renders in either
geometry (spans clamp for the render, persisted values untouched).
- logic/drag-controller.ts — pure pointer/press state machine: mouse
threshold-drag + tap-open; touch long-press lifts + selects, pre-lift
movement cancels so vertical scrolling never fights the gesture.
Shell:
- tile-layout-store.svelte.ts — thin reactive wrapper persisting through
the injected createLocalStore adapter (dispatch.workspaces.tiles), ops:
sync/resize/move/placeFirstEmpty/sortByRecentActivity.
- ui/HomeTileGrid.svelte — CSS-grid tile canvas (wide: horizontal scroll +
snap + wheel pan + pan arrow + scroll indicator; tall: native vertical
scroll), FLIP-animated reflow, drag ghost, transient resize preview.
- ui/HomeHeader.svelte — fixed chrome: Dispatch display title, New
workspace popover (same slug validation; creates via create-on-miss and
does NOT navigate — the new tile lands in the first empty slot in fill
order and enters rename mode), global Plugins button, sort-by-recent
overflow; compact icon buttons + bottom sheet on tall screens.
- ui/WorkspaceTile.svelte — tile face (title, /slug, conversation count,
relative last-activity, live active dots, starred tint); inline rename
with the old card's semantics.
- ui/TileActionBar.svelte — slides up on select (right-click / long-press):
Open, Rename, Resize, Star/Unstar, Details, Plugins, Delete (old confirm
+ store call preserved).
- ui/ResizePicker.svelte — Word-style insert-table hover grid (wide 4x2 /
tall 2x2) with arrow/Enter/Escape support and ghost preview on commit.
- ui/WorkspaceDetails.svelte — flyout holding the old card's default-cwd
input + default-computer select (same store calls + error states).
- WorkspacesHome.svelte orchestrates; App.svelte untouched (same props).
- WorkspaceCard.svelte is removed (replaced by the tile system).
Manual tile order rules; starred workspaces get a tint (star is no longer
a sort key); workspaces unknown to the layout append at the end.
vitest: jsdom gains PointerEvent (MouseEvent-based) + Element.animate
stubs — the pointer logic is the outermost edge for the drag tests.
Verification: svelte-check 0/0, vitest 1655 passed (102 files, twice),
biome clean, vite build OK.
Diffstat (limited to 'GLOSSARY.md')
| -rw-r--r-- | GLOSSARY.md | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/GLOSSARY.md b/GLOSSARY.md index 26d3844..1c1b68d 100644 --- a/GLOSSARY.md +++ b/GLOSSARY.md @@ -52,4 +52,5 @@ | **unload** | Drop the oldest COMMITTED chunks from the in-memory transcript (and DOM) past the **chat limit** — in BULK (`ceil(limit/4)` per pass, deferred while the reader is scrolled up), never one-per-delta (old Dispatch's scroll-jump bug). Purely local: the IndexedDB cache and the server keep everything; `TranscriptState.hiddenBeforeSeq` is the watermark. Distinct from the conversation-cache's cross-conversation **eviction**. | evict (reserved for the cross-conversation cache), prune, drop | | **show earlier** | The affordance at the top of a transcript with unloaded history ("Show earlier messages"): pages one unload-unit back in — local cache first, then the server (CR-5 `?beforeSeq=&limit=`) when the cache doesn't reach far enough back — preserving the reader's scroll position. Offered whenever the loaded window starts above seq 1 (the [email protected] 1-based gap-free seq contract). | load more, pagination | | **workspaces** | A URL-driven grouping of conversations that owns a **default cwd**. The root path `/` lists workspaces; `/<id>` opens one (visiting a nonexistent id creates it — create-on-miss). Each conversation belongs to exactly one workspace; the always-present `"default"` workspace is the fallback for unassigned/legacy conversations. Tabs are scoped per workspace (filtered client-side). Backend-owned (`[email protected]` `Workspace`); a conversation's cwd inherits `workspace.defaultCwd` when its own is unset. Distinct from the per-conversation cwd+LSP module (`features/cwd-lsp`, formerly `features/workspace`). | project, space | -| **starred** | A workspace flag (`Workspace.starred: boolean`, defaults `false`) that grants its agents PRIORITY in the concurrency limiter queue — they jump ahead of agents from non-starred workspaces, oldest-agent-first within each group. Takes effect immediately for already-queued agents (backend-owned). Toggled via dedicated `PUT`/`DELETE /workspaces/:id/star` endpoints (no body; create-on-miss; `PUT /workspaces/:id` does NOT accept `starred`). The FE sorts starred workspaces to the top of the home list (the display echo of their concurrency priority) and toggles optimistically with error revert. | favorited, pinned (and do NOT call it "priority" — priority is the EFFECT, starred is the FLAG) | +| **starred** | A workspace flag (`Workspace.starred: boolean`, defaults `false`) that grants its agents PRIORITY in the concurrency limiter queue — they jump ahead of agents from non-starred workspaces, oldest-agent-first within each group. Takes effect immediately for already-queued agents (backend-owned). Toggled via dedicated `PUT`/`DELETE /workspaces/:id/star` endpoints (no body; create-on-miss; `PUT /workspaces/:id` does NOT accept `starred`). The home grid renders starred workspaces with a tint (the display echo of their concurrency priority); the FE toggles optimistically with error revert. | favorited, pinned (and do NOT call it "priority" — priority is the EFFECT, starred is the FLAG) | +| **home tile** | One workspace's cell on the home page's Win8-Start-style **tile grid** (`features/workspaces`, branch `feature/win8-tiles-home`) — NOT the layout feature's nested split-tree tile (`features/layout` TileRoot). Rendered from an orientation-independent persisted layout (localStorage `dispatch.workspaces.tiles`: `{ version: 1, tiles: [{ id, colSpan, rowSpan, order }] }` — manual order + requested spans only, NEVER positions): `geometryFor(width, height)` picks WIDE (4 fixed ~120px rows, column-wise flow, 4×2 span cap) or TALL (2 columns, row-wise flow, 2×2 cap), and `pack` re-derives every position (the only order→coordinates transform). Spans render-clamped per geometry; the persisted span is untouched. Drag-to-reorder edits the ORDER; resize uses an insert-table picker; a tile's click opens the workspace, right-click/long-press selects it (action bar). | (do not conflate with the layout split-tree tile), card | |
