- Rust 35.6%
- JavaScript 24.3%
- HTML 16%
- Python 11.7%
- CSS 8.9%
- Other 3.5%
|
|
||
|---|---|---|
| .forgejo/workflows | ||
| crates | ||
| examples | ||
| .gitignore | ||
| .python-version | ||
| Cargo.toml | ||
| env.sh | ||
| install.sh | ||
| main.py | ||
| Makefile | ||
| pyproject.toml | ||
| README.md | ||
| uv.lock | ||
hero_claude — ACP Agent Control Protocol
Unix-socket JSON-RPC 2.0 server for controlling, inspecting, and coordinating AI agents.
Full spec: crates/hero_claude_server/openrpc.json
Architecture
hero_claude (CLI + lifecycle manager)
│
├── hero_claude_server Python ACP server ← unix socket: hero_claude_server.sock
├── hero_claude_sdk Rust client (auto-generated from openrpc.json)
├── hero_claude_ui Rust admin dashboard ← unix socket: hero_claude_ui.sock
└── hero_claude_examples usage examples
All communication uses Unix Domain Sockets only — no TCP, no HTTP.
Socket path: $HOME/hero/var/sockets/hero_claude_server.sock (or $ACP_SOCKET).
Lifecycle
hero_claude --start # register all components with hero_proc and start them
hero_claude --stop # stop all components via hero_proc
CLI reference
hero_claude ping
hero_claude health
# agents
hero_claude agent list [--status idle] [--kind worker]
hero_claude agent register --name mybot --kind worker [--version 1.0] [--description "..."]
hero_claude agent get <id>
hero_claude agent update <id>
hero_claude agent unregister <id>
hero_claude agent start <id>
hero_claude agent stop <id> [--reason "..."]
hero_claude agent restart <id>
hero_claude agent pause <id>
hero_claude agent resume <id>
hero_claude agent state <id>
hero_claude agent capabilities <id>
# tasks
hero_claude task submit --kind prompt [--agent-id <id>] [--prompt "Hello"] [--priority 50]
hero_claude task get <id>
hero_claude task list [--agent-id <id>] [--status running]
hero_claude task cancel <id> [--reason "..."]
hero_claude task retry <id>
hero_claude task result <id>
hero_claude task messages <id>
hero_claude task input <id>
hero_claude task steps <id>
hero_claude task logs <id>
# events
hero_claude event list [--agent-id <id>] [--task-id <id>] [--event-type task.completed] [--limit 20]
hero_claude event subscribe
hero_claude event unsubscribe <subscription-id>
hero_claude event poll <subscription-id>
# metrics
hero_claude metrics get [--agent-id <id>]
RPC methods
All methods follow JSON-RPC 2.0. Every list method supports limit/offset/cursor pagination
and returns a next_cursor field. Errors include a structured ErrorResponse in the data field.
Infrastructure
| Method | Description |
|---|---|
acp.ping |
Liveness check — returns ok, service name, timestamp |
acp.health |
Health status (ok/degraded/error) plus per-subsystem checks |
Agent lifecycle
| Method | Key params | Description |
|---|---|---|
acp.agent.list |
filter{status,kind,label_selector} |
List all registered agents |
acp.agent.register |
agent{name,kind,...} |
Register a new agent; returns agent_id |
acp.agent.update |
agent_id, update{...} |
Patch description, capabilities, labels, endpoint without re-registering |
acp.agent.unregister |
agent_id |
Remove an agent |
acp.agent.get |
agent_id |
Full agent record including status and last heartbeat |
acp.agent.start |
agent_id, input? |
Transition agent to running |
acp.agent.stop |
agent_id, reason? |
Stop a running agent |
acp.agent.restart |
agent_id |
Stop then start |
acp.agent.pause |
agent_id |
Suspend without stopping |
acp.agent.resume |
agent_id |
Resume a paused agent |
acp.agent.state |
agent_id |
Runtime state snapshot: status, current task, last error, heartbeat |
acp.agent.capabilities |
agent_id |
Declared capability list with input/output schemas |
acp.agent.heartbeat |
agent_id, state?, current_task_id? |
Agent reports liveness; server returns optional directive (stop/pause/restart) |
Agent statuses: created → idle → running → paused → stopped / error / stale
Task management
| Method | Key params | Description |
|---|---|---|
acp.task.submit |
task{kind,agent_id?,input,constraints?} |
Submit a task; returns task_id and initial status |
acp.task.get |
task_id |
Full task record including output, step/message counts, timing |
acp.task.list |
filter{agent_id,status,kind} |
List tasks with pagination |
acp.task.cancel |
task_id, reason? |
Cancel a queued or running task |
acp.task.retry |
task_id, agent_id?, constraints? |
Rerun a failed/cancelled task; returns new task_id linked via parent_task_id |
acp.task.result |
task_id |
Final output and artifact list |
acp.task.messages |
task_id, offset, limit |
Full conversation thread (user/assistant/system/tool roles) |
acp.task.input |
task_id, content |
Append a user message to an ongoing multi-turn task |
acp.task.steps |
task_id, offset, limit |
Execution steps: tool calls, results, reasoning, decisions |
acp.task.logs |
task_id, offset, limit, level? |
Raw log lines emitted during execution, filterable by level |
Task statuses: queued → running → completed / failed / cancelled / timed_out
Events
| Method | Key params | Description |
|---|---|---|
acp.event.list |
filter{agent_id,task_id,event_type,since} |
Query historical events |
acp.event.subscribe |
filter |
Open a subscription; server pushes acp.event.notification JSON-RPC notifications |
acp.event.unsubscribe |
subscription_id |
Cancel a subscription |
acp.event.poll |
subscription_id, limit |
Pull buffered events for clients that cannot handle push notifications |
Event types: agent.registered agent.updated agent.started agent.stopped agent.paused
agent.resumed agent.heartbeat agent.error agent.stale task.accepted task.started
task.progress task.step task.message task.completed task.failed task.cancelled
task.timed_out task.retried
Metrics
| Method | Key params | Description |
|---|---|---|
acp.metrics.get |
scope{agent_id?,task_id?,window?} |
Metric points for the ACP service or a specific agent/task over a time window (1m/5m/15m/1h/24h) |
Rust SDK
use hero_claude_sdk::*;
let client = AcpClient::connect_socket(&default_socket()).await?;
// health check
let h = client.acp_health(AcpHealthInput {}).await?;
// submit a task
let t = client.acp_task_submit(AcpTaskSubmitInput {
task: serde_json::json!({ "kind": "prompt", "input": { "prompt": "Hello" } }),
}).await?;
// read back messages
let msgs = client.acp_task_messages(AcpTaskMessagesInput {
task_id: t.task_id,
offset: None,
limit: None,
}).await?;
The SDK is generated at compile time from openrpc.json via hero_rpc_derive::openrpc_client!.
Changing the spec automatically updates the client — no manual sync needed.
Environment
| Variable | Default | Purpose |
|---|---|---|
ACP_SOCKET |
$HOME/hero/var/sockets/hero_claude_server.sock |
Socket path used by CLI and SDK |
RUST_LOG |
info |
Tracing log level |