@axiom-lattice/cli-a2a

中文文档
0.2.32发布于 2026/11/03ISCTypeScriptESM + CJS近 30 天下载 2942

Multi-provider A2A (Agent-to-Agent) CLI gateway wrapping local coding agents (OpenCode, Codex, Claude Code) as spec-compliant A2A servers

原始使用文档
文档目录23 节
  1. Quick Start
  2. Providers
  3. Usage
  4. Options
  5. OpenCode Options
  6. Codex Options
  7. Claude Code Options
  8. Gateway Registration
  9. Configuration File
  10. Environment Variables
  11. Endpoints
  12. Programmatic API
  13. Multi-Turn Conversations
  14. Session Persistence
  15. Session Config
  16. Architecture
  17. Networking — Exposing to External Networks
  18. Built-in WebSocket Bridge (Recommended)
  19. SSH Reverse Tunnel (Alternative)
  20. Same Network
  21. Multi-Project
  22. Package Exports
  23. License

@axiom-lattice/cli-a2a

Multi-provider A2A (Agent-to-Agent) CLI gateway. Wraps local coding agents (OpenCode, Codex, Claude Code) as spec-compliant A2A servers. Drop a JSON config, get a fully spec-compliant A2A agent — launchable via npx.

Quick Start

# 1. Start your local OpenCode server
opencode serve

# 2. Launch the A2A gateway
npx @axiom-lattice/cli-a2a --provider opencode --port 3000

# 3. Verify
curl http://localhost:3000/health
# → { "status": "healthy", "agent": "CLI A2A Agent", "provider": "opencode" }

curl http://localhost:3000/.well-known/agent-card.json
# → A2A v0.3 AgentCard JSON

Providers

ProviderStatusConnection
opencode✅ ReadyHTTP API (opencode serve)
codex✅ ReadyCLI subprocess (codex)
claude✅ ReadyCLI subprocess (claude -p)

Usage

npx @axiom-lattice/cli-a2a [options]

Options

  --provider <name>            Provider: opencode | codex | claude
  --config, -c <path>          Path to agent JSON config file
  --port, -p <number>          A2A server port (default: 3000)
  --hostname <addr>            Bind address (default: 0.0.0.0)
  --advertise-host <host>      Hostname for agent card URLs
  --agent-name <name>          Agent display name
  --agent-description <desc>   Agent description
  --log-level <level>          debug | info | warn | error (default: info)

