diff --git a/plans/enumerated-giggling-scone.md b/plans/enumerated-giggling-scone.md new file mode 100644 index 0000000..a2cd967 --- /dev/null +++ b/plans/enumerated-giggling-scone.md @@ -0,0 +1,844 @@ +# Plan: Transpose Claude Code Setup to OpenCode (Parallel) + +## Handoff Summary + +**Goal**: Set up OpenCode in parallel with Claude Code, sharing state files and syncing agents/skills. + +### Key Decisions Made + +1. **Use built-in `build` agent** as primary (not porting `personal-assistant`) +2. **Skip** `personal-assistant` and `master-orchestrator` (flat model, not needed) +3. **All other agents** become `mode: subagent` with `model: inherit` +4. **Claude Code is source of truth** - OpenCode references state files via `instructions` +5. **No JSON minification** needed (files too small, added to future considerations) + +### What Exists + +- OpenCode already installed with partial sync setup +- `~/.config/opencode/scripts/claude_sync.py` exists but needs enhancements +- `~/.config/opencode/agents/` has synced agents but missing `mode` field +- `~/.config/opencode/skills/` has most skills (missing `gtasks`) + +### What Needs To Be Done + +| Step | Time | Action | +|------|------|--------| +| 1 | 5m | Backup `~/.config/opencode/` and `~/.opencode/` | +| 2 | 45m | Enhance `claude_sync.py` (add skip list, mode, model mappings) | +| 3 | 10m | Run sync with `--dry-run`, then apply | +| 4 | 20m | Update `opencode.json` (instructions, models, permissions) | +| 5 | 30m | Test agents, skills, permissions | +| 6 | 20m | Create `README.md` documentation | +| 7 | - | Iterate as needed | + +### Critical Files + +**To Modify:** +- `~/.config/opencode/scripts/claude_sync.py` - Add skip list, mode, model mappings +- `~/.config/opencode/opencode.json` - Add instructions, models, permissions + +**To Create:** +- `~/.config/opencode/README.md` - Documentation + +**To Reference (not copy):** +- `~/.claude/CLAUDE.md` +- `~/.claude/state/kb.json` +- `~/.claude/state/personal-assistant/memory/*.json` + +### Architecture + +``` +OpenCode (after implementation) +├── Primary: build (built-in), plan (built-in) +├── Subagents: @linux-sysadmin, @k8s-orchestrator, @code-reviewer, etc. +├── Skills: auto-discovered from ~/.claude/skills/ +└── State: referenced via instructions from ~/.claude/state/ +``` + +### Start Command + +```bash +# Exit plan mode and begin implementation +# Step 1: Backup +BACKUP_DATE=$(date +%Y%m%d_%H%M%S) +tar -czvf ~/.config/opencode-backup-$BACKUP_DATE.tar.gz -C ~/.config opencode/ +tar -czvf ~/opencode-home-backup-$BACKUP_DATE.tar.gz -C ~ .opencode/ +``` + +--- + +## Goal + +Create a parallel OpenCode configuration that shares/reuses as much of the existing Claude Code infrastructure as possible, focusing on: +1. **Skills/scripts execution** (highest priority) +2. **Agent hierarchy/delegation** (second priority) +3. **State persistence** (if low complexity) + +## Key Discovery: Native Compatibility + +OpenCode **natively supports Claude-compatible skill paths**: +- `~/.claude/skills//SKILL.md` - Already supported! +- This means your 11 existing skills can work with minimal changes + +--- + +## Phase 0: Backup Existing OpenCode Setup + +### Current State Discovered + +OpenCode is already installed with substantial configuration: + +**`~/.config/opencode/`** (main config): +- `opencode.json` - Has `claude-sync` command already! +- `agent/` - 3 custom agents (coding-expert, k8s-expert, tdd-enforcer) +- `agents/` - 12 synced Claude Code agents (already converted!) +- `skills/` - 10 skills (some synced, one symlink to morning-report) +- `scripts/claude_sync.py` - Existing sync script! + +**`~/.opencode/`** (alternate config): +- `agent/` - 4 different agents (openagent, system-builder, etc.) +- `command/` - 12 commands (commit, optimize, validate-repo, etc.) + +### Backup Commands + +```bash +# Create timestamped backups +BACKUP_DATE=$(date +%Y%m%d_%H%M%S) + +# Backup ~/.config/opencode/ +tar -czvf ~/.config/opencode-backup-$BACKUP_DATE.tar.gz -C ~/.config opencode/ + +# Backup ~/.opencode/ +tar -czvf ~/opencode-home-backup-$BACKUP_DATE.tar.gz -C ~ .opencode/ + +# Verify backups +ls -la ~/.config/opencode-backup-*.tar.gz ~/opencode-home-backup-*.tar.gz +``` + +--- + +## Phase 1: Use Existing `claude_sync.py` Script + +The existing sync script is **comprehensive** and handles: + +| Category | Source | Destination | Transforms | +|----------|--------|-------------|------------| +| Skills | `~/.claude/skills/*/SKILL.md` | `~/.config/opencode/skills/*/SKILL.md` | `allowed-tools` → `metadata.claude_allowed_tools` | +| Agents | `~/.claude/agents/*.md` | `~/.config/opencode/agents/*.md` | `tools: X, Y` → `tools: { x: true, y: true }` | +| Commands | `~/.claude/commands/*.md` | `~/.config/opencode/claude/commands/*.md` | None | +| Workflows | `~/.claude/workflows/*.yaml` | `~/.config/opencode/claude/workflows/*.yaml` | None | + +### Sync Commands + +```bash +# Dry run - see what would change +python3 ~/.config/opencode/scripts/claude_sync.py --dry-run + +# Actually sync +python3 ~/.config/opencode/scripts/claude_sync.py + +# Clean stale files (dry run first) +python3 ~/.config/opencode/scripts/claude_sync.py --clean --dry-run +python3 ~/.config/opencode/scripts/claude_sync.py --clean --apply + +# Sync specific category only +python3 ~/.config/opencode/scripts/claude_sync.py --only agents +``` + +### Model Mapping Update Needed + +Current script maps old models. May need to add: +- `opus` → `anthropic/claude-opus-4` +- `sonnet` → `anthropic/claude-sonnet-4-5` +- `haiku` → `anthropic/claude-haiku-4-5` + +--- + +## Phase 1.5: OpenCode Optimization (NEW) + +The current sync just copies/transforms files. It doesn't optimize for **how OpenCode works**. + +### Key OpenCode Differences + +| Concept | Claude Code | OpenCode | Optimization Needed | +|---------|-------------|----------|---------------------| +| **Agent hierarchy** | PA → MO → agents | Flat: primary + subagents | Add `mode` field | +| **Agent invocation** | Delegation patterns | `@agent` mentions | Simplify prompts | +| **Permissions** | Hooks + guardrails | `permission` config | Move to opencode.json | +| **Model selection** | Per-agent in frontmatter | `model: inherit` option | Use inheritance | +| **Auto-invocation** | Keyword triggers in registry | Rich `description` field | Enhance descriptions | + +### Agent Mode Assignment + +```yaml +# PRIMARY - Use OpenCode's built-in agents +build: (built-in) # Full access, default primary +plan: (built-in) # Read-only analysis + +# SKIP - Not needed in OpenCode's flat model +personal-assistant: # Use built-in "build" instead +master-orchestrator: # Intermediary not needed + +# SUBAGENTS (invoked via @mention or Task tool) +linux-sysadmin: mode: subagent +k8s-orchestrator: mode: subagent +k8s-diagnostician: mode: subagent +argocd-operator: mode: subagent +prometheus-analyst: mode: subagent +git-operator: mode: subagent +programmer-orchestrator: mode: subagent +code-planner: mode: subagent +code-implementer: mode: subagent +code-reviewer: mode: subagent +``` + +### Hierarchy Simplification + +**Claude Code pattern** (complex, 3 layers): +``` +User → Personal Assistant → Master Orchestrator → linux-sysadmin + → k8s-orchestrator → k8s-diagnostician +``` + +**OpenCode pattern** (flat, 2 layers): +``` +User → build (built-in) → @linux-sysadmin + → @k8s-orchestrator + → @k8s-diagnostician + → @code-reviewer + → etc. +``` + +Benefits: +- No custom primary agent to maintain +- Built-in `build` agent is optimized for OpenCode +- Built-in `plan` agent available for read-only analysis +- Subagents invoked directly via @mention + +### Sync Script Enhancements Needed + +Update `claude_sync.py` to add: + +```python +# In transform_frontmatter() for agents: + +# 1. Skip agents not needed in OpenCode's flat model +SKIP_AGENTS = {"personal-assistant", "master-orchestrator"} + +if name in SKIP_AGENTS: + return None # Signal to skip this file + +# 2. All synced agents become subagents (built-in build/plan are primary) +frontmatter["mode"] = "subagent" + +# 3. Use model inheritance (subagents use parent's model) +frontmatter["model"] = "inherit" + +# 4. Map explicit models if not using inherit +MODEL_MAP = { + "opus": "anthropic/claude-opus-4", + "sonnet": "anthropic/claude-sonnet-4-5", + "haiku": "anthropic/claude-haiku-4-5", +} +if frontmatter.get("model") in MODEL_MAP: + frontmatter["model"] = MODEL_MAP[frontmatter["model"]] +``` + +Also update `sync_tree()` to handle `None` return (skip file). + +### Description Enhancement + +OpenCode uses descriptions for **auto-invocation**. Enhance with examples: + +**Current** (basic): +```yaml +description: Manages Arch Linux workstation - system maintenance... +``` + +**Optimized** (with examples): +```yaml +description: | + Manages Arch Linux workstation. Use for system maintenance, updates, + troubleshooting, and health checks. + Examples: + - "check system health" → @linux-sysadmin + - "update packages" → @linux-sysadmin + - "why is my disk full" → @linux-sysadmin +``` + +### Permission Migration + +Move guardrail logic to opencode.json: + +```json +{ + "permission": { + "edit": "ask", + "bash": { + "*": "ask", + "pacman -Q*": "allow", + "systemctl status*": "allow", + "kubectl get*": "allow", + "git status": "allow", + "git diff": "allow" + } + } +} +``` + +--- + +## Phase 2: Create OpenCode Config Structure + +### Directory Layout + +``` +~/.config/opencode/ +├── opencode.json # Main config +├── AGENTS.md # Global rules (symlink or copy from CLAUDE.md) +├── agent/ # Agent definitions +│ ├── personal-assistant.md +│ ├── linux-sysadmin.md +│ ├── k8s-orchestrator.md +│ └── ... (converted agents) +├── tool/ # Custom tool wrappers (TypeScript) +│ ├── gmail.ts # Wrapper for gmail scripts +│ ├── gcal.ts # Wrapper for gcal scripts +│ └── ... +└── skill/ # OpenCode-native skills (optional) +``` + +### Config File: `~/.config/opencode/opencode.json` + +```jsonc +{ + "$schema": "https://opencode.ai/config.json", + "model": "anthropic/claude-sonnet-4-5", + "small_model": "anthropic/claude-haiku-4-5", + "autoupdate": true, + + // OpenCode already searches ~/.claude/skills/ - no extra config needed! + + // Agent definitions + "agent": { + // Override built-in agents or define custom via files + }, + + // Default permissions (conservative like your current setup) + "permission": { + "edit": "ask", + "bash": "ask" + }, + + // Custom tools enabled + "tools": { + "gmail": true, + "gcal": true, + "gtasks": true + } +} +``` + +--- + +## Phase 3: Skills Migration + +### Already Compatible (No Changes Needed) + +OpenCode automatically discovers skills from: +- `~/.claude/skills/*/SKILL.md` + +Your existing skills should work if they have proper frontmatter: + +| Skill | Status | Notes | +|-------|--------|-------| +| gmail | Check frontmatter | Needs `name` + `description` | +| gcal | Check frontmatter | Needs `name` + `description` | +| gtasks | Check frontmatter | Needs `name` + `description` | +| sysadmin-health | Check frontmatter | | +| k8s-quick-status | Check frontmatter | | +| morning-report | Check frontmatter | | +| stock-lookup | Check frontmatter | | +| rag-search | Check frontmatter | | +| usage | Check frontmatter | | +| guardrails | N/A | Becomes permission config | + +### Frontmatter Requirements + +Each SKILL.md needs: +```yaml +--- +name: skill-name # Required, must match directory name +description: Brief desc # Required, 1-1024 chars +--- +``` + +### Audit Results (Already Compatible!) + +Checked skills have proper frontmatter: +- `gmail/SKILL.md` - Has `name: gmail`, `description: ...` +- `sysadmin-health/SKILL.md` - Has `name: sysadmin-health`, `description: ...` +- `morning-report/SKILL.md` - Has `name: morning-report`, `description: ...` + +The `allowed-tools` field in some skills will be ignored by OpenCode (not in their schema), but this is fine. + +### Action Items + +1. ~~Audit each SKILL.md for required frontmatter~~ **Done - already compatible!** +2. ~~Add missing `name`/`description` fields~~ **Not needed** +3. Test skill discovery in OpenCode after install + +--- + +## Phase 4: Agent Migration + +### Mapping Strategy + +| Claude Code | OpenCode | Notes | +|------------|----------|-------| +| `model: opus` | `model: anthropic/claude-opus-4` | Full provider/model path | +| `model: sonnet` | `model: anthropic/claude-sonnet-4-5` | | +| `model: haiku` | `model: anthropic/claude-haiku-4-5` | | +| `tools: Read, Write...` | `tools: { write: true, ... }` | Boolean map | +| Hierarchy (PA → MO → agent) | `mode: primary` + `mode: subagent` | Flattened | + +### Agent Conversion Template + +**From (Claude Code):** +```yaml +--- +name: linux-sysadmin +description: Manages Arch Linux workstation... +model: sonnet +tools: Bash, Read, Write, Edit, Grep, Glob +--- +``` + +**To (OpenCode):** +```yaml +--- +name: linux-sysadmin +description: Manages Arch Linux workstation... +mode: subagent +model: anthropic/claude-sonnet-4-5 +tools: + bash: true + read: true + write: true + edit: true +permission: + bash: + "*": ask + "pacman -Q*": allow + "systemctl status*": allow +--- +``` + +### Priority Agents to Convert + +1. **personal-assistant.md** → `mode: primary` (main interface) +2. **linux-sysadmin.md** → `mode: subagent` +3. **k8s-orchestrator.md** → `mode: subagent` +4. **master-orchestrator.md** → May not be needed (OpenCode doesn't have same hierarchy) + +### Hierarchy Adaptation + +OpenCode doesn't have hierarchical agent delegation like your current setup. Options: +- **Option A**: Flatten to primary + subagents, use `@agent` mentions +- **Option B**: Use OpenCode's Task tool for agent invocation +- **Option C**: Create a "dispatcher" primary agent that routes via @mentions + +**Recommendation**: Option A (simplest) - personal-assistant as primary, others as subagents invokable via `@linux-sysadmin`, `@k8s-orchestrator`, etc. + +--- + +## Phase 5: Custom Tools (Scripts Execution) + +### Wrapper Pattern + +Create TypeScript wrappers that invoke your existing Python scripts: + +**Example: `~/.config/opencode/tool/gmail.ts`** + +```typescript +import { tool } from "@opencode-ai/plugin" + +export const check_unread = tool({ + description: "Check unread emails from Gmail", + args: { + limit: tool.schema.number().optional().describe("Max emails to return"), + }, + async execute(args) { + const limit = args.limit ?? 10 + const result = await Bun.$`~/.claude/mcp/gmail/venv/bin/python ~/.claude/skills/gmail/scripts/check_unread.py --limit ${limit}`.text() + return result.trim() + }, +}) + +export const search = tool({ + description: "Search Gmail for specific emails", + args: { + query: tool.schema.string().describe("Search query"), + }, + async execute(args) { + const result = await Bun.$`~/.claude/mcp/gmail/venv/bin/python ~/.claude/skills/gmail/scripts/search.py "${args.query}"`.text() + return result.trim() + }, +}) +``` + +### Tools to Create Wrappers For + +| Script | Wrapper | +|--------|---------| +| `gmail/scripts/*.py` | `gmail.ts` | +| `gcal/scripts/*.py` | `gcal.ts` | +| `gtasks/scripts/*.py` | `gtasks.ts` | +| `sysadmin-health/scripts/*.sh` | `sysadmin.ts` | +| `morning-report/scripts/*.py` | `morning.ts` | +| `stock-lookup/scripts/*.py` | `stocks.ts` | + +--- + +## Phase 6: Rules/Instructions + +### Option A: Symlink CLAUDE.md + +```bash +ln -s ~/.claude/CLAUDE.md ~/.config/opencode/AGENTS.md +``` + +### Option B: Create Minimal AGENTS.md + Reference + +```markdown +# OpenCode Agent Rules + +Read @~/.claude/CLAUDE.md for shared conventions. + +## OpenCode-Specific + +- Use `@agent-name` to invoke subagents +- Skills are loaded via the `skill` tool +- Custom tools available: gmail, gcal, gtasks, sysadmin +``` + +### Option C: Use instructions config + +```json +{ + "instructions": ["~/.claude/CLAUDE.md", "~/.claude/state/system-instructions.json"] +} +``` + +**Recommendation**: Option C - cleanest, no duplication + +--- + +## Phase 7: State Persistence (Claude Code as Source of Truth) + +### Strategy + +Claude Code owns the state files. OpenCode reads them via: +1. `{file:path}` variable substitution in `opencode.json` +2. `instructions` array for context files +3. Skills that read state files directly + +### What Can Be Shared + +| File | Method | Notes | +|------|--------|-------| +| `~/.claude/CLAUDE.md` | `instructions` | Global rules | +| `~/.claude/state/kb.json` | `instructions` or skill | Knowledge base | +| `~/.claude/state/personal-assistant/memory/*.json` | `instructions` | Memory context | +| `~/.claude/state/system-instructions.json` | `instructions` | Process definitions | + +### Implementation in `opencode.json` + +```jsonc +{ + "$schema": "https://opencode.ai/config.json", + + // Load Claude Code state as instructions (read at session start) + "instructions": [ + "~/.claude/CLAUDE.md", + "~/.claude/state/kb.json", + "~/.claude/state/personal-assistant/memory/facts.json", + "~/.claude/state/personal-assistant/memory/preferences.json" + ] +} +``` + +### What Stays Separate + +| Item | Reason | +|------|--------| +| Session history | Different formats, different storage | +| Autonomy/permissions | OpenCode uses `permission` config instead | +| Component registry | OpenCode discovers via file paths | + +### Overhead Assessment + +**Low overhead** - just config changes: +- Add paths to `instructions` array +- No symlinks or sync scripts needed +- OpenCode reads files directly at session start +- Claude Code continues to write/update normally + +--- + +## Phase 8: What Won't Transfer + +| Feature | Claude Code | OpenCode Alternative | +|---------|-------------|---------------------| +| Hooks (SessionStart, etc.) | `hooks/hooks.json` | Plugins (future) | +| Guardrails hook | PreToolUse script | `permission` config | +| Component registry routing | Keyword triggers | Agent descriptions + @mentions | +| Hierarchical delegation | PA → MO → agent | Flat subagent model | + +--- + +## Implementation Order + +### Step 1: Backup (5 min) +- [ ] Create timestamped backup of `~/.config/opencode/` +- [ ] Create timestamped backup of `~/.opencode/` + +### Step 2: Enhance Sync Script (45 min) +- [ ] Add skip list: `{"personal-assistant", "master-orchestrator"}` +- [ ] Add `mode: subagent` to all synced agents +- [ ] Add `model: inherit` for subagents (use parent's model) +- [ ] Add model mappings for explicit models: + - `opus` → `anthropic/claude-opus-4` + - `sonnet` → `anthropic/claude-sonnet-4-5` + - `haiku` → `anthropic/claude-haiku-4-5` +- [ ] Update `sync_tree()` to handle skipped files +- [ ] Optionally enhance descriptions with examples + +### Step 3: Run Enhanced Sync (10 min) +- [ ] `python3 ~/.config/opencode/scripts/claude_sync.py --dry-run` +- [ ] Review output - verify mode/model changes +- [ ] `python3 ~/.config/opencode/scripts/claude_sync.py` +- [ ] Clean stale files: `--clean --apply` + +### Step 4: Update opencode.json (20 min) +- [ ] Add `instructions` array: + ```json + "instructions": [ + "~/.claude/CLAUDE.md", + "~/.claude/state/kb.json", + "~/.claude/state/personal-assistant/memory/facts.json", + "~/.claude/state/personal-assistant/memory/preferences.json" + ] + ``` +- [ ] Add global model defaults: + ```json + "model": "anthropic/claude-sonnet-4-5", + "small_model": "anthropic/claude-haiku-4-5" + ``` +- [ ] Add permission config (from guardrails): + ```json + "permission": { + "edit": "ask", + "bash": { + "*": "ask", + "pacman -Q*": "allow", + "systemctl status*": "allow", + "kubectl get*": "allow" + } + } + ``` + +### Step 5: Testing (30 min) +- [ ] Run `opencode` - verify it starts with built-in `build` agent +- [ ] Tab to switch to built-in `plan` agent (read-only mode) +- [ ] Check skill discovery (should see gmail, gcal, sysadmin-health, etc.) +- [ ] Test `@linux-sysadmin` subagent invocation +- [ ] Test `@k8s-orchestrator` subagent invocation +- [ ] Test skill loading: "check my email" should trigger gmail skill +- [ ] Verify permissions work (bash commands should prompt for confirmation) +- [ ] Verify instructions loaded (ask about something in CLAUDE.md) + +### Step 6: Documentation (20 min) +- [ ] Create `~/.config/opencode/README.md` using template from Phase 8 +- [ ] Document complete agent mapping table +- [ ] Document sync workflow with examples +- [ ] Note any gotchas discovered during testing +- [ ] Add future consideration to `~/.claude/state/future-considerations.json`: + ```json + { + "id": "fc-047", + "category": "opencode", + "title": "Minify JSON instructions for OpenCode", + "description": "Consider minifying JSON files loaded via OpenCode instructions config when files grow large", + "priority": "low", + "status": "deferred", + "created": "2026-01-07", + "notes": "Currently files are <1KB total, not worth minifying. Revisit if kb.json or memory files exceed 50KB. Could add minify step to claude_sync.py." + } + ``` + +### Step 7: Iterate (as needed) +- [ ] Adjust agent descriptions if auto-invocation isn't working well +- [ ] Tune permission patterns +- [ ] Consider dropping/hiding agents that don't fit OpenCode model +- [ ] Update documentation with lessons learned + +**Total: ~2.5 hours** (with proper OpenCode optimization + documentation) + +--- + +## Phase 8: Documentation + +### Documentation Deliverables + +Create `~/.config/opencode/README.md` with: + +1. **Architecture Overview** + - Relationship between Claude Code and OpenCode + - What's shared vs separate + - Source of truth (Claude Code) + +2. **Sync Workflow** + - How `claude_sync.py` works + - When to run it (after Claude Code changes) + - Command reference + +3. **Agent Mapping** + - Which Claude Code agents map to OpenCode + - Which are skipped and why + - How to invoke subagents (@mentions) + +4. **Skills** + - Auto-discovery from `~/.claude/skills/` + - How to add new skills + - Skill invocation patterns + +5. **State Sharing** + - Files referenced via `instructions` + - Claude Code as source of truth + - What stays separate + +6. **Permissions** + - How guardrails translated to `permission` config + - Safe vs prompted commands + +### Documentation Template + +```markdown +# OpenCode Configuration + +This OpenCode setup is synchronized from Claude Code (`~/.claude/`). + +## Quick Start + +```bash +# Start OpenCode (uses built-in build agent) +opencode + +# Switch to read-only plan agent +# Press Tab + +# Invoke a subagent +@linux-sysadmin check system health +``` + +## Architecture + +``` +Claude Code (source of truth) +├── ~/.claude/agents/ → synced to ~/.config/opencode/agents/ +├── ~/.claude/skills/ → synced to ~/.config/opencode/skills/ +├── ~/.claude/CLAUDE.md → referenced via instructions +└── ~/.claude/state/ → referenced via instructions + +OpenCode +├── Built-in: build (primary), plan (read-only) +├── Subagents: @linux-sysadmin, @k8s-orchestrator, etc. +└── Skills: gmail, gcal, sysadmin-health, etc. +``` + +## Sync Workflow + +After making changes in Claude Code: + +```bash +# Preview changes +python3 ~/.config/opencode/scripts/claude_sync.py --dry-run + +# Apply changes +python3 ~/.config/opencode/scripts/claude_sync.py + +# Clean stale files +python3 ~/.config/opencode/scripts/claude_sync.py --clean --apply +``` + +## Agents + +| Claude Code | OpenCode | Notes | +|-------------|----------|-------| +| personal-assistant | (skipped) | Use built-in `build` | +| master-orchestrator | (skipped) | Flat model, not needed | +| linux-sysadmin | @linux-sysadmin | Subagent | +| k8s-orchestrator | @k8s-orchestrator | Subagent | +| ... | ... | ... | + +## Skills + +Skills are auto-discovered from: +- `~/.claude/skills/*/SKILL.md` +- `~/.config/opencode/skills/*/SKILL.md` + +## State Files + +Referenced via `instructions` in opencode.json: +- `~/.claude/CLAUDE.md` - Global rules +- `~/.claude/state/kb.json` - Knowledge base +- `~/.claude/state/personal-assistant/memory/*.json` - Memory + +## Permissions + +Configured in opencode.json `permission` section. +Migrated from Claude Code's guardrail hooks. +``` + +### Implementation Step + +Add to Step 6: +- [ ] Create `~/.config/opencode/README.md` +- [ ] Document sync workflow +- [ ] Document agent mapping +- [ ] Document any gotchas discovered during testing + +--- + +## Files to Create/Modify + +### Files to Create +- `~/.config/opencode/README.md` - Documentation of setup, workflow, and requirements + +### Files to Modify +- `~/.config/opencode/opencode.json` - Add `instructions` array + model/permission config +- `~/.config/opencode/scripts/claude_sync.py` - Add mode, model mappings, skip list + +### Files Auto-Synced by Script +These are created/updated by `claude_sync.py`: +- `~/.config/opencode/agents/*.md` - From `~/.claude/agents/` +- `~/.config/opencode/skills/*/SKILL.md` - From `~/.claude/skills/` +- `~/.config/opencode/claude/commands/*.md` - From `~/.claude/commands/` +- `~/.config/opencode/claude/workflows/*.yaml` - From `~/.claude/workflows/` + +### Files Referenced (Not Copied) +These stay in Claude Code, referenced via `instructions`: +- `~/.claude/CLAUDE.md` +- `~/.claude/state/kb.json` +- `~/.claude/state/personal-assistant/memory/*.json` + +--- + +## Success Criteria + +1. `opencode` launches and shows available skills +2. Can invoke `@linux-sysadmin` and get expected behavior +3. Gmail/GCal/GTasks tools work via custom wrappers +4. Can switch between build/plan agents + custom agents +5. Both Claude Code and OpenCode can run in parallel without conflicts diff --git a/plans/structured-purring-whistle.md b/plans/structured-purring-whistle.md new file mode 100644 index 0000000..c809623 --- /dev/null +++ b/plans/structured-purring-whistle.md @@ -0,0 +1,115 @@ +# Implementation Plan: OpenCode Claude Sync Enhancements + +## Overview + +Transpose Claude Code agent/skill setup to OpenCode in parallel, per decisions from brainstorming session (`enumerated-giggling-scone.md`). + +## Key Decisions (from brainstorming) + +| Decision | Value | +|----------|-------| +| Primary agent | Use built-in `build` (don't port PA) | +| Agents to skip | `personal-assistant`, `master-orchestrator` | +| Other agents | All become `mode: subagent` | +| Model inheritance | Use `model: inherit` for subagents | +| State sharing | Reference via `instructions`, don't copy | +| Source of truth | Claude Code (`~/.claude/`) | + +## Files to Modify + +1. `~/.config/opencode/scripts/claude_sync.py` - Main sync script +2. `~/.config/opencode/opencode.json` - Config file + +## Files to Create + +1. `~/.config/opencode/README.md` - Documentation + +## Implementation Steps + +### Step 1: Backup (DONE) + +Created backups: +- `~/.config/opencode-backup-20260107_120135.tar.gz` +- `~/opencode-home-backup-20260107_120136.tar.gz` + +### Step 2: Enhance `claude_sync.py` + +**Location**: `~/.config/opencode/scripts/claude_sync.py` + +**Modifications**: + +1. Add constants near top of file: +```python +SKIP_AGENTS = {"personal-assistant", "master-orchestrator"} + +MODEL_MAP = { + "opus": "anthropic/claude-opus-4", + "sonnet": "anthropic/claude-sonnet-4-5", + "haiku": "anthropic/claude-haiku-4-5", +} +``` + +2. Modify `transform_frontmatter()` for agents: + - Check if agent name in `SKIP_AGENTS`, return `None` to signal skip + - Add `frontmatter["mode"] = "subagent"` + - Set `frontmatter["model"] = "inherit"` + - Map explicit models using `MODEL_MAP` + +3. Modify `sync_tree()` to handle `None` return from transform (skip file) + +4. Update `expected_dest_paths_for_tree()` to exclude skipped agents + +### Step 3: Run Sync + +```bash +python3 ~/.config/opencode/scripts/claude_sync.py --dry-run +python3 ~/.config/opencode/scripts/claude_sync.py +python3 ~/.config/opencode/scripts/claude_sync.py --clean --apply +``` + +### Step 4: Update `opencode.json` + +Add to existing config: +```json +{ + "model": "anthropic/claude-sonnet-4-5", + "small_model": "anthropic/claude-haiku-4-5", + "instructions": [ + "~/.claude/CLAUDE.md", + "~/.claude/state/kb.json", + "~/.claude/state/personal-assistant/memory/facts.json", + "~/.claude/state/personal-assistant/memory/preferences.json" + ], + "permission": { + "edit": "ask", + "bash": { + "*": "ask", + "pacman -Q*": "allow", + "systemctl status*": "allow", + "kubectl get*": "allow" + } + } +} +``` + +### Step 5: Test + +- Run `opencode` and verify skill discovery +- Test `@linux-sysadmin` subagent invocation +- Verify permissions work + +### Step 6: Create README.md + +Document: +- Architecture (Claude Code as source of truth) +- Sync workflow +- Agent mapping table +- How to invoke subagents + +### Step 7: Add Future Consideration + +Add entry to `~/.claude/state/future-considerations.json` about JSON minification for large instruction files. + +## Estimated Time + +~2 hours total (Step 1 already done) diff --git a/state/future-considerations.json b/state/future-considerations.json index 1d3e59f..3081fff 100644 --- a/state/future-considerations.json +++ b/state/future-considerations.json @@ -10,7 +10,7 @@ "priority": "medium", "status": "pending", "created": "2024-12-28", - "notes": "Design complete. Partially implemented: node_exporter running (port 9100), PrometheusRule deployed (12 alerts: 4 critical, 6 warning, 2 info), Prometheus scrape config updated. ⏳ PENDING TAILSACLE CONFIGURATION: Tailscale network attempted but ACLs preventing cluster ↔ workstation peering. See charts/willlaptop-monitoring/TAILSCALE-ACL-GUIDE.md for configuration steps. After ACL configuration, Prometheus should successfully scrape workstation metrics via 100.90.159.78:9100." + "notes": "Design complete. Partially implemented: node_exporter running (port 9100), PrometheusRule deployed (12 alerts: 4 critical, 6 warning, 2 info), Prometheus scrape config updated. \u23f3 PENDING TAILSACLE CONFIGURATION: Tailscale network attempted but ACLs preventing cluster \u2194 workstation peering. See charts/willlaptop-monitoring/TAILSCALE-ACL-GUIDE.md for configuration steps. After ACL configuration, Prometheus should successfully scrape workstation metrics via 100.90.159.78:9100." }, { "id": "fc-002", @@ -467,6 +467,16 @@ "status": "deferred", "created": "2025-01-21", "notes": "Optimization for when query volume justifies it. Consider TTL and invalidation strategy." + }, + { + "id": "fc-047", + "category": "opencode", + "title": "Minify JSON instructions for OpenCode", + "description": "Consider minifying JSON files loaded via OpenCode instructions config when files grow large", + "priority": "low", + "status": "deferred", + "created": "2026-01-07", + "notes": "Currently files are <1KB total, not worth minifying. Revisit if kb.json or memory files exceed 50KB. Could add minify step to claude_sync.py." } ] }