skills/opencode-runner/SKILL.md
Run coding tasks via opencode using free cloud models. Use when asked to offload work to opencode.ai or run a free model. Don't use for local models (Ollama, LM Studio), Claude/OpenAI calls, or when Claude should do the work itself.
npx skillsauth add luongnv89/skills opencode-runnerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Delegate coding tasks to opencode using free models — zero cost, fully automated.
OpenCode (opencode.ai) is a terminal AI coding assistant that supports multiple providers and models. This skill automates the process of selecting the best available free model, launching the task, and reporting progress back to you.
which opencode must succeed; install via npm i -g opencode-ai@latest or brew install opencode if missingNever do the task yourself. This skill exists solely to delegate work to opencode. If opencode is not installed, fails to run, or no free cloud model is available — report the problem to the user and stop. Do not fall back to editing files directly, writing code yourself, or using any other tool to accomplish the user's coding task. The whole point is that opencode does the work.
Only select cloud models. Never select local models (e.g., ollama/*, lmstudio/*, or any model running on localhost). Only select models from the opencode/* provider namespace, which are cloud-hosted on OpenCode Zen. Local models have unpredictable availability, performance, and may not support the tool-use capabilities opencode needs.
Always clean up after yourself. opencode spawns background processes (LSP servers, MCP servers, node workers) that persist after the task finishes. Every execution path — success, failure, error, timeout — must end with the cleanup steps in Phase 6. Orphaned opencode processes silently eat CPU and memory, and users won't notice until their machine slows to a crawl.
Before creating/updating/deleting files in an existing repository, sync the current branch with remote:
branch="$(git rev-parse --abbrev-ref HEAD)"
git fetch origin
git pull --rebase origin "$branch"
If the working tree is not clean, stash first, sync, then restore:
git stash push -u -m "pre-sync"
branch="$(git rev-parse --abbrev-ref HEAD)"
git fetch origin && git pull --rebase origin "$branch"
git stash pop
If origin is missing or conflicts occur, stop and ask the user before continuing.
Check that opencode is installed and at the latest version.
which opencode && opencode --version
If opencode is not found, tell the user:
opencode is not installed. Install it with one of these commands:
curl -fsSL https://opencode.ai/install | bashor
npm i -g opencode-ai@latestor (macOS)
brew install opencode
Then stop completely — do not proceed to any other phase, do not attempt the task yourself, do not edit any files. Wait for the user to install opencode and re-invoke this skill.
opencode upgrade
This will upgrade to the latest version if one is available, or confirm already up to date. If the upgrade fails, inform the user of the error and suggest running the command manually. If the upgrade itself breaks opencode, stop and report — do not continue.
Query the available models, present the free ones to the user, and let them choose. If the user doesn't choose, fall back to the priority order.
opencode models 2>/dev/null
| Priority | Model ID | Notes |
|----------|----------|-------|
| 1 | opencode/deepseek-v4-flash-free | Strong recent free coding model — preferred default |
| 2 | opencode/minimax-m2.5-free | MiniMax free tier — good general-purpose |
| 3 | opencode/nemotron-3-super-free | NVIDIA Nemotron free tier |
| 4 | opencode/big-pickle | Free fallback |
| 5 | opencode/gpt-5-nano | Small, low-cost fallback (verify pricing) |
Model IDs evolve. When parsing opencode models output, treat any opencode/* model whose ID ends in -free (or is explicitly priced $0) as free-tier eligible. Match by suffix, not by exact ID.
Run opencode models and collect all entries.
Filter out all non-opencode/* models — ignore anything from ollama/*, lmstudio/*, nvidia/*, or any other namespace. Only cloud-hosted opencode/* models qualify.
Among the remaining list, identify the free candidates (suffix -free or known-free IDs from the priority list).
Present the free models to the user as numbered options, in priority order, with priority 1 marked as the default. Use the <options> format if possible. Example:
I found these free cloud models available via opencode. Pick one, or accept the default.
opencode/deepseek-v4-flash-free(default — priority 1)opencode/minimax-m2.5-freeopencode/nemotron-3-super-freeopencode/big-pickle
If the user names a model, use that one. If the user says "default", "you pick", "any", or doesn't specify, use priority 1 (the highest-priority available free model).
If no free cloud models exist at all, inform the user and stop — do not fall back to local models, paid models, or doing the task yourself.
Privacy note (always show this with the model list): Free models on OpenCode Zen may use collected data for model improvement.
Before invoking opencode, show the user a one-screen summary and get explicit confirmation. This catches wrong-model or wrong-prompt mistakes before any tokens are burned.
Present this block:
Ready to delegate to opencode
- Model:
opencode/deepseek-v4-flash-free(free tier)- Working directory:
/Users/.../current-project- Context files:
path/to/foo.py,path/to/bar.py(or "none")- Prompt: (quote the prompt verbatim, multi-line OK)
- Estimated duration: unknown — opencode is non-deterministic; cleanup runs even on timeout
Confirm to proceed, or tell me what to change (model, prompt, files).
Then offer the user two <options>: "Proceed" and "Change something". Wait for confirmation. Do not invoke opencode run until the user confirms.
If the user asks to change anything (different model, edit prompt, add/remove context files), loop back: update the field, re-show the summary, and ask again.
Run the coding task with the confirmed model. Always run in the background with output redirected to a log file — this is required for the low-token monitoring strategy in Phase 5.
LOG=/tmp/opencode-$$.log
opencode run -m "[confirmed-model-id]" "[confirmed prompt]" > "$LOG" 2>&1 &
OPENCODE_PID=$!
echo "opencode started: pid=$OPENCODE_PID log=$LOG"
For tasks that reference files or need detailed context, use the --file flag:
opencode run -m "[confirmed-model-id]" --file path/to/relevant-file.py "[task description]" > "$LOG" 2>&1 &
OPENCODE_PID=$!
Foreground execution is discouraged — streaming the full opencode output back into your context wastes tokens. The Phase 5 monitor reads only the log tail.
opencode output is verbose. Streaming the full log back into your context is expensive — a single long run can easily push past 10k tokens of stream chatter. Use the lightweight polling protocol below instead.
Run one tiny status command per check. It returns at most ~200 bytes — enough to know status, elapsed time, and the latest activity line — without ingesting the whole log.
LOG=/tmp/opencode-$$.log # the same log file from Phase 4
status() {
if kill -0 $OPENCODE_PID 2>/dev/null; then s=running; else s=done; fi
bytes=$(wc -c < "$LOG" 2>/dev/null || echo 0)
last=$(tail -n 1 "$LOG" 2>/dev/null | tr -d '\r' | cut -c1-160)
printf 'status=%s pid=%s bytes=%s last=%q\n' "$s" "$OPENCODE_PID" "$bytes" "$last"
}
status
That single line is your full progress sample. Do not tail -n 50, do not cat $LOG, do not stream stdout — those defeat the purpose.
bytes= is unchanged for two consecutive polls (i.e., ≥60s of no output growth), treat the run as stalled — confirm with the user before killing.bytes growth, kill and report (then run Phase 6).One short line per check, derived from the status() output:
Poll 2 (t+60s): running, 4.2 KB written, last: "Editing src/foo.py …"
Do not paste the raw log. Do not summarize what opencode is "thinking" — you can't tell from a tail line. Stick to: status, elapsed, byte growth, last line.
When status=done:
tail -n 40 "$LOG". That's the summary opencode prints at the end (files changed, tokens used, errors).$LOG — do not paste it.opencode auth list to check provider auth.Every execution — success, failure, error, or timeout — must end with cleanup. opencode spawns child processes (LSP servers, MCP servers, node workers) that persist after the main process exits. Without cleanup, these orphaned processes accumulate and drain system resources.
If you launched opencode in the background with a tracked PID:
# Kill the main process and its children
kill $OPENCODE_PID 2>/dev/null
# Wait briefly for graceful shutdown
sleep 2
# Force kill if still running
kill -9 $OPENCODE_PID 2>/dev/null
After the task completes, scan for any lingering opencode processes from this session:
# List any remaining opencode processes
ps aux | grep '[o]pencode' | grep -v grep
If orphaned processes are found, kill them:
# Kill all opencode run processes (be specific to avoid killing the user's TUI)
pkill -f "opencode run" 2>/dev/null
Be careful to only kill opencode run processes, not the user's interactive TUI session (opencode without subcommand). If the user has an interactive opencode session open, leave it alone.
rm -f "$LOG" 2>/dev/null
Report to the user:
Cleanup complete — all opencode processes from this task have been terminated.
If you couldn't kill some processes (permission denied, etc.), warn the user:
Warning: Some opencode processes may still be running. Run
pkill -f "opencode run"manually to clean up.
See references/expected-output.md for the full set of example blocks the user should see at each phase (model picker, confirmation summary, low-token progress polls, cleanup confirmation). On error or timeout, the cleanup confirmation still runs.
which opencode returns nothing. The skill prints installation instructions for three methods (curl, npm, brew) and stops. It does not attempt the coding task itself.opencode models output contains no opencode/* models with $0 or "Free" pricing. The skill informs the user that no free option is available and stops. It does not fall back to local models (ollama, lmstudio) or paid models.opencode auth list), and stops.opencode run without explicit confirmation.opencode run child processes, leaving the interactive TUI (opencode without a subcommand) untouched.--file flag to pass context files separately, keeping the command-line prompt concise and avoiding shell escaping issues.The skill run is considered successful when all of the following are verifiable:
opencode is on PATH and reports its version before any other action.opencode/* models considered — Filter step rejects ollama/*, lmstudio/*, nvidia/*, and any other namespace. No local model is ever selected.opencode/* model with priority 1 as default, plus the privacy note. The user may pick one; if they defer, priority 1 is used.opencode run.opencode run, not by the skill editing files directly or writing code itself.status() helper. The raw log is never streamed back; only the last line, byte count, and status are reported per poll. Max 6 polls per run.status=done, the skill reads only tail -n 40 "$LOG" and summarizes files changed and token usage.opencode run processes remain.$LOG (and any other temp files created) are deleted during cleanup.After each phase, emit a compact status block so pass/fail is scannable:
◆ [Step Name] ([step N of M] — [context])
··································································
[Check 1]: √ pass
[Check 2]: × fail — [reason]
[Criteria]: √ N/M met
____________________________
Result: PASS | FAIL | PARTIAL
Use √ for pass, × for fail, and — to add brief context. Per-phase example blocks (Installation, Model Discovery, Confirmation, Execution, Monitor, Cleanup) are in references/expected-output.md.
| Command | Purpose |
|---------|---------|
| opencode --version | Check installed version |
| opencode upgrade | Update to latest |
| opencode models | List available models |
| opencode run -m MODEL "prompt" | Run task with specific model |
| opencode stats | View usage statistics |
| opencode auth list | Check authenticated providers |
| pkill -f "opencode run" | Kill orphaned run processes |
| ps aux \| grep opencode | Find running opencode processes |
documentation
Manage software releases end-to-end: bump version, generate changelog, tag, push, GitHub release, publish to PyPI/npm. Use when user asks to ship, cut a release, tag a version, or list changes since last tag. Skip routine commits and marketplace publishing.
development
Review UI for usability issues using Steve Krug's principles and produce a scannable report. Use when asked for a usability audit, UX review, or UI feedback on screenshots, URLs, or code. Don't use for visual/brand design critique, accessibility (WCAG) audits, or backend/API review.
development
Validate app/startup ideas with market, feasibility, commercial, and open-source competitor analysis. Use when asked to evaluate, validate, or score a product idea. Don't use for PRDs, go-to-market plans, or investor decks.
testing
Install local-first security hardening: pre-commit secret detection, offline dependency scans, static analysis, reports, and gated free CI. Use when hardening repos or adding security hooks. Don't use for incident response or cloud security reviews.