OpenCode Options

  --opencode-url <url>         OpenCode server URL (default: http://localhost:4096)
  --directory, -d <path>       Project directory
  --model, -m <provider/model> LLM model
  --agent <name>               OpenCode agent preset

Codex Options

  --codex-model <model>        Codex model ID (e.g. gpt-4o)
  --codex-api-key <key>        OpenAI API key

Claude Code Options

  --claude-model <model>       Claude Code model ID
  --claude-api-key <key>       Anthropic API key

Gateway Registration

The CLI can auto-register with an @axiom-lattice/gateway server so the gateway discovers and routes to it as a first-class remote agent.

  --register-url <url>         Gateway URL to register this agent with
  --register-key <key>         API key for gateway authentication
  --unregister-on-shutdown     Remove agent from gateway on exit
npx @axiom-lattice/cli-a2a \
  --provider opencode \
  --port 3001 \
  --register-url http://gateway:8080 \
  --register-key sk-a2a-gateway-key \
  --unregister-on-shutdown &

On startup the CLI POSTs to {registerUrl}/api/assistants with a graphDefinition of type a2a_remote pointing to its own agent card. On exit (if --unregister-on-shutdown) it DELETEs the assistant.

After registration the agent appears alongside all other agents in the gateway and can be invoked via the standard /api/runs endpoint.

Configuration File

{
  "provider": "opencode",
  "agentCard": {
    "name": "My Coding Agent",
    "description": "A coding assistant powered by OpenCode",
    "skills": [
      {
        "id": "code-gen",
        "name": "Code Generation",
        "description": "Generate and refactor code",
        "tags": ["coding", "typescript"]
      }
    ]
  },
  "server": {
    "port": 3000,
    "advertiseHost": "localhost"
  },
  "opencode": {
    "baseUrl": "http://localhost:4096",
    "projectDirectory": "/path/to/project",
    "model": "anthropic/claude-sonnet-4"
  },
  "features": {
    "autoApprovePermissions": true,
    "streamArtifactChunks": false
  },
  "timeouts": {
    "prompt": 600000
  }
}

Config layers merge in priority order: defaults ← config file ← env vars ← CLI args.

Environment Variables

VariableMaps to
OPENCODE_URLopencode.baseUrl
OPENCODE_DIRECTORYopencode.projectDirectory
OPENCODE_MODELopencode.model
OPENCODE_AGENTopencode.agent
OPENAI_API_KEYcodex.apiKey
ANTHROPIC_API_KEYclaude.apiKey

Endpoints

MethodPathDescription
GET/healthHealth check
GET/.well-known/agent-card.jsonA2A Agent Card
POST/a2a/jsonrpcA2A JSON-RPC transport
POST/a2a/restA2A REST transport

Programmatic API

import {
  createA2AServer,
  resolveConfig,
  registerExecutor,
  createOpenCodeExecutor,
  createCodexExecutor,
  createClaudeExecutor,
  SessionBindingStore,
} from '@axiom-lattice/cli-a2a';

// Register executors
registerExecutor('opencode', createOpenCodeExecutor);
registerExecutor('codex', createCodexExecutor);
registerExecutor('claude', createClaudeExecutor);

// Load config
const config = resolveConfig('agent-config.json');

// Start server
const server = await createA2AServer(config);

// Graceful shutdown
process.on('SIGINT', async () => {
  await server.shutdown();
  process.exit(0);
});

Multi-Turn Conversations

The A2A protocol uses contextId to group messages into a single conversation. cli-a2a maps each contextId to an underlying CLI session, enabling multi-turn continuity across all three providers:

ProviderNew SessionResume SessionSession ID Source
Codexcodex exec --json <prompt>codex exec resume <thread_id> <prompt>thread_id from JSONL thread.started event
Claude Codeclaude -p --session-id <uuid> <prompt>claude -p --resume <uuid> <prompt>Generated UUID
OpenCodeopencode run --format json <prompt>opencode run --session <sessionID> <prompt>sessionID from JSON events

How it works:

  1. The A2A client sends a message with a contextId
  2. cli-a2a looks up the contextId in the SessionBindingStore
  3. If found: uses the provider's resume command to continue the CLI session
  4. If not found: creates a new CLI session and saves the binding
  5. Subsequent messages with the same contextId reuse the same CLI session

History is maintained by the underlying CLI tool — no prompt concatenation needed.

Session Persistence

Bindings are persisted to disk so that cli-a2a restarts preserve conversations:

  • Default path: ~/Library/Application Support/axiom-lattice/cli-a2a/sessions.json
  • Format: JSON array of { provider, contextId, sessionId, ... }
  • TTL: 24 hours by default (configurable via session.ttl)
  • Cleanup: Expired bindings removed on load and periodically (every 1h)

To disable persistence:

{
  "session": {
    "persist": false
  }
}

To disable session reuse entirely (each request creates a new session):

{
  "session": {
    "reuseByContext": false
  }
}

Session Config

{
  "session": {
    "reuseByContext": true,
    "persist": true,
    "storePath": "~/custom/path/sessions.json",
    "ttl": 86400000,
    "cleanupInterval": 3600000
  }
}
FieldDefaultDescription
reuseByContexttrueMap contextId to CLI session for multi-turn
persisttrueSave bindings to disk across restarts
storePath~/Library/Application Support/axiom-lattice/cli-a2a/sessions.jsonCustom binding store path
ttl86400000 (24h)Session TTL in milliseconds
cleanupInterval3600000 (1h)Cleanup interval in milliseconds

Architecture

┌──────────────────────────────────────────────────────┐
│  cli-a2a (Express A2A Server)                        │
│                                                      │
│  ┌─────────────┐  ┌──────────┐  ┌──────────────────┐│
│  │ Agent Card  │  │ JSON-RPC │  │ REST             ││
│  └─────────────┘  └──────────┘  └──────────────────┘│
│                         │                            │
│  ┌──────────────────────▼───────────────────────────┐│
│  │  Executor Registry                                ││
│  │  ┌────────────┐ ┌─────────┐ ┌──────────────────┐ ││
│  │  │ OpenCode   │ │ Codex   │ │ Claude Code      │ ││
│  │  │ Executor   │ │ Executor│ │ Executor         │ ││
│  │  └─────┬──────┘ └────┬────┘ └───────┬──────────┘ ││
│  └────────┼─────────────┼──────────────┼────────────┘│
│           │             │              │              │
│  ┌────────▼─────────────▼──────────────▼────────────┐│
│  │  SessionBindingStore                              ││
│  │  contextId → CLI sessionId + file persistence     ││
│  └──────────────────────────────────────────────────┘│
└───────────┼─────────────┼──────────────┼─────────────┘
            │ HTTP        │ spawn        │ spawn
    ┌───────▼────────┐ ┌──▼───────┐ ┌───▼────────────┐
    │ opencode serve │ │ codex CLI│ │ claude CLI (-p) │
    └────────────────┘ └──────────┘ └────────────────┘

Networking — Exposing to External Networks

The agent runs a local HTTP server. To reach it from outside, use the built-in WebSocket bridge (no SSH tunnel or ngrok required).

# Agent — opens outbound WebSocket to gateway
npx @axiom-lattice/cli-a2a \
  --provider opencode \
  --port 3001 \
  --bridge-url ws://gateway:8080/api/a2a/bridge \
  --bridge-key sk-xxx \
  --register-url http://gateway:8080 \
  --register-key sk-xxx
Internal Network (agent)           Public (gateway)
┌──────────────────┐              ┌─────────────────────┐
│ cli-a2a :3001    │──WebSocket──→│ /api/a2a/bridge     │
│   ↑              │   outbound   │   ↑                 │
│   │ local call   │              │   │ HTTP proxy      │
│   │              │              │ /api/a2a/bridge/    │
│ Express A2A      │              │   proxy/{agentId}/* │
│ OpenCode/Codex/  │              │                     │
│ Claude           │              │ A2A_REMOTE agent →  │
└──────────────────┘              └─────────────────────┘

How it works:

  1. Agent opens an outbound WebSocket to gateway (outbound almost never blocked)
  2. Gateway stores the connection keyed by agent ID
  3. Gateway exposes GET/POST /api/a2a/bridge/proxy/{agentId}/*
  4. When the orchestrator calls the proxy URL, gateway pushes the request over WebSocket
  5. Agent makes a local HTTP call to its Express server, returns the response

The agent's agentCardUrl in registration points to http://gateway:8080/api/a2a/bridge/proxy/{agentId}/.well-known/agent-card.json.

SSH Reverse Tunnel (Alternative)

ssh -R 3001:localhost:3001 [email protected] -N &
npx cli-a2a --provider opencode --port 3001 \
  --advertise-host public-bastion.com \
  --register-url http://gateway:8080 --register-key sk-xxx

Same Network

npx cli-a2a --provider opencode --port 3001 \
  --advertise-host 192.168.1.42 \
  --register-url http://gateway:8080 --register-key sk-xxx

Multi-Project

Run multiple instances on different ports for different projects:

npx @axiom-lattice/cli-a2a --provider opencode -d /proj/frontend --port 3001 &
npx @axiom-lattice/cli-a2a --provider opencode -d /proj/backend  --port 3002 &

Package Exports

ExportDescription
createA2AServer(config)Start an Express A2A server
resolveConfig(path?, overrides?)Merge config layers
loadConfigFile(path)Read and parse a JSON config file
registerExecutor(provider, factory)Register an executor factory
createOpenCodeExecutor(config, store)Create an OpenCode executor
createCodexExecutor(config, store)Create a Codex executor
createClaudeExecutor(config, store)Create a Claude executor
SessionBindingStorecontextId → sessionId persistence
generateContextId()Generate a new UUID contextId
logger, LogLevelStructured logger

License

ISC

版本与发布记录

@axiom-lattice/cli-a2a 共发布 43 个版本,首次发布于 2026/06/11;过去 12 个月发布了 43 个版本。

版本发布日期距今
0.2.32latest2026/11/034 天前
0.2.312026/11/025 天前
0.2.302026/10/317 天前
0.2.292026/10/299 天前
0.2.282026/10/2810 天前
0.2.272026/10/2612 天前

关于 @axiom-lattice/cli-a2a 的常见问题

@axiom-lattice/cli-a2a 是什么?

Multi-provider A2A (Agent-to-Agent) CLI gateway wrapping local coding agents (OpenCode, Codex, Claude Code) as spec-compliant A2A servers

如何安装 @axiom-lattice/cli-a2a?

在项目目录运行 npm install @axiom-lattice/cli-a2a,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:uuid(^9.0.1)、express(^5.1.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。它还提供命令行工具 cli-a2a,可以用 npx cli-a2a 直接运行。

@axiom-lattice/cli-a2a 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@axiom-lattice/cli-a2a 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@axiom-lattice/cli-a2a 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.10.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@axiom-lattice/cli-a2a 可以商用吗?

@axiom-lattice/cli-a2a 使用 ISC 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@axiom-lattice/cli-a2a 的下载量有多少?

根据 npm 官方下载统计,@axiom-lattice/cli-a2a 在 2026/10/08 – 2026/11/06 这 30 天内被下载 2,942 次,日均约 98 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@axiom-lattice/cli-a2a 还在维护吗?

最新版本 0.2.32 发布于 2026/11/03(4 天前);至今共发布 43 个版本,其中过去 12 个月发布了 43 个;首次发布于 2026/06/11。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。