vault: session notes 2026-07-03
This commit is contained in:
parent
aec25e75fc
commit
023c92d77d
|
|
@ -0,0 +1,156 @@
|
|||
---
|
||||
type: howto
|
||||
title: Migrating a standalone plugin into cc-os
|
||||
summary: Step-by-step procedure for moving a plugin built standalone in ~/dev/cc-plugins/<name>/ into cc-os as plugins/os-<name>/, renaming, re-registering, and documenting it — replayable for any future plugin migration.
|
||||
tags:
|
||||
- type/howto
|
||||
- domain/claude-code-plugins
|
||||
- tool/claude-code
|
||||
- project/cc-os
|
||||
scope: global
|
||||
last_updated: 2026-07-03
|
||||
date: 2026-07-03
|
||||
update_note: experience-driven
|
||||
related:
|
||||
- cc-os-plugin-skill-naming-convention
|
||||
source: cc-os
|
||||
---
|
||||
|
||||
# Migrating a standalone plugin into cc-os
|
||||
|
||||
## Opening
|
||||
|
||||
Reach for this when a Claude Code plugin was prototyped standalone in `~/dev/cc-plugins/<name>/`
|
||||
and needs to move into `cc-os` — the canonical home for this person's Claude Code plugins,
|
||||
alongside `os-vault`, the reference implementation. First applied 2026-07-03 migrating
|
||||
`orchestration` → `os-orchestration`; next planned use: `doc-hygiene`. The steps assume two
|
||||
separate git repos (cc-plugins and cc-os) — this is a cross-repo move, not a `git mv`.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [ ] Plugin exists at `~/dev/cc-plugins/<name>/` with a `.claude-plugin/plugin.json`
|
||||
- [ ] `cc-os/plugins/os-vault/` is available to read as the structural reference to mirror
|
||||
- [ ] You know the plugin's current registration: check `~/.claude/plugins/.claude-plugin/marketplace.json`
|
||||
and `enabledPlugins` in `~/.claude/settings.json` for a `<name>@cc-plugins` entry
|
||||
|
||||
## Steps
|
||||
|
||||
### Step 1: Decide the new name
|
||||
|
||||
Apply the cc-os `os-` prefix convention (see [[cc-os-plugin-skill-naming-convention]]) —
|
||||
`<name>` becomes `os-<name>`. Decide this **before** touching registration files. Renaming after
|
||||
registration means redoing all three registration touchpoints (directory/symlink, marketplace
|
||||
manifest, `settings.json`).
|
||||
|
||||
### Step 2: Content-conflict check
|
||||
|
||||
Before moving any files, check whether the plugin's own instructional content (injected hook
|
||||
text, guidance it provides) conflicts or duplicates anything already hardcoded in cc-os's
|
||||
`CLAUDE.md` or other projects' `CLAUDE.md` files. Two blocks that look like "the same
|
||||
copy-pasted text" can have silently drifted into contradictory rules — this happened with
|
||||
`orchestration`'s `ORCHESTRATION.md` (permissive: "small ops direct, delegate wide work") vs.
|
||||
cc-os `CLAUDE.md`'s "Session Orchestration" section (absolutist: "delegate everything, no
|
||||
exceptions"), which read as duplicates but were opposites.
|
||||
|
||||
If a conflict exists: **surface it explicitly to the user as a decision point.** Do not pick a
|
||||
"canonical" version yourself, even if one side looks more specific or more recent — that
|
||||
intuition can point the wrong way (the more-permissive, more-evolved side may be the one the
|
||||
user actually intends as the global default). Ask two things: which version becomes the global
|
||||
default, and whether cc-os (or any other project) keeps a local override or adopts the global
|
||||
default outright.
|
||||
|
||||
**Expected result:** either no conflict found (proceed), or an explicit user decision recorded
|
||||
before Step 3.
|
||||
|
||||
### Step 3: Read the source and reference structure
|
||||
|
||||
Read the full plugin source tree (`~/dev/cc-plugins/<name>/`): manifest/`plugin.json`, `hooks/`,
|
||||
`skills/`, `agents/`, `commands/`, docs. Grep for hardcoded absolute paths (the old repo path, or
|
||||
unwarranted `$HOME` assumptions) that would break on a move — hook scripts should resolve their
|
||||
own root dynamically (e.g. `os.path.dirname(os.path.abspath(__file__))`, `${CLAUDE_PLUGIN_ROOT}`
|
||||
in `hooks.json`), not hardcode it.
|
||||
|
||||
Separately, read `cc-os/plugins/os-vault/` as the structural pattern to mirror: it is a
|
||||
git-tracked `plugins/<name>/` directory with its **own** `.claude-plugin/plugin.json` committed
|
||||
inside the repo — not something generated only under `~/.claude/plugins/.claude-plugin/`.
|
||||
|
||||
### Step 4: Copy files and rename in place
|
||||
|
||||
- Copy the plugin's files into `cc-os/plugins/os-<name>/`, `git add` them there.
|
||||
- Update the `name` field in `.claude-plugin/plugin.json` to `os-<name>`.
|
||||
- Check `hooks.json` and any scripts for hardcoded references to the *old* plugin name (not just
|
||||
English text) and update those too.
|
||||
- Do **not** edit the plugin's own instructional/content files (e.g. an injected markdown doc)
|
||||
unless Step 2's conflict check produced an explicit user decision to change them.
|
||||
|
||||
### Step 5: Remove the old source
|
||||
|
||||
In `~/dev/cc-plugins/`: delete `<name>/` entirely, and remove its entry from
|
||||
`~/dev/cc-plugins/.claude-plugin/marketplace.json` (if that manifest lists other plugins, remove
|
||||
only this one's entry).
|
||||
|
||||
**Expected result:** `~/dev/cc-plugins/<name>/` no longer exists; the cc-plugins marketplace
|
||||
manifest has no reference to it.
|
||||
|
||||
### Step 6: Do not auto-commit
|
||||
|
||||
Leave both repos' changes staged/unstaged for the user to review and commit explicitly at the
|
||||
end — this mirrors the standing "only commit when asked" rule.
|
||||
|
||||
### Step 7: Re-register under the local-plugins convention
|
||||
|
||||
This mirrors the existing "Renaming or moving a local plugin" procedure in `cc-os/CLAUDE.md`
|
||||
(written for pure renames) — this migration is the superset that also covers a cross-repo move
|
||||
and first-time registration.
|
||||
|
||||
- Symlink: `ln -s cc-os/plugins/os-<name> ~/.claude/plugins/os-<name>`
|
||||
- Add an entry to `~/.claude/plugins/.claude-plugin/marketplace.json` under `local-plugins`,
|
||||
matching the `os-vault` entry's exact JSON shape.
|
||||
- Add `"os-<name>@local-plugins": true` to `enabledPlugins` in `~/.claude/settings.json`; remove
|
||||
the old `"<name>@cc-plugins": true"` entry.
|
||||
- Run: `claude plugin marketplace update local-plugins`, then
|
||||
`claude plugin install os-<name>@local-plugins`, then — if a stale install record exists —
|
||||
`claude plugin uninstall <name>@cc-plugins`.
|
||||
- Verify with `claude plugin list` (new name enabled, old name gone) and
|
||||
`claude plugin details os-<name>@local-plugins` (hooks/skills resolved).
|
||||
|
||||
### Step 8: Update cc-os documentation
|
||||
|
||||
- `CLAUDE.md`: add or update an "Implemented Components" entry for the new plugin, following the
|
||||
`os-vault` entry's style — location, hooks, behavior, migration provenance/date.
|
||||
- If Step 2 surfaced and resolved a content conflict, or otherwise changed a locked decision, add
|
||||
an ADR to `docs/memory-system/03-architecture-decisions.md`: the problem, the decision, and
|
||||
what was rejected.
|
||||
- If the plugin's content supersedes a project-local block (e.g. a section in `CLAUDE.md` it now
|
||||
makes redundant), remove that section and replace it with a short pointer to the plugin.
|
||||
|
||||
## Verification
|
||||
|
||||
- `git -C cc-os status --short` shows the new `plugins/os-<name>/` files staged, plus the doc
|
||||
edits — nothing left in a half-migrated state.
|
||||
- `git -C cc-plugins status --short` (or equivalent) shows no trace of the old plugin directory.
|
||||
- `claude plugin list` shows `os-<name>@local-plugins` enabled and the old
|
||||
`<name>@cc-plugins` entry gone.
|
||||
- `claude plugin details os-<name>@local-plugins` resolves hooks/skills without error.
|
||||
- Start a fresh session and confirm the plugin's hook/skill behavior actually fires (e.g. a
|
||||
SessionStart hook's injected content appears).
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Two repos, not one `git mv`.** cc-plugins and cc-os are independent git repos — you must
|
||||
copy + `git add` in the destination and separately remove + (if tracked) `git rm` in the
|
||||
source.
|
||||
- **Drifted "duplicate" content.** Don't assume two blocks that look like copy-pasted duplicates
|
||||
actually agree — diff them. Silently picking one side to be "canonical" can flip behavior
|
||||
machine-wide without the user knowingly authorizing it.
|
||||
- **Doc drift on hook filenames.** When documentation is drafted by an agent that didn't directly
|
||||
inspect the final file tree, it can guess a conventional filename (e.g. `session_start.py`)
|
||||
instead of the plugin's actual hook script name (e.g. `inject.py`). Verify hook filenames
|
||||
against the actual directory listing before trusting generated doc updates.
|
||||
- **Rename before registration, not after.** Renaming a plugin post-registration means redoing
|
||||
the symlink, the marketplace entry, and the `settings.json` entry — decide the final name in
|
||||
Step 1.
|
||||
|
||||
## Related
|
||||
|
||||
- [[cc-os-plugin-skill-naming-convention]] — the `os-` prefix and verb-first skill naming rules applied in Step 1
|
||||
|
|
@ -30,3 +30,10 @@ tags: [scope/global, type/log]
|
|||
**Reason:** prompt_input_exit
|
||||
**Vault notes touched:**
|
||||
(none)
|
||||
|
||||
## Session — 2026-07-03T14:08:36Z
|
||||
|
||||
**Project:** /home/jared/dev/cc-os
|
||||
**Reason:** other
|
||||
**Vault notes touched:**
|
||||
(none)
|
||||
|
|
|
|||
Loading…
Reference in New Issue