CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 13s
CI & Build / integration (push) Successful in 28s
CI & Build / TypeScript typecheck (push) Successful in 37s
CI & Build / Python tests (push) Successful in 1m7s
CI & Build / Build & push image (push) Successful in 34s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
143 lines
8.7 KiB
Markdown
143 lines
8.7 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 the FIRST time a shape is built, record it as a snippet 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", or having just built the first instance of anything.
|
|
---
|
|
|
|
# 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 does the accounting: the code you then write that references
|
|
or resembles it is stamped an `instance` of that canon in the shape ledger
|
|
(classified_by=hook) — reuse from memory leaves no row.
|
|
- 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 Scribe 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") or a
|
|
canon elsewhere for a name you just wrote — for edits made through Bash
|
|
(sed, heredocs, scripts) as much as through Write/Edit. 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. Scribe 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** — one sharp line on when to reach for it. This becomes part
|
|
of the title, so it's what a later recall menu shows — make it earn the pull.
|
|
- **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).
|
|
|
|
## A shared snippet is a suggestion, not a standard
|
|
|
|
Scribe 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.
|