From 023c92d77df52745d6b577d6437e6a16db220087 Mon Sep 17 00:00:00 2001 From: jared Date: Fri, 3 Jul 2026 10:55:24 -0400 Subject: [PATCH] vault: session notes 2026-07-03 --- ...igrating-a-standalone-plugin-into-cc-os.md | 156 ++++++++++++++++++ journal/2026-07-03.md | 7 + 2 files changed, 163 insertions(+) create mode 100644 howto/migrating-a-standalone-plugin-into-cc-os.md diff --git a/howto/migrating-a-standalone-plugin-into-cc-os.md b/howto/migrating-a-standalone-plugin-into-cc-os.md new file mode 100644 index 0000000..ff7d051 --- /dev/null +++ b/howto/migrating-a-standalone-plugin-into-cc-os.md @@ -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// into cc-os as plugins/os-/, 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//` +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//` 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 `@cc-plugins` entry + +## Steps + +### Step 1: Decide the new name + +Apply the cc-os `os-` prefix convention (see [[cc-os-plugin-skill-naming-convention]]) — +`` becomes `os-`. 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//`): 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//` 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-/`, `git add` them there. +- Update the `name` field in `.claude-plugin/plugin.json` to `os-`. +- 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 `/` 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//` 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- ~/.claude/plugins/os-` +- Add an entry to `~/.claude/plugins/.claude-plugin/marketplace.json` under `local-plugins`, + matching the `os-vault` entry's exact JSON shape. +- Add `"os-@local-plugins": true` to `enabledPlugins` in `~/.claude/settings.json`; remove + the old `"@cc-plugins": true"` entry. +- Run: `claude plugin marketplace update local-plugins`, then + `claude plugin install os-@local-plugins`, then — if a stale install record exists — + `claude plugin uninstall @cc-plugins`. +- Verify with `claude plugin list` (new name enabled, old name gone) and + `claude plugin details os-@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-/` 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-@local-plugins` enabled and the old + `@cc-plugins` entry gone. +- `claude plugin details os-@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 diff --git a/journal/2026-07-03.md b/journal/2026-07-03.md index cb51a9e..53abcfd 100644 --- a/journal/2026-07-03.md +++ b/journal/2026-07-03.md @@ -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)