Vancetope — App scribblebook
Scribblebook for Handwriting: a folder as an app container for
kind: scribblesheets — a notebook with sheets, menu switching, live index. See also: doc-kind-scribble (the sheet kind), app-canvasbook (the model; there, the authoring interface is the app — here, the sheet is also editable standalone), app-workbook (the same container pattern over Workpages). Implementation track:planning/scribble.md.
1. Purpose
An app: scribblebook is a folder = a notebook: it collects all
*.scribble.yaml files of a project folder, maintains a machine-owned index
(_index.md), and serves as the authoring interface with sheet switching via a menu.
To tear out a sheet means: create a new sheet — the rest is the
Scribble Editor.
Manifest (_app.yaml):
$meta:
kind: application
app: scribblebook
title: "My Notebook"
Optional Config (Manifest body): index.outputPath (default _index.md).
2. Server
ScribblebookApplication (VanceApplication) owns exactly one derived
artifact, the _index.md index; sheet discovery is handled by the
ScribblebookFolderReader (scan over the folder, filter on
$meta.kind: scribble). promptInject provides the sheet list to the agent —
titles and paths, never strokes.
Route (under /brain/{tenant}/addon/scribble) |
Purpose |
|---|---|
GET /scan?projectId&folder |
Sheets of the folder (Id, path, title). |
POST /page |
Create new sheet in the folder (folder, title). |
POST /rebuild |
Recreate _index.md (Scan → Workpage body). |
The index is machine-owned like an installed/ record: rebuild
overwrites it, the user does not edit it. It exists so that folder browsing,
search, and agent context can see the notebook without reading every sheet body.
| Tool | Purpose |
|---|---|
scribblebook_app_create(folder, title?) |
New app in folder (manifest + first index). |
scribblebook_page_create(folder, title?) |
New sheet in notebook. |
When creating a new app, the client directly opens the first sheet. The document template
templates/scribble.yaml (+ Pebble body) creates a single sheet without a notebook —
the way for “a handwriting note, not a notebook”.
3. Web-UI
ScribblebookAppKind.vue (Addon @vance-addon/scribble):
- Header (Slim-Header, App manifest):
☰ <Title> ▾opens the sheet menu (all sheets, active one marked),+ New Sheet,↻ Rebuild Index, Save-State-Dot (saved / changes / saving). - Body: the Scribble Editor with the active sheet.
- Sheet switching is per-tab-state in the host (
?entry=): F5 and permalink open the same sheet; a switch does not remount, it jumps in the editor (:key= active path) and loads the sheet. - Chat binding:
reportActiveSubDocreports the open sheet to the session (chat selection points to the sheet, not the app manifest). - Live-Watch:
useDocumentPrefixReactionon the folder — if another client saves a sheet (or creates one), it appears in the menu and index without a reload. A Self-Write-Window prevents feedback: its own debounce-save does not trigger a re-scan/re-set of the editor.
Printing follows the kind: the app header is no-print, only the sheet
is on paper (see Kind-Spec §3).
4. Anti-Patterns / v1-Scope
- Sheets as app-internal data. Rejected — each sheet is a full document (export, search, agent access, OCR later).
- Editing the index manually. Machine-owned; the rebuild button is the only way.
- Strokes in the index. The index lists titles/paths — handwriting remains in
the sheet and becomes visible via
scribble_sheet_image, never copied as text. - Not in v1: Reordering sheets (array order = filename),
deleting sheets from the app (handled by document management), notebook PDF export
(noted follow-up track
scribble_book_pdf).