| 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\nif ! command -v jq &> /dev/null; then\n echo \"Warning: jq is required but not installed.\"\nfi\n","run":"echo \"OpenCode Control Skill is ready for use.\"\necho \"Please ensure the OpenCode server is running on port 4099.\"\n"}} |
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
- OpenCode server running (Preferred:
bash ./scripts/start_server.sh)
- Configuration file exists:
./config.json
- Required scripts in
./scripts/ directory
Configuration
Read settings from ./config.json:
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 ./scripts/start_server.sh
bash ./scripts/update_providers.sh
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 ./scripts/send_message.sh "Complex task" &
bash ./scripts/monitor_session.sh
Option 2: Intelligent polling
bash ./scripts/send_message.sh "Build application"
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
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 ./scripts/send_message.sh "Quick task"
sleep 10
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:
- Provider: Use default from config, or specify a provider (opencode, anthropic, gemini, etc.)?
- 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 ./scripts/get_diff.sh
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
curl -s "$BASE_URL/global/health" | jq
Step 2: Update Providers Cache
bash ./scripts/update_providers.sh
This caches only connected providers to ./providers.json.
Step 3: Create or Select Project
New Project:
PROJECT_NAME="dashboard-app"
PROJECT_PATH="$PROJECTS_DIR/$PROJECT_NAME"
mkdir -p "$PROJECT_PATH"
Existing Project:
PROJECT_NAME="existing-app"
PROJECT_PATH="$PROJECTS_DIR/$PROJECT_NAME"
[ -d "$PROJECT_PATH" ] || { echo "Project not found"; exit 1; }
Step 4: Create Session
Create a session in the project directory using the provided script:
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECT_PATH" "Session Title")
Step 5: Save Session State
bash ./scripts/save_state.sh "$SESSION_ID" "$PROJECT_PATH"
Step 6: Send Message
Use the provided script to send prompts to the AI:
bash ./scripts/send_message.sh "Your prompt here"
bash ./scripts/send_message.sh "Your prompt" "anthropic" "claude-sonnet-4-5"
Step 7: Monitor Progress (For Long Tasks)
bash ./scripts/monitor_session.sh &
bash ./scripts/check_status.sh
Provider Selection
Automatic (uses default from config.json)
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:
RESULT=$(bash ./scripts/select_provider.sh "gemini" "pro")
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 ./scripts/send_message.sh "Build app"
Planning phase:
bash ./scripts/send_message.sh "Analyze requirements" "plan"
Implementation phase:
bash ./scripts/send_message.sh "Implement features" "build"
Common Patterns
Pattern 1: New Project from Scratch
bash ./scripts/update_providers.sh
mkdir -p "$PROJECTS_DIR/new-app"
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECTS_DIR/new-app" "New App")
bash ./scripts/send_message.sh "Create React app with TypeScript and Tailwind"
bash ./scripts/monitor_session.sh
Pattern 2: Continue Existing Project
bash ./scripts/load_project.sh "existing-app"
bash ./scripts/send_message.sh "Add authentication feature"
Pattern 3: Multi-Phase Development
bash ./scripts/create_session.sh "$PROJECT_PATH" "Planning"
bash ./scripts/send_message.sh "Plan e-commerce platform" "plan"
bash ./scripts/send_message.sh "Implement the plan" "build"
bash ./scripts/get_diff.sh
Pattern 4: Use Specific 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)
mkdir -p "$PROJECTS_DIR/dashboard"
SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECTS_DIR/dashboard" "Dashboard")
bash ./scripts/send_message.sh "Create dashboard" "$PROVIDER_ID" "$MODEL_ID"
Event Monitoring
For long-running tasks, monitor events:
bash ./scripts/monitor_session.sh
State Management
All session state is saved in ./state/:
bash ./scripts/save_state.sh "$SESSION_ID" "$PROJECT_PATH"
source ./scripts/load_state.sh
echo $SESSION_ID
echo $PROJECT_PATH
bash ./scripts/save_project.sh "project-name"
bash ./scripts/load_project.sh "project-name"
ls -1 ./state/*.json | grep -v current.json | xargs -n1 basename .json
File Operations
Get session changes:
bash ./scripts/get_diff.sh
Get file content:
curl -s "$BASE_URL/file/content?directory=$PROJECT_PATH&path=src/App.tsx" \
jq -r '.content'
List directory:
curl -s "$BASE_URL/file?directory=$PROJECT_PATH&path=src" \
jq -r '.[] | "\(.type): \(.path)"'
Error Handling
All scripts return proper exit codes:
Check script status:
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
- Always run from skill directory: Scripts use relative paths
- Update providers at workflow start: Ensures cache is fresh
- Create projects in PROJECTS_BASE_DIR: Configured in config.json
- Each session belongs to one project directory: Don't mix
- Load state before curl commands: Ensures variables are set
- Scripts handle authentication: No need to add headers manually
Troubleshooting
"No active session":
bash ./scripts/create_session.sh "$PROJECT_PATH" "Title"
"Provider not found":
bash ./scripts/update_providers.sh
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 | Repository: OpenCode-CLI-Controller