agents-can-communicate 0.9.1 → 0.10.1
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 +46 -44
- package/bin/acc-update-worker.mjs +2 -1
- package/bin/entrypoints/hook-output.mjs +2 -0
- package/docs/ARCHITECTURE.md +26 -2
- package/docs/CLI.md +11 -1
- package/docs/GETTING_STARTED.md +4 -3
- package/docs/UPGRADING.md +62 -3
- package/docs/WHY_ACC.md +32 -9
- package/docs/index.md +7 -5
- package/node_modules/@agents-can-communicate/adapter-antigravity/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-antigravity/plugin/plugin.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-claude-code/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/adapter.mjs +3 -1
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/hooks.mjs +12 -0
- package/node_modules/@agents-can-communicate/adapter-codex/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-codex/src/adapter.mjs +2 -1
- package/node_modules/@agents-can-communicate/adapter-codex/src/hooks.mjs +11 -0
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/gemini-extension.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-grok/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-kimi/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/src/capabilities.mjs +6 -0
- package/node_modules/@agents-can-communicate/cli/package.json +1 -1
- package/node_modules/@agents-can-communicate/cli/src/args.mjs +4 -1
- package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +14 -0
- package/node_modules/@agents-can-communicate/cli/src/help.mjs +2 -0
- package/node_modules/@agents-can-communicate/cli/src/main.mjs +12 -3
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/activation.mjs +97 -10
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/launchers.mjs +1 -1
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/portable-fs.mjs +41 -20
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/refresh.mjs +4 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/schedule.mjs +17 -1
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/store-upgrade.mjs +105 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/worker.mjs +5 -0
- package/node_modules/@agents-can-communicate/cli/src/store-migration-command.mjs +39 -0
- package/node_modules/@agents-can-communicate/core/package.json +1 -1
- package/node_modules/@agents-can-communicate/core/src/conversations.mjs +21 -52
- package/node_modules/@agents-can-communicate/core/src/decision-changes.mjs +16 -11
- package/node_modules/@agents-can-communicate/core/src/inbox.mjs +12 -4
- package/node_modules/@agents-can-communicate/core/src/message-retry.mjs +43 -0
- package/node_modules/@agents-can-communicate/core/src/ports.mjs +12 -1
- package/node_modules/@agents-can-communicate/core/src/receipts.mjs +20 -6
- package/node_modules/@agents-can-communicate/delivery-router/package.json +1 -1
- package/node_modules/@agents-can-communicate/hook-runner/package.json +1 -1
- package/node_modules/@agents-can-communicate/hook-runner/src/runner.mjs +23 -3
- package/node_modules/@agents-can-communicate/installer/package.json +1 -1
- package/node_modules/@agents-can-communicate/mcp-server/package.json +1 -1
- package/node_modules/@agents-can-communicate/protocol/package.json +1 -1
- package/node_modules/@agents-can-communicate/protocol/src/index.mjs +1 -0
- package/node_modules/@agents-can-communicate/protocol/src/transaction-indexes.mjs +22 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/package.json +1 -1
- package/node_modules/@agents-can-communicate/storage-filesystem/src/identity.mjs +22 -10
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index-cache.mjs +144 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index-io.mjs +65 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index-pages.mjs +85 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index-reclaim-progress.mjs +35 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index-reclaim.mjs +142 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index-tree.mjs +142 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index.mjs +1 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/journal.mjs +2 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/portable-fs.mjs +41 -20
- package/node_modules/@agents-can-communicate/storage-filesystem/src/prune-durability.mjs +29 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/reclaim.mjs +13 -3
- package/node_modules/@agents-can-communicate/storage-filesystem/src/recovery.mjs +9 -3
- package/node_modules/@agents-can-communicate/storage-filesystem/src/session-read.mjs +6 -4
- package/node_modules/@agents-can-communicate/storage-filesystem/src/state-reads.mjs +43 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/store-migration.mjs +56 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/store.mjs +61 -110
- package/node_modules/@agents-can-communicate/storage-filesystem/src/transaction-view.mjs +131 -0
- package/package.json +5 -4
package/README.md
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
1
|
# Agents Can Communicate (ACC)
|
|
2
2
|
|
|
3
|
-
**
|
|
3
|
+
**The message your clients can’t send each other.**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
Claude Code can message your other Claude Code sessions, and Codex can queue a message for
|
|
6
|
+
another Codex session. Neither client offers a way to message the other’s sessions. ACC
|
|
7
|
+
carries questions, reviews and handoffs between sessions in different vendors’ clients, on
|
|
8
|
+
your machine.
|
|
7
9
|
|
|
8
10
|
You open each client normally and choose its work. Every session keeps its own model,
|
|
9
11
|
conversation, and permissions. Coordination runs locally, with no lead agent managing the
|
|
10
|
-
others.
|
|
12
|
+
others. If all your sessions run in one of these two clients, try its own messaging first.
|
|
11
13
|
|
|
12
14
|
```mermaid
|
|
13
15
|
flowchart TB
|
|
14
16
|
you["You choose the tools and work"]
|
|
15
17
|
codex["Codex<br/>Feature A"]
|
|
16
18
|
claude["Claude Code<br/>Feature B"]
|
|
17
|
-
|
|
19
|
+
antigravity["Antigravity CLI<br/>Feature C"]
|
|
18
20
|
acc["Communication via ACC"]
|
|
19
21
|
|
|
20
22
|
you -.-> codex
|
|
21
23
|
you -.-> claude
|
|
22
|
-
you -.->
|
|
24
|
+
you -.-> antigravity
|
|
23
25
|
codex <--> acc
|
|
24
26
|
claude <--> acc
|
|
25
|
-
|
|
27
|
+
antigravity <--> acc
|
|
26
28
|
|
|
27
|
-
subgraph handoff["When you switch
|
|
29
|
+
subgraph handoff["When you switch clients"]
|
|
28
30
|
direction LR
|
|
29
|
-
current["
|
|
30
|
-
saved --> next["
|
|
31
|
+
current["Claude Code<br/>session"] --> saved["Handoff<br/>Done · Decisions<br/>Next steps"]
|
|
32
|
+
saved --> next["Codex<br/>session"]
|
|
31
33
|
end
|
|
32
34
|
acc ~~~ handoff
|
|
33
35
|
|
|
@@ -35,7 +37,7 @@ flowchart TB
|
|
|
35
37
|
classDef session fill:#fff,stroke:#ced4d9,color:#202a35
|
|
36
38
|
classDef shared fill:#e8edff,stroke:#385cde,color:#202a35
|
|
37
39
|
class you human
|
|
38
|
-
class codex,claude,
|
|
40
|
+
class codex,claude,antigravity,current,next session
|
|
39
41
|
class acc,saved shared
|
|
40
42
|
style handoff fill:transparent,stroke:#ced4d9
|
|
41
43
|
linkStyle 3,4,5,6,7 stroke:#385cde,stroke-width:2px
|
|
@@ -43,14 +45,16 @@ flowchart TB
|
|
|
43
45
|
|
|
44
46
|
## When ACC helps
|
|
45
47
|
|
|
46
|
-
- **
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
- **Get a second opinion from another vendor’s model.** Ask a Codex session to review a change
|
|
49
|
+
your Claude Code session just made, and send its findings back to the session that wrote the
|
|
50
|
+
code.
|
|
51
|
+
- **Bring parallel features together.** Let sessions in different clients ask each other about
|
|
52
|
+
a shared API before they build around different assumptions.
|
|
53
|
+
- **Switch clients mid-feature.** When a limit approaches or another model suits the work
|
|
54
|
+
better, leave a handoff with decisions and unfinished work for a session in the client you
|
|
55
|
+
open next.
|
|
52
56
|
|
|
53
|
-
## Try one
|
|
57
|
+
## Try one review across clients
|
|
54
58
|
|
|
55
59
|
You’ll need **macOS, Linux or Windows 10/11, Node.js 24 or newer**, and supported coding
|
|
56
60
|
clients on the same machine and operating-system user. On Windows, ACC runs natively, with no
|
|
@@ -66,45 +70,41 @@ The installer connects supported clients it finds. Follow its activation instruc
|
|
|
66
70
|
any required hook or plugin trust, then restart your clients from the project directory. The
|
|
67
71
|
[setup guide](docs/GETTING_STARTED.md) covers client-specific steps.
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
Open Claude Code and Codex in the same project. After Claude Code has changed something, for
|
|
74
|
+
example an account-registration form, ask it:
|
|
70
75
|
|
|
71
76
|
```text
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
verified. I will continue in another session.
|
|
77
|
+
Ask the Codex session in ACC to review the registration form change
|
|
78
|
+
you just made. Name the files and what it should check.
|
|
75
79
|
```
|
|
76
80
|
|
|
77
|
-
|
|
81
|
+
Then ask Codex:
|
|
78
82
|
|
|
79
83
|
```text
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
unfinished step. Ask me if the scope is unclear.
|
|
84
|
+
Answer the review request in ACC. Read the files it names, check
|
|
85
|
+
what it asks, and reply with what you found.
|
|
83
86
|
```
|
|
84
87
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
Save the handoff while the first model can still respond. ACC preserves explicitly recorded
|
|
89
|
-
context; it cannot recover details that were never saved.
|
|
88
|
+
Codex should find the request without you pasting it, and Claude Code should see the findings
|
|
89
|
+
at its next turn without you copying them back. The sender can check whether its message was
|
|
90
|
+
delivered and answered.
|
|
90
91
|
|
|
91
92
|
## Client support
|
|
92
93
|
|
|
93
|
-
Integrations are available for **Antigravity CLI, Claude Code, Codex,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
instructions.
|
|
94
|
+
Integrations are available for **Antigravity CLI, Claude Code, Codex, Grok, and Kimi Code**.
|
|
95
|
+
Other clients can connect through [MCP](docs/MCP.md) with their own configuration and
|
|
96
|
+
coordination instructions.
|
|
97
97
|
|
|
98
98
|
Automatic delivery depends on the client version and platform. Verified integrations can
|
|
99
99
|
provide messages at the next normal turn; other sessions read their ACC inbox explicitly.
|
|
100
100
|
|
|
101
101
|
Experimental live delivery can wake eligible Claude Code, Codex and Antigravity CLI
|
|
102
|
-
sessions, conversations in the Antigravity desktop app, and local Code sessions in Claude.app.
|
|
103
|
-
connection, is off by default, and can spend model
|
|
104
|
-
the inbox that Claude Code itself opens, so you start
|
|
105
|
-
A busy Claude Code session gets the message between two
|
|
106
|
-
it when the current turn ends. Chats in the Codex app run
|
|
107
|
-
messages at their next turn.
|
|
102
|
+
sessions, conversations in the Antigravity desktop app, and local Code sessions in Claude.app.
|
|
103
|
+
It requires opt-in and an active verified connection, is off by default, and can spend model
|
|
104
|
+
tokens. Claude Code sessions wake through the inbox that Claude Code itself opens, so you start
|
|
105
|
+
Claude Code with your ordinary command. A busy Claude Code session gets the message between two
|
|
106
|
+
tool calls. A busy Codex session gets it when the current turn ends. Chats in the Codex app run
|
|
107
|
+
on the app’s own server and get messages at their next turn.
|
|
108
108
|
|
|
109
109
|
See [client capabilities](docs/CAPABILITIES.md) for exact support. Run `acc doctor` from your
|
|
110
110
|
project if a peer is missing or delivery differs from what you expect; see
|
|
@@ -125,9 +125,11 @@ Automatic updates are enabled on first install. Use `acc update --auto off` to d
|
|
|
125
125
|
[update controls](docs/UPGRADING.md) for details.
|
|
126
126
|
|
|
127
127
|
MIT-licensed and permanently noncommercial. Try it on one real task and
|
|
128
|
-
[
|
|
129
|
-
|
|
130
|
-
|
|
128
|
+
[open an issue](https://github.com/automatis-tools/agents-can-communicate/issues/new/choose)
|
|
129
|
+
with what happened: whether it worked, where it broke, or where you still had to carry
|
|
130
|
+
messages between sessions yourself. If it worked, watch the repository’s releases to hear
|
|
131
|
+
about the next one. Longer write-ups and setups are welcome in
|
|
132
|
+
[Discussions](https://github.com/automatis-tools/agents-can-communicate/discussions).
|
|
131
133
|
|
|
132
134
|
[Documentation](docs/index.md) ·
|
|
133
135
|
[Contributing](https://github.com/automatis-tools/agents-can-communicate/blob/main/AGENTS.md)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
// Private detached updater. It never
|
|
2
|
+
// Private detached updater. It never runs a model; the only workspace state it
|
|
3
|
+
// opens is an older store it migrates to this generation's contract.
|
|
3
4
|
import path from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import { runWorker, recordWorkerFailure } from "@agents-can-communicate/cli/managed-worker";
|
|
@@ -57,6 +57,8 @@ function tryWrite(stream, output) {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
const RECOVERY = new Map([
|
|
60
|
+
["store_migration_required", ": store contract 6 requires explicit migration; stop old ACC"
|
|
61
|
+
+ " clients and unmanaged store users, then run acc doctor --migrate-store in this workspace"],
|
|
60
62
|
["workspace_contains_runtime", ": workspace contains ACC runtime state; open a project"
|
|
61
63
|
+ " directory and restart the client (or set ACC_DATA_HOME outside the workspace)"],
|
|
62
64
|
["workspace_path_unquotable", ": this directory's path has a double quote, $, ` or %, which"
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -239,6 +239,25 @@ unknown holder postponed, is recorded as unfinished, and the next ACC command an
|
|
|
239
239
|
later starts the worker that finishes it. Parsed help, version, and update recovery remain
|
|
240
240
|
available when workspace admission is unavailable.
|
|
241
241
|
|
|
242
|
+
Store contract 7 adds exact transaction loads and two rebuildable indexes:
|
|
243
|
+
`messageByClientKey` and `receiptsByMessage`. Content-addressed pages contain
|
|
244
|
+
portable key tuples and record references, never message bodies. Each page is
|
|
245
|
+
bounded by 32 entries and 64 KiB; radix branches have at most 16 children.
|
|
246
|
+
Under the writer mutex, the cache is trusted only for the same workspace and the
|
|
247
|
+
current idle journal generation. Every message/receipt put or remove advances
|
|
248
|
+
that durable authority. Other journalled writes carry valid unchanged roots
|
|
249
|
+
forward, while ordinary single-record heartbeats keep their direct publication.
|
|
250
|
+
Authoritative writes commit first; cache pages and the manifest are unflushed
|
|
251
|
+
derived data. Cache loss or corruption requires verified rebuilding and cannot
|
|
252
|
+
turn a recorded message into a failed send.
|
|
253
|
+
|
|
254
|
+
Contract 6 writers can bypass that authority, so migration is explicit.
|
|
255
|
+
`doctor --migrate-store` holds runtime admission before the workspace writer
|
|
256
|
+
mutex, refuses incompatible or unknown live holders, recovers decided journals,
|
|
257
|
+
builds the complete cache, and durably replaces the identity last. The library
|
|
258
|
+
requires explicit opt-in after unmanaged callers are quiesced. A hook never
|
|
259
|
+
performs this migration. Record schemas and journal format 2 are unchanged.
|
|
260
|
+
|
|
242
261
|
An independent worker downloads npm packages with lifecycle scripts disabled, checks exact
|
|
243
262
|
stable package identity and the discovered integrity, and health-checks the staged runtime.
|
|
244
263
|
Installer detection and planning happen before exclusive admission. The worker then checks
|
|
@@ -248,8 +267,13 @@ every integration, and only publishes the new active pointer after all applicati
|
|
|
248
267
|
remains fenced and repairs forward, with the old active pointer retained but normal
|
|
249
268
|
workspace admission unavailable until recovery completes. Native bindings cease holding
|
|
250
269
|
after observed SessionEnd cleanup or confirmed process death; the vendor daemon may remain
|
|
251
|
-
running.
|
|
252
|
-
|
|
270
|
+
running. A binding that names no client process is judged by its session record instead
|
|
271
|
+
(#273): it stops holding when the record is gone, when the record names a process that has
|
|
272
|
+
exited, or, with no process recorded, when ACC's presence rule calls the session offline -
|
|
273
|
+
closed, or 30 minutes without a heartbeat. A live recorded process, or a record that cannot be
|
|
274
|
+
read, keeps it a hold. A client that wakes later runs its next hook through the launcher on
|
|
275
|
+
the active generation. For a binding that names its client, presence TTL, `acc finish`, and
|
|
276
|
+
delivery off do not prove native lifecycle end. Normal background updates never
|
|
253
277
|
restart a vendor daemon. An explicitly approved maintenance job can do so through the
|
|
254
278
|
adapter lifecycle port: it waits for idle work, validates exact process identity, stops
|
|
255
279
|
the service under the admission fence, refreshes integrations, and restores and verifies
|
package/docs/CLI.md
CHANGED
|
@@ -362,7 +362,7 @@ before leaving, request the concrete continuation and obtain a substantive reply
|
|
|
362
362
|
|---|---|
|
|
363
363
|
| `acc install` | `--adapter`, `--home`, `--delivery off|actionable|all`, `--dry-run`, `--downgrade` |
|
|
364
364
|
| `acc uninstall` | `--adapter`, `--home`, `--dry-run` |
|
|
365
|
-
| `acc doctor` | `--home`, `--repair` |
|
|
365
|
+
| `acc doctor` | `--home`, `--repair`, `--migrate-store` |
|
|
366
366
|
| `acc config init` | `--yes`, `--force` |
|
|
367
367
|
| `acc config validate` | — |
|
|
368
368
|
| `acc update` | `--check`, `--auto on\|off`, `--pin VERSION\|none`, `--yes`, `--apply` (alias) |
|
|
@@ -459,6 +459,16 @@ workspace state; `doctor --repair` remains blocked. Native clients may still req
|
|
|
459
459
|
or activation review. See [Upgrading](UPGRADING.md) for the initial 0.3.1 transition and
|
|
460
460
|
recovery details.
|
|
461
461
|
|
|
462
|
+
`acc doctor --migrate-store` explicitly migrates the selected workspace from store
|
|
463
|
+
contract 6 to 7. Stop old ACC clients and any direct library callers first. The
|
|
464
|
+
command fences runtime admission and refuses live holders with an old or unknown
|
|
465
|
+
contract. It preserves primary records, prepares the message indexes, then changes
|
|
466
|
+
the durable identity last. It neither installs a release nor restarts clients.
|
|
467
|
+
`--repair` is a separate operation and never changes the store contract; the two
|
|
468
|
+
flags cannot be combined. Hooks leave a version-6 identity unchanged and fail open
|
|
469
|
+
with the migration remedy. Doctor JSON includes bounded `indexDiagnostics`; a cache
|
|
470
|
+
failure after recording a message remains send success and is reported separately.
|
|
471
|
+
|
|
462
472
|
## Integrate a client lifecycle
|
|
463
473
|
|
|
464
474
|
`acc attach --participant <id>`, `acc heartbeat --session <id> --generation <token>`, and
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Getting started
|
|
2
2
|
|
|
3
|
-
Install ACC, open the AI sessions you already use
|
|
3
|
+
Install ACC, open the AI sessions you already use in clients from different vendors, such as
|
|
4
|
+
Claude Code and Codex, and give them related work. Supported
|
|
4
5
|
integrations make peers visible and teach each agent how to communicate. You do not need to
|
|
5
6
|
carry messages between windows or add coordination instructions to your task prompts.
|
|
6
7
|
|
|
@@ -16,8 +17,8 @@ pair or session-bound ACC MCP tools. See [CLI ownership](CLI.md#coordinate-from-
|
|
|
16
17
|
ACC requires Node.js 24 or newer on macOS, Linux, or Windows 10 or 11. On Windows, read
|
|
17
18
|
[Windows](#windows) below first.
|
|
18
19
|
|
|
19
|
-
Already using ACC? Follow the [upgrade guide](UPGRADING.md)
|
|
20
|
-
|
|
20
|
+
Already using ACC? Follow the [upgrade guide](UPGRADING.md#from-09x): from 0.9.x, each
|
|
21
|
+
store moves to contract 7 once no session still runs 0.9.x code.
|
|
21
22
|
|
|
22
23
|
```bash
|
|
23
24
|
npm install -g agents-can-communicate
|
package/docs/UPGRADING.md
CHANGED
|
@@ -1,5 +1,62 @@
|
|
|
1
1
|
# Upgrading
|
|
2
2
|
|
|
3
|
+
## Store contract 6 to 7
|
|
4
|
+
|
|
5
|
+
ACC moves each workspace's store from contract 6 to 7 by itself, right after an update
|
|
6
|
+
activates a contract-7 runtime. The activation already waits until no client runs older ACC
|
|
7
|
+
code, so at that point the migration is safe. It builds the message and receipt indexes from
|
|
8
|
+
validated live records, then replaces the store identity last. Message bytes, receipt bytes,
|
|
9
|
+
workspace identity and initialization time are preserved. There is no reverse migration:
|
|
10
|
+
version-6 code refuses a version-7 store.
|
|
11
|
+
|
|
12
|
+
A store that a live older client still holds, or whose migration fails, stays on contract 6.
|
|
13
|
+
The next ACC command or hook a minute or more later retries it. Until then, coordination is
|
|
14
|
+
paused in that workspace: Claude Code and Codex show a message about it, other clients write it
|
|
15
|
+
to stderr, `acc status` names it, and `acc doctor` names the command. To migrate a workspace at
|
|
16
|
+
once, stop older ACC clients and any program that imports the store directly, then run in that
|
|
17
|
+
workspace:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
acc doctor --migrate-store
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
The command refuses old or unknown live runtime holders, does not install or activate a
|
|
24
|
+
runtime, contact npm, or restart clients. If it is interrupted, run it again.
|
|
25
|
+
`doctor --repair` never migrates a store, and hooks never change a store's format. Runtime
|
|
26
|
+
admission cannot see unmanaged direct library users; stop them before an update.
|
|
27
|
+
|
|
28
|
+
## From 0.9.x
|
|
29
|
+
|
|
30
|
+
Update as usual:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
acc update
|
|
34
|
+
acc version
|
|
35
|
+
acc doctor
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
0.10.0 moves every store from contract 6 to 7, as described above. What you see:
|
|
39
|
+
|
|
40
|
+
- **Activation waits for 0.9.x sessions.** A client session that started under 0.9.x holds
|
|
41
|
+
contract 6 until it ends. `acc update` downloads 0.10.0 and reports
|
|
42
|
+
`ACC 0.10.0 is ready; waiting for N active or unidentified process(es)`, and `acc doctor`
|
|
43
|
+
names them. A session you start while 0.10.0 waits still runs 0.9.x, so activation needs a
|
|
44
|
+
moment when no such session runs: end or restart them together.
|
|
45
|
+
- **Stores move by themselves.** Right after 0.10.0 activates, it migrates every workspace's
|
|
46
|
+
store; you run no command.
|
|
47
|
+
- **0.9.x and 0.10.0 never share a workspace.** 0.9.x code refuses a contract-7 store. This
|
|
48
|
+
matters only for a copy of ACC that runs outside the managed runtime, such as an npm-global
|
|
49
|
+
0.9.x on another `PATH` or a development checkout: update or stop it.
|
|
50
|
+
- **Sending a message reads less of the store.** A send and its retries use a bounded index
|
|
51
|
+
instead of rereading unrelated messages and receipts.
|
|
52
|
+
|
|
53
|
+
0.10.1 lets this update finish where 0.10.0 could stay pending. A session that ended without
|
|
54
|
+
naming its client process could leave a native binding that 0.10.0 counted as a live client
|
|
55
|
+
forever, so `acc update` kept reporting `unknown client pid` holds after every session had
|
|
56
|
+
closed. 0.10.1 judges such a binding by its session record and removes it while it prepares
|
|
57
|
+
the update, so the update from 0.9.x finishes once no 0.9.x session runs. From 0.10.0, 0.10.1
|
|
58
|
+
keeps the store contract, so it activates without waiting for open sessions.
|
|
59
|
+
|
|
3
60
|
## From 0.8.x
|
|
4
61
|
|
|
5
62
|
Update as usual:
|
|
@@ -383,9 +440,11 @@ Running ACC processes, including idle MCP servers, still publish a hold for as l
|
|
|
383
440
|
live, and native bindings still hold until observed client SessionEnd cleanup or confirmed
|
|
384
441
|
process death; the vendor daemon can remain running after that lifecycle event. What
|
|
385
442
|
changed is which of those holds keeps an update pending: only one whose declared store
|
|
386
|
-
contract differs from the incoming version's, or that declares none at all.
|
|
387
|
-
|
|
388
|
-
|
|
443
|
+
contract differs from the incoming version's, or that declares none at all. From 0.10.1, a
|
|
444
|
+
binding that names no client process stops holding when its session record is gone, names an
|
|
445
|
+
exited process, or, with no process recorded, is offline: closed, or 30 minutes without a
|
|
446
|
+
heartbeat (#273). For a binding that names its client, `acc finish`, presence TTL, and
|
|
447
|
+
delivery off still do not prove native end. When a hold does block, close the relevant client
|
|
389
448
|
sessions and persistent ACC processes to release it, or accept the eligible Codex service
|
|
390
449
|
maintenance offer in `acc update`. Background updates never request fresh restart consent.
|
|
391
450
|
Hooks never wait for a network download. If integration refresh temporarily prevents
|
package/docs/WHY_ACC.md
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
1
|
# Why ACC
|
|
2
2
|
|
|
3
|
-
ACC fits
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
ACC fits work that spans clients from different vendors. Claude Code sessions can message
|
|
4
|
+
each other through Claude Code's
|
|
5
|
+
[cross-session messaging](https://code.claude.com/docs/en/cross-session-messaging), and
|
|
6
|
+
`codex queue` queues a message for another Codex session. Neither client offers a way to
|
|
7
|
+
message the other's sessions. When you ask another vendor's model for a review,
|
|
8
|
+
build related features in two clients, or switch clients in the middle of a feature, the
|
|
9
|
+
sessions need to ask and answer each other without making you carry every sentence between
|
|
10
|
+
windows.
|
|
7
11
|
|
|
8
|
-
|
|
12
|
+
Each session keeps its own context, permissions, checkout, and model.
|
|
13
|
+
|
|
14
|
+
Supported integrations make peers visible and teach agents the coordination interface.
|
|
9
15
|
The agents decide whether a dependency or peer is relevant. ACC does not assign tasks or
|
|
10
16
|
promise that every model will coordinate; it gives independent sessions a local, durable
|
|
11
17
|
place to discover peers, ask questions, answer in threads, acknowledge messages, reserve
|
|
@@ -15,12 +21,12 @@ resources, and hand off context.
|
|
|
15
21
|
|
|
16
22
|
```mermaid
|
|
17
23
|
flowchart TD
|
|
18
|
-
A["Do
|
|
19
|
-
A -->|
|
|
24
|
+
A["Do all your sessions run in Claude Code, or all in Codex?"] -->|yes| V["Try the client's own messaging first"]
|
|
25
|
+
A -->|no| B["Must they keep separate ownership and permissions?"]
|
|
20
26
|
B -->|no| M["A managed agent runtime may fit better"]
|
|
21
27
|
B -->|yes| C["Do they need direct questions, durable replies, or claim awareness?"]
|
|
22
28
|
C -->|yes| Y["ACC fits this workflow"]
|
|
23
|
-
C -->|no| N
|
|
29
|
+
C -->|no| N["ACC adds little and stays quiet"]
|
|
24
30
|
```
|
|
25
31
|
|
|
26
32
|
The useful result is simple: related tasks proceed without the human acting as a message
|
|
@@ -43,9 +49,26 @@ Claims support communication; they are not the product's center. The useful loop
|
|
|
43
49
|
retrieve, reply, acknowledge, and hand off. A claim merely makes “I am changing this”
|
|
44
50
|
actionable before two sessions collide.
|
|
45
51
|
|
|
52
|
+
## What hooks add over an MCP server or a script
|
|
53
|
+
|
|
54
|
+
A model calls an MCP tool only when it decides to: the tool sits in its list, and the session
|
|
55
|
+
remembers it or does not. ACC installs hooks in each supported client, so peers and their
|
|
56
|
+
messages arrive in the turn by themselves, and with live delivery enabled a message can wake a
|
|
57
|
+
session that is not polling for anything. For clients without an integration, ACC offers its
|
|
58
|
+
own [MCP server](MCP.md); without hooks, the agent there reads its inbox when it chooses to.
|
|
59
|
+
|
|
60
|
+
Claude Code documents its inbox socket for scripts and hooks, and `codex queue` is a command
|
|
61
|
+
any process can run, so two sessions can be wired together by hand. What that leaves to you is
|
|
62
|
+
what ACC does: one list of peers across clients, so a session finds the other without a socket
|
|
63
|
+
path or a thread id; a reply that returns to the sender in its own client; messages and
|
|
64
|
+
handoffs kept for a session that is closed or not open yet; receipts that show what happened
|
|
65
|
+
to each message; and instructions installed in each client, so agents use it without being
|
|
66
|
+
told how.
|
|
67
|
+
|
|
46
68
|
## Choose another layer when
|
|
47
69
|
|
|
48
|
-
|
|
70
|
+
Try the client's own messaging first when every session runs in Claude Code, or every one in
|
|
71
|
+
Codex; Claude Code's also reaches your sessions on other machines. Choose a managed runtime if you want the system to create agents, assign execution state,
|
|
49
72
|
select models, spend token budgets, or control ongoing agent execution. Choose a tracker when
|
|
50
73
|
you need organizational planning. Choose a hosted service when participants must
|
|
51
74
|
coordinate across machines.
|
package/docs/index.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# ACC documentation
|
|
2
2
|
|
|
3
|
-
ACC
|
|
4
|
-
|
|
3
|
+
ACC carries questions, reviews and handoffs between AI sessions you open yourself in clients
|
|
4
|
+
from different vendors, such as Claude Code and Codex. You continue to give each agent
|
|
5
|
+
ordinary work; supported integrations tell agents about their peers and
|
|
5
6
|
teach them how to coordinate when it is useful. The agents remain independent, and each
|
|
6
7
|
decides what its task requires.
|
|
7
8
|
|
|
@@ -9,12 +10,13 @@ decides what its task requires.
|
|
|
9
10
|
|
|
10
11
|
1. [Getting started](GETTING_STARTED.md) — install ACC, open two sessions, give them related
|
|
11
12
|
tasks, and know what coordination to look for.
|
|
12
|
-
2. [Why ACC](WHY_ACC.md) — decide whether
|
|
13
|
+
2. [Why ACC](WHY_ACC.md) — decide whether your work spans clients from different vendors and
|
|
14
|
+
needs ACC between them.
|
|
13
15
|
3. [Capabilities](CAPABILITIES.md) — check what your client and platform can actually do.
|
|
14
16
|
4. [Troubleshooting](TROUBLESHOOTING.md) — diagnose missing peers, queued messages, and
|
|
15
17
|
capability fallback.
|
|
16
|
-
5. [Upgrading ACC](UPGRADING.md) — update from 0.
|
|
17
|
-
|
|
18
|
+
5. [Upgrading ACC](UPGRADING.md) — update from 0.9.x, whose stores move to contract 7 by
|
|
19
|
+
themselves, or from an earlier release, and control automatic updates.
|
|
18
20
|
|
|
19
21
|
## See it in context
|
|
20
22
|
|
|
@@ -2,7 +2,8 @@ import { defineAdapter, projectContext, projectContextResult }
|
|
|
2
2
|
from "@agents-can-communicate/adapter-sdk";
|
|
3
3
|
import certification from "../certification.json" with { type: "json" };
|
|
4
4
|
|
|
5
|
-
import { denyOutcome, injectOutcome, injectStartOwnerOutcome, normalizeClaudeHook }
|
|
5
|
+
import { denyOutcome, failOpenNotice, injectOutcome, injectStartOwnerOutcome, normalizeClaudeHook }
|
|
6
|
+
from "./hooks.mjs";
|
|
6
7
|
import { MIN_VERSION, PROTOCOL_CONTRACT, bindNativeSession, offerMessage, planNativeActivation,
|
|
7
8
|
probeNativeDelivery, refreshNativeSession, retireNativeSession } from "./inbox-delivery.mjs";
|
|
8
9
|
import { observedInboxDirectories } from "./inbox-observed-directories.mjs";
|
|
@@ -110,6 +111,7 @@ export function createClaudeCodeAdapter() {
|
|
|
110
111
|
|
|
111
112
|
denyOutcome,
|
|
112
113
|
injectOutcome,
|
|
114
|
+
failOpenNotice,
|
|
113
115
|
injectStartOwnerOutcome,
|
|
114
116
|
normalizeHook: payload => normalizeClaudeHook(payload),
|
|
115
117
|
renderContext: (sync, options) => projectContext(sync, options),
|
|
@@ -120,3 +120,15 @@ export function injectStartOwnerOutcome(context) {
|
|
|
120
120
|
return { stdout: `${JSON.stringify({ hookSpecificOutput: {
|
|
121
121
|
hookEventName: "SessionStart", additionalContext: context } })}\n`, stderr: "", exitCode: 0 };
|
|
122
122
|
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* A line for the user when a hook fails open for a reason they can act on.
|
|
126
|
+
*
|
|
127
|
+
* Claude Code shows a hook's `systemMessage` to the user and never sends it to
|
|
128
|
+
* the model; a failed-open hook's stderr it shows to no one. Only on a session
|
|
129
|
+
* start and before a turn, the two hooks whose output a person is reading.
|
|
130
|
+
*/
|
|
131
|
+
export function failOpenNotice({ kind, message }) {
|
|
132
|
+
if (kind !== "sessionStart" && kind !== "beforeTurn") return null;
|
|
133
|
+
return JSON.stringify({ systemMessage: message });
|
|
134
|
+
}
|
|
@@ -9,7 +9,7 @@ import { createCodexDiscovery } from "./native-discovery.mjs";
|
|
|
9
9
|
export { sameMaintenanceIdentity } from "./maintenance.mjs";
|
|
10
10
|
|
|
11
11
|
import { CODEX_QUEUE_MINIMUM, PROTOCOL_CONTRACT } from "./app-server-client.mjs";
|
|
12
|
-
import { allowOutcome, denyOutcome, injectOutcome, normalizeCodexHook }
|
|
12
|
+
import { allowOutcome, denyOutcome, failOpenNotice, injectOutcome, normalizeCodexHook }
|
|
13
13
|
from "./hooks.mjs";
|
|
14
14
|
import { planCodexInstall, detectCodex, installCodexPlugin, preflightCodexUninstall,
|
|
15
15
|
uninstallCodexPlugin } from "./install.mjs";
|
|
@@ -121,6 +121,7 @@ export function createCodexAdapter() {
|
|
|
121
121
|
denyOutcome,
|
|
122
122
|
allowOutcome,
|
|
123
123
|
injectOutcome,
|
|
124
|
+
failOpenNotice,
|
|
124
125
|
normalizeHook: payload => normalizeCodexHook(payload),
|
|
125
126
|
renderContext: (sync, options) => projectContext(sync, options),
|
|
126
127
|
renderContextResult: (sync, options) => projectContextResult(sync, options),
|
|
@@ -160,3 +160,14 @@ export function injectOutcome(context, notice) {
|
|
|
160
160
|
hookSpecificOutput: { hookEventName: "UserPromptSubmit", additionalContext: context } }),
|
|
161
161
|
stderr: "", exitCode: 0 };
|
|
162
162
|
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* A line for the user when a hook fails open for a reason they can act on: the
|
|
166
|
+
* hook's `systemMessage`, which Codex shows in the chat and never sends to the
|
|
167
|
+
* model (0.147.0, 0.155.1 and 0.159.1). Only on a session start and before a
|
|
168
|
+
* turn, the two events where that display was measured.
|
|
169
|
+
*/
|
|
170
|
+
export function failOpenNotice({ kind, message }) {
|
|
171
|
+
if (kind !== "sessionStart" && kind !== "beforeTurn") return null;
|
|
172
|
+
return JSON.stringify({ systemMessage: message });
|
|
173
|
+
}
|
|
@@ -181,6 +181,12 @@ export function defineAdapter(manifest) {
|
|
|
181
181
|
if (manifest.inboundSockets !== undefined && typeof manifest.inboundSockets !== "function") {
|
|
182
182
|
usage("optional inboundSockets must be a function", { id: manifest.id });
|
|
183
183
|
}
|
|
184
|
+
// `failOpenNotice({ kind, message })` renders a line the user sees when a hook
|
|
185
|
+
// fails open for a reason the user can act on, or returns null. Only a client
|
|
186
|
+
// whose hook output reaches the user declares it.
|
|
187
|
+
if (manifest.failOpenNotice !== undefined && typeof manifest.failOpenNotice !== "function") {
|
|
188
|
+
usage("optional failOpenNotice must be a function", { id: manifest.id });
|
|
189
|
+
}
|
|
184
190
|
if (manifest.nativeDelivery !== undefined) {
|
|
185
191
|
const client = manifest.client.certificationName ?? manifest.client.command;
|
|
186
192
|
native.nativeDelivery = validateNativeDeliveryContract(manifest.nativeDelivery,
|