@buihongduc132/pi-acp-agents 0.3.1 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @buihongduc132/pi-acp-agents
2
2
 
3
- > Multi-agent orchestration for pi — spawn, control, and coordinate ACP-compatible agents (Gemini CLI, Claude, Codex, etc.) as first-class tools within the pi coding agent.
3
+ > Multi-agent orchestration for pi — spawn, control, and coordinate ACP-compatible agents (Gemini CLI, Claude, Codex, custom) as first-class tools within the pi coding agent.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@buihongduc132/pi-acp-agents.svg)](https://www.npmjs.com/package/@buihongduc132/pi-acp-agents)
6
6
  [![CI](https://github.com/buihongduc132/pi-acp-agents/actions/workflows/ci.yml/badge.svg)](https://github.com/buihongduc132/pi-acp-agents/actions/workflows/ci.yml)
@@ -8,26 +8,97 @@
8
8
 
9
9
  ---
10
10
 
11
- ## Features
11
+ ## Table of Contents
12
+
13
+ - [What works vs what does not](#what-works-vs-what-does-not) ← **read this first**
14
+ - [Install](#install)
15
+ - [Quick start](#quick-start)
16
+ - [Tool surface](#tool-surface)
17
+ - [DAG delegation](#dag-delegation)
18
+ - [Alias resolver + fallback chains](#alias-resolver--fallback-chains)
19
+ - [Persistent workers](#persistent-workers)
20
+ - [Configuration](#configuration)
21
+ - [Architecture](#architecture)
22
+ - [Resilience](#resilience)
23
+ - [Logs](#logs)
24
+ - [Supported agents](#supported-agents)
25
+ - [Development](#development)
26
+ - [Release process](#release-process)
27
+ - [Further documentation](#further-documentation)
12
28
 
13
- - Registers 10 pi tools for ACP agent management
14
- - Manages session lifecycle (create, load, set model/mode, cancel, dispose)
15
- - Provides multi-agent coordination (delegate, broadcast, compare)
16
- - Resilient by default: circuit breaker, stall timeout, health polling
17
- - TUI widget for real-time session status
18
- - Adapter pattern: one config format for any ACP agent
29
+ ---
30
+
31
+ ## What works vs what does not
32
+
33
+ Status as of `0.4.0`. Verified by full test suite (`npx vitest run` → 1627 passed / 0 failed / 83 skipped / 1 todo). Counts: **16 tools registered** (verified via `rg -c 'pi.registerTool' index.ts`), **42 entries** in `ACP_TOOL_NAMES` legacy schema.
34
+
35
+ ### ✅ Working
36
+
37
+ | Capability | Notes |
38
+ |---|---|
39
+ | `acp_prompt` (single agent) | Session create / reuse / archive-reload |
40
+ | `acp_status` (diagnostic) | Agent list, sessions, circuit breaker |
41
+ | `acp_cancel` (in-flight prompt abort) | Calls `adapter.cancel()`, archives handle |
42
+ | `acp_broadcast` (one prompt → N agents) | Scoped to caller session's agents |
43
+ | `acp_task_create` / `acp_task_update` | Multiplexed: status / assignee / deps / bulk `*` filter |
44
+ | `acp_message` (send + list) | DM / steer / broadcast via `kind` param |
45
+ | `acp_dag_submit` / `acp_dag_status` / `acp_dag_cancel` | Wave-based topological DAG execution, persistent resume |
46
+ | `acp_worker_spawn` / `_list` / `_steer` / `_shutdown` / `_kill` / `_prune` | Persistent named workers in `WorkerStore` |
47
+ | **Alias resolver** (failover + race) | `AliasResolver` class — sequential fallback OR parallel first-wins with cancel of losers |
48
+ | **Circuit breaker** | 3 failures → open, 60s → half-open, auto-recover |
49
+ | **Health monitor** | 30s background polling; distinct no-response vs completed-idle timers |
50
+ | **Session-scoped stores** | `tasks`/`mailboxes`/`governance`/`workers` partitioned per host session ID; `session-archive`/`session-name-registry`/`event-log` global |
51
+ | **Legacy migration** | Non-destructive flat → `legacy/` on first run after partitioning |
52
+ | **DAG widget** | `dagIndexEntryToWidgetDag` helper renders DAG state in TUI |
53
+ | **TUI widget** | Real-time session + DAG status panel |
54
+ | **Gemini CLI adapter** | Auto-auth, default |
55
+ | **Custom adapter** | Any ACP-speaking stdio agent |
56
+ | **Stall timeout** | Per-op with SIGTERM → SIGKILL escalation |
57
+ | **EPIPE safety** | stdin/stdout broken-pipe handled |
58
+ | **Tag-triggered CI publish** | `git push --follow-tags` → npm publish with provenance |
59
+
60
+ ### ❌ Not working / not implemented
61
+
62
+ | Gap | Status |
63
+ |---|---|
64
+ | **One-call parallel batch delegate** | No `acp_delegate_parallel` — must `acp_worker_spawn` × N + `acp_prompt` × N |
65
+ | **Plan approval flow as tool** | `acp_plan_request` / `acp_plan_resolve` are command-only stubs, not tools |
66
+ | **Hooks policy** | No `hooks_policy_*` — retry governance absent |
67
+ | **Model policy as tool** | `acp_model_policy_get` / `_check` are command-only |
68
+ | **Predefined teams** | No `predefined_teams_*` |
69
+ | **Workspace isolation (worktree mode)** | Workers use `cwd` only — no `git worktree` isolation |
70
+ | **Context inheritance** | No `contextMode: "branch"` (clone leader session) |
71
+ | **`task_dep_ls`** | Only add/rm via `task_update` — cannot list blockers |
72
+ | **`task_get` (single)** | Not exposed — only create + update |
73
+ | **Diagnostics as tools** | `acp_doctor`, `acp_runtime_info`, `acp_event_log`, `acp_env`, `acp_cleanup` are slash commands only |
74
+ | **Session lifecycle tools** | `acp_session_list` / `_shutdown` / `_kill` / `_prune` / `_set_model` / `_set_mode` are not exposed (automation-only) |
75
+ | **Streaming responses** | Planned — currently returns after full prompt completes |
76
+ | **Tool use forwarding** | Planned — ACP agent tool calls not relayed back to pi |
77
+ | **OAuth / token auth** | Planned — env vars only |
78
+ | **Config hot-reload** | Manual restart required |
79
+ | **Retry with backoff** | Circuit breaker handles fail-closed; no exponential backoff |
80
+ | **Session sharing across pi instances** | Single-host only |
81
+ | **Metrics export (Prometheus)** | Planned |
82
+ | **Agent routing (auto-select)** | Manual via alias or explicit |
83
+ | **Ensemble / chain-of-agents** | Manual via DAG composition |
84
+ | **Cost tracking** | Planned |
85
+ | **Claude Code / Codex ACP adapters** | Pending upstream ACP mode |
86
+
87
+ ### ⚠️ Known surface drift
88
+
89
+ `src/settings/config.ts` ships a legacy `ACP_TOOL_NAMES` array of **42 entries** (a settings toggle schema) while only **16 tools are actually registered** in `index.ts`. The 26-entry delta is NOT missing tools — it is the per-tool enable/disable toggle schema for `/acp settings`. See [`../pi-plugins/flow/intentions/pi-acp-agents/tool-consolidation.md`](https://github.com/buihongduc132/pi-plugins/blob/main/flow/intentions/pi-acp-agents/tool-consolidation.md) for the planned consolidation (42 → 7 multiplexed tools).
19
90
 
20
91
  ---
21
92
 
22
- ## Installation
93
+ ## Install
23
94
 
24
- ### For Humans
95
+ ### For humans
25
96
 
26
97
  ```bash
27
98
  npm install @buihongduc132/pi-acp-agents
28
99
  ```
29
100
 
30
- ### For AI Agents
101
+ ### For AI agents
31
102
 
32
103
  Add to `~/.pi/agent/settings.json`:
33
104
 
@@ -37,29 +108,13 @@ Add to `~/.pi/agent/settings.json`:
37
108
  }
38
109
  ```
39
110
 
40
- Or install via pi CLI:
41
-
42
- ### Humans
111
+ Or:
43
112
 
44
113
  ```bash
45
114
  pi install npm:@buihongduc132/pi-acp-agents
46
115
  ```
47
116
 
48
- Or with npm directly:
49
-
50
- ```bash
51
- npm install @buihongduc132/pi-acp-agents
52
- ```
53
-
54
- ### AI Agents (pip install)
55
-
56
- ```
57
- pi install npm:@buihongduc132/pi-acp-agents
58
- ```
59
-
60
- ### Git-sourced for pi
61
-
62
- Add to `~/.pi/agent/settings.json`:
117
+ ### Git-sourced
63
118
 
64
119
  ```json
65
120
  {
@@ -69,32 +124,18 @@ Add to `~/.pi/agent/settings.json`:
69
124
  }
70
125
  ```
71
126
 
72
- Or clone and link locally:
73
-
74
- ```bash
75
- git clone https://github.com/buihongduc132/pi-acp-agents.git
76
- cd pi-acp-agents && npm install
77
- ```
78
-
79
- Then reference the local path in `settings.json`:
80
-
81
- ```json
82
- {
83
- "packages": ["/path/to/pi-acp-agents"]
84
- }
85
- ```
86
- ```
127
+ ---
87
128
 
88
- ## Quick Start
129
+ ## Quick start
89
130
 
90
- 1. Ensure an ACP agent is installed (e.g., Gemini CLI):
131
+ 1. Install an ACP agent (Gemini CLI default):
91
132
 
92
133
  ```bash
93
134
  gemini --version
94
135
  gemini # first run to authenticate
95
136
  ```
96
137
 
97
- 2. Configure (optional — defaults to gemini):
138
+ 2. (Optional) Configure:
98
139
 
99
140
  ```bash
100
141
  mkdir -p ~/.pi/acp-agents
@@ -113,102 +154,138 @@ Then reference the local path in `settings.json`:
113
154
  ```
114
155
 
115
156
  3. Use in pi:
157
+
116
158
  ```
117
159
  Use the acp_prompt tool to ask gemini "What is the capital of France?"
118
160
  ```
119
161
 
120
- ---
162
+ For full usage patterns, DAG examples, alias configuration, and worker orchestration see [`docs/USAGE.md`](docs/USAGE.md).
121
163
 
122
- ## Tools
164
+ ---
123
165
 
124
- ### Session Management (Level 1)
166
+ ## Tool surface
125
167
 
126
- Friendly session names are globally unique across ACP sessions, immutable once assigned, persisted in the runtime directory, and remain resolvable after reload for both live and archived sessions.
168
+ **16 tools registered** (gated by `/acp settings` per-tool toggles):
127
169
 
128
- | Tool | Description |
129
- | ------------ | -------------------------------------------------------------- |
130
- | `acp_prompt` | Send a prompt to an ACP agent, get the text response |
170
+ | Tool | Purpose |
171
+ |---|---|
172
+ | `acp_prompt` | Send a prompt to an ACP agent, get the text response |
131
173
  | `acp_status` | Show configured agents, active sessions, circuit breaker state |
174
+ | `acp_cancel` | Cancel an ongoing prompt by ID or friendly name |
175
+ | `acp_broadcast` | Send same prompt to multiple agents in parallel |
176
+ | `acp_task_create` | Create a persistent task in the runtime task store |
177
+ | `acp_task_update` | Multiplexed mutations: status, assignee, deps, result, bulk `*` |
178
+ | `acp_message` | Send or list messages (dm / steer / broadcast) |
179
+ | `acp_dag_submit` | Submit a DAG of tasks (validates, persists, starts background exec) |
180
+ | `acp_dag_status` | Get DAG state by `dagId`, or list all DAGs when called without it |
181
+ | `acp_dag_cancel` | Cancel a running DAG |
182
+ | `acp_worker_spawn` | Spawn a persistent named worker |
183
+ | `acp_worker_list` | List workers + status |
184
+ | `acp_worker_steer` | In-flight redirect — inject context mid-prompt |
185
+ | `acp_worker_shutdown` | Graceful shutdown |
186
+ | `acp_worker_kill` | Force kill |
187
+ | `acp_worker_prune` | Prune stale workers |
188
+
189
+ **Slash command surface** (`/acp ...`):
190
+
191
+ ```
192
+ /acp session <new|load|list|shutdown|kill|prune|set-model|set-mode|cancel>
193
+ /acp prompt
194
+ /acp delegate
195
+ /acp broadcast
196
+ /acp compare
197
+ /acp task <create|list|get|assign|set-status|dep-add|dep-rm|clear>
198
+ /acp message <send|list>
199
+ /acp plan <request|resolve>
200
+ /acp runtime <status|config|env|info|event-log|cleanup|doctor>
201
+ /acp settings — configure tool visibility
202
+ Aliases: /acp-doctor, /acp-config
203
+ ```
204
+
205
+ For tool-parameter reference and examples see [`docs/USAGE.md`](docs/USAGE.md).
206
+
207
+ ---
208
+
209
+ ## DAG delegation
210
+
211
+ Submit a complete DAG of ACP agent tasks in a single call. The DAG executor:
212
+ - **Validates statically** (cycles, dangling refs, duplicate IDs, agent availability)
213
+ - **Persists state** to disk under `<runtimeDir>/dag/`
214
+ - **Executes in topological wave-order** (parallel within wave, serial across waves)
215
+ - **Resumes automatically** after pi restart (running steps retried, completed steps skipped)
216
+
217
+ ### Submission JSON
132
218
 
133
- ### Session Lifecycle (Level 2)
219
+ ```json
220
+ {
221
+ "tasks": [
222
+ { "id": "analyze", "agent": "gemini", "prompt": "Analyze the codebase for security issues" },
223
+ { "id": "fix", "agent": "claude", "prompt": "Fix the issues: {analyze.output}", "dependsOn": ["analyze"] },
224
+ { "id": "verify", "agent": "gemini", "prompt": "Verify: {fix.output}", "dependsOn": ["fix"], "gate": "after" }
225
+ ],
226
+ "args": { "project": "my-app" },
227
+ "options": { "failFast": true, "maxRetries": 0 },
228
+ "cwd": "/path/to/project"
229
+ }
230
+ ```
231
+
232
+ ### Template variables
134
233
 
135
- | Tool | Description |
136
- | ----------------------- | ------------------------------------------------------ |
137
- | `acp_session_new` | Create a new isolated session with an agent; optional immutable `session_name`, caller cannot choose fresh session IDs |
138
- | `acp_session_load` | Load/resume an existing session by ID or friendly name, including archived auto-closed sessions |
139
- | `acp_session_set_model` | Change the model for an active session by ID or friendly name |
140
- | `acp_session_set_mode` | Change the mode (thinking level) for an active session by ID or friendly name |
141
- | `acp_cancel` | Cancel an ongoing prompt by ID or friendly name |
234
+ | Variable | Resolves to |
235
+ |---|---|
236
+ | `{<step-id>.output}` | Output of referenced step (truncated to `dagOutputTruncateChars`) |
237
+ | `{<step-id>.status}` | Terminal status (`completed` / `failed` / `skipped` / `cancelled`) |
238
+ | `{dag.args.<key>}` | Workflow arg from `args` at submission |
142
239
 
143
- ### Multi-Agent Coordination (Level 3)
240
+ Unresolvable variables fail the step at dispatch time.
144
241
 
145
- | Tool | Description |
146
- | --------------- | ---------------------------------------------------- |
147
- | `acp_delegate` | Delegate a task (short-lived session, auto-disposed) |
148
- | `acp_broadcast` | Send same prompt to multiple agents in parallel |
149
- | `acp_compare` | Get responses from multiple agents and compare them |
242
+ ### Gates
150
243
 
151
- **Commands:** `/acp` ACP root command with session, prompt, delegate, broadcast, compare, task, message, plan, runtime groups
244
+ | Gate | Behavior |
245
+ |---|---|
246
+ | `needs` (default) | **Success-gate** — all deps must `complete`. Failure cascades. |
247
+ | `after` | **Completion-gate** — deps just need a terminal state. Use for cleanup/verify steps. |
152
248
 
153
- **Compatibility aliases:** `/acp-doctor`, `/acp-config`
249
+ ### Config
250
+
251
+ | Option | Default | Description |
252
+ |---|---|---|
253
+ | `dagStaleTimeoutMs` | `3_600_000` (1h) | No step transitions for this long → `stale` |
254
+ | `dagOutputTruncateChars` | `8000` | Max chars injected into downstream prompts |
255
+
256
+ For DAG executor internals, persistence model, and resume semantics see [`docs/USAGE.md`](docs/USAGE.md).
154
257
 
155
258
  ---
156
259
 
157
- ## Architecture
260
+ ## Alias resolver + fallback chains
158
261
 
159
- ```
160
- ┌─────────────────────────────────────────────────┐
161
- │ pi agent │
162
- │ │
163
- │ acp_prompt ──┐ │
164
- │ acp_status ──┤ │
165
- │ acp_session ─┤──► AgentCoordinator ──┐ │
166
- │ acp_cancel ──┤ │ │
167
- │ acp_compare ─┘ ▼ │
168
- │ AcpCircuitBreaker │
169
- │ │ │
170
- │ ┌────────┴────────┐ │
171
- │ │ Adapter Factory │ │
172
- │ └────┬───────┬────┘ │
173
- │ GeminiAdapter │ │
174
- │ CustomAdapter │
175
- │ │ │
176
- │ AcpClient (stdio) │
177
- │ │ │
178
- │ HealthMonitor ◄──────┤
179
- │ SessionManager │
180
- └─────────────────────────────────────────────────┘
181
-
182
- ┌────────┴────────┐
183
- │ ACP Agent (gemini│
184
- │ --acp, claude, │
185
- │ codex, custom) │
186
- └─────────────────┘
187
- ```
262
+ Resolves an alias name to a concrete agent using configurable strategies. Used internally by `acp_prompt` / `acp_delegate` when called with an alias name.
188
263
 
189
- ### Patterns
264
+ | Strategy | Behavior |
265
+ |---|---|
266
+ | **failover** (sequential) | Try agents in order; first success wins; throws `AllAgentsFailedError` if all fail |
267
+ | **race** (parallel) | Send to all healthy agents in parallel; first success cancels losers (default race timeout 30s) |
268
+
269
+ Both strategies consult the circuit breaker (`isHealthyFn`) before dispatching and skip unhealthy agents.
190
270
 
191
- | Pattern | Implementation |
192
- | ------------------- | ----------------------------------------------------------- |
193
- | **Adapter** (GoF) | `AcpAgentAdapter` → `GeminiAcpAdapter` / `CustomAcpAdapter` |
194
- | **Factory** | `createAdapter()` — string dispatch |
195
- | **Circuit Breaker** | Closed → Open → Half-Open with configurable thresholds |
196
- | **Health Monitor** | Background polling with distinct 1-hour no-response and completed-idle auto-close |
197
- | **Coordinator** | Multi-agent delegate/broadcast/compare |
271
+ For alias configuration schema and examples see [`docs/USAGE.md`](docs/USAGE.md).
198
272
 
199
273
  ---
200
274
 
201
- ## Resilience
275
+ ## Persistent workers
276
+
277
+ Spawn long-lived named workers via `acp_worker_spawn`. Workers persist across task completions and are managed via:
278
+
279
+ | Tool | Purpose |
280
+ |---|---|
281
+ | `acp_worker_spawn` | Spawn worker + bind to ACP session + optional init prompt |
282
+ | `acp_worker_list` | List workers + status (online / offline / busy / disposed) |
283
+ | `acp_worker_steer` | In-flight redirect — inject context mid-prompt |
284
+ | `acp_worker_shutdown` | Graceful shutdown |
285
+ | `acp_worker_kill` | Force kill |
286
+ | `acp_worker_prune` | Prune stale workers |
202
287
 
203
- | Feature | Default | Description |
204
- | --------------- | ----------------- | ----------------------------------------------------------- |
205
- | Circuit breaker | 3 failures → open | Auto-recovers after 60s in half-open state |
206
- | Stall timeout | 1 hour | Per-operation timeout with SIGTERM→SIGKILL escalation |
207
- | Health polling | 30s | Background monitor enforces separate no-response and completed-idle timers |
208
- | Busy mutex | per-session | Prevents concurrent prompts on the same session |
209
- | Process safety | SIGTERM→SIGKILL | Graceful process shutdown with escalation |
210
- | EPIPE handling | stdin/stdout | Prevents crashes on broken pipes |
211
- | Non-blocking | all paths | Errors return as tool error results, never unhandled throws |
288
+ Workers share the caller's filesystem (no `git worktree` isolation). For parallel worktree-isolated delegation use the `teams` pi-plugin instead.
212
289
 
213
290
  ---
214
291
 
@@ -219,15 +296,8 @@ Config file: `~/.pi/acp-agents/config.json`
219
296
  ```json
220
297
  {
221
298
  "agent_servers": {
222
- "gemini": {
223
- "command": "gemini",
224
- "args": ["--acp"],
225
- "default_model": "gemini-2.5-pro"
226
- },
227
- "custom": {
228
- "command": "/path/to/my-acp-agent",
229
- "args": ["--mode", "acp"]
230
- }
299
+ "gemini": { "command": "gemini", "args": ["--acp"], "default_model": "gemini-2.5-pro" },
300
+ "custom": { "command": "/path/to/my-acp-agent", "args": ["--mode", "acp"] }
231
301
  },
232
302
  "defaultAgent": "gemini",
233
303
  "staleTimeoutMs": 3600000,
@@ -238,94 +308,116 @@ Config file: `~/.pi/acp-agents/config.json`
238
308
  }
239
309
  ```
240
310
 
241
- ### Global config
242
-
243
- | Field | Default | Description |
244
- | --------------------------- | ----------------------- | ----------------------------------------- |
245
- | `agent_servers` | `{ gemini: {...} }` | Map of agent name → config |
246
- | `defaultAgent` | `"gemini"` | Agent used when not specified |
247
- | `staleTimeoutMs` | `3600000` (1 hour) | Auto-close threshold for each separate lifecycle policy: stalled-no-response and completed-idle |
248
- | `healthCheckIntervalMs` | `30000` (30s) | Background health polling interval |
249
- | `circuitBreakerMaxFailures` | `3` | Consecutive failures before circuit opens |
250
- | `circuitBreakerResetMs` | `60000` (60s) | Time before circuit half-opens |
251
- | `stallTimeoutMs` | `3600000` (1 hour) | Per-operation timeout |
252
- | `logsDir` | `~/.pi/acp-agents/logs` | Log directory |
253
-
254
- ### Per-agent config
255
-
256
- | Field | Required | Description |
257
- | -------------- | -------- | ----------------------------- |
258
- | `command` | **yes** | Executable to spawn |
259
- | `args` | no | Arguments (e.g., `["--acp"]`) |
260
- | `env` | no | Extra environment variables |
261
- | `cwd` | no | Working directory override |
262
- | `default_model` | no | Default model ID |
311
+ ### Global
312
+
313
+ | Field | Default | Description |
314
+ |---|---|---|
315
+ | `agent_servers` | `{ gemini: {...} }` | Map of agent name → config |
316
+ | `defaultAgent` | `"gemini"` | Agent used when not specified |
317
+ | `staleTimeoutMs` | `3600000` (1h) | Auto-close: stalled-no-response AND completed-idle |
318
+ | `healthCheckIntervalMs` | `30000` (30s) | Background health polling interval |
319
+ | `circuitBreakerMaxFailures` | `3` | Consecutive failures before circuit opens |
320
+ | `circuitBreakerResetMs` | `60000` (60s) | Time before circuit half-opens |
321
+ | `stallTimeoutMs` | `3600000` (1h) | Per-operation timeout |
322
+ | `logsDir` | `~/.pi/acp-agents/logs` | Log directory |
323
+ | `dagStaleTimeoutMs` | `3600000` | DAG stale threshold |
324
+ | `dagOutputTruncateChars` | `8000` | DAG downstream prompt truncation |
325
+
326
+ ### Per-agent
327
+
328
+ | Field | Required | Description |
329
+ |---|---|---|
330
+ | `command` | **yes** | Executable to spawn |
331
+ | `args` | no | Args (e.g. `["--acp"]`) |
332
+ | `env` | no | Extra env vars |
333
+ | `cwd` | no | Working dir override |
334
+ | `default_model` | no | Default model ID |
335
+
336
+ For aliases, model policy, and runtime store paths see [`docs/USAGE.md`](docs/USAGE.md).
263
337
 
264
338
  ---
265
339
 
266
- ## Logs
267
-
268
- Central logs: `~/.pi/acp-agents/logs/`
269
-
270
- - `main.log` — general structured JSON log
271
- - `session-{id}/trace.jsonl` — per-session ACP JSON-RPC traces
340
+ ## Architecture
272
341
 
273
- ---
342
+ ```
343
+ ┌─────────────────────────────────────────────────────┐
344
+ │ pi agent │
345
+ │ │
346
+ │ acp_prompt ──┐ │
347
+ │ acp_status ──┤ │
348
+ │ acp_cancel ──┤──► AliasResolver ──► Coordinator ──┐ │
349
+ │ acp_dag_* ───┤ │ │ │
350
+ │ acp_worker_* ┤ ▼ │ │
351
+ │ acp_message ─┤ AcpCircuitBreaker │ │
352
+ │ acp_task_* ──┘ │ │ │
353
+ │ ┌────────┴────────┐ │ │
354
+ │ │ Adapter Factory │ │ │
355
+ │ └────┬───────┬────┘ │ │
356
+ │ GeminiAdapter│ │ │
357
+ │ CustomAdapter │ │
358
+ │ │ │ │
359
+ │ AcpClient (stdio) │ │
360
+ │ │ │ │
361
+ │ HealthMonitor ◄───────┤ │
362
+ │ SessionManager │ │
363
+ │ DagStore + DagExecutor│ │
364
+ │ WorkerStore │ │
365
+ │ SessionStoreFactory │ │
366
+ └─────────────────────────────────────────────────────┘
367
+ ```
274
368
 
275
- ## Supported Agents
369
+ ### Patterns
276
370
 
277
- | Agent | Status | Config |
278
- | --------------- | ------------------------- | ------------------------------------ |
279
- | **Gemini CLI** | Built-in adapter | `command: "gemini", args: ["--acp"]` |
280
- | **Claude Code** | 🔜 Planned | ACP mode pending upstream |
281
- | **Codex** | 🔜 Planned | ACP mode pending upstream |
282
- | **Custom** | Via `CustomAcpAdapter` | Any command speaking ACP over stdio |
371
+ | Pattern | Implementation |
372
+ |---|---|
373
+ | **Adapter** | `AcpAgentAdapter` `GeminiAcpAdapter` / `CustomAcpAdapter` |
374
+ | **Factory** | `createAdapter()` string dispatch |
375
+ | **Circuit breaker** | Closed Open Half-Open with configurable thresholds |
376
+ | **Health monitor** | Background polling; distinct no-response and completed-idle auto-close |
377
+ | **Coordinator** | Multi-agent delegate / broadcast / compare |
378
+ | **Alias resolver** | failover (sequential) + race (parallel first-wins) |
379
+ | **DAG executor** | Topological wave-execution + persistent resume |
380
+ | **Session-store factory** | Per-host-session lazy-instantiated stores (4 session-scoped + 3 global) |
283
381
 
284
382
  ---
285
383
 
286
- ## Roadmap
287
-
288
- ### v0.2.x — Current (Foundation)
289
-
290
- - [x] ACP stdio JSON-RPC client
291
- - [x] Gemini CLI adapter with auto-auth
292
- - [x] Session lifecycle (new, load, set model/mode, cancel)
293
- - [x] Circuit breaker + health monitor
294
- - [x] Multi-agent: delegate, broadcast, compare
295
- - [x] TUI widget for session status
296
- - [x] 148 unit + integration tests
297
- - [x] CI/CD pipeline with provenance publishing
384
+ ## Resilience
298
385
 
299
- ### v0.3.x Streaming & Auth
386
+ | Feature | Default | Description |
387
+ |---|---|---|
388
+ | Circuit breaker | 3 failures → open | Auto-recovers after 60s in half-open state |
389
+ | Stall timeout | 1 hour | Per-operation timeout with SIGTERM → SIGKILL escalation |
390
+ | Health polling | 30s | Background monitor with separate no-response and completed-idle timers |
391
+ | Busy mutex | per-session | Prevents concurrent prompts on the same session |
392
+ | Process safety | SIGTERM → SIGKILL | Graceful shutdown with escalation |
393
+ | EPIPE handling | stdin / stdout | Prevents crashes on broken pipes |
394
+ | Non-blocking | all paths | Errors return as tool error results, never unhandled throws |
395
+ | Alias failover | automatic | Sequential fallback on agent failure |
396
+ | Alias race | 30s timeout | Parallel first-wins with cancel of losers |
397
+ | DAG resume | on pi restart | `resumeAll()` discovers running DAGs, skips completed steps |
300
398
 
301
- - [ ] **Streaming responses** — forward `agent_message_chunk` events to pi in real-time
302
- - [ ] **Tool use forwarding** — expose ACP agent tool calls back to pi's tool registry
303
- - [ ] **OAuth/token auth** — support API key and OAuth flows per-agent
304
- - [ ] **Config hot-reload** — watch config file, reload without restart
305
- - [ ] **Retry with backoff** — exponential backoff for transient failures
306
- - [ ] Custom adapter smoke tests
399
+ ---
307
400
 
308
- ### v0.4.x — Persistence & Recovery
401
+ ## Logs
309
402
 
310
- - [ ] **Session persistence** — save/restore sessions across pi restarts
311
- - [ ] **Session sharing** — share ACP sessions between pi instances via file lock
312
- - [x] **Checkpoint/resume** — archived runtime metadata reopens auto-closed ACP sessions by original session ID
313
- - [ ] **Metrics export** — Prometheus-compatible metrics (session count, latency, error rate)
403
+ Central logs at `~/.pi/acp-agents/logs/`:
314
404
 
315
- ### v0.5.xAdvanced Orchestration
405
+ - `main.log`general structured JSON log
406
+ - `session-{id}/trace.jsonl` — per-session ACP JSON-RPC traces
407
+ - `<runtimeDir>/dag/<dagId>.json` + `dag-index.json` — DAG state persistence
408
+ - `<runtimeDir>/<sessionId>/{tasks,mailboxes,governance,workers}.json` — session-scoped stores
409
+ - `<runtimeDir>/{events,session-archive,session-name-registry}.jsonl|json` — global stores
316
410
 
317
- - [ ] **Agent routing** — automatic agent selection based on task type
318
- - [ ] **Ensemble mode** — run same prompt across N agents, merge via configurable strategy (vote, rank, consensus)
319
- - [ ] **Chain-of-agents** — pipe output of one agent as input to next
320
- - [ ] **Cost tracking** — per-agent, per-session token usage and cost estimation
321
- - [ ] **Agent health dashboard** — web UI for monitoring all connected agents
411
+ ---
322
412
 
323
- ### v1.0.0 — Production
413
+ ## Supported agents
324
414
 
325
- - [ ] **Stable API** no breaking changes without major version bump
326
- - [ ] **Full ACP spec compliance** — implement all optional ACP capabilities
327
- - [ ] **Multi-platform support** OpenClaw, Claude Code plugin, standalone MCP server
328
- - [ ] **Comprehensive docs** API reference, migration guides, examples
415
+ | Agent | Status | Config |
416
+ |---|---|---|
417
+ | **Gemini CLI** | Built-in | `command: "gemini", args: ["--acp"]` |
418
+ | **Claude Code** | 🔜 Planned | ACP mode pending upstream |
419
+ | **Codex** | 🔜 Planned | ACP mode pending upstream |
420
+ | **Custom** | ✅ Via `CustomAcpAdapter` | Any command speaking ACP over stdio |
329
421
 
330
422
  ---
331
423
 
@@ -333,27 +425,35 @@ Central logs: `~/.pi/acp-agents/logs/`
333
425
 
334
426
  ```bash
335
427
  npm install
336
- npm test # run all tests
337
- npm run test:ci # run with coverage
428
+ npm test # all tests
429
+ npm run test:ci # with coverage
338
430
  npm run typecheck # TypeScript validation
339
431
  npm run publish:dry # verify package contents before publish
340
432
  ```
341
433
 
342
- ### Release process
434
+ ---
435
+
436
+ ## Release process
343
437
 
344
438
  ```bash
345
- npm run release:patch # 0.2.0 → 0.2.1
346
- npm run release:minor # 0.2.0 → 0.3.0
347
- npm run release:beta # 0.2.0 → 0.2.1-beta.0
439
+ npm run release:patch # 0.4.0 → 0.4.1
440
+ npm run release:minor # 0.4.0 → 0.5.0
441
+ npm run release:beta # 0.4.0 → 0.4.1-beta.0
348
442
  git push --follow-tags # triggers CI → auto-publish with provenance
349
443
  ```
350
444
 
351
445
  ---
352
446
 
353
- ## License
354
-
355
- MIT
356
-
357
- ## Attribution
358
-
359
- Maintained by [buihongduc132](https://github.com/buihongduc132). Forked from [walodayeet/pi-acp-agents](https://github.com/walodayeet/pi-acp-agents).
447
+ ## Further documentation
448
+
449
+ | Topic | Location |
450
+ |---|---|
451
+ | **Full usage guide** (DAG examples, alias config, worker patterns, slash command reference) | [`docs/USAGE.md`](docs/USAGE.md) |
452
+ | **Tool consolidation plan** (39 → 7 multiplexed tools) | [`../pi-plugins/flow/intentions/pi-acp-agents/tool-consolidation.md`](https://github.com/buihongduc132/pi-plugins/blob/main/flow/intentions/pi-acp-agents/tool-consolidation.md) |
453
+ | **ACP vs teams gap analysis** | [`../pi-plugins/flow/findings/acp-vs-teams-analysis.md`](https://github.com/buihongduc132/pi-plugins/blob/main/flow/findings/acp-vs-teams-analysis.md) |
454
+ | **DAG delegation design** | [`openspec/changes/archive/2026-06-20-acp-dag-delegation/`](openspec/changes/archive/2026-06-20-acp-dag-delegation/) |
455
+ | **DAG widget design** | [`openspec/changes/archive/2026-06-22-acp-dag-widget/`](openspec/changes/archive/2026-06-22-acp-dag-widget/) |
456
+ | **Session-scoped runtime stores** | [`openspec/changes/archive/2026-06-19-scope-runtime-stores-per-session/`](openspec/changes/archive/2026-06-19-scope-runtime-stores-per-session/) |
457
+ | **Branch consolidation record** (this release) | [`docs/branch-consolidation-2026-06-22.md`](docs/branch-consolidation-2026-06-22.md) |
458
+ | **OpenSpec changes** | [`openspec/changes/`](openspec/changes/) |
459
+ | **Specs (canonical)** | [`openspec/specs/`](openspec/specs/) |