rename(547): the plugin is grimoire — manifest, MCP key, hooks, env, skills
CI & Build / Python lint (push) Successful in 3s
CI & Build / Plugin hooks (push) Successful in 14s
CI & Build / TypeScript typecheck (push) Successful in 53s
CI & Build / integration (push) Successful in 1m2s
CI & Build / Python tests (push) Failing after 1m26s
CI & Build / Build & push image (push) Skipped

Step 3 of the Scribe -> Grimoire rename.

- Plugin `grimoire` in marketplace `grimoire-plugin`, MCP server key
  `grimoire`, so tools reach a session as mcp__plugin_grimoire_grimoire__*.
- hooks/scribe_* -> hooks/grimoire_*, their shell functions and the TMPDIR
  ledgers with them; SCRIBE_URL / SCRIBE_TOKEN / SCRIBE_HOOK_DIR /
  SCRIBE_LEDGER_DIRS -> GRIMOIRE_*; the project marker is `.grimoire`.
- skills/using-scribe -> using-grimoire, /grimoire:sync, stored processes
  arrive as grimoire-proc-<slug>; moment_actions names them the same way.
- Migration 0124 rewrites stored skill names (rule_moments,
  rule_moment_judgments, moment_mappings) from scribe:/scribe-proc- to
  grimoire:/grimoire-proc-, so a rule mounted on a skill keeps firing.
- Settings' install commands and MCP-only defaults, the docs and the
  tests follow.
- scripts/check_plugin.py drops the smoke event for a report-check hook
  that has no file in plugin/hooks.

