agents-can-communicate 0.8.4 → 0.9.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 +11 -7
- package/bin/entrypoints/acc-antigravity-relay.mjs +2 -4
- package/bin/entrypoints/acc-hook.mjs +33 -19
- package/bin/entrypoints/hook-output.mjs +14 -5
- package/docs/ADAPTER_AUTHORING.md +32 -0
- package/docs/ARCHITECTURE.md +7 -4
- package/docs/CAPABILITIES.md +7 -6
- package/docs/CLI.md +5 -0
- package/docs/CONFIGURATION.md +15 -10
- package/docs/DESIGN_DECISIONS.md +0 -2
- package/docs/GETTING_STARTED.md +39 -6
- package/docs/HOW_IT_WORKS.md +13 -8
- package/docs/SECURITY_MODEL.md +26 -5
- package/docs/TROUBLESHOOTING.md +74 -12
- package/docs/UPGRADING.md +50 -5
- package/node_modules/@agents-can-communicate/adapter-antigravity/certification.json +78 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/certification-provenance.json +111 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/delivery/antigravity-desktop-2.19.1-product-evidence.json +156 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/delivery/antigravity-desktop-2.19.1-product.json +25 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/desktop-2.19.1.json +141 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/package.json +4 -1
- package/node_modules/@agents-can-communicate/adapter-antigravity/plugin/plugin.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/adapter.mjs +13 -2
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/agentapi.mjs +7 -5
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/allow-rule.mjs +98 -17
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/client-process.mjs +64 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/desktop-allow-rule.mjs +140 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/desktop-delivery.mjs +110 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/desktop-endpoint.mjs +203 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/install.mjs +61 -30
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/native-delivery.mjs +61 -24
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/relay-endpoint.mjs +30 -20
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/relay-start.mjs +2 -1
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/relay.mjs +20 -12
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/relays.mjs +18 -4
- 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 +6 -0
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/inbox-delivery.mjs +50 -37
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/inbox-endpoint.mjs +44 -31
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/inbox-registry.mjs +99 -14
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/inbox-settings.mjs +3 -7
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/inbox-socket-directories.mjs +6 -4
- package/node_modules/@agents-can-communicate/adapter-claude-code/src/install.mjs +32 -7
- package/node_modules/@agents-can-communicate/adapter-codex/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-codex/src/app-server-client.mjs +68 -3
- package/node_modules/@agents-can-communicate/adapter-codex/src/daemon-layouts.mjs +13 -0
- package/node_modules/@agents-can-communicate/adapter-codex/src/embedded-host.mjs +87 -13
- package/node_modules/@agents-can-communicate/adapter-codex/src/hooks.mjs +16 -6
- package/node_modules/@agents-can-communicate/adapter-codex/src/install.mjs +18 -9
- package/node_modules/@agents-can-communicate/adapter-codex/src/maintenance-host.mjs +68 -27
- package/node_modules/@agents-can-communicate/adapter-codex/src/native-delivery.mjs +66 -26
- package/node_modules/@agents-can-communicate/adapter-codex/src/native-endpoint.mjs +39 -16
- package/node_modules/@agents-can-communicate/adapter-codex/src/ws-json-rpc.mjs +4 -2
- 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-gemini-cli/src/adapter.mjs +2 -1
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/src/install.mjs +15 -9
- package/node_modules/@agents-can-communicate/adapter-grok/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-grok/src/install.mjs +25 -14
- package/node_modules/@agents-can-communicate/adapter-kimi/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-kimi/src/adapter.mjs +2 -1
- package/node_modules/@agents-can-communicate/adapter-kimi/src/install.mjs +15 -10
- package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/src/capabilities.mjs +50 -5
- package/node_modules/@agents-can-communicate/adapter-sdk/src/certification.mjs +11 -2
- package/node_modules/@agents-can-communicate/adapter-sdk/src/executables.mjs +149 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/hook-shim.mjs +79 -12
- package/node_modules/@agents-can-communicate/adapter-sdk/src/index.mjs +11 -2
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-attempt.mjs +6 -2
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-delivery.mjs +82 -17
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-vocabulary.mjs +9 -2
- package/node_modules/@agents-can-communicate/adapter-sdk/src/private-files.mjs +35 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/process-table.mjs +232 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/session-binding.mjs +8 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/src/windows-command.mjs +69 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/windows-process-chain.wsf +45 -0
- package/node_modules/@agents-can-communicate/cli/package.json +2 -1
- package/node_modules/@agents-can-communicate/cli/src/config-command.mjs +2 -1
- package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +60 -4
- package/node_modules/@agents-can-communicate/cli/src/hook-support.mjs +9 -0
- package/node_modules/@agents-can-communicate/cli/src/hook-workspace.mjs +12 -3
- package/node_modules/@agents-can-communicate/cli/src/main.mjs +2 -1
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/activation.mjs +3 -2
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/download.mjs +12 -3
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/entry.mjs +7 -5
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/generation.mjs +7 -7
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/launchers.mjs +8 -5
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/maintenance.mjs +1 -1
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/mutex.mjs +7 -6
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/portable-fs.mjs +165 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/schedule.mjs +1 -1
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/state.mjs +18 -8
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/worker.mjs +18 -3
- package/node_modules/@agents-can-communicate/cli/src/native-session-diagnostics.mjs +15 -4
- package/node_modules/@agents-can-communicate/cli/src/platform-paths.mjs +15 -10
- package/node_modules/@agents-can-communicate/cli/src/runtime-paths.mjs +3 -2
- package/node_modules/@agents-can-communicate/cli/src/update-command.mjs +11 -1
- package/node_modules/@agents-can-communicate/cli/src/workspace-discovery.mjs +4 -2
- package/node_modules/@agents-can-communicate/core/package.json +1 -1
- package/node_modules/@agents-can-communicate/core/src/delivery-bindings.mjs +7 -0
- package/node_modules/@agents-can-communicate/core/src/materialisation.mjs +39 -1
- package/node_modules/@agents-can-communicate/core/src/session-opening.mjs +11 -0
- package/node_modules/@agents-can-communicate/core/src/sessions.mjs +8 -2
- package/node_modules/@agents-can-communicate/delivery-router/package.json +1 -1
- package/node_modules/@agents-can-communicate/delivery-router/src/native-reason.mjs +6 -2
- package/node_modules/@agents-can-communicate/delivery-router/src/router.mjs +9 -5
- package/node_modules/@agents-can-communicate/hook-runner/package.json +1 -1
- package/node_modules/@agents-can-communicate/hook-runner/src/client-pid.mjs +65 -6
- package/node_modules/@agents-can-communicate/hook-runner/src/client-version.mjs +80 -0
- package/node_modules/@agents-can-communicate/hook-runner/src/native-attempt.mjs +7 -2
- package/node_modules/@agents-can-communicate/hook-runner/src/native-binding.mjs +6 -3
- package/node_modules/@agents-can-communicate/hook-runner/src/owner-context.mjs +34 -6
- package/node_modules/@agents-can-communicate/hook-runner/src/process-table.mjs +3 -50
- package/node_modules/@agents-can-communicate/hook-runner/src/runner.mjs +167 -34
- package/node_modules/@agents-can-communicate/installer/package.json +3 -2
- package/node_modules/@agents-can-communicate/installer/src/delivery-diagnostics.mjs +11 -2
- package/node_modules/@agents-can-communicate/installer/src/detect.mjs +13 -3
- package/node_modules/@agents-can-communicate/installer/src/hook-support.mjs +5 -0
- package/node_modules/@agents-can-communicate/installer/src/native-activation.mjs +6 -14
- package/node_modules/@agents-can-communicate/installer/src/plan.mjs +14 -0
- 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/config.mjs +6 -2
- package/node_modules/@agents-can-communicate/protocol/src/resources.mjs +6 -2
- package/node_modules/@agents-can-communicate/storage-filesystem/package.json +1 -1
- package/node_modules/@agents-can-communicate/storage-filesystem/src/active-journal.mjs +5 -2
- package/node_modules/@agents-can-communicate/storage-filesystem/src/atomic-json.mjs +41 -23
- package/node_modules/@agents-can-communicate/storage-filesystem/src/doomed-directory.mjs +4 -12
- package/node_modules/@agents-can-communicate/storage-filesystem/src/identity.mjs +7 -3
- package/node_modules/@agents-can-communicate/storage-filesystem/src/index.mjs +1 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/journal.mjs +24 -7
- package/node_modules/@agents-can-communicate/storage-filesystem/src/portable-fs.mjs +165 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/publication-path.mjs +8 -0
- package/node_modules/@agents-can-communicate/storage-filesystem/src/reclaim.mjs +26 -17
- package/node_modules/@agents-can-communicate/storage-filesystem/src/recovery.mjs +7 -5
- package/node_modules/@agents-can-communicate/storage-filesystem/src/retention.mjs +7 -16
- package/node_modules/@agents-can-communicate/storage-filesystem/src/safe-directory.mjs +138 -24
- package/node_modules/@agents-can-communicate/storage-filesystem/src/safe-file.mjs +3 -2
- package/node_modules/@agents-can-communicate/storage-filesystem/src/stage-sweep.mjs +9 -6
- package/node_modules/@agents-can-communicate/storage-filesystem/src/store.mjs +30 -8
- package/node_modules/@agents-can-communicate/storage-filesystem/src/writer-mutex.mjs +102 -32
- package/package.json +1 -5
package/README.md
CHANGED
|
@@ -52,8 +52,10 @@ flowchart TB
|
|
|
52
52
|
|
|
53
53
|
## Try one handoff
|
|
54
54
|
|
|
55
|
-
You’ll need **macOS or
|
|
56
|
-
machine and operating-system user.
|
|
55
|
+
You’ll need **macOS, Linux or Windows 10/11, Node.js 24 or newer**, and supported coding
|
|
56
|
+
clients on the same machine and operating-system user. On Windows, ACC runs natively, with no
|
|
57
|
+
WSL, and live delivery reaches Claude Code, Codex and Antigravity CLI there too. See
|
|
58
|
+
[Windows](docs/GETTING_STARTED.md#windows).
|
|
57
59
|
|
|
58
60
|
```bash
|
|
59
61
|
npm install -g agents-can-communicate
|
|
@@ -96,11 +98,13 @@ instructions.
|
|
|
96
98
|
Automatic delivery depends on the client version and platform. Verified integrations can
|
|
97
99
|
provide messages at the next normal turn; other sessions read their ACC inbox explicitly.
|
|
98
100
|
|
|
99
|
-
Experimental live delivery can wake eligible Claude Code
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
between two tool calls. A busy Codex session gets
|
|
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. It requires opt-in and an active verified
|
|
103
|
+
connection, is off by default, and can spend model tokens. Claude Code sessions wake through
|
|
104
|
+
the inbox that Claude Code itself opens, so you start Claude Code with your ordinary command.
|
|
105
|
+
A busy Claude Code session gets the message between two tool calls. A busy Codex session gets
|
|
106
|
+
it when the current turn ends. Chats in the Codex app run on the app's own server and get
|
|
107
|
+
messages at their next turn.
|
|
104
108
|
|
|
105
109
|
See [client capabilities](docs/CAPABILITIES.md) for exact support. Run `acc doctor` from your
|
|
106
110
|
project if a peer is missing or delivery differs from what you expect; see
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
// The relay the agent starts: `start` in its tool shell, `run` detached from it.
|
|
3
3
|
// Fails open everywhere - `start` prints one line and exits 0; `run` answers its
|
|
4
4
|
// ready line and exits quietly when anything it needs is missing.
|
|
5
|
-
import { execFile } from "node:child_process";
|
|
6
5
|
import { randomBytes } from "node:crypto";
|
|
7
6
|
import { appendFile } from "node:fs/promises";
|
|
8
7
|
import path from "node:path";
|
|
@@ -11,7 +10,7 @@ import { agentApiCommand, createAgentApi } from "@agents-can-communicate/adapter
|
|
|
11
10
|
import { createRelay } from "@agents-can-communicate/adapter-antigravity/relay";
|
|
12
11
|
import { listRegistrations, newRelayId, relayDir } from "@agents-can-communicate/adapter-antigravity/relay-endpoint";
|
|
13
12
|
import { findConversation, spawnRelay, startRelay } from "@agents-can-communicate/adapter-antigravity/relay-start";
|
|
14
|
-
import { loadSessionBinding } from "@agents-can-communicate/adapter-sdk";
|
|
13
|
+
import { loadSessionBinding, readProcessArgs } from "@agents-can-communicate/adapter-sdk";
|
|
15
14
|
import { platformDataHome } from "@agents-can-communicate/cli";
|
|
16
15
|
import { createCoordinationService } from "@agents-can-communicate/core";
|
|
17
16
|
import { resolveClientPid } from "@agents-can-communicate/hook-runner/client-pid";
|
|
@@ -27,8 +26,7 @@ const ids = { next: kind => createId(kind, randomBytes) };
|
|
|
27
26
|
const alive = pid => { try { process.kill(pid, 0); return true; } catch { return false; } };
|
|
28
27
|
const READY_MS = 10_000;
|
|
29
28
|
|
|
30
|
-
const argvOf = pid =>
|
|
31
|
-
{ timeout: 1_000 }, (_error, out) => resolve(String(out ?? "").trim().split(/\s+/).filter(Boolean))));
|
|
29
|
+
const argvOf = async pid => await readProcessArgs(pid, { timeoutMs: 1_000 }) ?? [];
|
|
32
30
|
|
|
33
31
|
// Through the launcher that ran `start`, never this module directly: an entry
|
|
34
32
|
// module does not run itself, and under the managed runtime the launcher takes
|
|
@@ -10,26 +10,36 @@ import { pathToFileURL } from "node:url";
|
|
|
10
10
|
|
|
11
11
|
import { createId } from "@agents-can-communicate/protocol";
|
|
12
12
|
import { runHook } from "@agents-can-communicate/hook-runner";
|
|
13
|
-
import { hookEntrypointFor, resolvePinnedGeneration }
|
|
13
|
+
import { hookEntrypointFor, resolvePinnedGeneration }
|
|
14
|
+
from "@agents-can-communicate/cli/hook-support";
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
import { createGrokAdapter } from "@agents-can-communicate/adapter-grok";
|
|
20
|
-
import { createKimiAdapter } from "@agents-can-communicate/adapter-kimi";
|
|
21
|
-
|
|
22
|
-
const adapters = {
|
|
16
|
+
// A hook runs one client's adapter, and loads only that one: every other
|
|
17
|
+
// adapter was a set of modules loaded on each turn and never run, about a
|
|
18
|
+
// millisecond each on windows-latest.
|
|
19
|
+
const ADAPTERS = {
|
|
23
20
|
// Registered like any other client. Its hook commands carry an extra
|
|
24
21
|
// argument - the event name - because this client's payload has none.
|
|
25
|
-
antigravity:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
22
|
+
antigravity: () => import("@agents-can-communicate/adapter-antigravity")
|
|
23
|
+
.then(module => module.createAntigravityAdapter()),
|
|
24
|
+
claude_code: () => import("@agents-can-communicate/adapter-claude-code")
|
|
25
|
+
.then(module => module.createClaudeCodeAdapter()),
|
|
26
|
+
codex: () => import("@agents-can-communicate/adapter-codex")
|
|
27
|
+
.then(module => module.createCodexAdapter()),
|
|
28
|
+
gemini_cli: () => import("@agents-can-communicate/adapter-gemini-cli")
|
|
29
|
+
.then(module => module.createGeminiCliAdapter()),
|
|
30
|
+
grok: () => import("@agents-can-communicate/adapter-grok")
|
|
31
|
+
.then(module => module.createGrokAdapter()),
|
|
32
|
+
kimi: () => import("@agents-can-communicate/adapter-kimi")
|
|
33
|
+
.then(module => module.createKimiAdapter()),
|
|
31
34
|
};
|
|
32
35
|
|
|
36
|
+
// The adapters this hook can use: its own, or none for an id nobody registered,
|
|
37
|
+
// which runHook answers the way it always has.
|
|
38
|
+
async function adaptersFor(adapterId) {
|
|
39
|
+
if (!Object.hasOwn(ADAPTERS, adapterId)) return {};
|
|
40
|
+
return { [adapterId]: await ADAPTERS[adapterId]() };
|
|
41
|
+
}
|
|
42
|
+
|
|
33
43
|
const readStdin = () => new Promise(resolve => {
|
|
34
44
|
// A hook is always given its payload on stdin, but a client that closes it
|
|
35
45
|
// without writing must not leave this process hanging in front of a turn.
|
|
@@ -50,7 +60,7 @@ import { completeHookOutput } from "./hook-output.mjs";
|
|
|
50
60
|
// a hook that has no pin to look up pays nothing beyond it. Any adapter or
|
|
51
61
|
// payload that will not yield a session id simply has no pin to find, same as
|
|
52
62
|
// today's no-pin behaviour.
|
|
53
|
-
async function harnessSessionIdFor(adapterId, payload, args) {
|
|
63
|
+
async function harnessSessionIdFor(adapters, adapterId, payload, args) {
|
|
54
64
|
try {
|
|
55
65
|
const event = await adapters[adapterId]?.normalizeHook(payload, { args });
|
|
56
66
|
return typeof event?.sessionId === "string" ? event.sessionId : null;
|
|
@@ -75,9 +85,10 @@ async function harnessSessionIdFor(adapterId, payload, args) {
|
|
|
75
85
|
// mid-resolution by another hook for the same session, or simply wrong)
|
|
76
86
|
// could say. Unbounded delegation would be a hang, worse than any of the
|
|
77
87
|
// failures this file already falls open from.
|
|
78
|
-
async function delegateToPin({ managerRoot, packageRoot, adapterId, payload, args,
|
|
88
|
+
async function delegateToPin({ managerRoot, packageRoot, adapters, adapterId, payload, args,
|
|
89
|
+
delegated }) {
|
|
79
90
|
if (delegated || managerRoot === null || packageRoot === null) return false;
|
|
80
|
-
const harnessSessionId = await harnessSessionIdFor(adapterId, payload, args);
|
|
91
|
+
const harnessSessionId = await harnessSessionIdFor(adapters, adapterId, payload, args);
|
|
81
92
|
if (harnessSessionId === null) return false;
|
|
82
93
|
const pinned = await resolvePinnedGeneration({ root: managerRoot, harnessSessionId, active: packageRoot });
|
|
83
94
|
if (pinned === null) return false;
|
|
@@ -103,7 +114,10 @@ export async function main({ managerRoot = null, packageRoot = null, payload, de
|
|
|
103
114
|
}
|
|
104
115
|
}
|
|
105
116
|
|
|
106
|
-
|
|
117
|
+
// A broken adapter module fails the hook open like any other error here.
|
|
118
|
+
const adapters = await adaptersFor(adapterId).catch(() => ({}));
|
|
119
|
+
if (await delegateToPin({ managerRoot, packageRoot, adapters, adapterId, payload, args,
|
|
120
|
+
delegated })) return;
|
|
107
121
|
|
|
108
122
|
const result = await runHook({ adapterId, payload, args, adapters,
|
|
109
123
|
runtime: { clock: { now: () => new Date().toISOString() },
|
|
@@ -56,16 +56,25 @@ function tryWrite(stream, output) {
|
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
const RECOVERY = new Map([
|
|
60
|
+
["workspace_contains_runtime", ": workspace contains ACC runtime state; open a project"
|
|
61
|
+
+ " directory and restart the client (or set ACC_DATA_HOME outside the workspace)"],
|
|
62
|
+
["workspace_path_unquotable", ": this directory's path has a double quote, $, ` or %, which"
|
|
63
|
+
+ " no Windows shell quotes alike; rename it and restart the client"],
|
|
64
|
+
]);
|
|
65
|
+
|
|
66
|
+
// The step a hook was in when its budget ran out, as the runner names it: a few
|
|
67
|
+
// plain words, never text from the hook's input.
|
|
68
|
+
const PHASE = /^[a-z][a-z ]{0,59}$/;
|
|
69
|
+
|
|
59
70
|
export async function completeHookOutput(result,
|
|
60
71
|
{ stdout = process.stdout, stderr = process.stderr } = {}) {
|
|
61
72
|
if (result.failed || result.timedOut) {
|
|
62
73
|
// Only a known code selects static recovery advice. Arbitrary payload or
|
|
63
74
|
// filesystem error text must never become client-visible instructions.
|
|
64
|
-
const recovery = result.failureCode
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
: "";
|
|
68
|
-
tryWrite(stderr, `acc: coordination unavailable${recovery}; hook continued without context\n`);
|
|
75
|
+
const recovery = RECOVERY.get(result.failureCode) ?? "";
|
|
76
|
+
const held = result.timedOut && PHASE.test(result.phase ?? "") ? ` (timed out while ${result.phase})` : "";
|
|
77
|
+
tryWrite(stderr, `acc: coordination unavailable${recovery}${held}; hook continued without context\n`);
|
|
69
78
|
}
|
|
70
79
|
try {
|
|
71
80
|
await writeOutput(stdout, result.stdout ?? "", { deadlineAt: result.deadlineAt });
|
|
@@ -92,6 +92,30 @@ command that matches neither resolves nothing, and the failure is silent: the se
|
|
|
92
92
|
`pid: null`, falls back to reading presence by age alone, and is not pinned to its
|
|
93
93
|
generation, with nothing telling you why.
|
|
94
94
|
|
|
95
|
+
Some vendors ship a second product that runs the same hooks: Antigravity 2.0, the desktop
|
|
96
|
+
app, runs `~/.gemini/config/hooks.json` under its own language server, with no `agy`, on a
|
|
97
|
+
version line of its own. Declare such a product as a variant and recognise its process:
|
|
98
|
+
|
|
99
|
+
```js
|
|
100
|
+
client: { command: "agy", certificationName: "antigravity-cli", versionArgs: ["--version"],
|
|
101
|
+
variants: [{ certificationName: "antigravity-desktop", displayName: "Antigravity" }] },
|
|
102
|
+
identifyClientProcess: entry => /* null, or { certificationName, version } */,
|
|
103
|
+
clientVersionOf: async ({ pid, entry, env }) => /* the running client's version, or null */,
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
- `identifyClientProcess(entry)` is called with each ancestor `{ comm, args }` before the
|
|
107
|
+
`client.command` match. It is synchronous and reads only the entry it is given; a throw is a
|
|
108
|
+
"no". A `certificationName` that names no declared variant is ignored, with its version.
|
|
109
|
+
- Evidence may name a declared variant. A variant is judged only by its own evidence: its
|
|
110
|
+
versions count on its own line, so the primary client's captures never stand in for it.
|
|
111
|
+
Declaring a capability `true` still needs passing evidence of the primary client.
|
|
112
|
+
- The session's version is, in order: the version `identifyClientProcess` returned, then
|
|
113
|
+
`clientVersionOf()`, then the client's own executable when `ps` names it by absolute path,
|
|
114
|
+
then `client.command` on `PATH`. The `PATH` probe alone named the wrong build for a
|
|
115
|
+
Claude.app session (its own claude, 2.1.286, against 2.1.289 on `PATH`) and for every
|
|
116
|
+
Claude Code session that outlived an in-place update; Claude Code's adapter therefore reads
|
|
117
|
+
the version from the session record Claude Code keeps for that pid.
|
|
118
|
+
|
|
95
119
|
## Declare only proven capabilities
|
|
96
120
|
|
|
97
121
|
Fourteen booleans in four groups, declared in the manifest's `capabilities` object:
|
|
@@ -168,6 +192,11 @@ The rules `defineAdapter` enforces, and the ones the runtime applies:
|
|
|
168
192
|
anchor must have passing `delivery.livePush` evidence for the same client and version, and
|
|
169
193
|
the minimum must itself be an anchor. The platform an evidence row names is where the
|
|
170
194
|
capture was taken; it is provenance, and the anchor names no platform.
|
|
195
|
+
- An anchor may name a declared variant, `{ version, protocolContract, client }`, for a
|
|
196
|
+
delivery protocol only that product speaks. Each protocol's floor is its own first passing
|
|
197
|
+
capture: a handshake or probe is judged against the floor of the protocol it reports, and
|
|
198
|
+
one protocol cannot be anchored for two products. `minimum` stays the primary client's
|
|
199
|
+
first capture, and `knownBad` names the primary client's versions.
|
|
171
200
|
- There is intentionally **no maximum version** and **no platform**. A newer release is
|
|
172
201
|
admitted, on every platform, only when a current read-only feature probe
|
|
173
202
|
(`probeNativeDelivery()`) and a per-session handshake (`bindNativeSession()`) both report
|
|
@@ -192,6 +221,9 @@ transport that is technically different on some platform is the probe's fact to
|
|
|
192
221
|
`docs/design/2026-09-26-native-delivery-across-platforms.md` in the repository.
|
|
193
222
|
- Native methods return closed facts (`validateNativeActivationPlan()` closes the
|
|
194
223
|
activation plan) and never put vendor data - endpoints, sockets, raw errors - into core.
|
|
224
|
+
A refused handshake may add `launchOption`: the bare command-line option, such as
|
|
225
|
+
`--search`, that made the client refuse. Doctor and the sender name it; a value, a vendor
|
|
226
|
+
string or anything but an option token is rejected.
|
|
195
227
|
|
|
196
228
|
`nativeDelivery.policySource` accepts only `"installation-record"`, which is also the
|
|
197
229
|
default. Hooks and senders read the current recorded recipient consent, independently of
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -231,10 +231,13 @@ store contract this one does, and run the active generation otherwise. Apart fro
|
|
|
231
231
|
`SessionEnd`, only the client's confirmed death releases a pin, so a session whose client
|
|
232
232
|
process cannot be found is not pinned, and a pin that names no client is reaped. A
|
|
233
233
|
generation directory is reclaimed once no control pointer, live lease, live pin or staging
|
|
234
|
-
hold names it. An update is run by the installed code, so
|
|
235
|
-
|
|
236
|
-
recorded in `reclaim.json
|
|
237
|
-
|
|
234
|
+
hold names it. An update is run by the installed code, so right after an activation the
|
|
235
|
+
activated generation's own reclaim runs from its files, and its worker reclaims on every later
|
|
236
|
+
pass; each pass is recorded in `reclaim.json`. The updating process still runs from the
|
|
237
|
+
generation it replaced, and its lease keeps that one through the pass. Such a pass, like one an
|
|
238
|
+
unknown holder postponed, is recorded as unfinished, and the next ACC command an hour or more
|
|
239
|
+
later starts the worker that finishes it. Parsed help, version, and update recovery remain
|
|
240
|
+
available when workspace admission is unavailable.
|
|
238
241
|
|
|
239
242
|
An independent worker downloads npm packages with lifecycle scripts disabled, checks exact
|
|
240
243
|
stable package identity and the discovered integrity, and health-checks the staged runtime.
|
package/docs/CAPABILITIES.md
CHANGED
|
@@ -4,8 +4,8 @@ Use this page to set expectations after installation. Integration means ACC can
|
|
|
4
4
|
peer awareness and coordination instructions; it does not guarantee what a model will do
|
|
5
5
|
with them. Delivery also varies independently from awareness. The durable inbox works for
|
|
6
6
|
every participant, a client at or after a captured version may add next-turn delivery, and the
|
|
7
|
-
experimental Codex LocalDaemon, Claude Code inbox wake and Antigravity
|
|
8
|
-
deliver while a session is idle.
|
|
7
|
+
experimental Codex LocalDaemon, Claude Code inbox wake and Antigravity relay and desktop paths
|
|
8
|
+
can deliver while a session is idle.
|
|
9
9
|
|
|
10
10
|
Capability honesty separates four questions that are easy to collapse:
|
|
11
11
|
|
|
@@ -64,16 +64,17 @@ What may refuse live delivery is exactly three things:
|
|
|
64
64
|
|
|
65
65
|
Nothing else: not the platform, not a prerelease suffix, not where the evidence was taken.
|
|
66
66
|
A platform whose transport is technically different is refused by the probe as a fact about
|
|
67
|
-
that transport
|
|
67
|
+
that transport. Codex, Claude Code and Antigravity CLI reply through `acc reply`. Their native
|
|
68
68
|
`replyRoute` remains false.
|
|
69
69
|
|
|
70
70
|
The limitations belong next to the adapters they affect:
|
|
71
71
|
|
|
72
72
|
| Adapter | Exact limitation and evidence |
|
|
73
73
|
|---|---|
|
|
74
|
-
| Antigravity CLI | 1.2.7 on darwin-arm64, captured in print mode, and every later release by the forward rule. Only `SessionStart`, `PreInvocation`, `PostInvocation` and `Stop` load; `SessionEnd`, `PreToolUse` and `PostToolUse` are accepted into the config file and silently dropped, so there is no tool guard and no session-end deregistration - a session goes offline by presence age or an explicit `acc finish`. Payloads carry no `hook_event_name`, so each registered command passes its own event name. The end-of-turn `Stop` continuation reaches the model and is a bounded nudge, not a gate: ACC continues a turn at most once and fails open, and the client caps consecutive continuations itself (vendor 1.1.9). `agy agentapi send-message` can wake an idle session - captured - but only with that session's language-server address and CSRF token, which exist in the agent's own shell and in no hook
|
|
75
|
-
|
|
|
76
|
-
|
|
|
74
|
+
| Antigravity CLI | 1.2.7 on darwin-arm64, captured in print mode, and every later release by the forward rule. Only `SessionStart`, `PreInvocation`, `PostInvocation` and `Stop` load; `SessionEnd`, `PreToolUse` and `PostToolUse` are accepted into the config file and silently dropped, so there is no tool guard and no session-end deregistration - a session goes offline by presence age or an explicit `acc finish`. Payloads carry no `hook_event_name`, so each registered command passes its own event name. The end-of-turn `Stop` continuation reaches the model and is a bounded nudge, not a gate: ACC continues a turn at most once and fails open, and the client caps consecutive continuations itself (vendor 1.1.9). `agy agentapi send-message` can wake an idle session - captured - but only with that session's language-server address and CSRF token, which exist in the agent's own shell and in no hook; reply routing is false. A peer message that arrives while the model writes its last answer is carried by the `Stop` continuation instead. A write that parses can register nothing, so install and doctor read `agy -p "/hooks"` back instead of trusting the file. Live push (1.2.7, darwin-arm64, TUI only, experimental, recorded opt-in) runs through a relay the agent starts once per conversation from its own shell - the only process holding the session endpoint - after ACC's context asks it to, up to three times while none is serving; install allows that command too, so the agent starts the relay without a prompt (1.2.16, 2026-10-04); on Windows, where install adds no rule, the operator approves it at the client's permission prompt. An idle session wakes; a busy one sees the message after its running answer, or at the next model invocation when the turn waits on a tool. Print mode and the first session in a folder trusted at that launch get no relay. The client asks before every shell command (1.2.12), so install adds the prefix rule `command(<wrapper>)` to the client's settings, except on Windows, to let the woken agent's ACC commands run without that prompt. A woken session answered with no prompt under that rule on 1.2.12 (2026-09-28); print mode with it has not been captured. On Windows the relay listens on a named pipe, `\\.\pipe\acc-relay-<32 hex>`, starts with `node`, and runs `agy.exe` itself, never a `.cmd`, since the message reaches agy as an argument. |
|
|
75
|
+
| Antigravity 2.0 (desktop app) | 2.19.1 on darwin-arm64, captured 2026-10-04. The app runs the same `~/.gemini/config/hooks.json` under its own language server, with no `agy`, so ACC identifies the session by that server and the version on its command line (`--override_ide_version`), and judges it by the desktop's own evidence, never by Antigravity CLI's version line. `SessionStart` and `PreInvocation` fire; a peer message reaches the model at the next model invocation. Live push (2.19.1, darwin-arm64, experimental, recorded opt-in) needs no relay and no command from the agent: ACC reads the endpoint from the language server's command line when it binds and when it delivers, keeps the token only in one `agentapi` child's environment, and pushes into the conversation through the server's own `agentapi`. A product capture passed all six cases: an idle conversation woke with no user input; a push during a long answer was shown after it, uninterrupted; the woken agent answered with `acc reply` without an approval prompt; a resent message reached the model once; with the app quit the message stayed queued; after a restart the conversation's next turn bound it again. The app runs no `SessionStart` for a conversation it reopens, so after a restart live delivery returns at that next turn. One language server serves every window and conversation, so a desktop participant goes offline when the app quits. The app runs the agent's commands in a sandbox where ACC's wrapper cannot run; the model then retries outside it, which the app allows by the grants in `~/.gemini/config/config.json`, and install adds ACC's rule there once the app has run. Installing the integration still needs Antigravity CLI, whose `agy -p "/hooks"` reads the registration back. |
|
|
76
|
+
| Codex | Next-turn context, captured on 0.147.0, requires plugin trust. The observed stock 0.153.4 upgrade from ACC 0.3.1 to 0.4 required fresh review of five modified hook definitions; a subsequent restart retained all five active (activation evidence, not new event certification). LocalDaemon native delivery was captured through the installed package on 0.152.1 and 0.153.4, darwin-arm64; minimum 0.152.1, recorded opt-in, current feature probe and exact thread/cwd/process/version/protocol checks are required. Ordinary launch preserves the receiver workspace without ACC arguments or daemon ownership. On Windows, where Node cannot open the daemon's AF_UNIX socket, ACC speaks the same protocol over the stdio of `codex app-server proxy` (measured on 0.159.3); Codex starts its daemon only from a terminal that is not elevated. Embedded or unreachable sessions keep their inbox. The Codex app (inside ChatGPT.app, read on 26.928) runs every chat on a private app server over stdio rather than the shared daemon (openai/codex#41014); its chats run ACC's hooks, receive messages at their next turn, and are reported as `client_session_embedded`. Native `replyRoute` remains false. |
|
|
77
|
+
| Claude Code | 2.1.233 next-turn delivery waits for the next user prompt. From 2.1.282, captured on darwin-arm64 and applied on every platform, `delivery.livePush` is a live capability behind the native contract (experimental, off until opted in). ACC wakes the session through the inbox socket that Claude Code opens for every session, with one line of fixed ACC text and the message id. An idle session starts a turn. A busy session takes the wake between two tool calls. Each delivered wake fires `UserPromptSubmit`, so the next-turn hook shows the body and records the receipt `offered` via `next-turn`. The model answers with `acc reply`, so `delivery.replyRoute` stays false. A session in `bypassPermissions` mode holds each wake for approval unless `crossSessionInbound` is `accept`, and `refuse` drops wakes. Claude.app runs a local Code session on a Claude Code build of its own with the same `~/.claude`: such a session registers the same inbox (`entrypoint: claude-desktop`), and on 2.1.286 (2026-10-04) an idle one woke and answered with `acc reply` with no adapter change. Its Cloud, SSH and Cowork sessions run on another machine. ACC takes a session's version from the record Claude Code keeps for that process, because the `claude` on `PATH` can be another build. On native Windows the inbox is a named pipe, `\\.\pipe\LOCAL\cc-msg-<32 hex>`, that drops a frame without an auth line; ACC authenticates with the peer key Claude Code publishes beside the session record for other sessions of the same user, never the session's own token, so the recipient's inbound settings apply as on POSIX. Measured on 2.1.286; the real-clients CI job wakes an idle interactive Claude Code on Linux and on Windows. |
|
|
77
78
|
| Gemini CLI | Package-shipped next-turn certification starts at 0.57.0. Its TUI has no captured external wake or queue interface and `--acp` changes launch ownership, so native delivery is fallback-only; live push and reply routing remain false. |
|
|
78
79
|
| Grok | The Grok 1.0.24 installed-client check observed own CLI arguments after a terminal result, followed by owned work, message, and finish calls. This identity-only path does not certify peer-context injection. Documentation-shaped payloads do not count as real captures. The public leader surface exposed no proven addressed injection into an ordinary TUI session, so native delivery is `awaiting_compatibility_capture`; all capabilities remain false. |
|
|
79
80
|
| Kimi Code | Next-turn and guard evidence was captured on 0.36.1, plus a 60-second heartbeat. Its server/queue APIs do not prove a transparent binding to an independently opened session, so native delivery is fallback-only. |
|
package/docs/CLI.md
CHANGED
|
@@ -369,6 +369,11 @@ before leaving, request the concrete continuation and obtain a substantive reply
|
|
|
369
369
|
| `acc help` | — |
|
|
370
370
|
| `acc version` | — |
|
|
371
371
|
|
|
372
|
+
`acc uninstall` takes back what the current ACC data home installed. A client on the machine
|
|
373
|
+
that this data home has no install record for - one another data home wired, such as your own
|
|
374
|
+
beside an isolated `ACC_DATA_HOME` - is skipped with the reason; name it with `--adapter` to
|
|
375
|
+
remove its ACC wiring anyway.
|
|
376
|
+
|
|
372
377
|
`--delivery off|actionable|all` is a per-client recipient policy request, not a capability
|
|
373
378
|
switch, and the default is `off`. `--adapter` is repeatable to name several clients. An
|
|
374
379
|
explicit `--delivery` applies uniformly and never prompts; omitting it on an interactive
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -222,22 +222,26 @@ bundle and reports it for review. Plugin registration can still be removed indep
|
|
|
222
222
|
|
|
223
223
|
Antigravity CLI asks for approval before each shell command, ACC's included. A session that
|
|
224
224
|
live delivery wakes while you are away would therefore stop at the agent's first ACC command,
|
|
225
|
-
and the peer would get no answer until someone approved it.
|
|
226
|
-
|
|
225
|
+
and the peer would get no answer until someone approved it. The relay that lets ACC wake an
|
|
226
|
+
idle session is started by the agent too, with a command the client would also ask about. So
|
|
227
|
+
when `acc install` installs the Antigravity adapter, it always adds two rules to the client's
|
|
228
|
+
own settings:
|
|
227
229
|
|
|
228
230
|
```text
|
|
229
231
|
~/.gemini/antigravity-cli/settings.json
|
|
230
232
|
permissions.allow: command(<home>/.gemini/config/acc/acc-cli.sh)
|
|
233
|
+
command(sh "<home>/.gemini/config/acc/acc-relay.sh" start)
|
|
231
234
|
```
|
|
232
235
|
|
|
233
236
|
A one-word rule is a prefix: every command that starts with that path runs without asking.
|
|
234
237
|
The agent then runs every ACC command without asking you, including one a peer's message
|
|
235
|
-
prompts
|
|
236
|
-
|
|
237
|
-
are
|
|
238
|
+
prompts. The second rule is the exact command that starts live delivery, in the words the
|
|
239
|
+
client itself saves when you choose to always allow it. Every other command still asks.
|
|
240
|
+
Install does not ask about the rules, and the delivery policy does not change them: they are
|
|
241
|
+
part of ACC's Antigravity integration, as its hooks are.
|
|
238
242
|
|
|
239
243
|
ACC keeps every other key and rule in the file, leaves a rule you already had as yours, and
|
|
240
|
-
records what it added in its own data home. `acc uninstall` removes every copy of
|
|
244
|
+
records what it added in its own data home. `acc uninstall` removes every copy of each rule (one
|
|
241
245
|
in the same words cannot be told from ACC's), and a
|
|
242
246
|
container or file ACC created only if nothing else is in it. A rule removed by hand comes back
|
|
243
247
|
at the next `acc install` or automatic refresh; uninstall is what keeps it out. A file that is
|
|
@@ -246,9 +250,10 @@ client reads the file when it starts, so restart `agy` after install.
|
|
|
246
250
|
|
|
247
251
|
The rule matches only a command whose first word is the path without quotes, so ACC's skill
|
|
248
252
|
for this client writes the path without quotes. When your home path contains a space or a
|
|
249
|
-
shell metacharacter, the path needs quotes, no rule can match it, and ACC adds
|
|
250
|
-
|
|
251
|
-
`acc
|
|
253
|
+
shell metacharacter, the path needs quotes, no rule can match it, and ACC adds neither rule:
|
|
254
|
+
without the wrapper's, the agent would still ask before each ACC command.
|
|
255
|
+
`acc doctor` reports each rule as present, absent, or unable to apply, and asks for
|
|
256
|
+
`acc install --adapter antigravity` when one of ACC's rules is missing.
|
|
252
257
|
|
|
253
258
|
## Override local paths and identity
|
|
254
259
|
|
|
@@ -258,7 +263,7 @@ that resolves inside a workspace.
|
|
|
258
263
|
|
|
259
264
|
| Variable | Purpose |
|
|
260
265
|
|---|---|
|
|
261
|
-
| `ACC_DATA_HOME` | Base directory under which ACC creates `acc/` for runtime and coordination state. Defaults: `~/Library/Application Support` on macOS; `~/.local/share` on Linux, or `XDG_DATA_HOME
|
|
266
|
+
| `ACC_DATA_HOME` | Base directory under which ACC creates `acc/` for runtime and coordination state. Defaults: `~/Library/Application Support` on macOS; `~/.local/share` on Linux, or `XDG_DATA_HOME`; `%LOCALAPPDATA%` on Windows |
|
|
262
267
|
| `ACC_CONFIG_HOME` | Parsed and validated path override; no current configuration-storage consumer |
|
|
263
268
|
| `ACC_CACHE_HOME` | Parsed and validated path override; no current cache-storage consumer |
|
|
264
269
|
| `ACC_PARTICIPANT` | Which participant a session belongs to, when the client does not say |
|
package/docs/DESIGN_DECISIONS.md
CHANGED
|
@@ -90,8 +90,6 @@ where a guard stops behaves better than one that believes it absolute.
|
|
|
90
90
|
4. **Multi-root discovery rules** beyond the current `roots` list.
|
|
91
91
|
5. **Default claim lease length** for hook-only adapters. A hook-only session cannot sustain
|
|
92
92
|
a short renewal cadence, so lease policy must not assume one.
|
|
93
|
-
6. **Windows.** Measured as not working, not merely untested — see the
|
|
94
|
-
[repository changelog](https://github.com/automatis-tools/agents-can-communicate/blob/main/CHANGELOG.md).
|
|
95
93
|
|
|
96
94
|
---
|
|
97
95
|
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -13,7 +13,8 @@ pair or session-bound ACC MCP tools. See [CLI ownership](CLI.md#coordinate-from-
|
|
|
13
13
|
|
|
14
14
|
## 1. Install once on this machine
|
|
15
15
|
|
|
16
|
-
ACC requires
|
|
16
|
+
ACC requires Node.js 24 or newer on macOS, Linux, or Windows 10 or 11. On Windows, read
|
|
17
|
+
[Windows](#windows) below first.
|
|
17
18
|
|
|
18
19
|
Already using ACC? Follow the [upgrade guide](UPGRADING.md) for the 0.4.x → 0.5.0
|
|
19
20
|
update or the data-format boundary when upgrading from 0.3.1.
|
|
@@ -72,8 +73,9 @@ Code opens for every session. After you opt in, start Claude Code with your ordi
|
|
|
72
73
|
ACC adds no launch flag, shell change or wrapper. A session in `bypassPermissions` mode asks
|
|
73
74
|
you to approve each ACC wake. See
|
|
74
75
|
[held or dropped wakes](TROUBLESHOOTING.md#a-claude-code-session-holds-or-drops-acc-wakes).
|
|
75
|
-
The feature is off by default, can spend model tokens, and
|
|
76
|
-
|
|
76
|
+
The feature is off by default, can spend model tokens, and requires Claude Code 2.1.282 or
|
|
77
|
+
newer. Local sessions in Claude.app's Code tab wake the same way; its Cloud, SSH and Cowork
|
|
78
|
+
sessions run on another machine. You do not need it for durable messages or supported
|
|
77
79
|
next-turn delivery.
|
|
78
80
|
|
|
79
81
|
## 2. Open two sessions and give them ordinary tasks
|
|
@@ -142,8 +144,8 @@ Antigravity CLI carries one extra condition: its hooks are given a project direc
|
|
|
142
144
|
when the session has an open workspace. A session started without one attaches nothing, and
|
|
143
145
|
the client shows no hook output to say so - `acc doctor` names it.
|
|
144
146
|
|
|
145
|
-
Codex LocalDaemon and the Claude Code inbox wake offer optional native delivery
|
|
146
|
-
|
|
147
|
+
Codex LocalDaemon and the Claude Code inbox wake offer optional native delivery. They are
|
|
148
|
+
experimental and can spend tokens. Codex queues a message
|
|
147
149
|
until a running turn finishes. A busy Claude Code session takes the wake between two tool
|
|
148
150
|
calls. Claude Code requires 2.1.282 or newer and recorded opt-in, and it wakes through the
|
|
149
151
|
inbox that each session opens itself. Codex requires 0.152.1 or newer, LocalDaemon
|
|
@@ -157,7 +159,12 @@ three times while none is running, and you approve that command at the client's
|
|
|
157
159
|
Antigravity also asks before each shell command, so install adds a rule that lets ACC's own
|
|
158
160
|
commands run without that prompt, and a woken session can answer while you are away; see
|
|
159
161
|
[Antigravity CLI command approval](CONFIGURATION.md#antigravity-cli-command-approval).
|
|
160
|
-
|
|
162
|
+
Antigravity 2.0, the desktop app, runs the same hooks under its own language server, and ACC
|
|
163
|
+
delivers into its conversations through that server: nothing for the agent to start. The app
|
|
164
|
+
keeps its own command grants in `~/.gemini/config/config.json`; install adds ACC's rule there
|
|
165
|
+
once the app has run. After the app restarts, a conversation is reachable again from its next
|
|
166
|
+
turn. Chats in the Codex app run on the app's own server and get messages at their
|
|
167
|
+
next turn. [Capabilities](CAPABILITIES.md) explains policy, versions and fallback.
|
|
161
168
|
|
|
162
169
|
Delivery evidence is deliberately narrow: `queued -> offered -> retrieved -> acknowledged`.
|
|
163
170
|
An offer is not proof that the model read anything, retrieval is not proof of attention, and
|
|
@@ -199,5 +206,31 @@ acc uninstall
|
|
|
199
206
|
Uninstall removes only bytes ACC wrote that still match its install record. User edits are
|
|
200
207
|
reported and preserved.
|
|
201
208
|
|
|
209
|
+
## Windows
|
|
210
|
+
|
|
211
|
+
ACC runs natively on Windows 10 and 11, with no WSL. Install it the same way, in PowerShell or
|
|
212
|
+
in a Command Prompt:
|
|
213
|
+
|
|
214
|
+
```powershell
|
|
215
|
+
npm install -g agents-can-communicate
|
|
216
|
+
acc install
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
What is different on Windows:
|
|
220
|
+
|
|
221
|
+
- ACC keeps its state in `%LOCALAPPDATA%\acc`, never in the roaming profile.
|
|
222
|
+
- Each client's hooks run a small Node script instead of a shell script, in the form that
|
|
223
|
+
client's hook runner reads. `node` must be on `PATH` for Grok and Antigravity CLI hooks.
|
|
224
|
+
Claude Code needs 2.1.139 or later.
|
|
225
|
+
- Live delivery reaches a running session as on macOS and Linux: Claude Code through its inbox
|
|
226
|
+
pipe, Codex through its app-server daemon, Antigravity CLI through ACC's relay. Codex starts
|
|
227
|
+
its daemon only from a terminal that is not running as administrator.
|
|
228
|
+
- Antigravity CLI cannot run a hook whose path is quoted. When your profile path has a space,
|
|
229
|
+
ACC writes the path's 8.3 short name. ACC adds no allow rule on Windows, so Antigravity CLI
|
|
230
|
+
asks before each ACC command.
|
|
231
|
+
- The first hook after the machine starts can take a few seconds, because ACC reads the
|
|
232
|
+
process tree through WMI, in Windows Script Host or, where Script Host is off, PowerShell.
|
|
233
|
+
If it runs out of time, the session attaches on the first prompt instead.
|
|
234
|
+
|
|
202
235
|
Next: [Why ACC](WHY_ACC.md) · [Capabilities](CAPABILITIES.md) · [CLI](CLI.md) ·
|
|
203
236
|
[Troubleshooting](TROUBLESHOOTING.md)
|
package/docs/HOW_IT_WORKS.md
CHANGED
|
@@ -102,16 +102,16 @@ All recipients have the same durable record, but adapters expose different accel
|
|
|
102
102
|
- **Next normal turn:** exact captured versions of Codex, Claude Code, Gemini CLI, Antigravity CLI and Kimi
|
|
103
103
|
Code can receive complete attributed peer context when the user next prompts that client.
|
|
104
104
|
This does not wake an idle session.
|
|
105
|
-
- **Optional Claude Code inbox wake:**
|
|
106
|
-
|
|
107
|
-
wake is one line of fixed ACC text with the message id. It carries no subject, body or
|
|
105
|
+
- **Optional Claude Code inbox wake:** with Claude Code 2.1.282 or later, ACC wakes the
|
|
106
|
+
session through the inbox that the session opens itself: a Unix socket on macOS and Linux,
|
|
107
|
+
a named pipe on Windows. The wake is one line of fixed ACC text with the message id. It carries no subject, body or
|
|
108
108
|
sender name. An idle session starts a turn. A busy session takes the wake between two tool
|
|
109
109
|
calls and keeps its turn. Each delivered wake fires `UserPromptSubmit`, ACC's next-turn
|
|
110
110
|
hook, which shows the message in its untrusted block. The model answers with
|
|
111
111
|
`acc reply`. This is experimental, off by default and can spend tokens. Claude Code's
|
|
112
112
|
own inbound controls apply to each wake.
|
|
113
113
|
|
|
114
|
-
- **Optional Codex LocalDaemon delivery:**
|
|
114
|
+
- **Optional Codex LocalDaemon delivery:** a captured
|
|
115
115
|
minimum of 0.152.1 plus a current probe and exact session checks allow delivery
|
|
116
116
|
to an independently opened thread. It is experimental, off by default, and can
|
|
117
117
|
spend tokens. Messages wait for a running turn to finish; a daemon-retained
|
|
@@ -120,13 +120,18 @@ All recipients have the same durable record, but adapters expose different accel
|
|
|
120
120
|
and does not manage the vendor daemon during message delivery. Separately,
|
|
121
121
|
[confirmed update maintenance](UPGRADING.md#confirmed-client-service-maintenance) can restart it.
|
|
122
122
|
|
|
123
|
-
- **Optional Antigravity CLI relay:**
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
- **Optional Antigravity CLI relay:** with 1.2.7 or later, the session endpoint exists only
|
|
124
|
+
in the agent's own shell, so ACC's context asks the agent once per conversation to start a
|
|
125
|
+
relay, a command install allows. The relay keeps the endpoint
|
|
126
126
|
in memory, wakes an idle session with a fenced peer message, holds one for a busy session,
|
|
127
127
|
and ends with the client. It is experimental, off by default, and can spend tokens. The
|
|
128
128
|
woken agent's ACC commands run without the client's approval prompt because install adds
|
|
129
|
-
|
|
129
|
+
an allow rule for ACC's wrapper. On Windows install adds no rule, so the client asks first.
|
|
130
|
+
|
|
131
|
+
- **Optional Antigravity desktop delivery:** with Antigravity 2.19.1 or later, ACC pushes a
|
|
132
|
+
message into a desktop conversation through the app's own language server, reading its
|
|
133
|
+
endpoint when it binds and when it delivers, and storing no token. The agent starts
|
|
134
|
+
nothing. It is experimental, off by default, and can spend tokens.
|
|
130
135
|
|
|
131
136
|
Grok, generic MCP, unsupported versions and uncaptured platforms use inbox polling.
|
|
132
137
|
[Capabilities](CAPABILITIES.md) lists evidence and fallback.
|
package/docs/SECURITY_MODEL.md
CHANGED
|
@@ -103,12 +103,26 @@ unchanged; edited or newly referenced settings remain intact. See
|
|
|
103
103
|
[Codex outgoing permissions](CONFIGURATION.md#codex-outgoing-permissions). Configuration
|
|
104
104
|
readiness does not prove that an active session's overrides permit a live offer.
|
|
105
105
|
|
|
106
|
-
Antigravity CLI asks before each shell command. Installing its adapter adds
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
Antigravity CLI asks before each shell command. Installing its adapter adds two rules to that
|
|
107
|
+
client's `permissions.allow`: a prefix rule for ACC's own wrapper path, and the exact command
|
|
108
|
+
that starts the relay. The agent then runs every ACC command, and starts live delivery,
|
|
109
|
+
without a prompt, including when a peer's message prompts it. Every other command still asks.
|
|
110
|
+
ACC records the rules it added and uninstall removes only those.
|
|
110
111
|
It never writes a settings file that it cannot parse. See
|
|
111
112
|
[Antigravity CLI command approval](CONFIGURATION.md#antigravity-cli-command-approval).
|
|
113
|
+
Antigravity 2.0, the desktop app, keeps its grants in `~/.gemini/config/config.json`. Once the
|
|
114
|
+
app has created that file, install adds the same wrapper rule there, under the same ownership
|
|
115
|
+
record, and never creates the file itself.
|
|
116
|
+
|
|
117
|
+
Antigravity 2.0 starts its language server with the server's CSRF token on its command line,
|
|
118
|
+
where every process on the machine can read it. To deliver into a desktop conversation, ACC
|
|
119
|
+
reads that command line from the one server its own hook ran under: the pid and start time
|
|
120
|
+
recorded when the session bound, and the arguments checked again at every use. The token goes
|
|
121
|
+
into the environment of one `agentapi` child for one call and nowhere else: not into the
|
|
122
|
+
endpoint record, the delivery binding, the native-attempt record, logs or diagnostics. The
|
|
123
|
+
record names the server's pid, its start time and the loopback port that answered `/healthz`.
|
|
124
|
+
What the token lets ACC do there is what the relay does for Antigravity CLI: put one fenced,
|
|
125
|
+
ACC-rendered peer message into one conversation.
|
|
112
126
|
|
|
113
127
|
## Claims
|
|
114
128
|
|
|
@@ -125,7 +139,14 @@ from operating merely because its own state is unavailable.
|
|
|
125
139
|
## Filesystem and installation
|
|
126
140
|
|
|
127
141
|
- Runtime state, bindings, sockets, and install ownership records stay outside repositories.
|
|
128
|
-
- Managed paths are checked for containment and symlink escape.
|
|
142
|
+
- Managed paths are checked for containment and symlink escape. Windows has no `O_NOFOLLOW`:
|
|
143
|
+
ACC refuses a symlink or junction at the last component by name, then checks that the
|
|
144
|
+
opened handle is the file it checked.
|
|
145
|
+
- On Windows, ACC state lives in `%LOCALAPPDATA%`, whose ACL grants only the user, SYSTEM and
|
|
146
|
+
Administrators; files inherit it. Mode bits do not exist there.
|
|
147
|
+
- A workspace config root that starts with a separator or a drive letter is refused on every
|
|
148
|
+
platform. On Windows such a root could name another drive or a network share (`\\host\share`),
|
|
149
|
+
which a hook would then contact.
|
|
129
150
|
- Store publication uses atomic no-replace behavior, journaling, and writer locks.
|
|
130
151
|
- Corrupt or incompatible store versions fail closed before mutation.
|
|
131
152
|
- Client installers preserve unrelated settings and record content hashes.
|