@nynb/sandpaper 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: sandpaper
3
+ description: >-
4
+ Use when working in a repo that has (or should have) a Sandpaper "project brain" — a
5
+ brain/ folder of static HTML that is a living service-manual mirroring the project's
6
+ state. Invoke to STAMP the brain after substantive turns (log the work, refresh the
7
+ digest, flip plan tasks, record decisions/learnings), to scaffold a new brain, to serve
8
+ it, or to re-skin it. Keeps the brain current and link-never-copy.
9
+ ---
10
+
11
+ # Sandpaper — the living project brain
12
+
13
+ Sandpaper turns a project's state into a navigable, always-current web **service manual**
14
+ (`brain/`) that the agent maintains. A fresh `claude` reads the brain to rehydrate; after
15
+ each substantive turn the agent **stamps** it. The brain is the **eyes** (state made
16
+ visible); steering stays in the terminal (the **mouth**).
17
+
18
+ ## Layout
19
+ - `brain/index.html` — the cover/portal: a `#brain-state` JSON **digest** (read first), the
20
+ **NOW** line, derived progress, **needs-you**, **latest**.
21
+ - Lenses: `product/`, `engineering/`, `project/` (the **plan board**) — the prose home per lens.
22
+ - Books: `log.html` (work log), `decisions.html` (ledger), `learnings.html` (gotchas), `wiki/`.
23
+ - `assets/theme.css` — one file re-skins everything; `assets/brain.js` derives all numbers.
24
+
25
+ ## Grammar
26
+ Every durable fact is an `.entry` carrying `data-cid` (mirrored to `id`), `data-kind`,
27
+ `data-status`, `data-date`, at least one `data-ref` into a canonical anchor, and an optional
28
+ `data-lens`. **Link, never copy** — point at the canonical doc; don't restate it (the wiki is
29
+ the one prose exception). Every block carries `data-cid`; an agent must never strip cids.
30
+
31
+ ## STAMP — after every substantive turn (not optional)
32
+ Templated, never free-form. Regenerate whole regions; never prose-edit inside one.
33
+ 1. **LOG** — prepend exactly one row to the top of `log.html` (verb-led, ≤12 words, ends in a
34
+ link). Never edit a prior row.
35
+ 2. **NOW** — overwrite the cover's `<!-- BRAIN:NOW -->…` region with one present-tense
36
+ sentence (≤120 chars) + a link to what you touched. Replace, never append.
37
+ 3. **DIGEST** — overwrite `#brain-state` so `focus`, the newest worklog line, and `open` match.
38
+ 4. **DECISIONS** — if a call was made/resolved: append a status-typed entry, or flip ONE
39
+ `data-status`. A reversal is a NEW entry with `data-rel="supersedes:<id>"` — never rewrite.
40
+ 5. **LEARNINGS** — if a gotcha bit, append one callout.
41
+ 6. **PLAN** — flip the relevant task's `data-status`; progress **derives** (never type a number).
42
+ 7. **CANVAS** — board-first (see below): if the turn's reply is a substantive summary or explanation,
43
+ it should already BE the current board on the whiteboard — demote the previous current into
44
+ *Earlier*, cap at 5, leave a `📋 … → on the canvas` pointer. (Pure-conversation turns don't stamp,
45
+ but board-first still applies to their replies.)
46
+
47
+ ## CANVAS — board-first: substantial replies go on the cover, not the scrollback
48
+ The cover hosts a **canvas** (the `<!-- BRAIN:CANVAS -->` region of `index.html`): a **whiteboard** —
49
+ a white `.whiteboard` container whose content scrolls inside it. The newest board sits full and live
50
+ in the whiteboard; older ones fold into a collapsed *Earlier* stack below it (normal page flow).
51
+
52
+ **Board-first is the default.** When your reply would be a substantial summary or explanation — the
53
+ recap of a turn, an architecture, a comparison, a walkthrough, an analysis — the **board IS the reply**:
54
+ write the elevated version as the current board and leave the terminal ONE line (`📋 <gist> → on the
55
+ canvas`). Don't write it twice. Short answers, confirmations, and the back-and-forth stay in the
56
+ terminal. The terminal **steers**; the canvas **shows**. No hook enforces this — boarding a *judgment*
57
+ can't be enforced the way "you changed code, go stamp" can; the pointer is the tripwire (no pointer
58
+ means nothing was boarded).
59
+
60
+ - **A board** is freeform, self-contained, theme-skinned rich HTML (SVG/CSS diagrams, tables, code,
61
+ side-by-sides — the things that die in a terminal). NOT the `.entry` grammar — boards are working
62
+ output; lavish is fine.
63
+ - **To add one:** the new board becomes the CURRENT one — replace the `<article class="board board--live"
64
+ data-cid="board-NNNN" …>…</article>` inside `.whiteboard`. Move the previously-current board to the
65
+ TOP of the `.canvas-earlier` list (below the whiteboard) as a collapsed `<details class="board board--past">
66
+ <summary class="board-row"><span class="board-row-dot"></span><span class="board-row-when">MM-DD · NNN</span><span
67
+ class="board-row-title">…</span><span class="board-row-chev">›</span></summary>…body + foot…</details>`.
68
+ Cap the stack at **5 total** — drop the oldest `<details>`. Update the `canvas-count` and the
69
+ `Earlier · N` label. Then in the terminal: `📋 <gist> → on the canvas`.
70
+ - **When NOT to:** short answers, direct edits, confirmations, lookups — those stay in the terminal.
71
+ Don't over-produce; a board is for something worth a second screen.
72
+ - **Canvas → brain.** Boards are the *working* layer; the brain (wiki/decisions/learnings) is the
73
+ *settled* layer. Promote a board only when it proves durable — via the STAMP — and never write
74
+ live explanations straight into the wiki. `/sandpaper:canvas <topic>` forces a board on demand.
75
+
76
+ ## Plan model
77
+ `phase → initiative → task → session`. Initiatives carry `data-phase`; tasks carry
78
+ `data-initiative`/`data-status`/`data-session`. `brain.js` sums task status into the
79
+ initiative, phase, and overall bars. The only operations: FLIP a task's status, APPEND a
80
+ task/initiative, STAMP a session. Never reuse a cid; re-scope = append + flip the old one.
81
+
82
+ ## Auto-update — the brain stays current without prodding
83
+ Two Claude Code hooks (scripts in `bin/`):
84
+ - **SessionStart → `bin/brain-inject.js`** — surfaces the digest so a fresh session
85
+ rehydrates from the brain automatically.
86
+ - **Stop → `bin/brain-stamp-check.js`** — if a turn changed project files but didn't touch
87
+ `brain/`, it **blocks once** with a reminder to STAMP. Self-limiting: it honors
88
+ `stop_hook_active` (never loops), is idempotent (stops firing once `brain/` is touched), and
89
+ the agent can override by simply stopping again.
90
+
91
+ Enable by merging into `.claude/settings.json` (project) or `~/.claude/settings.json` (user):
92
+
93
+ ```json
94
+ {
95
+ "hooks": {
96
+ "SessionStart": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node bin/brain-inject.js", "timeout": 10 }] }],
97
+ "Stop": [{ "matcher": "*", "hooks": [{ "type": "command", "command": "node bin/brain-stamp-check.js", "timeout": 20 }] }]
98
+ }
99
+ }
100
+ ```
101
+
102
+ Remove either entry to disable. This is the difference between the brain being a discipline
103
+ you might forget and a system that cannot silently drift.
104
+
105
+ ## Commands
106
+ `/help` (this list) · `/init` (harvest → interview → generate a brain) · `/stamp` (the 6-step
107
+ stamp) · `/canvas` (elevate an explanation into a board on the cover) · `/plan` · `/decide` ·
108
+ `/learn` · `/log` · `/sync` (reconcile + heal drift) ·
109
+ `/open` (serve + open the brain in a browser) · `/serve` (on-page refine toolbar) · `/theme`
110
+ (re-skin from a brand hex). Run `/sandpaper:help` for the full grouped list.
111
+
112
+ ## Serve / refine in place
113
+ `npx sandpaper <dir>` serves the brain with an on-page toolbar — **Sand** (scoped AI edit),
114
+ **✎ Hands** (direct edit, no AI), **❯ Sling** (hand a terminal-ready instruction over).
@@ -0,0 +1,31 @@
1
+ ---
2
+ description: Elevate an explanation into a rich board on the cover's canvas (not the terminal)
3
+ ---
4
+
5
+ Write the current (or named) summary/explanation as a **board** on the cover's canvas — the
6
+ `<!-- BRAIN:CANVAS -->` region of `brain/index.html`, a white `.whiteboard` container — instead of
7
+ leaving it in the terminal. The terminal steers; the canvas shows.
8
+
9
+ A board is freeform, self-contained, **theme-skinned** rich HTML: lead with the point, then make it
10
+ *visual* where that helps — a CSS/SVG diagram, a comparison table, code, a side-by-side. It is NOT
11
+ the `.entry` grammar (boards are working output; lavish is fine), but it must use the project's
12
+ theme classes so it matches the rest of the surface.
13
+
14
+ The canvas is a **whiteboard, not a notebook**: the newest board is the CURRENT one (full + live);
15
+ older boards fold into a collapsed *Earlier* stack, capped at five.
16
+
17
+ Steps:
18
+ 1. The new board becomes the CURRENT one — replace the `<article class="board board--live"
19
+ data-cid="board-NNNN" data-kind="board" data-date="YYYY-MM-DD" data-ref="<source>">` inside
20
+ `.whiteboard`, with a `.board-head` (dot · title · `MM-DD · board NNN`), a rich `.board-body`, and a
21
+ `.board-foot`.
22
+ 2. Move the previously-current board to the TOP of the `.canvas-earlier` list (below the whiteboard) as
23
+ a collapsed `<details class="board board--past"><summary class="board-row">…dot · `MM-DD · NNN` · title · ›…</summary>…body + foot…</details>`.
24
+ Remove any `.canvas-empty` placeholder.
25
+ 3. Cap the stack at **5 boards total** — drop the oldest `<details>`. Update the `canvas-count` and
26
+ the `Earlier · N` label.
27
+ 4. In the terminal, leave one line: `📋 <gist> → on the canvas`.
28
+
29
+ Keep boards for things worth a second screen (architecture, comparisons, walkthroughs, analyses);
30
+ short answers stay in the terminal. Durable boards are **promoted** into the brain later via the
31
+ STAMP — the canvas never writes straight into the wiki or decisions.
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Record a decision (or open/resolve a question) in the brain ledger
3
+ argument-hint: "<the decision, and why>"
4
+ ---
5
+
6
+ Append a decision to `brain/decisions.html`: $ARGUMENTS.
7
+
8
+ Use the grammar: `<article class="entry entry--decision" data-kind="decision" data-status="accepted"
9
+ data-date data-ref data-lens id="d-…" data-cid="d-…">` with **Decision / Because / Instead-of**
10
+ fields and a link to the canonical anchor. Next monotonic `D-NNN`.
11
+
12
+ - To **resolve** a question, flip its `data-status`.
13
+ - To **reverse** a prior call, add a NEW entry with `data-rel="supersedes:<id>"` — never rewrite
14
+ the old one.
15
+
16
+ Then LOG it (`/sandpaper:log`) and bump the cover's `<b data-count="decision">` count.
@@ -0,0 +1,25 @@
1
+ ---
2
+ description: List the Sandpaper commands and what each one does
3
+ ---
4
+
5
+ Show the user the Sandpaper command set, grouped like this, then offer to run one:
6
+
7
+ **Maintain the brain**
8
+ - `/sandpaper:stamp` — stamp the brain after a substantive turn (the 6-step update)
9
+ - `/sandpaper:log` — add one work-log row (the heartbeat)
10
+ - `/sandpaper:plan` — add or flip a task / initiative on the plan board
11
+ - `/sandpaper:decide` — record a decision, or open/resolve a question
12
+ - `/sandpaper:learn` — record a gotcha or verdict learning
13
+ - `/sandpaper:canvas` — elevate an explanation into a board on the cover's canvas
14
+ - `/sandpaper:sync` — reconcile the brain against the code; find + heal drift
15
+
16
+ **Set up & run**
17
+ - `/sandpaper:init` — scaffold a new brain for this repo (harvest → interview → generate)
18
+ - `/sandpaper:open` — start the server and open the brain in your browser
19
+ - `/sandpaper:serve` — serve the brain (or any doc) with the on-page refine toolbar
20
+ - `/sandpaper:theme` — re-skin the whole brain from one brand colour
21
+ - `/sandpaper:help` — this list
22
+
23
+ Then note: the brain also auto-maintains via two hooks — **SessionStart** rehydrates from the
24
+ digest, **Stop** nudges you to stamp if a turn changed code but not the brain
25
+ (`skill/sandpaper/SKILL.md` → Auto-update). Keep it concise; don't dump file contents.
@@ -0,0 +1,113 @@
1
+ ---
2
+ description: Scaffold a living Sandpaper brain for this repo — discover widely, run a wizard, generate
3
+ ---
4
+
5
+ Build a living project brain (`brain/`) for this repo. Five movements: **INTRODUCE**, **DISCOVER**
6
+ (scan widely), **WIZARD** (interactive — fill the gaps + shape the brain), **GENERATE**, **WELCOME**.
7
+
8
+ ## 0. INTRODUCE — a premium, human welcome (then a go-ahead gate)
9
+ Make the first impression feel crafted, not chatty. **Open with the banner, printed verbatim in a code block:**
10
+
11
+ ```
12
+ ░█▀▀░█▀█░█▀█░█▀▄░█▀█░█▀█░█▀█░█▀▀░█▀▄
13
+ ░▀▀█░█▀█░█░█░█░█░█▀▀░█▀█░█▀▀░█▀▀░█▀▄
14
+ ░▀▀▀░▀░▀░▀░▀░▀▀░░▀░░░▀░▀░▀░░░▀▀▀░▀░▀
15
+ refine on the page
16
+ ```
17
+
18
+ Then a **short, warm, plain-language** intro — no jargon, no wall of text. In ~3 lines the owner
19
+ actually cares about:
20
+ - **What you'll get** — a living "brain" for this repo: a small local website that shows what the
21
+ project is, its plan, the decisions, and its history — and stays current as you work. Your project,
22
+ made legible at a glance.
23
+ - **What happens now** — I skim the repo, ask you a few quick questions, then build it.
24
+ - **You're in control** — stop me anytime; it's all local files, nothing leaves your machine.
25
+
26
+ Keep it human and brief — a welcome, not a manual.
27
+
28
+ Then **gate on a go-ahead with the AskUserQuestion tool** (never plain prose — it breaks the flow and
29
+ forces typing). Do a quick, cheap size read first (count source files, list top dirs — don't read
30
+ everything). **Be honest about time:** building a real brain is a lot of writing, so even a SMALL repo
31
+ is roughly **15–30 minutes** and a fair chunk of tokens; bigger repos take longer — never lowball it.
32
+ Ask: header "Build it?", question e.g. *"~N source files. Building the brain runs ~15–30 min and uses
33
+ a fair few tokens — a one-time setup. Go?"*, options **Build it** · **Scope it down (just code)** ·
34
+ **Not now**. Begin DISCOVER only once they pick; honor a scoped choice.
35
+
36
+ ## 1. DISCOVER — cast a wide net; classify by content, not filename
37
+ Projects are organised every which way, so don't assume fixed paths. Glob broadly
38
+ (`**/*.md`, `docs/**`, `spec/**`, `rfc*/**`, `adr/**`, `design/**`), read what you find, and group it:
39
+
40
+ - **Code** — the manifest (`package.json` / `pyproject.toml` / `go.mod` / `Cargo.toml` / …), entry
41
+ points, the source layout + module graph, tests, the build/CI config.
42
+ - **Specs & design** — `SPEC*.md`, RFCs, ADRs (`docs/adr/`, `decisions/`), `ARCHITECTURE.md`,
43
+ design docs, anything spec-shaped by its contents.
44
+ - **Work history & plans** — `CHANGELOG.md`, `TODO.md`, `ROADMAP.md`, `NOTES`, the `git log`, and
45
+ any issue/PR references in commit messages.
46
+ - **Meta** — `README`, `CONTRIBUTING`, a `docs/` site, the `LICENSE`.
47
+ - **External pointers** — links in the README/docs to a Notion / wiki / Figma / issue tracker. You
48
+ can't read those; note them and raise them in the wizard.
49
+
50
+ From all of it infer: the project's name + what it is, its components + their status, the recent
51
+ work, the apparent roadmap, and any decisions/gotchas already written down somewhere.
52
+
53
+ ## 2. WIZARD — interactive; never guess what you can ask
54
+ Show the owner a short summary of what you found, **grouped** (code · specs · logs · docs ·
55
+ external links). Then run a brief wizard — **use the AskUserQuestion tool for the shaping choices**
56
+ (lenses, books, theme, phases), not a wall of prose; ask in small batches:
57
+
58
+ **a. Fill discovery gaps.** "Did I miss anything? Where's your spec / design / roadmap if I didn't
59
+ find it? Any external docs (Notion / wiki / Figma) I should fold in by hand?" Let them point you at
60
+ artifacts the scan missed — and paste/summarise anything you can't reach.
61
+
62
+ **b. Shape the brain** — confirm what *this* project's brain should hold (don't impose the full
63
+ template):
64
+ - Which **lenses** matter — product, engineering, project (the plan board), a subset, or a custom one?
65
+ - Which **books** — decisions, learnings, a glossary, a stats page? (default: decisions + learnings + log)
66
+ - The current **focus**, near-term **goals**, and any **open decisions/risks** you couldn't infer.
67
+ - A **theme** — a brand colour to skin it (else the warm default)?
68
+ - Do they think in **phases / milestones / rungs**? (to seed the plan board's grouping)
69
+ - A **port** — if they run Sandpaper for several repos at once, suggest pinning a distinct
70
+ `port` in `.sandpaper/manifest.json` (default 4848; the server auto-bumps if it's taken).
71
+
72
+ Keep it to ~5–8 questions total; infer everything else.
73
+
74
+ ## 3. GENERATE — seeded with REAL content, shaped by the answers
75
+ The design-system assets are **already in `brain/assets/`** (`theme.css` + `brain.css` + `brain.js`) —
76
+ `install-skill` scaffolded them from the Sandpaper package, along with a starter `brain/index.html`.
77
+ **Use them as-is.** Do NOT regenerate the assets, and **NEVER read, copy, or take templates / a
78
+ reference brain from any other directory or sibling project on disk** — that's someone else's repo,
79
+ not the Sandpaper package, and it won't exist on a distributed install. If `brain/assets/` is somehow
80
+ missing, stop and run `npx sandpaper init` (or ask the owner for the package path) — never go hunting.
81
+
82
+ **The multi-page skeleton is already on disk** — `install-skill` scaffolded the cover (`index.html`),
83
+ three lens pages (`product/index.html`, `engineering/index.html`, `project/index.html`), and three
84
+ books (`log.html`, `decisions.html`, `learnings.html`), each with the shared shell nav wired to
85
+ relative paths. **FILL these existing pages** (replace the `<!-- FILL: … -->` stubs with real content).
86
+ The brain is a **MULTI-PAGE site**: every lens and book is a SEPARATE `.html` file the shell nav links
87
+ to by relative path — **never collapse it into one page, and never turn the nav into in-page
88
+ `#anchors`.** Use the `.entry` grammar (`data-cid`→`id`, `data-kind`, `data-status`, `data-date`,
89
+ ≥1 `data-ref`, optional `data-lens`). **Link, never copy** — `data-ref` points at the real artifacts you
90
+ discovered (a spec's heading anchor if it has one, else the source file / README section). Generate
91
+ ONLY the lenses + books the owner chose; dim any deferred chrome so nothing dangles. Seed the plan
92
+ board from the discovered state (shipped = `done`; gaps between the code and the README/spec = the
93
+ honest backlog), the log from the git history, and the decisions/learnings books from anything
94
+ already written down. **Keep the scaffolded canvas** on the cover as-is — the `<!-- BRAIN:CANVAS -->`
95
+ region with its plain-language empty state; don't rewrite that copy into jargon (it fills with boards
96
+ as you work). Stamp the first log row, verify the `#brain-state` JSON parses and links resolve.
97
+
98
+ ## 4. WELCOME — a tight close, then OPEN it (the money shot)
99
+ Don't spread this into blabber. A short, confident close, then the payoff:
100
+ - **One line of what got built** — e.g. *"Your brain is live: a cover, 3 lenses, and 4 books, all
101
+ seeded from the real repo."*
102
+ - **One line on using it** — refine on the page with **Sand** (say a change) · **✎ Hands** (edit
103
+ directly) · **❯ Sling** (hand a job to the terminal); it also stays current on its own as you work.
104
+
105
+ Then **OPEN it yourself — the payoff must not be left to chance.** Serve the brain + open the browser
106
+ by running the `open` command **in the background** (so it keeps serving without blocking the turn):
107
+ read the `pkg` in `.sandpaper/manifest.json` and run `node <pkg>/bin/cli.js open` in the background
108
+ (or `sandpaper open` if it's on PATH). It opens their browser on the brain and greets them with the
109
+ one-time tour. Actually do it — don't just suggest it; if it genuinely can't run, hand them the one
110
+ exact command.
111
+
112
+ Keep the whole close under ~8 lines. `/sandpaper:help` lists every command. If you didn't commit
113
+ (e.g. a branch rule you discovered), offer that as the very last line.
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: Record a gotcha or verdict learning in the brain
3
+ argument-hint: "<what bit you, and the takeaway>"
4
+ ---
5
+
6
+ Append one callout to `brain/learnings.html`: $ARGUMENTS.
7
+
8
+ `<aside class="entry entry--learning callout gotcha|verdict" data-kind="learning"
9
+ data-status="active" data-date data-area data-tags id="l-…" data-cid="l-…">` — a **bold one-line
10
+ claim**, the why in a sentence, and a back-link to where it bit. `gotcha` = something that broke;
11
+ `verdict` = a settled judgement. Then LOG it (`/sandpaper:log`).
@@ -0,0 +1,9 @@
1
+ ---
2
+ description: Add a work-log row to the brain (the heartbeat)
3
+ argument-hint: "<what you did, ≤12 words>"
4
+ ---
5
+
6
+ Prepend one `<li>` row to the top of `brain/log.html` AND the cover's `<!-- BRAIN:LOG -->` feed:
7
+ $ARGUMENTS. Next monotonic `w-NNNN` cid; verb-led, ≤12 words, ends in a link to a canonical anchor.
8
+ Never edit a prior row. Refresh the cover NOW + `#brain-state` digest so the newest worklog line
9
+ matches.
@@ -0,0 +1,15 @@
1
+ ---
2
+ description: Start the Sandpaper server and open the brain in your browser
3
+ ---
4
+
5
+ Open the project's brain dashboard:
6
+
7
+ 1. Check whether a server is already on port 4848 (`lsof -ti :4848`). If not, start one in the
8
+ background from the repo root: `node bin/cli.js .` (serving the repo so the brain's `spec ↗` /
9
+ `engg ↗` links resolve), or `node bin/cli.js brain/` for the brain alone.
10
+ 2. Open the cover in the default browser — `open http://127.0.0.1:4848/brain/index.html` on macOS
11
+ (`xdg-open` on Linux, `start` on Windows).
12
+ 3. Tell the user the URL. Every page carries the on-page toolbar — **Sand** (scoped AI edit),
13
+ **✎ Hands** (direct edit, no AI), **❯ Sling** (copy a terminal-ready instruction).
14
+
15
+ The file on disk stays the single source of truth; the page always reflects disk.
@@ -0,0 +1,16 @@
1
+ ---
2
+ description: Add or update a task/initiative on the Sandpaper plan board
3
+ argument-hint: "flip t-NNNN done | add \"<task>\" to <initiative> | new initiative \"<name>\" in phase <0|1>"
4
+ ---
5
+
6
+ Update `brain/project/index.html` per: $ARGUMENTS.
7
+
8
+ - **FLIP a task** = change ONE `data-status` (todo→doing→done|blocked). On `done`, set
9
+ `data-session` and prepend a log row.
10
+ - **ADD a task** = next monotonic `t-NNNN` under the right `data-initiative`, status `todo`.
11
+ - **ADD an initiative** = a new `.entry--initiative` with `data-phase`, `data-lens="project"`, and
12
+ an empty `data-rollup` / `data-progress` (brain.js fills them).
13
+
14
+ Never reuse a cid; re-scoping = append a new task + flip the old one to done/blocked. Never type a
15
+ progress number — `brain.js` derives every bar from task status. Then run the rest of the STAMP if
16
+ the turn was substantive (`/sandpaper:stamp`).
@@ -0,0 +1,8 @@
1
+ ---
2
+ description: Serve the brain (or any Sandpaper doc) with the on-page refine toolbar
3
+ ---
4
+
5
+ Run `node bin/cli.js brain/` (or `node bin/cli.js <doc.html>`) in the background — it serves on
6
+ http://127.0.0.1:4848 with the on-page toolbar: **Sand** (scoped AI edit), **✎ Hands** (direct
7
+ edit, no AI), **❯ Sling** (copy a terminal-ready instruction). Tell the owner the URL and that the
8
+ file on disk stays the single source of truth.
@@ -0,0 +1,25 @@
1
+ ---
2
+ description: Stamp the Sandpaper brain after a substantive turn (the 6-step update)
3
+ argument-hint: "[optional one-line summary of the turn]"
4
+ ---
5
+
6
+ Update the project brain in `brain/` to reflect the work just done $ARGUMENTS. Follow the STAMP
7
+ contract exactly (`skill/sandpaper/SKILL.md` → STAMP / the project's CLAUDE.md). Do every step
8
+ that applies, regenerating WHOLE regions — never prose-edit inside one:
9
+
10
+ 1. **LOG** — prepend exactly one `<li>` row to the top of `brain/log.html` AND the cover's
11
+ `<!-- BRAIN:LOG -->` feed. Verb-led, ≤12 words, ends in a link to a canonical anchor. Use the
12
+ next monotonic `w-NNNN` cid. Never edit a prior row.
13
+ 2. **NOW** — overwrite the cover's `<!-- BRAIN:NOW -->…` region with one present-tense sentence
14
+ (≤120 chars) + a link to what you touched. Replace, never append.
15
+ 3. **DIGEST** — overwrite `#brain-state` so `focus`, the newest worklog line, and `open` match.
16
+ 4. **DECISIONS** — if a call was made or a question opened/resolved, append a status-typed
17
+ `.entry` to `brain/decisions.html` (or flip ONE `data-status`). A reversal is a NEW entry with
18
+ `data-rel="supersedes:<id>"` — never rewrite the old one.
19
+ 5. **LEARNINGS** — if a gotcha bit, append one callout to `brain/learnings.html`.
20
+ 6. **PLAN** — flip the relevant task's `data-status` in `brain/project/index.html`. Progress is
21
+ DERIVED — never type a number. Append a task/initiative if the work was new.
22
+
23
+ Keep it link-never-copy and respect the `.entry` grammar (data-cid→id, data-kind, data-status,
24
+ data-date, ≥1 data-ref, optional data-lens). Then verify `#brain-state` still parses and the new
25
+ links resolve, and commit.
@@ -0,0 +1,17 @@
1
+ ---
2
+ description: Reconcile the brain against the code — find and flag drift
3
+ ---
4
+
5
+ Audit the brain against reality and report drift (the brain's periodic checkup):
6
+
7
+ 1. Read `#brain-state`, the plan board, and the component map.
8
+ 2. Check each claim against the code — the `git log`, the file structure, the actual source.
9
+ Flag: stale facts, components whose status changed, decisions overtaken by events, plan tasks
10
+ that are actually done/blocked, counts that no longer match, and any `data-ref` whose anchor no
11
+ longer exists (a dangling link).
12
+ 3. Present the drift as a concise list.
13
+ 4. With the owner's OK, fix it via the STAMP ops — flip statuses, append entries, **supersede**
14
+ stale decisions (a new entry with `data-rel="supersedes:<id>"`). Never silently rewrite history.
15
+
16
+ This is the manual companion to the Stop hook: the hook prevents NEW drift; `/sync` heals existing
17
+ drift.
@@ -0,0 +1,12 @@
1
+ ---
2
+ description: Re-skin the Sandpaper brain from a brand colour or preset
3
+ argument-hint: "<a brand hex like #2E6F95, or \"preset: <name>\">"
4
+ ---
5
+
6
+ Re-skin by editing ONLY `brain/assets/theme.css` (the single token file): $ARGUMENTS.
7
+
8
+ Derive a coherent palette from the brand hex — a paper/ink base plus an accent and supporting
9
+ hues (a green, an amber, a red) — keeping contrast and legibility (WCAG AA for text). Touch no
10
+ other file: every brain surface reads its colour from `theme.css`, so one edit re-skins the whole
11
+ manual. If the owner also wants the injected toolbar reskinned, keep its `#sp-panel` `--sp-*`
12
+ mirror in `public/toolbar.css` in sync (it's deliberately host-independent).