agentsclimarketplace

Opencode skill

Skill pcx-wave/opencode-skill

Claude Code skill — delegate coding tasks to Opencode, supervise via git diff & save 50-90% Claude token usage

Install
npx -y skills add pcx-wave/opencode-skill

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 12 stars12 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

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 file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.

SKILL.md

12.5 KB, ~3.3k tokens by cl100k_base, as published. Nobody here has run it

/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 locatedSkip 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 logicDecompose

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
workdirAbsolute path, must exist
promptSelf-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-readgrep -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!

What ships with it: 10 files

46.7 KB alongside SKILL.md, 2 of them executable

docs/

tools/

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.