Skip to content
cccskills
FreePublished on GitHub

opencode

Delegate a coding task to OpenCode CLI and supervise the result via git diff. Trigger: /opencode <instruction>. Claude orchestrates, OpenCode codes. Also handles /opencodeon, /opencodeoff, /opencodestatus, /opencode-report, /opencode-model-pick, /opencode-model-clear.

The English summary is being prepared. Showing the original description.

See how to install

Files included (11)

  • SKILL.md12.5 KB
  • .gitignore42 B
  • docs/PLAN.md5.4 KB
  • OPENCODEMODELCLEAR.md351 B
  • OPENCODEMODELPICK.md771 B
  • OPENCODEOFF.md366 B
  • OPENCODEON.md397 B
  • OPENCODESTATUS.md276 B
  • README.md8.0 KB
  • tools/delegate-report17.1 KB
  • tools/opencode-delegate14.0 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

/opencodeon | /opencodeoff | /opencodestatus

Toggle auto-delegate mode — OpenCode automatically handles coding tasks without requiring /opencode each time.

CommandAction
/opencodeontouch ~/.local/share/opencode-auto.flag → confirm "Auto-opencode ON"
/opencodeoffrm -f ~/.local/share/opencode-auto.flag → confirm "Auto-opencode OFF"
/opencodestatusrun test -f ~/.local/share/opencode-auto.flag && echo ON || echo OFF

Run the bash command, print one confirmation line, and stop.


/opencode-report

If the user invokes /opencode-report, run ~/tools/delegate-report with any flags extracted from the arguments, display output verbatim, and stop.

User saysFlag
last 7 days, 7d--since 7
last 30 days, 30d--since 30
project foo--project foo
only failures, fails--fails
(nothing)(no flags, full report)

/opencode-model-pick | /opencode-model-clear

Override the model for all subsequent delegations without editing the script.

CommandAction
/opencode-model-pick modelecho model > ~/.local/share/opencode-model.flag, confirm
/opencode-model-clearrm -f ~/.local/share/opencode-model.flag, confirm back to default

Run the bash command, print one confirmation line, and stop.


OpenCode Orchestrator

When the user invokes /opencode <instruction>, Claude delegates the implementation to OpenCode CLI via its headless run mode (opencode run <prompt> --format json), monitors in real time, and reports.


Known Limits

Hard constraints — not config options.

1. No --max-turns flag

Timeout is the only runaway-control lever. Set timeouts conservatively and decompose tasks.

2. --dangerously-skip-permissions

Passed automatically by the delegate script — all tool calls auto-approved. Review the git diff afterwards.

3. --dir flag

Passed automatically by the delegate script. Sets the working directory for OpenCode.

4. No pseudo-TTY needed

Plain pipe — no script -q -c wrapper required.

5. Free model queue delays

opencode/deepseek-v4-flash-free — no API key cost; may queue during peak usage.

6. Orchestration chain — 5 failure points

LinkFailure modeSymptom
OpenCode CLIAuth expired, quota hit, networkImmediate exit or silent hang
Stream parserOpenCode changes JSON event schemaTool calls not detected
Token aggregationstep_finish missing or malformedTokens logged as 0
git diffNot a git repo, or OpenCode committed mid-runWrong file count
JSON log~/.local/share/ not writableSilent log skip

When a run produces unexpected results, check these links top to bottom.


Step 1 — Detect workdir

  1. git rev-parse --show-toplevel in the current directory.
  2. If ambiguous or no git repo → ask with AskUserQuestion.

Step 2 — Decompose the task

Critical rule: keep tasks atomic and focused — one objective, one prompt.

SignalAction
1 file, ≤ ~10 lines to change, location already knownDo it directly — don't delegate
1 file, logic non-trivial OR location unclearDelegate
2–3 files, single objectiveDelegate
>3 files OR multi-step logic OR migrationsDelegate, broken into sub-tasks
SizeDefinitionTimeoutApproach
Trivial1 file, change is obvious and located—Skip delegation — edit directly
Simple1 file, non-trivial logic or unknown location180s1 opencode call
Medium2–3 related files, 1 goal300s1 opencode call with structured prompt
Complex>3 files OR multi-step logic—Decompose

