CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 12s
CI & Build / TypeScript typecheck (push) Successful in 52s
CI & Build / integration (push) Successful in 1m1s
CI & Build / Python tests (push) Successful in 1m55s
CI & Build / Build & push image (push) Successful in 36s
Step 1 of the Scribe -> Grimoire rename: every capitalised "Scribe" in prose
becomes "Grimoire" ("Fabled Scribe" -> "Fabled Grimoire") across the UI,
the PWA manifest and page title, the MCP instructions and tool docstrings,
hook and skill text, docs and README, with the tests that assert on that
prose moving with it. Old migrations keep their wording.
Identifiers are untouched here: the package, plugin name, MCP server key,
hook file names, env vars, the .scribe marker and FabledScribe repo/image
names move in steps 2 and 3, along with prose that quotes them.
The sweep matched "Scribe" only as a whole word, so describe/subscribe and
friends are untouched. The longer name took the MCP instructions one
character over their 1,600 budget; two phrases are shortened to fit.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
176 lines
11 KiB
Markdown
176 lines
11 KiB
Markdown
---
|
|
name: reusing-code
|
|
description: Use when you're about to build ANY shape — a component, control, route handler, service class, helper, test scaffold — search recorded snippets FIRST and start from the recorded shape instead of re-solving it. And before the turn that built it ends, say what it is — record the reusable as a snippet, classify the rest — so every later instance starts from it. Triggers on "write a util/helper", "I need a function that…", "let me add a component/button/field/route", having just built the first instance of anything, or the end-of-turn list of shapes to judge.
|
|
metadata:
|
|
moments: work.change
|
|
---
|
|
|
|
# Reusing code — the pattern library
|
|
|
|
Snippets are the project's **pattern library**, not a dedup net. Each records a
|
|
named shape — with its language, signature, canonical location (repo · path ·
|
|
symbol), a one-line *"when to reach for it,"* and the code — so every later
|
|
instance STARTS from the recorded shape: buttons start from the button shape,
|
|
fields from the field shape, and "special" is a deliberate, named exception
|
|
rather than drift. A mature project's snippet corpus reads as a map of every
|
|
shape in it, from the humblest control to the most complex subsystem pattern.
|
|
Snippets are ordinary embedded notes, so a recorded one also surfaces on its own
|
|
through recall/auto-inject; this skill is the active reflex around that.
|
|
|
|
## Before you build any shape — search first
|
|
|
|
- About to build a component, control, route handler, service class, utility,
|
|
hook, formatter, adapter, or test scaffold?
|
|
**Search snippets before writing it.** `list_snippets(q="…")` (or a plain
|
|
`search`) — a matching one may already exist, in this project or another.
|
|
`list_snippets` searches every project by default; that's deliberate, since a
|
|
helper you need here was quite possibly written somewhere else. Narrow with
|
|
`project_id` only when you specifically want this project's own.
|
|
- **About to edit an existing file? Ask by place, not just by meaning.**
|
|
`list_snippets(repo="…", path="…")` answers "what canonical helpers are already
|
|
recorded here?" — `path` matches the exact file or anything beneath it, so
|
|
`path="frontend/src"` covers the whole tree. Cheaper and sharper than a
|
|
wording search when you already know where the code is going, and it catches
|
|
the helper you'd otherwise duplicate a few lines down. `symbol="…"` narrows
|
|
further, and all three must match the same recorded location. Combine with `q`
|
|
to ask both at once.
|
|
- If a snippet fits, pull it in full with `get_snippet(id)` and reuse it — its
|
|
`location` points at the reference implementation. Adapt, don't re-derive.
|
|
The pull also feeds the accounting: the code you then write that references
|
|
or resembles it is offered back to you as "looks like #N" when you judge the
|
|
turn's shapes — reuse from memory leaves no such evidence.
|
|
- If auto-inject already surfaced a snippet title that looks relevant, that's
|
|
your cue to `get_snippet` it rather than start from scratch.
|
|
- **Prior art offered beside a write is not noise — read it.** When Grimoire notes
|
|
that a snippet is already recorded for the file you just wrote or edited, open
|
|
it before you go any further. Either it's the helper you were about to
|
|
duplicate — reuse it and drop yours — or it isn't, and the record needs the new
|
|
location adding. Both are cheaper now than after the duplicate settles in.
|
|
- **A `Shape ledger at …` line is the ledger speaking, not the record.** It
|
|
names a duplicate family ("identical body in N other files, no canon"), a
|
|
repeated name ("defined in N other files") or a canon elsewhere for a name
|
|
you just wrote — for edits made through a shell
|
|
(sed, heredocs, scripts) as much as through your editor tools. Derive the family or
|
|
reuse the canon *now*; a family that is convention rather than copies is
|
|
dismissed with `classify_shapes(..., status="exempt",
|
|
reason_code="convention-plumbing")`, never ignored.
|
|
- **A `[records this file]` hint is a duty, not a menu.** When the hint says a
|
|
snippet records the very file you're editing, the record's freshness is now
|
|
YOUR edit's responsibility: if the edit changes the recorded shape,
|
|
`update_snippet(id, code=…)` with the new form as part of the same task; if
|
|
it doesn't, `verify_snippet(id, status="ok", commit_sha=…)` costs one call
|
|
and re-stamps the record as checked. Grimoire never reads the repo — this
|
|
moment, in the session that has the context, is the only place the record
|
|
gets kept true.
|
|
|
|
## The first time a shape is built — record it
|
|
|
|
- Just built the FIRST instance of anything with a shape — a component, a
|
|
field, a route, a service pattern, a scaffold? Record it with
|
|
`create_snippet` while it's fresh. Do **not** stop to judge whether it will
|
|
recur: the builder of the first instance can never know, and a missed record
|
|
is invisible until it resurfaces as an uninformed duplicate. Over-recording
|
|
is safe — dead weight shows up in the usage counters and can be pruned;
|
|
under-recording has no signal at all. The record is cheap — these fields:
|
|
- **name** — what it's called, e.g. `useDebouncedRef`.
|
|
- **code** — the implementation.
|
|
- **when_to_use** — the situation to reach for it in, in a sentence or two.
|
|
The snippet is ranked on this, so state the moment it applies and nothing
|
|
else — make it earn the pull.
|
|
- **notes** — everything that isn't the situation: why it's shaped this way,
|
|
what it replaced, caveats. When you learn something about a snippet later,
|
|
add it here rather than to `when_to_use`.
|
|
- **language**, **signature**, and **location** (`repo` / `path` / `symbol`)
|
|
so the recorded copy points back at the canonical source.
|
|
- **project_id** / **system_ids** to associate it with the work it belongs to.
|
|
- Record the *reference* implementation, not every call site — one good entry
|
|
per reusable thing. If it already exists, `update_snippet` it instead of
|
|
recording a second copy (the create gate will flag a near-duplicate anyway).
|
|
|
|
## Before the turn ends — say what you built
|
|
|
|
You are the one who knows what the code you just wrote is. The shape ledger
|
|
records it from your answer, not from a guess made later, so give the answer
|
|
in the turn that built it — while it is still true. When a turn wrote
|
|
definitions nobody has judged, the plugin's Stop hook lists them once, with
|
|
whatever evidence the machinery holds ("looks like #N", "#M is canon in this
|
|
directory", "new"); other clients reach the same moment through
|
|
`list_shapes(project_id, path=…)`. For each one, decide:
|
|
|
|
- **Something another part of the code should reuse** → record it with
|
|
`create_snippet` (the fields above). Its own row becomes the canon.
|
|
- **Built from a recorded snippet** → `instance` of it.
|
|
- **A deliberate departure from one** → `variant`, with the why.
|
|
- **A genuine one-off** → `exempt`, with a reason (`reason_code` such as
|
|
`one-off-handler`, `test-helper`, `scoped-css` or `pure-helper` indexes it).
|
|
|
|
One call records them all: `classify_shapes(project_id, repo="<the repo's
|
|
remote>", classifications=[{path, symbol, kind, status, snippet_id?, reason?}])`.
|
|
`repo` lets a verdict land on a shape the ledger has not synced yet — the one
|
|
you wrote a minute ago. A component file is a shape too (`kind: "file"`, named
|
|
by its stem): when a card, chip or dialog is the reusable thing, the file is
|
|
what you record. An unsure call is still yours to make — the reason you write
|
|
is what the next reader judges it by — and a verdict is permanent, so each
|
|
shape is asked about once.
|
|
|
|
## A shared snippet is a suggestion, not a standard
|
|
|
|
Grimoire is multi-user, so a search can return snippets other people own. Those
|
|
come back marked `shared: true` with an `owner`.
|
|
|
|
- Read one as **that person's suggestion**, not as the way things are done here.
|
|
Judge the code on its merits before reaching for it.
|
|
- Say whose it is when you propose it — "there's a snippet from *alex* that does
|
|
this" — so the operator can weigh the source, not just the code.
|
|
- Don't treat it as the house pattern, and don't build on it at scale, without
|
|
the operator agreeing to adopt it.
|
|
- Snippets shared directly with the operator only appear when you search for
|
|
them, never in a plain `list_snippets` — so anything ambient is genuinely
|
|
theirs.
|
|
|
|
## Keep the record honest
|
|
|
|
A recorded snippet is offered as prior art on every matching turn, so a wrong
|
|
one costs more than a missing one.
|
|
|
|
- Details gone stale — a renamed symbol, a moved file, a signature that's
|
|
changed? Fix it with `update_snippet`. Passing an **empty string** clears a
|
|
field, so a wrong signature or location can be removed, not just written over.
|
|
- Recorded something that turned out not to be reusable, or that no longer
|
|
exists? Retire it with `delete_snippet` — it goes to the trash and can be
|
|
restored. Don't leave it competing for attention.
|
|
|
|
## Found the same thing in several places — unify it
|
|
|
|
When you notice the same reusable thing recorded (or written) as several
|
|
one-offs, don't leave the duplicates competing in recall — **merge them**.
|
|
`merge_snippets(canonical_id, [other_ids])` keeps one canonical record, folds in
|
|
the others' call sites as locations, and retires the duplicates to the trash.
|
|
The result is a single entry that shows every place the thing is used — which is
|
|
exactly the signal that it was worth consolidating. This is the cure the create
|
|
gate only hints at when it blocks a near-duplicate.
|
|
|
|
## Consumer maps are rows, never prose
|
|
|
|
Every enumerated relationship between code and canon belongs in the shape
|
|
ledger, not in a sentence. When you establish that call sites route through a
|
|
canonical helper — during an audit, a verify pass, or a consolidation —
|
|
record each consuming definition with
|
|
`classify_shapes(project_id, [{path, symbol, status: "instance", snippet_id}])`.
|
|
A deliberate departure is a `"variant"` (reason required — the why IS the
|
|
record); a judged one-off is `"exempt"` (reason required). Prose in a
|
|
verification detail cannot be sorted, queried, or diffed; rows are what make
|
|
"what uses this?" answerable forever. `list_shapes(project_id,
|
|
status="unclassified")` is the standing todo — and N same-shaped occurrences
|
|
matching no canon means derive one first (consolidate, `create_snippet`,
|
|
then classify the rest against it), never N loose classifications.
|
|
|
|
## Why this pays off
|
|
|
|
A one-off written a second time is the cost this avoids — and at project
|
|
scale, the cost is an application whose buttons, fields, and services each
|
|
exist in four diverging shapes. Recording every shape once — with a location
|
|
and a crisp "when to use" — means every later session starts from the pattern
|
|
library instead of re-deriving it. Search before building; record every shape
|
|
at first build.
|