A powerful skill to control Open Code CLI via a local web server API. Allows executing commands, managing sessions, and automating code generation remotely i...
---
name: OpenCode-CLI-Controller
description: A powerful skill to control Open Code CLI via a local web server API. Allows executing commands, managing sessions, and automating code generation remotely in the local network.
version: 1.1.0
emoji: ๐๏ธ
author: Malek-Rsh
tags:
- cli
- api
- automation
- web-server
- opencode
metadata:
openclaw:
requires:
bins:
- curl
- jq
- bash
install: |
chmod +x scripts/*.sh
if ! command -v jq &> /dev/null; then
echo "Warning: jq is required but not installed."
fi
run: |
echo "OpenCode Control Skill is ready for use."
echo "Please ensure the OpenCode server is running on port 4099."
---
# OpenCode CLI API Control
> [!IMPORTANT]
> **OPERATIONAL GUIDELINES**:
> While you may use `ls` or basic file system checks to verify that files/directories exist, you are **EXPLICITLY PROHIBITED** from reading or modifying the project's source code files directly.
> Your primary channel for task execution and progress monitoring is the **OpenCode API and the provided scripts**.
## Overview
This skill provides a set of tools to programmatically interface with the Open Code CLI through its local web server API. It enables you to act as a **Supervisor/Orchestrator** who directs OpenCode to handle all coding, file operations, and quality checks.
## Core Mandate: Orchestrator vs. Executor
- **You are NOT the Coder**: You do not write or verify code directly. OpenCode handles the implementation.
- **You are the Orchestrator**: You send high-level instructions to OpenCode, monitor its progress, and report the outcome to the user.
- **Trust the System**: OpenCode is responsible for its own file operations. Your job is to wait for it to finish and then check the *status* and *diff summary*, not the file contents.
## When to Use
- User requests creating or managing projects through OpenCode
- User asks for coding tasks, debugging, or code analysis via OpenCode
- User wants AI-powered development with specific providers/models
- User needs to manage multiple OpenCode sessions or monitor tasks
## Prerequisites
1. OpenCode server running (Preferred: `bash ./scripts/start_server.sh`)
2. Configuration file exists: `./config.json`
3. Required scripts in `./scripts/` directory
## Configuration
Read settings from `./config.json`:
```bash
BASE_URL=$(jq -r '.base_url' ./config.json)
PROJECTS_DIR=$(jq -r '.projects_base_dir' ./config.json)
```
## Important Agent Responsibilities
### Your Role as Orchestrator
You are the **supervisor and communication bridge** between the user and OpenCode.
**Operational Boundaries**:
- โ **NEVER** read or edit the code files generated by OpenCode directly for development tasks.
- โ **NEVER** try to fix or verify code logic by inspecting the project files yourself.
- โ
**MAY** use `ls` or simple directory checks only to confirm file existence if necessary.
- โ ๏ธ **PREFER** using the provided scripts and API for all project-related information.
**Required Workflow**:
- โ
**PRIMARY**: Use `monitor_session.sh` or `check_status.sh` to track progress.
- โ
**PRIMARY**: Use `get_diff.sh` to see a summary of what was changed.
- โ
**ALWAYS** report the results based on the API response or script output.
- โ
**TRUST** OpenCode's implementation of the requested features.
### Server Initialization Wait
**CRITICAL**: After starting OpenCode web server, it takes **10-15 seconds** to fully initialize. You **MUST** verify server readiness before sending any requests.
**Correct initialization sequence**:
```bash
# Start server using the robust backgrounding script
bash ./scripts/start_server.sh
# 3. Now safe to proceed with operations
bash ./scripts/update_providers.sh
# ... continue workflow
```
**Never** send requests immediately after starting the server - always verify health first.
### Intelligent Task Monitoring
For long-running tasks, use **smart monitoring** strategies:
**Option 1: Event-based monitoring (Recommended)**
```bash
# Start task
bash ./scripts/send_message.sh "Complex task" &
# Monitor events (blocks until completion)
bash ./scripts/monitor_session.sh
```
**Option 2: Intelligent polling**
```bash
# For environments where event streaming is unreliable
bash ./scripts/send_message.sh "Build application"
# Smart polling with exponential backoff
SLEEP_TIME=2
MAX_SLEEP=30
while true; do
STATUS=$(bash ./scripts/check_status.sh)
if [ "$STATUS" = "idle" ]; then
echo "โ Task completed"
break
elif [ "$STATUS" = "busy" ]; then
echo "โณ Still working... (checking again in ${SLEEP_TIME}s)"
sleep $SLEEP_TIME
# Increase wait time (but cap at MAX_SLEEP)
SLEEP_TIME=$((SLEEP_TIME < MAX_SLEEP ? SLEEP_TIME + 2 : MAX_SLEEP))
else
echo "โ Unexpected status: $STATUS"
break
fi
done
```
**Option 3: Timeout-based waiting**
```bash
# For predictable task durations
bash ./scripts/send_message.sh "Quick task"
# Wait reasonable time before checking
sleep 10
# Then check once
if [ "$(bash ./scripts/check_status.sh)" = "idle" ]; then
bash ./scripts/get_diff.sh
fi
```
**Anti-patterns to AVOID**:
- โ Checking status every 1-2 seconds (wastes resources)
- โ Reading files repeatedly to see if task is done
- โ Using `ls` or file system checks for progress
- โ Making multiple API calls without waiting
**Best practices**:
- โ
Use `monitor_session.sh` for real-time updates
- โ
Use exponential backoff for polling (start 2s, increase to 30s)
- โ
Estimate task duration and wait appropriately
- โ
Only check final results after confirmation of completion
- โ
Let OpenCode agents work independently - don't micromanage
## Task Initiation Protocol
Before starting any task (new project, code analysis, debugging, etc.), **ask the user in ONE message**:
> I'll help you with that. Two quick questions:
> 1. **Provider**: Use default from config, or specify a provider (opencode, anthropic, gemini, etc.)?
> 2. **Monitoring**:
> - **Standard** (recommended): Send task โ wait for completion summary โ notify you when done (saves tokens)
> - **Real-time**: Show live progress, file edits, and events as they happen (uses more tokens)
>
> How would you like to proceed?
**Default if not specified**: Use config defaults + Standard mode.
### Why This Matters
- **Standard mode**: Uses `send_message.sh` โ waits โ shows final summary. Efficient for most tasks.
- **Real-time mode**: Uses `monitor_session.sh` with event streaming. Good for long/complex tasks where you want visibility.
### Example Response Handling
- "Default provider, standard mode" โ Proceed immediately
- "Use Claude Sonnet, real-time" โ Run `select_provider.sh` then `monitor_session.sh`
- "Gemini Pro" โ Find provider + ask monitoring preference if not specified
---
### Task Completion Verification
When a task completes, get summary via:
```bash
# Get file changes summary (not individual files)
bash ./scripts/get_diff.sh
# Output example:
# added: src/App.tsx (+120/-0)
# modified: package.json (+5/-2)
# added: src/components/Dashboard.tsx (+89/-0)
```
This gives you all information needed to report to the user without reading actual file contents.
**Only read specific files if**:
- User explicitly asks to see code
- User requests explanation of specific implementation
- Debugging a reported issue
Otherwise, trust the diff summary and OpenCode's implementation.
## Core Workflow
### Step 1: Verify Server
```bash
# Check health
curl -s "$BASE_URL/global/health" | jq
# Expected: {"healthy": true, "version": "..."}
```
### Step 2: Update Providers Cache
```bash
# Run provider update script
bash ./scripts/update_providers.sh
```
This caches **only connected providers** to `./providers.json`.
### Step 3: Create or Select Project
**New Project**:
```bash
PROJECT_NAME="dashboard-app"
PROJECT_PATH="$PROJECTS_DIR/$PROJECT_NAME"
mkdir -p "$PROJECT_PATH"
```
**Existing Project**:
```bash
PROJECT_NAME="existing-app"
PROJECT_PATH="$PROJECTS_DIR/$PROJECT_NAME"
# Verify exists
[ -d "$PROJECT_PATH" ] || { echo "Project not found"; exit 1; }
```
### Step 4: Create Session
Create a session in the project directory using the provided script:
```bash
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECT_PATH" "Session Title")
```
### Step 5: Save Session State
```bash
# Use state management script
bash ./scripts/save_state.sh "$SESSION_ID" "$PROJECT_PATH"
```
### Step 6: Send Message
Use the provided script to send prompts to the AI:
```bash
# Use defaults from config
bash ./scripts/send_message.sh "Your prompt here"
# Or use a specific provider and model
bash ./scripts/send_message.sh "Your prompt" "anthropic" "claude-sonnet-4-5"
```
### Step 7: Monitor Progress (For Long Tasks)
```bash
# Start monitoring in background
bash ./scripts/monitor_session.sh &
# Or check status periodically
bash ./scripts/check_status.sh
```
## Provider Selection
### Automatic (uses default from config.json)
```bash
bash ./scripts/send_message.sh "Create app"
```
### User Specifies Provider
When the user specifies a provider (e.g., "use Gemini Pro" or "with Claude Sonnet"), use the search script:
```bash
# Search for provider and model hints
RESULT=$(bash ./scripts/select_provider.sh "gemini" "pro")
# Returns: gemini gemini-3-pro
# Extract and use the returned values
PROVIDER_ID=$(echo "$RESULT" | cut -d' ' -f1)
MODEL_ID=$(echo "$RESULT" | cut -d' ' -f2)
bash ./scripts/send_message.sh "Your prompt" "$PROVIDER_ID" "$MODEL_ID"
```
## Agent Selection
**Default (no agent specified - recommended)**:
```bash
bash ./scripts/send_message.sh "Build app"
```
**Planning phase**:
```bash
bash ./scripts/send_message.sh "Analyze requirements" "plan"
```
**Implementation phase**:
```bash
bash ./scripts/send_message.sh "Implement features" "build"
```
## Common Patterns
### Pattern 1: New Project from Scratch
```bash
# 1. Update providers
bash ./scripts/update_providers.sh
# 2. Create project directory
mkdir -p "$PROJECTS_DIR/new-app"
# 3. Create session
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECTS_DIR/new-app" "New App")
# 4. Send initial task
bash ./scripts/send_message.sh "Create React app with TypeScript and Tailwind"
# 5. Monitor progress
bash ./scripts/monitor_session.sh
```
### Pattern 2: Continue Existing Project
```bash
# 1. Load saved project state
bash ./scripts/load_project.sh "existing-app"
# 2. Send new task
bash ./scripts/send_message.sh "Add authentication feature"
```
### Pattern 3: Multi-Phase Development
```bash
# Phase 1: Planning
bash ./scripts/create_session.sh "$PROJECT_PATH" "Planning"
bash ./scripts/send_message.sh "Plan e-commerce platform" "plan"
# Phase 2: Implementation
bash ./scripts/send_message.sh "Implement the plan" "build"
# Phase 3: Review
bash ./scripts/get_diff.sh
```
### Pattern 4: Use Specific Provider
```bash
# User says: "Create dashboard using Claude Sonnet"
# 1. Select provider
PROVIDER_MODEL=$(bash ./scripts/select_provider.sh "claude" "sonnet")
PROVIDER_ID=$(echo "$PROVIDER_MODEL" | cut -d' ' -f1)
MODEL_ID=$(echo "$PROVIDER_MODEL" | cut -d' ' -f2)
# 2. Create project and session
mkdir -p "$PROJECTS_DIR/dashboard"
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECTS_DIR/dashboard" "Dashboard")
# 3. Send with selected provider
bash ./scripts/send_message.sh "Create dashboard" "$PROVIDER_ID" "$MODEL_ID"
```
## Event Monitoring
For long-running tasks, monitor events:
```bash
# Start monitoring (shows progress in real-time)
bash ./scripts/monitor_session.sh
# This will:
# - Show text deltas as they're generated
# - Display status changes (busy/idle)
# - Show final token count and cost
# - Exit when task completes
```
## State Management
All session state is saved in `./state/`:
```bash
# Save current session
bash ./scripts/save_state.sh "$SESSION_ID" "$PROJECT_PATH"
# Load state (sets environment variables)
source ./scripts/load_state.sh
echo $SESSION_ID
echo $PROJECT_PATH
# Save project-specific state
bash ./scripts/save_project.sh "project-name"
# Load project-specific state
bash ./scripts/load_project.sh "project-name"
# List all saved projects
ls -1 ./state/*.json | grep -v current.json | xargs -n1 basename .json
```
## File Operations
Get session changes:
```bash
bash ./scripts/get_diff.sh
```
Get file content:
```bash
curl -s "$BASE_URL/file/content?directory=$PROJECT_PATH&path=src/App.tsx" \
jq -r '.content'
```
List directory:
```bash
curl -s "$BASE_URL/file?directory=$PROJECT_PATH&path=src" \
jq -r '.[] | "\(.type): \(.path)"'
```
## Error Handling
All scripts return proper exit codes:
- `0` = Success
- `1` = Error
Check script status:
```bash
if bash ./scripts/send_message.sh "prompt"; then
echo "Success"
else
echo "Failed - check server or authentication"
fi
```
## Authentication
This skill assumes the OpenCode server is running in a trusted local environment and does not use password authentication by default.
## Quick Reference
| Task | Command |
|------|---------|
| Update providers | `bash ./scripts/update_providers.sh` |
| Create session | `bash ./scripts/create_session.sh "$PATH" "Title"` |
| Send message | `bash ./scripts/send_message.sh "prompt"` |
| With provider | `bash ./scripts/send_message.sh "prompt" "provider" "model"` |
| Monitor progress | `bash ./scripts/monitor_session.sh` |
| Check status | `bash ./scripts/check_status.sh` |
| Get changes | `bash ./scripts/get_diff.sh` |
| Save state | `bash ./scripts/save_state.sh "$SID" "$PATH"` |
| Load state | `source ./scripts/load_state.sh` |
| Save project | `bash ./scripts/save_project.sh "name"` |
| Load project | `bash ./scripts/load_project.sh "name"` |
| Select provider | `bash ./scripts/select_provider.sh "name" "model"` |
## Important Notes
1. **Always run from skill directory**: Scripts use relative paths
2. **Update providers at workflow start**: Ensures cache is fresh
3. **Create projects in PROJECTS_BASE_DIR**: Configured in config.json
4. **Each session belongs to one project directory**: Don't mix
5. **Load state before curl commands**: Ensures variables are set
6. **Scripts handle authentication**: No need to add headers manually
## Troubleshooting
**"No active session"**:
```bash
# Load or create session first
bash ./scripts/create_session.sh "$PROJECT_PATH" "Title"
```
**"Provider not found"**:
```bash
# Update providers cache
bash ./scripts/update_providers.sh
# Check available providers
jq -r '.providers[] | .id' ./providers.json
```
**"HTML response instead of JSON"**:
- Missing `directory` parameter
- Check: Are you using full PROJECT_PATH?
## Advanced Usage
For complex workflows, state management, or advanced patterns, see:
- `Reference/STATE_MANAGEMENT.md` - Advanced state handling
- `Reference/PROVIDERS_REFERENCE.md` - Provider selection details
- `Reference/EVENTS_GUIDE.md` - Event monitoring patterns
- `Reference/COMPLETE_EXAMPLES.md` - Full workflow examples
- `Reference/API_QUICK_REFERENCE.md` - Raw API endpoints
## Directory Structure
```
opencode-api-control/
โโโ SKILL.md # This file
โโโ config.json # Configuration
โโโ providers.json # Connected providers cache
โโโ scripts/ # Helper scripts
โ โโโ update_providers.sh
โ โโโ create_session.sh
โ โโโ send_message.sh
โ โโโ monitor_session.sh
โ โโโ check_status.sh
โ โโโ get_diff.sh
โ โโโ save_state.sh
โ โโโ load_state.sh
โ โโโ save_project.sh
โ โโโ load_project.sh
โ โโโ select_provider.sh
โโโ state/ # Session state
โ โโโ current.json
โ โโโ project-name.json
โโโ Reference/ # Reference docs
โโโ STATE_MANAGEMENT.md
โโโ PROVIDERS_REFERENCE.md
โโโ EVENTS_GUIDE.md
โโโ COMPLETE_EXAMPLES.md
โโโ API_QUICK_REFERENCE.md
```
---
**Author:** [Malek RSH](https://github.com/malek262) | **Repository:** [OpenCode-CLI-Controller](https://github.com/malek262/opencode-api-control-skill)don't have the plugin yet? install it then click "run inline in claude" again.