Decomposition for complex tasks:

Sub-task 1: Explore relevant files (180s)
Sub-task 2: Implement change A in file X (300s)
Sub-task 3: Implement change B in file Y (300s)
Sub-task 4: Verify / test (180s)

→ Check git diff between sub-tasks before launching the next.


Step 3 — Write the OpenCode prompt

The prompt must be self-contained.

Structure:

Stack: Python/Flask, SQLAlchemy, SQLite
Key files: app.py (routes + fetch), models.py (Entry)

TASK: [one single thing to do, stated as an imperative]

CONSTRAINTS:
- [what must not break]
- [expected format if relevant]

VERIFY: grep for "def function_name" in file.py and confirm it exists.

Formulation rules:

  • One task per prompt — never "also do X and Y"
  • Name the exact files to modify
  • Include a grep-based verification criterion (not a file re-read)
  • Language: English (best model performance)

Prompt adaptations:

  • Any task that defines or calls a specific function: include the exact signature — def validate(data: dict) -> tuple[bool, list[str]]:.
  • No fixed signature, but conventions matter: point at the file to read first ("read app.py, follow its route/jsonify style") instead — don't do both, they're substitutes.

Verification — always use grep, not file re-read:

VERIFY: grep for "def extract_labels" in app.py and confirm it exists.

Examples:

❌ Bad (too vague, too wide):

Fix the API, add a signal classifier, update the UI with colored badges

✅ Good (atomic, verifiable):

Stack: Python/Flask. Files: app.py, templates/index.html

TASK: In fetch_data(), convert the date string (format "YYYY-MM-DD")
to datetime.date before returning.

CONSTRAINTS:
- Keep the existing route structure
- Use the same import style as the rest of the file

VERIFY: grep for "datetime.date" in app.py and confirm it exists.

Step 4 — Launch OpenCode

~/tools/opencode-delegate "<workdir>" "<prompt>" [timeout-secs] [model]
ArgumentDefaultNotes
workdir—Absolute path, must exist
prompt—Self-contained task description
timeout-secs300Wall-clock kill timer
modelopencode/deepseek-v4-flash-freeOpenCode model string

Recommended timeouts:

  • Explore only: 120
  • Simple change (1 file): 180
  • Medium change (2–3 files): 300

Model selection:

  • opencode/deepseek-v4-flash-free (default) — free, no API key needed, may have queue delays
  • google/gemini-2.5-flash — cheap, fast (requires GOOGLE_GENERATIVE_AI_API_KEY)

Examples:

# Simple change
~/tools/opencode-delegate "/path/to/project" "Stack: Flask. File: app.py. TASK: ..." 180

# Background run
~/tools/opencode-delegate "/path/to/project" "..." 300 > /tmp/opencode_out.txt 2>&1 &
# Monitor with: tail -f /tmp/opencode_out.txt

Step 5 — Supervise in real time

The script prints live:

=== OPENCODE START ===
Workdir : /path/to/project
Model   : opencode/deepseek-v4-flash-free
Timeout : 300s
Prompt  : Stack: Python/Flask. File: app.py ...
======================
  [read]   app.py
  [edit]   app.py  (+2/-1)
  [opencode] Done. Converted date to datetime.date in fetch_data().
Tool calls: 3
OpenCode tokens: 4,800  (4,600 in + 200 out)  |  ~$0.000000
=== OPENCODE DONE (exit: 0) ===
=== SYNTAX OK (1 file(s) checked) ===

=== UNCOMMITTED CHANGES ===
 app.py | 4 ++--
[log] → ~/.local/share/delegate-runs.jsonl  (4800 tokens, exit 0, 42.1s)

Event types emitted by the parser:

EventMeaning
[read]File read
[edit]File edited (+additions/-deletions)
[write]File created
[search]Grep / search tool called
[shell]Shell command executed
[opencode]Assistant text response
[WARN]Tool error detected
[ERROR]OpenCode runtime error

OpenCode never commits. All changes are left unstaged — git checkout . reverts everything if needed.

Red flags to act on immediately:

