🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

OpenCode CLI API Controller

by @malek262

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...

Versionv1.1.0
Downloads1,075
Stars⭐ 2
TERMINAL
clawhub install opencode-api-control-skill

πŸ“– About This Skill


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:

    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:

    # 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)

    # Start task
    bash ./scripts/send_message.sh "Complex task" &

    Monitor events (blocks until completion)

    bash ./scripts/monitor_session.sh

    Option 2: Intelligent polling

    # 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

    # 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:

    # 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

    # Check health
    curl -s "$BASE_URL/global/health" | jq

    Expected: {"healthy": true, "version": "..."}

    Step 2: Update Providers Cache

    # 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:

    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"
    

    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:
    SESSION_ID=$(bash ./scripts/create_session.sh "$PROJECT_PATH" "Session Title")
    

    Step 5: Save Session State

    # 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:
    # 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)

    # 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 ./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:
    # 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 ./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

    # 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

    # 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

    # 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

    # 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:

    # 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/:

    # 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 ./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:

  • 0 = Success
  • 1 = Error
  • 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

    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":

    # Load or create session first
    bash ./scripts/create_session.sh "$PROJECT_PATH" "Title"
    

    "Provider not found":

    # 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 | Repository: OpenCode-CLI-Controller

    ⚑ When to Use

    TriggerAction
    - 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

    βš™οΈ Configuration

    Read settings from ./config.json:

    BASE_URL=$(jq -r '.base_url' ./config.json)
    PROJECTS_DIR=$(jq -r '.projects_base_dir' ./config.json)
    

    πŸ“‹ Tips & Best Practices

    "No active session":

    # Load or create session first
    bash ./scripts/create_session.sh "$PROJECT_PATH" "Title"
    

    "Provider not found":

    # 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?