Kept on purpose: the secret-sealing label, and the names that let backups
written as Scribe restore and be counted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-22 10:52:55 -04:00
co-authored by Claude Opus 5.5
parent 0f5ef0be63
commit c5eeec471f
87 changed files with 1027 additions and 989 deletions
+22 -22
View File
@@ -4,7 +4,7 @@ Turns a self-hosted [Grimoire](https://git.fabledsword.com/bvandeusen/FabledScri
instance into a first-class Claude Code extension:
- **MCP tools** over your notes, tasks, projects, milestones, systems, and
rulebook (the `scribe` server).
rulebook (the `grimoire` server).
- **Session-start push channel** — a `SessionStart` hook injects the
active project's live state (from the server) and this adapter's short
Claude Code guidance, so Grimoire surfaces *without being asked*. Rules are
@@ -14,15 +14,15 @@ instance into a first-class Claude Code extension:
path, and what resembles the code) and offers them before the helper is
rewritten. Titles only, never blocks the edit.
- **The shared Grimoire skills** — client-neutral Agent Skills, the same files
any client's package would ship: using-scribe, writing-plans, reporting-back
any client's package would ship: using-grimoire, writing-plans, reporting-back
(reply to the operator in a shape that says where the work stands),
systematic-debugging, verification, brainstorming, reusing-code (record and
recall reusable code as snippets), shape-accounting and family-canon.
Replaces superpowers.
- **Your Grimoire Processes as skills** — saved Processes are synced into local
`~/.claude/skills/scribe-proc-*` stubs that auto-surface by relevance; the
`~/.claude/skills/grimoire-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`.
on demand with `/grimoire:sync`.
It is designed so you can uninstall `superpowers` and depend on Grimoire instead
of auto-memory — leave auto-memory at its default; Grimoire replaces its job by
@@ -31,8 +31,8 @@ holding the one copy, not by switching it off.
**How the pieces divide the work**: the Grimoire server orients
every MCP client and serves live state; the skills in `skills/` state every
reflex in full and name no client; this plugin is the Claude Code adapter —
hooks that deliver at the right moment, `/scribe:sync`, and the few things only
Claude Code needs said (`hooks/scribe_static_context.md`). Packaging Grimoire for
hooks that deliver at the right moment, `/grimoire:sync`, and the few things only
Claude Code needs said (`hooks/grimoire_static_context.md`). Packaging Grimoire for
another client: see [PACKAGING.md](PACKAGING.md).
## Install
@@ -42,25 +42,25 @@ you always get the plugin version that matches your Grimoire instance.
```
/plugin marketplace add https://git.fabledsword.com/bvandeusen/FabledScribe.git
/plugin install scribe@scribe-plugin
/plugin install grimoire@grimoire-plugin
```
On install you'll be asked for:
| Setting | What |
|---|---|
| **Grimoire base URL** | e.g. `https://scribe.example.com` (no trailing slash) |
| **Grimoire base URL** | e.g. `https://grimoire.example.com` (no trailing slash) |
| **Grimoire API key** | a write-scoped `fmcp_` key from **Settings → MCP Access** (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`),
- `plugin.json` `mcpServers` → the `grimoire` MCP server at `<base URL>/mcp` (Bearer auth).
- `hooks/hooks.json` → SessionStart hook (`hooks/grimoire_session_context.sh`),
**fail-open**: if Grimoire 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
(`hooks/grimoire_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
@@ -74,12 +74,12 @@ On install you'll be asked for:
checked"; an answer clears the marker. The local by-name arm needs no
server and always runs. Toggle in **Settings → General → Knowledge
auto-inject**.
- `hooks/hooks.json` → UserPromptSubmit hook (`hooks/scribe_autoinject.sh`) →
- `hooks/hooks.json` → UserPromptSubmit hook (`hooks/grimoire_autoinject.sh`) →
`GET /api/plugin/retrieve`: the rules, preferences and records that match the
message, as a short menu of titles and matched passages.
- `hooks/hooks.json` → PreToolUse hook on `Bash` (`hooks/scribe_tool_rules.sh`)
- `hooks/hooks.json` → PreToolUse hook on `Bash` (`hooks/grimoire_tool_rules.sh`)
→ `GET /api/plugin/tool-rules`: the rules that match the command about to run.
- `hooks/hooks.json` → PreToolUse hook on every tool (`hooks/scribe_moment.sh`)
- `hooks/hooks.json` → PreToolUse hook on every tool (`hooks/grimoire_moment.sh`)
→ `POST /api/plugin/moment`: the rules mounted on the moments the call
reaches. It skips tools that `GET /api/plugin/moment-tools` says reach
nothing mounted, and Grimoire's own tools, whose responses carry
@@ -90,7 +90,7 @@ On install you'll be asked for:
`POST /api/plugin/rule-opened`), and claim the task being worked
(`GET /api/plugin/claim-session`) so it comes back after a compaction.
- `hooks/hooks.json` → PostToolUse hook on `Bash`
(`hooks/scribe_after_write.sh`): code written through sed/heredocs/scripts
(`hooks/grimoire_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,
@@ -98,8 +98,8 @@ On install you'll be asked for:
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`.
- `hooks/hooks.json` → Stop hook (`hooks/scribe_reply_check.sh`): sends the
duplicate arm and the outage line are shared in `hooks/grimoire_defs.sh`.
- `hooks/hooks.json` → Stop hook (`hooks/grimoire_reply_check.sh`): sends the
reply that ends the turn to `POST /api/plugin/reply-rules`, which holds it
once for an unopened rule mounted on the reply moments or matching the reply.
When the turn closed a Grimoire task (`update_task`/`create_task` with status
@@ -109,7 +109,7 @@ On install you'll be asked for:
the rewrite came out; it never blocks twice, and never blocks when the
instance did not record the check (unconfigured or unreachable). Outcomes
land in the admin logs under category `plugin`, action `report_check`.
- `hooks/hooks.json` → a second Stop hook (`hooks/scribe_shape_check.sh`): the
- `hooks/hooks.json` → a second Stop hook (`hooks/grimoire_shape_check.sh`): the
write hooks note every definition a write names (and every new file) in a
session ledger; at the end of the turn this sends them to
`GET /api/plugin/shape-check`, which answers with the ones nobody has judged.
@@ -119,14 +119,14 @@ On install you'll be asked for:
as the report check: never twice, never without a recorded check. Outcomes
land under category `plugin`, action `shape_check`.
- `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 Grimoire
- `hooks/grimoire_sync_processes.sh` (a 2nd SessionStart hook) + the `/grimoire:sync`
command → generate `~/.claude/skills/grimoire-proc-*` stubs from your Grimoire
Processes (via `GET /api/plugin/processes`); also **fail-open**, and pruned to
match what exists in Grimoire.
- `hooks/hooks.json` → PreCompact hook (`hooks/scribe_precompact_preserve.sh`):
- `hooks/hooks.json` → PreCompact hook (`hooks/grimoire_precompact_preserve.sh`):
tells the summarizer which parts of the conversation to keep literally. Local
only, and it never blocks, because a blocked compaction is skipped outright.
- `hooks/hooks.json` → SessionEnd hook (`hooks/scribe_session_end.sh`) →
- `hooks/hooks.json` → SessionEnd hook (`hooks/grimoire_session_end.sh`) →
`GET /api/plugin/release-session`: releases the session's task claims.
## Notes