FlagMeaningAction
[WARN]Tool errorRead the error, fix manually
[ERROR]Runtime errorCheck auth, model availability
exit: 1 or non-zeroOpenCode failedRead diff, correct prompt
No [edit] after 60sLooping or queue delayAbort if persists
exit 0 + no [edit] eventsWROTE_NOTHING — OpenCode ran but wrote nothingDo not compensate — fix prompt and relaunch
=== SYNTAX ERRORS ===Post-run syntax check failedFix before committing
=== OPENCODE TIMEOUT ===Timed outCheck what was done before retrying
Same file read 5+ timesOpenCode is circling — run likely lostAbort, check diff, try again

Common issues and workarounds:

IssueCauseFix
No tool calls, empty responseModel overloaded or queue delayRetry; increase timeout to 300
Timeout with no writesModel not respondingTry a different model
File not modified despite "done"OpenCode described but didn't editAdd "make the edit now, do not describe it"
[ERROR] API key missingProvider not configuredCheck opencode auth list
Exit 124 (timeout)Task too large for given timeoutDecompose or increase timeout

Step 6 — Iteration

  • Max 3 attempts per sub-task before escalating to the user.
  • Between attempts, read the git diff to avoid doubling partial work.
  • If OpenCode completed ≥50% and timed out: finish the rest manually rather than relaunching.

Step 6b — Log manual completion

When you finish a task manually (after OpenCode failures), run this:

python3 -c "
import json, datetime, subprocess, os
workdir = subprocess.run(['git','rev-parse','--show-toplevel'], capture_output=True, text=True).stdout.strip() or os.getcwd()
project = os.path.basename(workdir.rstrip('/'))
stat = subprocess.run(['git','-C',workdir,'diff','--stat'], capture_output=True, text=True).stdout
lines_added = sum(int(l.split('+')[1].split()[0]) for l in stat.splitlines() if '|' in l and '+' in l) if stat else 0
files_changed = len([l for l in stat.splitlines() if '|' in l])
tokens_out = lines_added * 10
tokens_in  = lines_added * 40
cost = (tokens_in * 3.0 + tokens_out * 15.0) / 1_000_000
entry = {'ts': datetime.datetime.utcnow().isoformat() + 'Z', 'delegate': 'claude-manual', 'workdir': workdir, 'project': project, 'exit_code': 0, 'files_changed': files_changed, 'tokens_in': tokens_in, 'tokens_out': tokens_out, 'tokens_total': tokens_in + tokens_out, 'cost_usd': round(cost, 6), 'cost_estimated': True, 'lines_added': lines_added}
log = os.path.expanduser('~/.local/share/delegate-runs.jsonl')
open(log, 'a').write(json.dumps(entry) + '\n')
print(f'[log] claude-manual -> {project}  ~{lines_added} lines  est. cost \${cost:.4f}')
"

Run from anywhere inside the project. Flagged cost_estimated: true in the log.


Step 7 — Report to the user

✓ OpenCode finished — <1-line summary>

Files modified:
  - path/to/file.ext (+X / -Y lines)

[If problem]:
⚠ <description> — completing manually / retrying?

Ready to commit?

Orchestration rules

  • Decompose before delegating — one task, one prompt.
  • Check diff between sub-tasks — never launch the next step blind.
  • Don't code in OpenCode's place unless OpenCode did ≥50% and timed out.
  • Timeout is the only turn limit — decompose rather than extending.
  • VERIFY with grep, not re-read — grep -n "def foo" file.py.

Run Log

Every run appends one JSON entry to ~/.local/share/delegate-runs.jsonl. The shared ~/tools/delegate-report script can query all runs across delegates.

~/tools/delegate-report                  # full report
~/tools/delegate-report --since 7        # last 7 days
~/tools/delegate-report --project myapp  # filter by project
~/tools/delegate-report --fails          # failures only

Useful queries:

# All recent runs
cat ~/.local/share/delegate-runs.jsonl | python3 -m json.tool | less

# Total cost
jq -r '.cost_usd' ~/.local/share/delegate-runs.jsonl \
  | awk '{sum+=$1} END {printf "Total: $%.4f\n", sum}'

This skill is improved regularly — run update-skills to pull the latest version of this skill, as well as all your other skills!

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

Report a problem with this skill