59 lines
3.7 KiB
Markdown
59 lines
3.7 KiB
Markdown
|
|
---
|
||
|
|
id: "0018"
|
||
|
|
date: 2026-07-03
|
||
|
|
status: Accepted
|
||
|
|
supersedes:
|
||
|
|
superseded-by:
|
||
|
|
affected-paths: []
|
||
|
|
affected-components: []
|
||
|
|
migration_confidence: medium
|
||
|
|
migration_source: "docs/memory-system/03-architecture-decisions.md### ADR-018 — Plugin renames must update the marketplace manifest, not just the directory and settings.json"
|
||
|
|
---
|
||
|
|
|
||
|
|
# 0018 — Plugin renames must update the marketplace manifest, not just the directory and settings.json
|
||
|
|
|
||
|
|
## Context
|
||
|
|
|
||
|
|
The `memory` plugin directory was renamed to `os-vault` (git rename,
|
||
|
|
`plugins/memory/` → `plugins/os-vault/`), the `~/.claude/plugins/os-vault` symlink was
|
||
|
|
updated, and `settings.json`'s `enabledPlugins` was flipped to `os-vault@local-plugins`.
|
||
|
|
Despite this, no `os-vault` slash commands (skills) were available in-session. Root cause:
|
||
|
|
the `local-plugins` marketplace manifest (`~/.claude/plugins/.claude-plugin/marketplace.json`)
|
||
|
|
— which explicitly lists each plugin's `name`/`source` rather than auto-discovering the
|
||
|
|
directory — still declared only `memory`/`./memory`, and `installed_plugins.json` still held
|
||
|
|
a stale install record for `memory@local-plugins`. Hooks kept firing throughout (they're
|
||
|
|
wired by absolute path directly in `settings.json`, bypassing plugin resolution entirely),
|
||
|
|
which masked the break — everything looked healthy except the skills/slash-commands.
|
||
|
|
|
||
|
|
## Decision
|
||
|
|
|
||
|
|
A local-plugin rename/move is a three-file operation: (1) the plugin directory
|
||
|
|
or symlink, (2) the marketplace manifest entry (`name` + `source`), (3) `settings.json`
|
||
|
|
`enabledPlugins`. After all three, run `claude plugin marketplace update <marketplace>` to
|
||
|
|
re-validate, `claude plugin install <new>@<marketplace>` to create the new install record,
|
||
|
|
and `claude plugin uninstall <old>@<marketplace>` to drop the stale one — then verify with
|
||
|
|
`claude plugin list` and `claude plugin details <new>@<marketplace>` (skills/agents/hooks
|
||
|
|
inventory). Documented as a standing procedure in `CLAUDE.md` under "Renaming or moving a
|
||
|
|
local plugin."
|
||
|
|
- **Rationale**: The marketplace manifest is the actual source of truth for what plugins exist
|
||
|
|
under a directory-source marketplace — the directory listing itself is not consulted for
|
||
|
|
plugin identity. Because hooks are independently wired by path, they give a false signal that
|
||
|
|
the plugin is fully operational; skill/slash-command registration must be checked separately
|
||
|
|
via `claude plugin details`.
|
||
|
|
|
||
|
|
## Consequences
|
||
|
|
|
||
|
|
Renaming a local plugin is now a documented three-file operation (directory/symlink, marketplace manifest entry, settings.json enabledPlugins) followed by marketplace update, install of the new record, and uninstall of the stale one, verified via `claude plugin details`. This was necessitated because the memory→os-vault rename left skills unavailable despite hooks still firing, since hooks are wired by absolute path and gave a false signal of full functionality while the marketplace manifest (the actual source of plugin identity) still pointed at the old name.
|
||
|
|
|
||
|
|
## Alternatives rejected
|
||
|
|
|
||
|
|
**Rely on directory listing / auto-discovery** — not how
|
||
|
|
`local-plugins` (a directory-source marketplace) resolves plugins; the manifest is
|
||
|
|
authoritative. **Skip the install/uninstall refresh, just fix the manifest** — leaves a stale
|
||
|
|
cached install record in `installed_plugins.json` under the old name, which is confusing and
|
||
|
|
can mask a future rename of the same kind.
|
||
|
|
- **Consequences / ongoing contracts**: any future rename of `os-vault` (or a new local plugin)
|
||
|
|
must touch the marketplace manifest, not just `settings.json`. `claude plugin details
|
||
|
|
<plugin>@<marketplace>` is the verification step to run after any plugin registration change
|
||
|
|
— it surfaces the skill/agent/hook inventory that a passing hook test would not.
|