From c5eeec471f262c756916e17ef4227c4b513a052d Mon Sep 17 00:00:00 2001 From: Bryan Van Deusen Date: Thu, 22 Oct 2026 10:52:55 -0400 Subject: [PATCH] =?UTF-8?q?rename(547):=20the=20plugin=20is=20grimoire=20?= =?UTF-8?q?=E2=80=94=20manifest,=20MCP=20key,=20hooks,=20env,=20skills?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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-; 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 --- .claude-plugin/marketplace.json | 4 +- .../0124_skill_names_follow_the_plugin.py | 45 +++ docs/api-keys-and-mcp.md | 6 +- docs/design-system.md | 2 +- docs/features.md | 2 +- frontend/src/views/SettingsView.vue | 14 +- plugin/.claude-plugin/plugin.json | 8 +- plugin/PACKAGING.md | 36 +- plugin/README.md | 44 +-- plugin/commands/sync.md | 6 +- ...after_write.sh => grimoire_after_write.sh} | 62 ++-- ...e_autoinject.sh => grimoire_autoinject.sh} | 66 ++-- ...m_session.sh => grimoire_claim_session.sh} | 16 +- .../{scribe_defs.sh => grimoire_defs.sh} | 322 +++++++++--------- .../{scribe_json.awk => grimoire_json.awk} | 2 +- .../{scribe_moment.sh => grimoire_moment.sh} | 60 ++-- ...rve.sh => grimoire_precompact_preserve.sh} | 10 +- ...ibe_prior_art.sh => grimoire_prior_art.sh} | 102 +++--- ...rd_opened.sh => grimoire_record_opened.sh} | 34 +- ..._outcome.sh => grimoire_record_outcome.sh} | 16 +- ...reply_check.sh => grimoire_reply_check.sh} | 54 +-- ...context.sh => grimoire_session_context.sh} | 74 ++-- ...session_end.sh => grimoire_session_end.sh} | 16 +- ...shape_check.sh => grimoire_shape_check.sh} | 36 +- ..._context.md => grimoire_static_context.md} | 14 +- ...rocesses.sh => grimoire_sync_processes.sh} | 36 +- ...e_tool_rules.sh => grimoire_tool_rules.sh} | 72 ++-- .../{scribe_turn.awk => grimoire_turn.awk} | 6 +- plugin/hooks/hooks.json | 28 +- .../{using-scribe => using-grimoire}/SKILL.md | 4 +- .../missed-retrieval.md | 2 +- .../moments.md | 2 +- .../projects.md | 6 +- .../writing-records.md | 2 +- scripts/check_plugin.py | 69 ++-- src/grimoire/mcp/server.py | 4 +- src/grimoire/mcp/tools/processes.py | 2 +- src/grimoire/restore.py | 2 +- src/grimoire/routes/plugin.py | 12 +- src/grimoire/services/coverage.py | 6 +- src/grimoire/services/moment_actions.py | 12 +- src/grimoire/services/plugin_context.py | 6 +- src/grimoire/services/retrieval_registry.py | 2 +- src/grimoire/services/shape_ledger.py | 2 +- tests/test_after_write_hook.py | 12 +- tests/test_autoinject_context.py | 2 +- tests/test_contract_around_the_change.py | 12 +- tests/test_db_ready.py | 4 +- tests/test_family_delivery.py | 2 +- ...ribe_marker.py => test_grimoire_marker.py} | 42 +-- tests/test_guidance_ownership.py | 18 +- tests/test_hook_duplicate_confirmation.py | 14 +- tests/test_hook_json_reader.py | 54 +-- tests/test_hook_pipefail_head.py | 4 +- tests/test_instruction_surfaces_agree.py | 12 +- tests/test_moment_actions.py | 26 +- tests/test_moment_delivery.py | 30 +- tests/test_moments.py | 4 +- tests/test_pattern_coverage.py | 6 +- tests/test_plugin_shipped_set.py | 10 +- tests/test_plugin_version_mint.py | 18 +- tests/test_pre_act_checkpoint.py | 26 +- tests/test_precompact_hook.py | 4 +- tests/test_prompt_boundary_filter.py | 12 +- tests/test_records_are_named_not_numbered.py | 4 +- tests/test_reply_moment.py | 10 +- tests/test_reply_shape_turn.py | 10 +- tests/test_retrieval_miss_route.py | 8 +- tests/test_retrieval_registry.py | 2 +- tests/test_rule_ledger_ageing.py | 20 +- tests/test_rule_moment_signal_hooks.py | 40 +-- tests/test_rule_opened_ledger.py | 22 +- tests/test_rule_usage_wiring.py | 26 +- tests/test_services_backup_job.py | 4 +- tests/test_services_forge.py | 4 +- tests/test_services_plugin_context.py | 4 +- tests/test_services_snippets.py | 34 +- tests/test_session_context_failure.py | 6 +- tests/test_session_context_ledger.py | 8 +- tests/test_session_ledger_clear.py | 34 +- tests/test_session_slippage_readout.py | 48 +-- tests/test_shape_check_hook.py | 8 +- tests/test_skill_structure.py | 2 +- tests/test_task_claims.py | 14 +- tests/test_verification_guidance_survives.py | 4 +- tests/test_wide_net.py | 2 +- tests/test_write_path_trigger.py | 64 ++-- 87 files changed, 1027 insertions(+), 989 deletions(-) create mode 100644 alembic/versions/0124_skill_names_follow_the_plugin.py rename plugin/hooks/{scribe_after_write.sh => grimoire_after_write.sh} (81%) rename plugin/hooks/{scribe_autoinject.sh => grimoire_autoinject.sh} (74%) rename plugin/hooks/{scribe_claim_session.sh => grimoire_claim_session.sh} (76%) rename plugin/hooks/{scribe_defs.sh => grimoire_defs.sh} (87%) rename plugin/hooks/{scribe_json.awk => grimoire_json.awk} (99%) rename plugin/hooks/{scribe_moment.sh => grimoire_moment.sh} (75%) rename plugin/hooks/{scribe_precompact_preserve.sh => grimoire_precompact_preserve.sh} (92%) rename plugin/hooks/{scribe_prior_art.sh => grimoire_prior_art.sh} (79%) rename plugin/hooks/{scribe_record_opened.sh => grimoire_record_opened.sh} (79%) rename plugin/hooks/{scribe_record_outcome.sh => grimoire_record_outcome.sh} (81%) rename plugin/hooks/{scribe_reply_check.sh => grimoire_reply_check.sh} (71%) rename plugin/hooks/{scribe_session_context.sh => grimoire_session_context.sh} (82%) rename plugin/hooks/{scribe_session_end.sh => grimoire_session_end.sh} (80%) rename plugin/hooks/{scribe_shape_check.sh => grimoire_shape_check.sh} (75%) rename plugin/hooks/{scribe_static_context.md => grimoire_static_context.md} (73%) rename plugin/hooks/{scribe_sync_processes.sh => grimoire_sync_processes.sh} (69%) rename plugin/hooks/{scribe_tool_rules.sh => grimoire_tool_rules.sh} (70%) rename plugin/hooks/{scribe_turn.awk => grimoire_turn.awk} (94%) rename plugin/skills/{using-scribe => using-grimoire}/SKILL.md (99%) rename plugin/skills/{using-scribe => using-grimoire}/missed-retrieval.md (98%) rename plugin/skills/{using-scribe => using-grimoire}/moments.md (98%) rename plugin/skills/{using-scribe => using-grimoire}/projects.md (90%) rename plugin/skills/{using-scribe => using-grimoire}/writing-records.md (99%) rename tests/{test_scribe_marker.py => test_grimoire_marker.py} (78%) diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index fb00c4ef..7257961f 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -1,10 +1,10 @@ { - "name": "scribe-plugin", + "name": "grimoire-plugin", "owner": { "name": "Bryan Van Deusen" }, "description": "Grimoire ships its own Claude Code plugin from this repo, versioned in lockstep with the app + the /api/plugin/context contract.", "plugins": [ { - "name": "scribe", + "name": "grimoire", "source": "./plugin", "description": "Grimoire second brain: MCP tools + session-start push channel + universal process-skills." } diff --git a/alembic/versions/0124_skill_names_follow_the_plugin.py b/alembic/versions/0124_skill_names_follow_the_plugin.py new file mode 100644 index 00000000..2ae3ac0a --- /dev/null +++ b/alembic/versions/0124_skill_names_follow_the_plugin.py @@ -0,0 +1,45 @@ +"""skill names follow the plugin's name + +Revision ID: 0124 +Revises: 0123 +Create Date: 2026-10-22 + +The plugin is named `grimoire`, so its skills reach a session as +`grimoire:` and stored processes as `grimoire-proc-`. A rule +mounted on one of those skills, a judgment about that mount, and an install's +own action mapping all store the skill's name, and a stored name the harness no +longer sends never matches again. This rewrites the plugin's earlier prefixes, +`scribe:` and `scribe-proc-`, to the current ones. + +Cost: three small tables, each one row per mount, judgment or mapping. +""" +from alembic import op + +revision = "0124" +down_revision = "0123" +branch_labels = None +depends_on = None + +_MOMENT_TABLES = ("rule_moments", "rule_moment_judgments", "moment_mappings") + + +def _rename(old: str, new: str) -> None: + for table in _MOMENT_TABLES: + op.execute( + f"UPDATE {table} SET moment = regexp_replace(moment, " + f"'^skill\\.{old}(:|-proc-)', 'skill.{new}\\1') " + f"WHERE moment ~ '^skill\\.{old}(:|-proc-)'" + ) + op.execute( + f'UPDATE moment_mappings SET "match" = regexp_replace("match", ' + f"'skill={old}(:|-proc-)', 'skill={new}\\1', 'g') " + f"WHERE \"match\" ~ 'skill={old}(:|-proc-)'" + ) + + +def upgrade() -> None: + _rename("scribe", "grimoire") + + +def downgrade() -> None: + _rename("grimoire", "scribe") diff --git a/docs/api-keys-and-mcp.md b/docs/api-keys-and-mcp.md index 775b3a7e..7e47018b 100644 --- a/docs/api-keys-and-mcp.md +++ b/docs/api-keys-and-mcp.md @@ -54,7 +54,7 @@ The plugin connects the MCP server and adds the hooks and skills that put Grimoi ``` /plugin marketplace add https://git.fabledsword.com/bvandeusen/FabledScribe.git -/plugin install scribe@scribe-plugin +/plugin install grimoire@grimoire-plugin ``` It asks for your Grimoire base URL, an API key (kept in your OS keychain) and, optionally, a project id. Settings → MCP Access shows the exact command for your instance. [`plugin/README.md`](../plugin/README.md) describes each hook. @@ -67,9 +67,9 @@ your instance's `/mcp` endpoint: ```json { "mcpServers": { - "scribe": { + "grimoire": { "type": "http", - "url": "https://your-scribe-instance.example.com/mcp", + "url": "https://your-grimoire-instance.example.com/mcp", "headers": { "Authorization": "Bearer fmcp_your-api-key" } diff --git a/docs/design-system.md b/docs/design-system.md index 2c9b575b..f91e605e 100644 --- a/docs/design-system.md +++ b/docs/design-system.md @@ -332,7 +332,7 @@ Home server management. The accent appears on: the wordmark, healthy/online stat } /* Per-app accent — set ONE of these on the root for each app */ -[data-app="scribe"] { --fs-accent: #5B4A8A; } +[data-app="grimoire"] { --fs-accent: #5B4A8A; } [data-app="minstrel"] { --fs-accent: #4A6B5C; } [data-app="forge"] { --fs-accent: #8B5A2B; } [data-app="roundtable"]{ --fs-accent: #4A5D7E; } diff --git a/docs/features.md b/docs/features.md index e7599746..46734f89 100644 --- a/docs/features.md +++ b/docs/features.md @@ -53,7 +53,7 @@ Tokens (colour, type, space, motion, ...) and written guidance, with inheritance ## Stored processes -Saved procedures, such as a drift audit or a DRY pass. The plugin syncs each one into a Claude Code skill (`/scribe:sync`), which fetches the live procedure when it is invoked. +Saved procedures, such as a drift audit or a DRY pass. The plugin syncs each one into a Claude Code skill (`/grimoire:sync`), which fetches the live procedure when it is invoked. ## Search and context injection diff --git a/frontend/src/views/SettingsView.vue b/frontend/src/views/SettingsView.vue index 0a5ed8b5..aa2c0e74 100644 --- a/frontend/src/views/SettingsView.vue +++ b/frontend/src/views/SettingsView.vue @@ -570,7 +570,7 @@ const copiedSnippetKey = ref(null); // preferences carry across visits without needing a server-side setting. const _MCP_NAME_KEY = 'mcp_server_name'; const _MCP_SCOPE_KEY = 'mcp_scope'; -const _DEFAULT_MCP_NAME = 'scribe'; +const _DEFAULT_MCP_NAME = 'grimoire'; const _isValidScope = (v: unknown): v is 'user' | 'project' | 'local' => v === 'user' || v === 'project' || v === 'local'; @@ -635,8 +635,8 @@ const DEAD_PCT_WARN = 20; // dead-tuple ratio above this = autovacuum falling be const pluginInstallCommands = computed(() => { const mkt = (pluginMarketplaceUrl.value || '').trim() || serverMarketplaceUrl.value - || '.git'; - return `/plugin marketplace add ${mkt}\n/plugin install scribe@scribe-plugin`; + || '.git'; + return `/plugin marketplace add ${mkt}\n/plugin install grimoire@grimoire-plugin`; }); const mcpConfigSnippet = computed(() => JSON.stringify({ @@ -2644,7 +2644,7 @@ async function deleteUser(userId: number) { project id to scope the session-start context.
  • - Restart Claude Code — /mcp shows scribe connected and your + Restart Claude Code — /mcp shows grimoire connected and your standing rules load at session start.
  • @@ -2669,9 +2669,9 @@ async function deleteUser(userId: number) {