From 0ea3bff797c760e0933ad92346cfda1d75cfe7eb Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Sat, 25 Jul 2026 14:00:07 -0400 Subject: [PATCH] =?UTF-8?q?feat(scribe):=20snippet=20recording=20nudge=20?= =?UTF-8?q?=E2=80=94=20reusing-code=20skill=20+=20MCP/SessionStart=20guida?= =?UTF-8?q?nce?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Step 5 of the Drafter recall milestone (#227): teach agents the two snippet reflexes — search recorded snippets before writing a new helper/util/component, and record something reusable the moment it's built — via the app's own instruction surfaces, not a Scribe rule (project rule #119). All instance-agnostic (rule #115). - plugin/skills/reusing-code/SKILL.md: new auto-surfacing process-skill covering both reflexes (recall-before-rebuild + record-when-reusable). - src/scribe/mcp/server.py: a Snippets paragraph in the MCP _INSTRUCTIONS. - plugin/hooks/scribe_static_context.md: a "reuse before rebuilding" bullet in the SessionStart static context. - plugin/.claude-plugin/plugin.json: version 0.1.12 -> 0.1.13 in the same change so the autoUpdate marketplace ships it (the #1040 lesson); description skill list updated. - plugin/README.md: trued the process-skill list to what actually ships. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Pa2EsuB54BuWQ8GfJq9c7t --- plugin/.claude-plugin/plugin.json | 4 +-- plugin/README.md | 5 +-- plugin/hooks/scribe_static_context.md | 5 +++ plugin/skills/reusing-code/SKILL.md | 45 +++++++++++++++++++++++++++ src/scribe/mcp/server.py | 13 ++++++++ 5 files changed, 68 insertions(+), 4 deletions(-) create mode 100644 plugin/skills/reusing-code/SKILL.md diff --git a/plugin/.claude-plugin/plugin.json b/plugin/.claude-plugin/plugin.json index dc90135..2f925e7 100644 --- a/plugin/.claude-plugin/plugin.json +++ b/plugin/.claude-plugin/plugin.json @@ -1,7 +1,7 @@ { "name": "scribe", - "description": "Scribe system-of-record for Claude Code: MCP tools over your notes/tasks/projects/rules, a session-start push channel that surfaces your always-on rules + active-project context, process-skills (writing-plans, systematic-debugging, verification, brainstorming), and your saved Scribe Processes auto-surfaced as skills (/scribe:sync). Replaces superpowers + file-memory with one app-backed plugin.", - "version": "0.1.12", + "description": "Scribe system-of-record for Claude Code: MCP tools over your notes/tasks/projects/rules, a session-start push channel that surfaces your always-on rules + active-project context, process-skills (writing-plans, systematic-debugging, verification, brainstorming, reusing-code), and your saved Scribe Processes auto-surfaced as skills (/scribe:sync). Replaces superpowers + file-memory with one app-backed plugin.", + "version": "0.1.13", "author": { "name": "Bryan Van Deusen" }, "mcpServers": { "scribe": { diff --git a/plugin/README.md b/plugin/README.md index b6ab7ff..9a76a44 100644 --- a/plugin/README.md +++ b/plugin/README.md @@ -7,8 +7,9 @@ instance into a first-class Claude Code extension: rulebook (the `scribe` server). - **Session-start push channel** — a `SessionStart` hook injects your always-on rules + active-project context so Scribe surfaces *without being asked*. -- **Universal process-skills** — brainstorm, systematic-debugging, TDD, - writing-plans, verification, receiving-code-review (replaces superpowers). +- **Universal process-skills** — using-scribe, writing-plans, + systematic-debugging, verification, brainstorming, reusing-code (record and + recall reusable code as snippets). Replaces superpowers. - **Your Scribe Processes as skills** — saved Processes are synced into local `~/.claude/skills/scribe-proc-*` stubs that auto-surface by relevance; the stub fetches the live procedure via `get_process`. Refreshed each session and diff --git a/plugin/hooks/scribe_static_context.md b/plugin/hooks/scribe_static_context.md index 180ecf1..dd5a313 100644 --- a/plugin/hooks/scribe_static_context.md +++ b/plugin/hooks/scribe_static_context.md @@ -37,6 +37,11 @@ for the operator's work, and as your own working memory across sessions. moment it's complete. When you **fix** something — even in passing — record it as its own issue (`create_task(kind="issue")`), not as a work-log line on an unrelated open task. +- **Reuse before rebuilding** — before writing a new helper/utility/component, + search recorded **snippets** (reusable code recorded once for recall) and + reuse the prior art instead of re-solving it; when you build something + reusable, record it with `create_snippet` (name, code, when-to-reach-for-it, + location) so a later session is offered it, not left to write it again. - Do **not** keep the operator's rules, plans, or project notes in local memory / CLAUDE.md in parallel with Scribe — Scribe holds the single copy. - **Compact at clean seams** — because you record as you go, a context diff --git a/plugin/skills/reusing-code/SKILL.md b/plugin/skills/reusing-code/SKILL.md new file mode 100644 index 0000000..cf1cccd --- /dev/null +++ b/plugin/skills/reusing-code/SKILL.md @@ -0,0 +1,45 @@ +--- +name: reusing-code +description: Use when you're about to write a helper, utility, hook, or reusable component — search recorded snippets FIRST so prior art is reused instead of re-solved. And the moment you build or notice something reusable, record it as a snippet so a later session finds it. Triggers on "write a util/helper", "I need a function that…", "let me add a component", or just having built something worth reusing. +--- + +# Reusing code — recall before you rebuild + +Reusable code is worth writing once. Scribe stores **snippets** — a named, +reusable function or component recorded with its language, signature, canonical +location (repo · path · symbol), a one-line *"when to reach for it,"* and the +code itself — so prior art can surface *before* it's re-written as a one-off. +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 write a new helper — search first + +- About to write a utility, hook, formatter, adapter, or a reusable component? + **Search snippets before writing it.** `list_snippets(q="…")` (or a plain + `search`) — a matching one may already exist, in this project or another. +- 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. +- If auto-inject already surfaced a snippet title that looks relevant, that's + your cue to `get_snippet` it rather than start from scratch. + +## The moment you build something reusable — record it + +- Just wrote (or noticed) a helper, hook, pattern, or component worth repeating? + Record it with `create_snippet` while it's fresh: + - **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). + +## Why this pays off + +A one-off written a second time is the cost this avoids. Recording a snippet +once — with a location and a crisp "when to use" — means the next session is +offered the prior art instead of re-solving it. Search before writing; record +what's worth reusing. diff --git a/src/scribe/mcp/server.py b/src/scribe/mcp/server.py index 44be3af..5c1f8ca 100644 --- a/src/scribe/mcp/server.py +++ b/src/scribe/mcp/server.py @@ -209,6 +209,19 @@ get_process(name) and follow the returned prompt verbatim, including any "clarify first" steps it contains. Author a new one with create_process(title, body); edit with update_process. +Scribe also stores Snippets — reusable functions/components recorded once for +recall (note_type "snippet"): a name, language, signature, canonical location +(repo · path · symbol), a one-line "when to reach for it", and the code. They +are ordinary embedded notes, so a recorded snippet also surfaces through the +same search + proactive recall as everything else. Two reflexes: (1) before you +write a new helper/utility/component, search first (list_snippets(q=...) or +search) — reuse the prior art with get_snippet(id) instead of re-deriving a +one-off; (2) the moment you build or notice something reusable, record it with +create_snippet(name, code, when_to_use, language, signature, repo, path, symbol, +project_id, system_ids) so a later session is offered it. Make when_to_use sharp +— it becomes the title, which is what a recall menu shows. Edit an existing one +with update_snippet rather than recording a second copy. + When developing Scribe itself, honor its multi-user sharing ACL: scope every read and mutation of user data by owner + shares — never assume a single operator. "Works for one user" is not done.