An OpenClaw plugin that lets AI agents orchestrate coding agent sessions as managed background processes. Launch, monitor, and interact with multiple concurrent coding sessions directly from Telegram, Discord, or any OpenClaw-supported messaging platform β without leaving your chat interface.
This plugin started as a response to a real gap in OpenClaw's built-in ACP support. At the time, ACP was effectively a raw relay into ACP backends: useful for handing off a prompt, but without the orchestration layer needed for coding-agent work in chat. There was no plan review flow, no plugin-managed pause/resume model, no fork flow, no cost or session stats, and no async notification path back to the originating chat when a session needed input or finished.
ACP has improved since then. OpenClaw core ACP now supports multi-turn sessions, resuming prior work, and a broader set of ACP runtimes and harnesses. That closes part of the original gap.
What still remains is the orchestration layer this plugin was built to provide: propose/revise/approve plan review before execution, forkable coding sessions, dedicated session catalog + operator-facing stats, cost accounting, and an explicit async notification pipeline that wakes the origin chat only when the job needs attention or completes.
For the current version-pinned breakdown, see docs/ACP-COMPARISON.md.
Plan review and approval in ask mode: the agent pauses for your decision before executing.
In delegate mode, the orchestrator auto-approves low-risk plans and only escalates when needed.
| Agent | Status | Notes |
|---|---|---|
| Claude Code | β Supported | Full support via @anthropic-ai/claude-agent-sdk |
| Codex | β Supported | Full support via @openai/codex-sdk thread API |
| Other agents | π§ Planned | Plugin architecture supports adding new harnesses |
vs. built-in ACP? See docs/ACP-COMPARISON.md for the current version-pinned breakdown.
- Multi-session management β Run multiple concurrent coding agent sessions, each with a unique ID and human-readable name
- Plan β Execute workflow β Claude Code sessions expose plan mode; Codex uses a soft first-turn planning prompt while staying externally in implement mode
- Real Codex approval policy support β Codex sessions default to the real Codex SDK/CLI
approvalPolicy: "on-request"and can be pinned back to"never"viaharnesses.codex.approvalPolicy - Thread-based routing β Notifications go to the Telegram thread/topic where the session was launched
- Pause + auto-resume β Non-question turn completion pauses sessions (
done) and nextagent_respondauto-resumes with context intact - Turn-end wake signaling β Every turn end emits a deterministic wake signal with output preview and waiting hint
- Smart waiting detection β Heuristic waiting detector reduces false-positive wake escalations
- Multi-turn conversations β Send follow-up messages, interrupt, or iterate with a running agent
- Session resume & fork β Resume any completed session or fork it into a new conversation branch
- Merged session listing β
agent_sessionsshows active + persisted sessions in one view (deduped by internal session ID) - Pending MessageStream safety β queued follow-ups are preserved across turn completion so messages are not dropped
- Codex SDK streaming harness β uses
@openai/codex-sdkthread streaming with soft first-turn planning, waiting detection, and activity heartbeats - Multi-agent support β Route notifications to the correct agent/chat via workspace-based channel mapping
- Auto-respond rules β Orchestrator auto-handles permission requests and confirmations; forwards real decisions to you
- Anti-cascade protection β Orchestrator never launches new sessions from wake events
- Automatic cleanup β Completed sessions are garbage-collected after a configurable TTL (
sessionGcAgeMinutes, default 24h); IDs persist for resume - Harness-agnostic architecture β Pluggable
AgentHarnessinterface allows adding new coding agent backends
openclaw plugins install openclaw-code-agent
openclaw plugins enable openclaw-code-agent
openclaw gateway restartAdd to ~/.openclaw/openclaw.json under plugins.entries["openclaw-code-agent"]:
{
"plugins": {
"entries": {
"openclaw-code-agent": {
"enabled": true,
"config": {
"fallbackChannel": "telegram|my-bot|123456789",
"maxSessions": 20,
"harnesses": {
"codex": {
"defaultModel": "gpt-5.4",
"allowedModels": ["gpt-5.4"],
"reasoningEffort": "medium",
"approvalPolicy": "on-request"
},
"claude-code": {
"defaultModel": "sonnet",
"allowedModels": ["sonnet", "opus"]
}
}
}
}
}
}
}Replace my-bot with your Telegram bot account name and 123456789 with your Telegram chat ID.
If you run Codex sessions, strongly recommend forcing ChatGPT login in your Codex config:
forced_login_method = "chatgpt"Put that in ~/.codex/config.toml. This keeps Codex on the ChatGPT auth path and avoids account/login mismatches that can surface as unsupported-model or auth failures.
- Ask your agent: "Fix the bug in auth.ts"
- A coding agent session launches and explores the task. Claude Code exposes plan mode; Codex can do a plan-first turn without surfacing plan mode in session status
- The agent's questions and plan appear in the same Telegram thread where you launched
- When a session is awaiting plan approval, approve it with
agent_respond(..., approve=true)and the session switches to implement mode - The agent implements with full permissions, then you get a brief completion summary
| Tool | Description | Key Parameters |
|---|---|---|
agent_launch |
Start a new coding agent session in background | prompt, name, workdir, model, resume_session_id, fork_session, permission_mode, harness |
agent_respond |
Send a follow-up message to a running session | session, message, interrupt, approve, userInitiated |
agent_kill |
Terminate or complete a running session | session, reason |
agent_output |
Read buffered output from a session | session, lines, full |
agent_sessions |
List recent sessions (5 by default, full for 24h view) |
status, full |
agent_stats |
Show usage metrics (counts, durations, costs) | (none) |
Core orchestration workflows use agent_launch, agent_respond, agent_output, agent_sessions, and agent_kill.
All tools are also available as chat commands (/agent, /agent_respond, /agent_kill, /agent_sessions, /agent_resume, /agent_stats, /agent_output).
# Launch a session (starts in plan mode by default)
/agent Fix the authentication bug in src/auth.ts
/agent --name fix-auth Fix the authentication bug
# Monitor
/agent_sessions
/agent_sessions --full
# Interact with a running session
/agent_respond fix-auth Also add unit tests
/agent_respond --interrupt fix-auth Stop that and do this instead
# Approve a pending plan (tool call)
agent_respond(session='fix-auth', message='Approved. Go ahead.', approve=true)
# Lifecycle management
/agent_kill fix-auth
/agent_resume fix-auth Add error handling
/agent_resume --fork fix-auth Try a different approach
/agent_statsThe plugin sends targeted notifications to the originating Telegram thread:
| Emoji | Event | Description |
|---|---|---|
| π | Launched | Session started with prompt summary |
| π | Agent asks | Session is waiting for user input |
| π | Plan ready | Plan approval requested β reply "go" to approve |
| π | Turn done | Turn completed, session paused (auto-resumable) |
| β | Completed | Completion summary with cost and duration |
| β | Failed | Error notification with hint |
| β | Killed | Session terminated with kill reason |
| π€ | Idle-killed | Auto-resumes on next respond |
- Claude Code starts in
planmode by default. Approve a pending plan withagent_respond(..., approve=true)and the session switches tobypassPermissions. - Codex does not surface
planorawaiting-plan-approvalin session state. When launched withpermissionMode: "plan", its first turn is prompted to return a plan and ask whether to proceed, while the exposed session phase remains implementation-oriented. - For Codex, plugin
permissionModeis a plugin-orchestrated planning/approval workflow. It is not the same thing as the Codex SDK/CLIapprovalPolicy. - The real Codex SDK/CLI approval behavior is controlled by
harnesses.codex.approvalPolicy. Supported values are"on-request"(default) and"never".
On approval, the plugin prepends a system instruction telling the agent to exit plan mode and implement with full permissions.
The orchestrator agent follows strict auto-respond rules to minimize noise:
Auto-respond (immediate):
- Permission requests (file read/write/bash) β "Yes, proceed."
- Explicit "should I continue?" confirmations β "Yes, continue."
Forward to user (everything else):
- Architecture/design decisions
- Destructive operations
- Scope changes
- Credential/production questions
- Any ambiguous or non-trivial question
When forwarding, the orchestrator quotes the agent's exact question without adding its own commentary.
Set values in ~/.openclaw/openclaw.json under plugins.entries["openclaw-code-agent"].config:
| Option | Type | Default | Description |
|---|---|---|---|
agentChannels |
object |
β | Map workdir paths β notification channels (see docs/AGENT_CHANNELS.md) |
fallbackChannel |
string |
β | Default notification channel when no workspace match found |
maxSessions |
number |
20 |
Maximum concurrent sessions |
maxAutoResponds |
number |
10 |
Max consecutive auto-responds before requiring user input |
permissionMode |
string |
"plan" |
Plugin orchestration mode: "default" / "plan" / "acceptEdits" / "bypassPermissions" |
idleTimeoutMinutes |
number |
15 |
Idle timeout before auto-kill |
sessionGcAgeMinutes |
number |
1440 |
TTL for completed/failed/killed runtime sessions before GC eviction |
maxPersistedSessions |
number |
10000 |
Max completed sessions kept for resume; the 24h GC TTL (sessionGcAgeMinutes) is the primary retention control |
planApproval |
string |
"delegate" |
"approve" (orchestrator can auto-approve) / "ask" (always forward to user) / "delegate" (orchestrator decides) |
defaultHarness |
string |
"claude-code" |
Default harness for new sessions ("claude-code" / "codex") |
harnesses |
object |
built-in defaults | Per-harness defaults and restrictions. Built-in defaults: claude-code.defaultModel = "sonnet", claude-code.allowedModels = ["sonnet","opus"], codex.defaultModel = "gpt-5.4", codex.allowedModels = ["gpt-5.4"], codex.reasoningEffort = "medium", codex.approvalPolicy = "on-request" |
defaultWorkdir |
string |
β | Default working directory for new sessions |
Permission modes are shared at the plugin API, but each harness maps them differently:
- Claude Code harness
default,plan,acceptEdits,bypassPermissionsare passed through the SDK
- Codex harness
- Always runs with SDK thread option
sandboxMode: "danger-full-access" - Uses Codex SDK/CLI
approvalPolicy: "on-request"by default, or"never"whenharnesses.codex.approvalPolicyis set - Supports
harnesses.codex.defaultModel,harnesses.codex.allowedModels,harnesses.codex.reasoningEffort, andharnesses.codex.approvalPolicy - In
bypassPermissions, the harness adds filesystem root (/on POSIX) to CodexadditionalDirectories, plus optional extras fromOPENCLAW_CODEX_BYPASS_ADDITIONAL_DIRS(comma-separated) setPermissionMode()is applied by recreating the thread on the next turn viaresumeThread(same thread ID)plan/acceptEditsremain plugin behavioral orchestration constraints (planning/approval flow), not Codex sandbox or SDK approval settings
- Always runs with SDK thread option
OPENCLAW_CODE_AGENT_SESSIONS_PATHβ explicit persisted session index pathOPENCLAW_HOMEβ base dir for persisted session index when explicit path is unset ($OPENCLAW_HOME/code-agent-sessions.json)OPENCLAW_CODEX_BYPASS_ADDITIONAL_DIRSβ comma-separated extra directories for Codex bypass modeOPENCLAW_CODEX_HEARTBEAT_MSβ Codex activity heartbeat interval in milliseconds (default10000)
- Active sessions live in runtime memory (
SessionManager.sessions) - Terminal sessions are persisted with metadata/output stubs for resume and listing
- Runtime records are evicted after
sessionGcAgeMinutes(default 1440 / 24h) - Eviction means removed from runtime cache, not deleted permanently; persisted session records remain resumable
{
"plugins": {
"entries": {
"openclaw-code-agent": {
"enabled": true,
"config": {
"maxSessions": 3,
"harnesses": {
"codex": {
"defaultModel": "gpt-5.4",
"allowedModels": ["gpt-5.4"],
"reasoningEffort": "high",
"approvalPolicy": "on-request"
},
"claude-code": {
"defaultModel": "sonnet",
"allowedModels": ["sonnet", "opus"]
}
},
"permissionMode": "plan",
"fallbackChannel": "telegram|my-bot|123456789",
"agentChannels": {
"/home/user/project-alpha": "telegram|my-bot|123456789",
"/home/user/project-beta": "telegram|ops-bot|987654321"
}
}
}
}
}
}Example orchestration skill (click to expand)
The plugin is a transparent transport layer β business logic lives in OpenClaw skills:
---
name: Coding Agent Orchestrator
description: Orchestrates coding agent sessions with auto-response rules.
metadata: {"openclaw": {"requires": {"plugins": ["openclaw-code-agent"]}}}
---
# Coding Agent Orchestrator
## Anti-cascade rule
When woken by a waiting-for-input or completion event, ONLY use agent_respond
or agent_output for the referenced session. NEVER launch new sessions from wake events.
## Auto-response rules
When a coding agent session asks a question, analyze and decide:
### Auto-respond (use `agent_respond` immediately):
- Permission requests for file reads, writes, or bash commands -> "Yes, proceed."
- Confirmations like "Should I continue?" -> "Yes, continue."
### Forward to user (everything else):
- Architecture decisions, destructive operations, ambiguous requirements,
scope changes, credential/production questions
- Quote the agent's exact question. No commentary.
## Workflow
1. User sends a coding task -> `agent_launch(prompt, ...)`
2. Session runs in background. Monitor via wake events.
3. On wake event -> `agent_output` to read the question, then auto-respond or forward.
4. On completion -> summarize briefly: files changed, cost, duration, issues.A comprehensive orchestration skill is available at skills/code-agent-orchestration/SKILL.md.
For a detailed look at how the plugin works internally, see the docs/ directory:
| Document | Description |
|---|---|
| docs/ARCHITECTURE.md | System design, component breakdown, and data flow |
| docs/NOTIFICATIONS.md | Notification architecture, delivery model, and wake mechanism |
| docs/AGENT_CHANNELS.md | Multi-agent setup, notification routing, and workspace mapping |
| docs/TOOLS.md | Detailed tool reference with parameters and examples |
| docs/DEVELOPMENT.md | Development guide, project structure, and build instructions |
Build output is an ESM bundle at dist/index.js (package.json has "type": "module").
# Install dependencies
pnpm install
# Build (esbuild β dist/index.js)
pnpm run build
# Type-check
pnpm run typecheck
# Run tests
pnpm testopenclaw-code-agent/
βββ index.ts # Plugin entry point
βββ openclaw.plugin.json # Plugin manifest & config schema
βββ src/
β βββ harness/ # Agent harness abstraction layer
β β βββ types.ts # AgentHarness interface & message types
β β βββ claude-code.ts # Claude Code harness (SDK wrapper)
β β βββ codex.ts # Codex harness (@openai/codex-sdk thread stream wrapper)
β β βββ index.ts # Harness registry
β βββ types.ts # TypeScript interfaces
β βββ config.ts # Config singleton + channel resolution
β βββ format.ts # Formatting utilities
β βββ singletons.ts # Module-level singleton refs
β βββ session.ts # Session class (state machine, timers, harness)
β βββ session-manager.ts # Session pool management + lifecycle
β βββ session-store.ts # Persisted session/index storage abstraction
β βββ session-metrics.ts # Metrics recorder abstraction
β βββ wake-dispatcher.ts # Wake delivery + retry abstraction
β βββ notifications.ts # Notification service
β βββ actions/respond.ts # Shared respond logic (tool + command)
β βββ application/ # Shared app-layer logic used by tools + commands
β βββ tools/ # Tool implementations (6 tools)
β βββ commands/ # Chat command implementations (7 commands)
βββ tests/ # Unit tests (node:test + tsx)
βββ skills/ # Orchestration skill definitions
βββ docs/ # Architecture & reference docs
- Plugin installed but the gateway does not see it yet: run
openclaw gateway restart. - Notifications are not arriving: verify
fallbackChanneluses the exact format"telegram|bot-name|chat-id"in~/.openclaw/openclaw.json.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes with tests
- Submit a pull request
MIT β see LICENSE for details.
Originally based on alizarion/openclaw-claude-code-plugin. Renamed to openclaw-code-agent to be harness-agnostic.

