e0328f2b1c
CI & Build / Python lint (push) Successful in 4s
CI & Build / integration (push) Successful in 27s
CI & Build / TypeScript typecheck (push) Successful in 35s
CI & Build / Python tests (push) Successful in 47s
CI & Build / Build & push image (push) Successful in 1m2s
The milestone headline. Auto-inject fires on the operator's prompt; the moment reuse is actually lost is later, when the agent decides mid-task to write a helper. A PreToolUse hook on Write|Edit now fires there. Channel: `additionalContext` with NO permissionDecision, so the note reaches Claude beside the tool result and the write is never blocked — a recall aid must not be able to stop the operator's work. Plain stdout would have been invisible to the model, and deny/ask would have made a nudge into a gate. Two arms, different in kind: - BY PLACE — a snippet recorded at this path (or its directory) is prior art by definition, not resemblance, so it is neither scored nor thresholded. This is what #2083's reverse lookup was built to answer. - BY MEANING — semantic search restricted to snippets (new `note_type` filter on semantic_search_notes) over the code about to be written. Place ranks first; the top-k cap spans both arms. Gates carried over from milestone 93 verbatim: threshold, margin, session dedup, titles-never-bodies. Own `source='write_path'` in retrieval_logs so precision is tunable separately — the docstring records that the place arm is unlogged and hands that to #2085. Its own on/off in Settings but the SAME threshold/top-k: one "how loud may Scribe be" knob is easier to reason about than two that drift, and splitting them later is then a data-backed change rather than a guess. Details worth keeping: the hook sends a REPO-RELATIVE path because that is how locations are recorded; the git remote resolves to a project and is never used as the location `repo` filter (different namespaces, would silently match nothing); the endpoint stays a GET because a read-scoped API key cannot POST and every other hook depends on that. plugin.json 0.1.17 -> 0.1.18. Refs #2082, milestone #232.
67 lines
3.1 KiB
Markdown
67 lines
3.1 KiB
Markdown
# Scribe plugin for Claude Code
|
|
|
|
Turns a self-hosted [Scribe](https://git.fabledsword.com/bvandeusen/FabledScribe)
|
|
instance into a first-class Claude Code extension:
|
|
|
|
- **MCP tools** over your notes, tasks, projects, milestones, systems, and
|
|
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*.
|
|
- **Prior-art recall on writes** — a `PreToolUse` hook on Write/Edit checks the
|
|
file about to be written against your recorded snippets (what's kept at that
|
|
path, and what resembles the code) and offers them before the helper is
|
|
rewritten. Titles only, never blocks the edit.
|
|
- **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
|
|
on demand with `/scribe:sync`.
|
|
|
|
It is designed so you can uninstall `superpowers` and disable auto-memory and
|
|
depend on neither.
|
|
|
|
## Install
|
|
|
|
The plugin ships inside the Scribe app repo, so the marketplace *is* that repo —
|
|
you always get the plugin version that matches your Scribe instance.
|
|
|
|
```
|
|
/plugin marketplace add https://git.fabledsword.com/bvandeusen/FabledScribe.git
|
|
/plugin install scribe@scribe-plugin
|
|
```
|
|
|
|
On install you'll be asked for:
|
|
|
|
| Setting | What |
|
|
|---|---|
|
|
| **Scribe base URL** | e.g. `https://scribe.example.com` (no trailing slash) |
|
|
| **Scribe API key** | an `fmcp_` key from **Settings → API Keys** (stored in your OS keychain) |
|
|
| **Active project id** | optional — numeric project id to scope the session-start context |
|
|
|
|
## What gets wired
|
|
|
|
- `plugin.json` `mcpServers` → the `scribe` MCP server at `<base URL>/mcp` (Bearer auth).
|
|
- `hooks/hooks.json` → SessionStart hook (`hooks/scribe_session_context.sh`),
|
|
**fail-open**: if Scribe is unreachable it injects nothing and never blocks
|
|
the session.
|
|
- `hooks/hooks.json` → PreToolUse hook on `Write|Edit`
|
|
(`hooks/scribe_prior_art.sh`) → `GET /api/plugin/prior-art`. Returns
|
|
`additionalContext` with **no** permission decision, so it can inform the write
|
|
but never stop it; silent when nothing is recorded, which is most of the time.
|
|
Toggle in **Settings → Knowledge auto-inject**.
|
|
- `skills/` → the universal process-skills, surfaced by description match.
|
|
- `hooks/scribe_sync_processes.sh` (a 2nd SessionStart hook) + the `/scribe:sync`
|
|
command → generate `~/.claude/skills/scribe-proc-*` stubs from your Scribe
|
|
Processes (via `GET /api/plugin/processes`); also **fail-open**, and pruned to
|
|
match what exists in Scribe.
|
|
|
|
## Notes
|
|
|
|
- Set a `version` bump in `.claude-plugin/plugin.json` per release so clients
|
|
pick up changes.
|
|
- The session-start, auto-inject and prior-art hooks need only a **read**-scoped
|
|
key; the MCP tools need **write** scope to create/update. Every hook is a GET
|
|
for that reason — a read key cannot POST.
|