Add OpenCode sync enhancement plan and future consideration

- Add fc-047: Consider JSON minification for OpenCode instructions
- Add brainstorming plan for OpenCode Claude sync enhancements
- Add implementation status plan

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
OpenCode Test
2026-01-07 12:15:33 -08:00
parent 0780b4c17d
commit 7c37e9adb3
3 changed files with 970 additions and 1 deletions

View File

@@ -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/<name>/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

View File

@@ -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)

View File

@@ -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."
}
]
}