Files
FabledScribe/plugin/skills/reusing-code/SKILL.md
T
bvandeusenandClaude Fable 5 475f0857c9
CI & Build / Plugin hooks (push) Failing after 2s
CI & Build / Python lint (push) Successful in 4s
CI & Build / integration (push) Failing after 28s
CI & Build / TypeScript typecheck (push) Successful in 36s
CI & Build / Python tests (push) Successful in 1m5s
CI & Build / Build & push image (push) Successful in 39s
feat(ledger): write-path stamping — a pulled canon the session then instantiates lands as a hook instance row (#2791, milestone 294 step 5)
The prior-art hook now names the shapes being written (shapes=kind:name —
every definition in the payload, or the one enclosing an Edit found by
walking the file upward) and the server stamps them as instance rows when
the session PULLED a snippet inside PULL_WINDOW that the payload references
by symbol or that the semantic arm scored for this very payload.
classified_by=hook, evidence in reason; never overrides a judgment or a
canonical row, overridable by classify_shapes. Offered-but-unopened stamps
nothing. Pulled-and-already-seen snippets stay in the semantic query as
evidence without re-entering the deduped menu. A brand-new shape gets a
provisional row the next sync confirms or vanishes. Read-scoped keys get
the hint, never the stamp. Plugin 0.1.34.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-20 20:19:45 -04:00

8.2 KiB

name, description
name description
reusing-code 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 [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.