--- name: config-sync description: > Sync configuration changes across the settings-opencode repo and live harness directories (OpenCode and Claude Code). Invoke when adding, updating, or removing agents, rules, hooks, commands, prompts, skills, or harness config. Keywords: "add agent", "change rule", "update skill", "modify config", "add hook", "keep configs in sync", "propagate settings", "update my config", "harness configuration" --- # Configuration Sync ## Overview This repo is the **single source of truth** for both OpenCode and Claude Code harness configuration. Never hand-edit the live directories (`~/.config/opencode`, `~/.claude`). Always edit the repo first, then propagate via `settings-sync` (works from any directory) or `bash install.sh --yes` (from the repo root). ## What Goes Where: Decision & Mapping Table **Verified directory structure:** - OpenCode target (`~/.config/opencode`) receives: entire repo tree minus `.claude` and excludes - Claude target (`~/.claude`) receives: ONLY the allowlist from `.claude/` subtree - Skills are the **only "edit once → both" case** via union sync (root `skills/` ∪ `.claude/skills/`, root wins) | Item | Repo source location(s) | OpenCode | Claude | Edit location(s) | Notes | |------|---|---|---|---|---| | **Agents (OpenCode)** | `opencode.jsonc` (inline defs) + `prompts/agents/*.txt` (prompts) | ✓ | ✗ | `opencode.jsonc` or `prompts/agents/` | OpenCode-only. Agents defined inline in opencode.jsonc or as prompt templates. NO top-level `agents/` dir exists. | | **Agents (Claude)** | `.claude/agents/` | ✗ | ✓ | `.claude/agents/` | Claude-only agent definitions. | | **Rules** | `.claude/rules/` | ✗ | ✓ | `.claude/rules/` | Claude-only rules (e.g., orchestration.md, verification-gate.md, codebase-exploration.md). | | **Hooks** | `.claude/hooks/` | ✗ | ✓ | `.claude/hooks/` | Claude-only runtime hooks (e.g., installed by learning runtime). | | **Commands** | `commands/` | ✓ | ✗ | `commands/` | OpenCode-only slash commands. | | **Prompts** | `prompts/` | ✓ | ✗ | `prompts/` (including `prompts/agents/` for agent prompts) | OpenCode-only prompt templates. | | **Contexts** | `contexts/` | ✓ | ✗ | `contexts/` | OpenCode-only context definitions. | | **Tools** | `tools/` | ✓ | ✗ | `tools/` | OpenCode-only tool definitions. | | **Plugins** | `plugins/` | ✓ | ✗ | `plugins/` | OpenCode-only plugins. | | **Skills (shared)** | `skills/` (primary source) | ✓ | ✓ | `skills/` | The **ONLY "edit once, both harnesses" type**. Root `skills/` wins on name conflict with `.claude/skills/` via union sync. | | **Skills (Claude-only/override)** | `.claude/skills/` (secondary source) | ✓ | ✓ | `.claude/skills/` | Lower priority; root `skills/` overrides. Both targets receive via union sync. | | **Harness config** | `opencode.jsonc` | ✓ | ✗ | `opencode.jsonc` | OpenCode harness configuration (models, providers, settings, agent defs). | | **Global instructions** | `.claude/CLAUDE.md` + `.claude/RTK.md` | ✗ | ✓ | `.claude/CLAUDE.md`, `.claude/RTK.md` | Claude-only global instructions and token-optimization guide. | | **Personal: settings.json** | `.claude/settings.json` (seed) or `settings.json` (root seed, if exists) | ⚠ | ⚠ | Manual merge if needed | Seed-only; never overwritten on reinstall. Edit live copy or merge after repo changes. | | **Personal: settings.local.json** | `.claude/settings.local.json` (seed) | ⚠ | ⚠ | Manual merge if needed | Seed-only; local overrides. | | **Personal: policy-limits.json** | `.claude/policy-limits.json` (seed) | ⚠ | ⚠ | Manual merge if needed | Seed-only; rate limit policies. User edits in live dir will NOT propagate via reinstall. | | **Personal: *.local.json** | `*.local.json` (seed) | ⚠ | ⚠ | Manual merge if needed | Seed-only; any other .local.json files. | **Legend:** - ✓ = Item is propagated to this target - ✗ = Item does not reach this target - ⚠ (seed-only) = Only populated on first install; user edits in the live dir are **NOT synced back** to the repo on reinstall. To propagate changes: edit repo source, run `bash install.sh --yes`, then manually re-apply personal customizations to the live copy. ## Workflow: Edit → Propagate → Verify This workflow is **cwd-independent** — it works from any directory, not just the repo root. The `settings-sync` command (installed globally onto `PATH` by `install.sh`) locates the repo for you. ### Repo discovery order `settings-sync` resolves the repo path in this order: 1. `$SETTINGS_OPENCODE_REPO` — exported by the managed shell rc block, if it points at a directory with an executable `install.sh` 2. `$HOME/Workspace/settings-opencode` 3. `$HOME/.local/share/settings-opencode` If none resolve, it exits with an error asking you to set `SETTINGS_OPENCODE_REPO`. ### Step 1: Edit the Repo Edit files under `$SETTINGS_OPENCODE_REPO/...` (absolute paths — always edit the canonical repo, never a live harness directory). Example: ```bash # Add a Claude-only agent mkdir -p /Users/fmflurry/Workspace/settings-opencode/.claude/agents vi /Users/fmflurry/Workspace/settings-opencode/.claude/agents/my-agent/AGENT.md # Add an OpenCode agent (edit opencode.jsonc or create a prompt template) vi /Users/fmflurry/Workspace/settings-opencode/opencode.jsonc # OR add a prompt template: echo "..." > /Users/fmflurry/Workspace/settings-opencode/prompts/agents/my-agent.txt # Edit a Claude rule vi /Users/fmflurry/Workspace/settings-opencode/.claude/rules/common/my-rule.md # Add a new shared skill mkdir -p /Users/fmflurry/Workspace/settings-opencode/skills/my-skill echo "..." > /Users/fmflurry/Workspace/settings-opencode/skills/my-skill/SKILL.md ``` ### Step 2: Propagate via settings-sync From any directory: ```bash settings-sync ``` This single command: 1. Copies the repo tree → `~/.config/opencode` (OpenCode target) 2. Copies the `.claude/` allowlist → `~/.claude` (Claude target) 3. Runs `scripts/sync-skills.sh` to build the canonical skill union (root `skills/` ∪ `.claude/skills/`) 4. Installs learning runtime (if applicable) **Fast path — skills only:** ```bash settings-sync --skills-only ``` Use this only if you changed ONLY skills and want to skip the full install cycle. **Fallback (raw scripts, if `settings-sync` isn't on `PATH` yet):** ```bash cd "$SETTINGS_OPENCODE_REPO" && bash install.sh --yes # or, skills only: bash "$SETTINGS_OPENCODE_REPO/scripts/sync-skills.sh" ~/.config/opencode/skills ~/.claude/skills ``` ### Step 3: Verify Propagation Spot-check that the edited file landed in the live directory: ```bash # Example: check that a Claude agent propagated ls -la ~/.claude/agents/my-agent # Example: check that an OpenCode prompt template propagated ls -la ~/.config/opencode/prompts/agents/my-agent.txt # Example: check that a new shared skill propagated to both ls -la ~/.config/opencode/skills/my-skill ls -la ~/.claude/skills/my-skill # Example: check that a rule updated diff /Users/fmflurry/Workspace/settings-opencode/.claude/rules/common/my-rule.md ~/.claude/rules/common/my-rule.md # Example: check that opencode.jsonc propagated diff /Users/fmflurry/Workspace/settings-opencode/opencode.jsonc ~/.config/opencode/opencode.jsonc ``` Propagation is complete when the edited files appear in their respective target locations. ## Encode Lessons in Structure A second written rule for the same failure is a signal: build a mechanism instead of another rule. Strength order: **unrepresentable state** (makes the error impossible) > **lint rule / CI gate** (fails the build) > **shared helper / utility** (reusable code) > **runtime check** (guards at the boundary) > **prose rule** (text). One-off slip → add a note. Recurring pattern → encode it: a hook, linter, plugin, or script, then delete the duplicated rule file. ## Important: Seed-Only Personal Files Files marked **seed-only** in the table above are populated only on first install. On subsequent reinstalls, `install.sh` preserves user edits in those files **by never overwriting them**. Example: 1. First install: `~/.claude/settings.json` is seeded from the repo with defaults. 2. User edits `~/.claude/settings.json` manually (e.g., changes a model preference). 3. Second install (`bash install.sh --yes`): The edited `~/.claude/settings.json` is left untouched. 4. To apply new defaults from the repo, you must **manually merge or replace** the file in the live dir. **Workaround:** If you need to push a new default to a seed-only file: ```bash # Backup the current live version cp ~/.claude/settings.json ~/.claude/settings.json.backup # Copy the repo version (with new defaults) cp /Users/fmflurry/Workspace/settings-opencode/.claude/settings.json ~/.claude/settings.json # Manually re-apply your user edits vi ~/.claude/settings.json # add back your custom values ``` **tldr:** Do NOT expect `bash install.sh --yes` to overwrite your personal config files. They are managed by you, not the repo. ## When NOT to Use This Skill - **Project-local installations** (`--local` flag): These create `./.opencode` and `./.claude` in your working directory for project-specific config. Do not use this skill for project-local installs; the propagation model is different (cwd-scoped, no global shell rc). - **Runtime/session state**: Do not use this skill to sync session data (conversations, proposals, cached proposals, debug state). Those are harness runtime artifacts and are excluded from propagation. - **Manual editing of live dirs:** If you hand-edited `~/.config/opencode` or `~/.claude` directly (not via the repo), those changes are local and will NOT propagate back to the repo on reinstall. Always edit the repo source first. ## Command Reference Run from anywhere via `settings-sync`; the raw `install.sh`/`sync-skills.sh` invocations below are the documented fallback (require `cd "$SETTINGS_OPENCODE_REPO"` or an absolute path first). **Full install (both harnesses, repo → ~/.config/opencode + ~/.claude):** ```bash settings-sync # fallback: bash install.sh --yes ``` **OpenCode target only:** ```bash settings-sync --opencode-only # fallback: bash install.sh --yes --no-claude ``` **Claude target only:** ```bash settings-sync --claude-only # fallback: bash install.sh --yes --no-opencode ``` **Skills sync only (fast path):** ```bash settings-sync --skills-only # fallback: bash scripts/sync-skills.sh ~/.config/opencode/skills ~/.claude/skills ``` **Where is the repo resolved to?** ```bash settings-sync --where ``` **Uninstall (removes live copies, keeps repo):** ```bash settings-sync --uninstall # fallback: bash install.sh --uninstall ``` **Project-scoped (local mode, creates ./.opencode + ./.claude in cwd):** ```bash bash install.sh --yes --local ``` See `bash install.sh --help` for full flag reference.