Preparing your workspace...

assistant-chat.tsx2.5k
utils.ts850
button.tsx720
Quick Actions
codmir
Docs
Discord
Get started
API
  • Introduction
  • Installation
  • Your First Project
  • Your First Agent

The WebSocket message protocol between Codmir clients and the daemon's agent system

Agent Protocol

The daemon's agent system uses a bidirectional WebSocket protocol. Clients send commands and receive events. All messages are JSON with a type field that determines the shape.

Commands (client → daemon)

Start a session

{
  "type": "agent:start",
  "task": "Fix the login bug in auth.ts",
  "cwd": "/Users/you/projects/myapp",
  "model": "claude-sonnet-4-20250514",
  "maxIterations": 50,
  "autoApprove": ["safe"]
}
FieldTypeRequiredDescription
taskstringyesThe user's instruction
cwdstringnoWorking directory (defaults to daemon's cwd)
modelstringnoModel to use (default: claude-sonnet-4-20250514)
maxIterationsnumbernoMax tool-use loops (default: 50)
autoApprovestring[]noDanger levels to auto-approve: safe, moderate, dangerous

Send a follow-up message

{
  "type": "agent:message",
  "sessionId": "sess_abc123",
  "content": "Actually, also fix the logout flow"
}

Approve a tool call

{
  "type": "agent:approve",
  "sessionId": "sess_abc123",
  "toolCallId": "tc_xyz789"
}

Deny a tool call

{
  "type": "agent:deny",
  "sessionId": "sess_abc123",
  "toolCallId": "tc_xyz789",
  "reason": "Don't run rm -rf"
}

Cancel a session

{
  "type": "agent:cancel",
  "sessionId": "sess_abc123"
}

List sessions / Get session

{ "type": "agent:list" }
{ "type": "agent:get", "sessionId": "sess_abc123" }

Events (daemon → client)

Events are broadcast to all connected WebSocket clients. Both the desktop app and IDE extension receive every event.

agent:started

Fired when a new agent session begins.

{
  "type": "agent:started",
  "session": {
    "id": "sess_abc123",
    "task": "Fix the login bug",
    "status": "running",
    "iteration": 0,
    "maxIterations": 50,
    "createdAt": 1718000000000,
    "cwd": "/Users/you/projects/myapp",
    "model": "claude-sonnet-4-20250514"
  }
}

agent:thinking

Streamed thinking/reasoning content. Arrives in chunks as the LLM generates.

{
  "type": "agent:thinking",
  "sessionId": "sess_abc123",
  "content": "Let me look at the auth.ts file first..."
}

agent:tool_call

The agent wants to use a tool.

{
  "type": "agent:tool_call",
  "sessionId": "sess_abc123",
  "toolCall": {
    "id": "tc_xyz789",
    "tool": "read_file",
    "input": { "path": "src/auth.ts" },
    "danger": "safe",
    "requiresApproval": false,
    "approved": true,
    "result": null
  }
}

agent:approval_required

The agent wants to use a dangerous tool and needs user approval. The session pauses until an agent:approve or agent:deny command is received.

{
  "type": "agent:approval_required",
  "sessionId": "sess_abc123",
  "toolCall": {
    "id": "tc_xyz789",
    "tool": "shell",
    "input": { "command": "npm test" },
    "danger": "dangerous",
    "requiresApproval": true,
    "approved": null,
    "result": null
  }
}

agent:shell_output

Real-time output chunks from a running tool (shell commands, Python scripts). Streamed as the process produces output.

{
  "type": "agent:shell_output",
  "sessionId": "sess_abc123",
  "toolCallId": "tc_xyz789",
  "chunk": "PASS src/auth.test.ts\n"
}

agent:tool_result

A tool call has completed.

{
  "type": "agent:tool_result",
  "sessionId": "sess_abc123",
  "result": {
    "toolCallId": "tc_xyz789",
    "tool": "read_file",
    "success": true,
    "output": "import { verify } from 'jsonwebtoken';\n...",
    "error": null,
    "durationMs": 12
  }
}

agent:message

The agent has produced a response message (complete, not streamed).

{
  "type": "agent:message",
  "sessionId": "sess_abc123",
  "message": {
    "role": "assistant",
    "content": "I've fixed the login bug. The issue was...",
    "timestamp": 1718000005000
  }
}

agent:completed

The session has finished successfully.

{
  "type": "agent:completed",
  "session": { "id": "sess_abc123", "status": "completed", "..." : "..." }
}

agent:failed / agent:cancelled

{
  "type": "agent:failed",
  "sessionId": "sess_abc123",
  "error": "Token budget exceeded (500000 tokens)"
}
{
  "type": "agent:cancelled",
  "sessionId": "sess_abc123",
  "message": "Session cancelled by user"
}

agent:list

Response to an agent:list command.

{
  "type": "agent:list",
  "sessions": [
    { "id": "sess_abc123", "task": "Fix login", "status": "completed", "..." : "..." },
    { "id": "sess_def456", "task": "Add tests", "status": "running", "..." : "..." }
  ]
}

Event flow diagram

A typical agent interaction follows this pattern:

Client                          Daemon                          LLM
  │                               │                              │
  │  agent:start(task)            │                              │
  ├──────────────────────────────→│                              │
  │                               │  messages.create(task)       │
  │                               ├─────────────────────────────→│
  │     agent:started(session)    │                              │
  │←──────────────────────────────┤                              │
  │                               │     thinking chunks          │
  │     agent:thinking(chunk)     │←─────────────────────────────┤
  │←──────────────────────────────┤                              │
  │                               │     tool_use: read_file      │
  │     agent:tool_call(tc)       │←─────────────────────────────┤
  │←──────────────────────────────┤                              │
  │                               │  executeTool(read_file)      │
  │     agent:tool_result(r)      │──→ local filesystem          │
  │←──────────────────────────────┤                              │
  │                               │     tool_use: shell (danger) │
  │     agent:approval_required   │←─────────────────────────────┤
  │←──────────────────────────────┤                              │
  │                               │  ⏸ waiting_approval          │
  │  agent:approve(toolCallId)    │                              │
  │──────────────────────────────→│                              │
  │                               │  executeTool(shell)          │
  │     agent:shell_output(chunk) │──→ spawns bash process       │
  │←──────────────────────────────┤                              │
  │     agent:tool_result(r)      │                              │
  │←──────────────────────────────┤                              │
  │                               │  messages.create(results)    │
  │                               ├─────────────────────────────→│
  │                               │     end_turn + text          │
  │     agent:message(content)    │←─────────────────────────────┤
  │←──────────────────────────────┤                              │
  │     agent:completed(session)  │                              │
  │←──────────────────────────────┤                              │

Session states

starting → running ⇄ waiting_approval → completed
                                       → failed
                                       → cancelled
StateDescription
startingSession created, first LLM call about to begin
runningAgent loop active — thinking, calling tools, or waiting for LLM response
waiting_approvalA dangerous tool call needs user approval before execution
completedAgent finished its task (LLM returned end_turn with no tool calls)
failedAn error occurred (token budget, timeout, LLM error)
cancelledUser sent agent:cancel

Limits

LimitDefaultDescription
Max iterations50Maximum tool-use loop cycles per session
Token budget500,000Maximum total tokens (input + output)
Runtime30 minutesMaximum wall-clock time per session
Shell timeout30 secondsPer-command timeout for shell tool
Python timeout60 secondsPer-execution timeout for python tool

Using KernelClient

The @codmir/kernel package exports a KernelClient class that wraps the WebSocket protocol:

import { KernelClient } from '@codmir/kernel/client';

const client = new KernelClient(7700);
client.connect();

// Listen for events
client.onAgentSession((session) => {
  console.log('Session started:', session.id);
});

client.onAgentThinking((sessionId, content) => {
  process.stdout.write(content);
});

client.onAgentToolCall((sessionId, toolCall) => {
  console.log(`Tool: ${toolCall.tool}`, toolCall.input);
});

client.onAgentApproval((sessionId, toolCall) => {
  // Auto-approve safe tools, prompt for dangerous ones
  if (toolCall.danger === 'safe') {
    client.agentApprove(sessionId, toolCall.id);
  }
});

client.onAgentMessage((sessionId, message) => {
  console.log('Response:', message.content);
});

// Start a session
client.agentStart('Fix the login bug in auth.ts', {
  cwd: '/path/to/project',
});
Open in ChatGPTOpen in ClaudeConnect MCP on CursorConnect MCP on WindsurfEdit on GitHub
codmir
Products
Desktop AppMobile AppIDE ExtensionAI AgentsOverseerVoice ModeCortex ProtocolHive MindGame Dev (Godat)PricingDownload
Solutions
AI Code AgentsCode ReviewError TrackingSelf-HealingDeploy TrackingAI Tracking SDKWorkflow AutomationTesting FrameworkTime TrackingVoice Control
Platform
ProjectsTickets & BoardsAgent MarketplaceIntegrationsTemplatesApp HubAdmin PanelAnalytics
Integrations
GitHubSlackDiscordVercelSentryRailwayLinearAll Integrations
Developers
DocumentationAPI ReferenceSDKCLIDeveloper PortalMarketplaceMCP ConnectorsWebhooksExamplesnpm Packages
Resources
BlogChangelogCommunityTutorialsGet StartedSupportStatusFeedback
Company
AboutCareersContact SalesKickstarterReferral Program
Legal
Terms of UsePrivacy PolicyEULATrademarkSecurity
Download on the App StoreGet it on Google Play

Codmir™ 2026. All rights reserved.

Free & open source SDK — Apache 2.0 License