# 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.
  Two framings: a REUSE menu (similar/nearby records), and a SYNC nudge when a
  snippet records the exact file being edited — "updating the record is part of
  the edit" — each with its own once-per-session dedup. A third, ledger-fed
  line names a duplicate family (no canon) or a canon recorded elsewhere for
  the names being written (its own dedup channel, `exclude_derive`).
  Fail-open but not fail-silent: a configured instance that does not answer
  in time is said, once per outage ("Scribe did not answer … this write went
  UNCHECKED"), so a session can tell "checked, nothing there" from "never
  checked"; an answer clears the marker. The local by-name arm needs no
  server and always runs. Toggle in **Settings → Knowledge auto-inject**.
- `hooks/hooks.json` → PostToolUse hook on `Bash`
  (`hooks/scribe_after_write.sh`): code written through sed/heredocs/scripts
  never reaches the PreToolUse hook, so this one diffs the working tree after
  every Bash call (per-session path+blob snapshot; one `git status` when
  nothing changed) and runs the same arms on the definitions just written,
  through the same endpoint and the same dedup channels. `additionalContext`
  only; never blocks, and shares the pre-write hook's once-per-outage "did not
  answer" line (8 s budget here — it runs after the tool, so it gates
  nothing). The extractor, the prose/data skip list, the local by-name
  duplicate arm and the outage line are shared in `hooks/scribe_defs.sh`.
- `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.
