agents-can-communicate 0.5.10 → 0.6.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 +2 -1
- package/bin/acc-antigravity-relay.mjs +7 -0
- package/bin/entrypoints/acc-antigravity-relay.mjs +116 -0
- package/bin/entrypoints/acc-bootstrap.mjs +4 -0
- package/bin/entrypoints/acc-hook.mjs +11 -7
- package/bin/entrypoints/antigravity-relay-binding.mjs +43 -0
- package/docs/ADAPTER_AUTHORING.md +33 -0
- package/docs/ARCHITECTURE.md +5 -3
- package/docs/CAPABILITIES.md +22 -16
- package/docs/CONFIGURATION.md +1 -0
- package/docs/GETTING_STARTED.md +10 -4
- package/docs/HOW_IT_WORKS.md +7 -1
- package/docs/TROUBLESHOOTING.md +72 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/certification.json +91 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/PreInvocation-1.2.7.json +11 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/SessionStart-1.2.7.json +9 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/agentapi-error-answers-1.2.7.json +19 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/agentapi-live-push-1.2.7.json +31 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/certification-provenance.json +217 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/delivery/antigravity-cli-1.2.7-relay-product-evidence.json +132 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/delivery/antigravity-cli-1.2.7-relay-product.json +29 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/hooks-first-trust-no-workspace-1.2.7.json +37 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/fixtures/live-push-surfaces-1.2.7.json +38 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/package.json +28 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/plugin/plugin.json +5 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/plugin/skills/acc/SKILL.md +329 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/adapter.mjs +119 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/agentapi.mjs +98 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/hooks.mjs +201 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/install.mjs +708 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/native-delivery.mjs +170 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/relay-endpoint.mjs +116 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/relay-start.mjs +123 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/relay.mjs +195 -0
- package/node_modules/@agents-can-communicate/adapter-antigravity/src/relays.mjs +64 -0
- package/node_modules/@agents-can-communicate/adapter-claude-code/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-codex/package.json +1 -1
- 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 +37 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/src/certification.mjs +25 -5
- package/node_modules/@agents-can-communicate/adapter-sdk/src/hook-shim.mjs +1 -0
- package/node_modules/@agents-can-communicate/adapter-sdk/src/index.mjs +1 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/src/native-attempt.mjs +1 -1
- package/node_modules/@agents-can-communicate/cli/package.json +1 -1
- package/node_modules/@agents-can-communicate/cli/src/install-command.mjs +17 -3
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/entry.mjs +2 -2
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/launchers.mjs +1 -0
- package/node_modules/@agents-can-communicate/core/package.json +1 -1
- package/node_modules/@agents-can-communicate/core/src/sessions.mjs +1 -2
- 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/native-attempt.mjs +31 -0
- package/node_modules/@agents-can-communicate/hook-runner/src/runner.mjs +59 -9
- package/node_modules/@agents-can-communicate/installer/package.json +1 -1
- package/node_modules/@agents-can-communicate/installer/src/detect.mjs +4 -0
- package/node_modules/@agents-can-communicate/installer/src/plan.mjs +10 -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/storage-filesystem/package.json +1 -1
- package/node_modules/@agents-can-communicate/storage-filesystem/src/retention.mjs +23 -13
- package/node_modules/@agents-can-communicate/storage-filesystem/src/store.mjs +18 -1
- package/package.json +3 -1
package/README.md
CHANGED
|
@@ -88,7 +88,8 @@ context; it cannot recover details that were never saved.
|
|
|
88
88
|
|
|
89
89
|
## Client support
|
|
90
90
|
|
|
91
|
-
Integrations are available for **Claude Code, Codex, Gemini CLI, Grok, and
|
|
91
|
+
Integrations are available for **Antigravity CLI, Claude Code, Codex, Gemini CLI, Grok, and
|
|
92
|
+
Kimi Code**. Other
|
|
92
93
|
clients can connect through [MCP](docs/MCP.md) with their own configuration and coordination
|
|
93
94
|
instructions.
|
|
94
95
|
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { invokedDirectly, runEntry } from "@agents-can-communicate/cli/managed-entry";
|
|
4
|
+
|
|
5
|
+
if (invokedDirectly(import.meta.url)) await runEntry({
|
|
6
|
+
kind: "acc-antigravity-relay", packageRoot: fileURLToPath(new URL("..", import.meta.url)),
|
|
7
|
+
});
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// The relay the agent starts: `start` in its tool shell, `run` detached from it.
|
|
3
|
+
// Fails open everywhere - `start` prints one line and exits 0; `run` answers its
|
|
4
|
+
// ready line and exits quietly when anything it needs is missing.
|
|
5
|
+
import { execFile } from "node:child_process";
|
|
6
|
+
import { randomBytes } from "node:crypto";
|
|
7
|
+
import { appendFile } from "node:fs/promises";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
|
|
10
|
+
import { agentApiCommand, createAgentApi } from "@agents-can-communicate/adapter-antigravity/agentapi";
|
|
11
|
+
import { createRelay } from "@agents-can-communicate/adapter-antigravity/relay";
|
|
12
|
+
import { listRegistrations, newRelayId, relayDir } from "@agents-can-communicate/adapter-antigravity/relay-endpoint";
|
|
13
|
+
import { findConversation, spawnRelay, startRelay } from "@agents-can-communicate/adapter-antigravity/relay-start";
|
|
14
|
+
import { loadSessionBinding } from "@agents-can-communicate/adapter-sdk";
|
|
15
|
+
import { platformDataHome } from "@agents-can-communicate/cli";
|
|
16
|
+
import { createCoordinationService } from "@agents-can-communicate/core";
|
|
17
|
+
import { resolveClientPid } from "@agents-can-communicate/hook-runner/client-pid";
|
|
18
|
+
import { readProcessTable } from "@agents-can-communicate/hook-runner/process-table";
|
|
19
|
+
import { readInstalledLivePolicy } from "@agents-can-communicate/installer";
|
|
20
|
+
import { createId } from "@agents-can-communicate/protocol";
|
|
21
|
+
import { openFilesystemStore } from "@agents-can-communicate/storage-filesystem";
|
|
22
|
+
|
|
23
|
+
import { activateAntigravityRelay } from "./antigravity-relay-binding.mjs";
|
|
24
|
+
|
|
25
|
+
const clock = { now: () => new Date().toISOString() };
|
|
26
|
+
const ids = { next: kind => createId(kind, randomBytes) };
|
|
27
|
+
const alive = pid => { try { process.kill(pid, 0); return true; } catch { return false; } };
|
|
28
|
+
const READY_MS = 10_000;
|
|
29
|
+
|
|
30
|
+
const argvOf = pid => new Promise(resolve => execFile("ps", ["-o", "args=", "-p", String(pid)],
|
|
31
|
+
{ timeout: 1_000 }, (_error, out) => resolve(String(out ?? "").trim().split(/\s+/).filter(Boolean))));
|
|
32
|
+
|
|
33
|
+
// Through the launcher that ran `start`, never this module directly: an entry
|
|
34
|
+
// module does not run itself, and under the managed runtime the launcher takes
|
|
35
|
+
// the lease that keeps this generation installed for as long as the relay lives.
|
|
36
|
+
const spawnRun = ({ env, payload }) => spawnRelay({ command: process.execPath,
|
|
37
|
+
args: [process.argv[1], "run"], env, payload, readyMs: READY_MS });
|
|
38
|
+
|
|
39
|
+
async function start() {
|
|
40
|
+
const dataHome = platformDataHome({ platform: process.platform, env: process.env });
|
|
41
|
+
const line = await startRelay({ env: process.env, pid: process.pid,
|
|
42
|
+
readTable: () => readProcessTable(), argvOf,
|
|
43
|
+
resolveAgyPid: (table, from) => resolveClientPid({ table, from, command: "agy" }),
|
|
44
|
+
readPolicy: () => readInstalledLivePolicy({ dataHome, adapterId: "antigravity" }),
|
|
45
|
+
findConversation: ({ conversationId, agyPid }) => findConversation({ dataHome, conversationId, agyPid }),
|
|
46
|
+
liveRelayFor: async ({ runtimeDir, conversationId }) => (await listRegistrations({ runtimeDir }))
|
|
47
|
+
.some(record => record.conversationId === conversationId && alive(record.relayPid)),
|
|
48
|
+
spawnRun });
|
|
49
|
+
process.stdout.write(`${line}\n`);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function readPayload() {
|
|
53
|
+
let text = "";
|
|
54
|
+
for await (const chunk of process.stdin) text += chunk;
|
|
55
|
+
return JSON.parse(text);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Event names, message ids and closed reason codes only: never a body, the
|
|
59
|
+
// token, the address or the nonce.
|
|
60
|
+
const logger = file => entry => appendFile(file, `${JSON.stringify({ at: clock.now(), ...entry })}\n`,
|
|
61
|
+
{ mode: 0o600 }).catch(() => {});
|
|
62
|
+
|
|
63
|
+
async function run() {
|
|
64
|
+
const ready = result => process.stdout.write(`${JSON.stringify(result)}\n`);
|
|
65
|
+
const payload = await readPayload();
|
|
66
|
+
const { runtimeDir, conversationId, agyPid } = payload;
|
|
67
|
+
const dataHome = platformDataHome({ platform: process.platform, env: process.env });
|
|
68
|
+
const store = await openFilesystemStore({ root: runtimeDir, clock, ids, workspaceId: payload.workspaceId });
|
|
69
|
+
const service = createCoordinationService({ store, clock, ids });
|
|
70
|
+
const current = () => loadSessionBinding({ runtimeDir, harnessSessionId: conversationId });
|
|
71
|
+
const bound = await current();
|
|
72
|
+
if (bound === null || bound.clientPid !== agyPid) {
|
|
73
|
+
ready({ ok: false, reason: "no ACC session for this conversation" });
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const endpointId = newRelayId();
|
|
77
|
+
const relay = createRelay({ runtimeDir, conversationId, agyPid, isAlive: alive, endpointId,
|
|
78
|
+
clientVersion: bound.clientVersion,
|
|
79
|
+
observe: logger(path.join(relayDir(runtimeDir), `${endpointId}.log`)),
|
|
80
|
+
api: createAgentApi({ endpoint: payload, baseEnv: process.env,
|
|
81
|
+
command: agentApiCommand(process.env) }),
|
|
82
|
+
// The conversation can reopen under a new ACC generation while this relay
|
|
83
|
+
// keeps serving it, so renew whichever binding is current, never a copy.
|
|
84
|
+
refreshBinding: async leaseUntil => {
|
|
85
|
+
const now = await current();
|
|
86
|
+
if (now?.clientPid !== agyPid) return;
|
|
87
|
+
await service.refreshDeliveryBinding({ sessionId: now.accSessionId, generation: now.generation,
|
|
88
|
+
leaseUntil });
|
|
89
|
+
},
|
|
90
|
+
onExit: async () => {
|
|
91
|
+
const now = await current().catch(() => null);
|
|
92
|
+
if (now !== null) {
|
|
93
|
+
await service.clearDeliveryBinding({ sessionId: now.accSessionId, generation: now.generation,
|
|
94
|
+
opaqueEndpointRef: endpointId }).catch(() => {});
|
|
95
|
+
}
|
|
96
|
+
process.exit(0);
|
|
97
|
+
} });
|
|
98
|
+
await relay.listen();
|
|
99
|
+
process.on("SIGTERM", () => { relay.close("terminated"); });
|
|
100
|
+
const activation = await activateAntigravityRelay({ session: { sessionId: bound.accSessionId,
|
|
101
|
+
generation: bound.generation, clientPid: bound.clientPid, harnessSessionId: conversationId },
|
|
102
|
+
service, runtimeDir, dataHome }).catch(() => null);
|
|
103
|
+
if (activation?.state === "active") {
|
|
104
|
+
ready({ ok: true });
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
ready({ ok: false, reason: activation?.reasonCode ?? "binding was not published" });
|
|
108
|
+
await relay.close("not_activated");
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export async function main() {
|
|
112
|
+
const [command] = process.argv.slice(2);
|
|
113
|
+
if (command === "run") await run().catch(() => process.exit(0));
|
|
114
|
+
else await start().catch(() => process.stdout.write(
|
|
115
|
+
"ACC: live delivery did not start; peers still reach this conversation at its next turn.\n"));
|
|
116
|
+
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
// empty unless ACC_BOOTSTRAP_DEBUG=1 asks for one safe line.
|
|
8
8
|
import { checkNativeBootstrap } from "@agents-can-communicate/installer";
|
|
9
9
|
|
|
10
|
+
import { createAntigravityAdapter } from "@agents-can-communicate/adapter-antigravity";
|
|
10
11
|
import { createClaudeCodeAdapter } from "@agents-can-communicate/adapter-claude-code";
|
|
11
12
|
import { createCodexAdapter } from "@agents-can-communicate/adapter-codex";
|
|
12
13
|
import { createGeminiCliAdapter } from "@agents-can-communicate/adapter-gemini-cli";
|
|
@@ -29,6 +30,9 @@ try {
|
|
|
29
30
|
const registry = {
|
|
30
31
|
claude_code: createClaudeCodeAdapter, codex: createCodexAdapter,
|
|
31
32
|
gemini_cli: createGeminiCliAdapter, grok: createGrokAdapter, kimi: createKimiAdapter,
|
|
33
|
+
// No native delivery contract: this reports the client unsupported rather
|
|
34
|
+
// than unknown, which is a different and more useful thing to read.
|
|
35
|
+
antigravity: createAntigravityAdapter,
|
|
32
36
|
};
|
|
33
37
|
const adapter = registry[options.adapter]?.();
|
|
34
38
|
if (adapter === undefined) {
|
|
@@ -12,6 +12,7 @@ import { createId } from "@agents-can-communicate/protocol";
|
|
|
12
12
|
import { runHook } from "@agents-can-communicate/hook-runner";
|
|
13
13
|
import { hookEntrypointFor, resolvePinnedGeneration } from "@agents-can-communicate/cli";
|
|
14
14
|
|
|
15
|
+
import { createAntigravityAdapter } from "@agents-can-communicate/adapter-antigravity";
|
|
15
16
|
import { createClaudeCodeAdapter } from "@agents-can-communicate/adapter-claude-code";
|
|
16
17
|
import { createCodexAdapter } from "@agents-can-communicate/adapter-codex";
|
|
17
18
|
import { createGeminiCliAdapter } from "@agents-can-communicate/adapter-gemini-cli";
|
|
@@ -19,6 +20,9 @@ import { createGrokAdapter } from "@agents-can-communicate/adapter-grok";
|
|
|
19
20
|
import { createKimiAdapter } from "@agents-can-communicate/adapter-kimi";
|
|
20
21
|
|
|
21
22
|
const adapters = {
|
|
23
|
+
// Registered like any other client. Its hook commands carry an extra
|
|
24
|
+
// argument - the event name - because this client's payload has none.
|
|
25
|
+
antigravity: createAntigravityAdapter(),
|
|
22
26
|
claude_code: createClaudeCodeAdapter(),
|
|
23
27
|
codex: createCodexAdapter(),
|
|
24
28
|
gemini_cli: createGeminiCliAdapter(),
|
|
@@ -46,9 +50,9 @@ import { completeHookOutput } from "./hook-output.mjs";
|
|
|
46
50
|
// a hook that has no pin to look up pays nothing beyond it. Any adapter or
|
|
47
51
|
// payload that will not yield a session id simply has no pin to find, same as
|
|
48
52
|
// today's no-pin behaviour.
|
|
49
|
-
async function harnessSessionIdFor(adapterId, payload) {
|
|
53
|
+
async function harnessSessionIdFor(adapterId, payload, args) {
|
|
50
54
|
try {
|
|
51
|
-
const event = await adapters[adapterId]?.normalizeHook(payload);
|
|
55
|
+
const event = await adapters[adapterId]?.normalizeHook(payload, { args });
|
|
52
56
|
return typeof event?.sessionId === "string" ? event.sessionId : null;
|
|
53
57
|
} catch {
|
|
54
58
|
return null;
|
|
@@ -71,9 +75,9 @@ async function harnessSessionIdFor(adapterId, payload) {
|
|
|
71
75
|
// mid-resolution by another hook for the same session, or simply wrong)
|
|
72
76
|
// could say. Unbounded delegation would be a hang, worse than any of the
|
|
73
77
|
// failures this file already falls open from.
|
|
74
|
-
async function delegateToPin({ managerRoot, packageRoot, adapterId, payload, delegated }) {
|
|
78
|
+
async function delegateToPin({ managerRoot, packageRoot, adapterId, payload, args, delegated }) {
|
|
75
79
|
if (delegated || managerRoot === null || packageRoot === null) return false;
|
|
76
|
-
const harnessSessionId = await harnessSessionIdFor(adapterId, payload);
|
|
80
|
+
const harnessSessionId = await harnessSessionIdFor(adapterId, payload, args);
|
|
77
81
|
if (harnessSessionId === null) return false;
|
|
78
82
|
const pinned = await resolvePinnedGeneration({ root: managerRoot, harnessSessionId, active: packageRoot });
|
|
79
83
|
if (pinned === null) return false;
|
|
@@ -87,7 +91,7 @@ async function delegateToPin({ managerRoot, packageRoot, adapterId, payload, del
|
|
|
87
91
|
}
|
|
88
92
|
|
|
89
93
|
export async function main({ managerRoot = null, packageRoot = null, payload, delegated = false } = {}) {
|
|
90
|
-
const [adapterId] = process.argv.slice(2);
|
|
94
|
+
const [adapterId, ...args] = process.argv.slice(2);
|
|
91
95
|
|
|
92
96
|
// A delegating caller already read stdin once for the whole process and
|
|
93
97
|
// hands its parsed payload down; only the outermost call reads it here.
|
|
@@ -99,9 +103,9 @@ export async function main({ managerRoot = null, packageRoot = null, payload, de
|
|
|
99
103
|
}
|
|
100
104
|
}
|
|
101
105
|
|
|
102
|
-
if (await delegateToPin({ managerRoot, packageRoot, adapterId, payload, delegated })) return;
|
|
106
|
+
if (await delegateToPin({ managerRoot, packageRoot, adapterId, payload, args, delegated })) return;
|
|
103
107
|
|
|
104
|
-
const result = await runHook({ adapterId, payload, adapters,
|
|
108
|
+
const result = await runHook({ adapterId, payload, args, adapters,
|
|
105
109
|
runtime: { clock: { now: () => new Date().toISOString() },
|
|
106
110
|
ids: { next: kind => createId(kind, randomBytes) } },
|
|
107
111
|
env: process.env });
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { createAntigravityAdapter } from "@agents-can-communicate/adapter-antigravity";
|
|
2
|
+
import { loadSessionBinding, storeNativeAttempt } from "@agents-can-communicate/adapter-sdk";
|
|
3
|
+
import { createCoordinationService } from "@agents-can-communicate/core";
|
|
4
|
+
import { establishNativeBinding } from "@agents-can-communicate/hook-runner/native-binding";
|
|
5
|
+
import { withSessionLifecycle } from "@agents-can-communicate/hook-runner/session-lifecycle";
|
|
6
|
+
import { readInstalledLivePolicyState } from "@agents-can-communicate/installer";
|
|
7
|
+
import { openFilesystemStore } from "@agents-can-communicate/storage-filesystem";
|
|
8
|
+
|
|
9
|
+
// No hook runs when the agent starts a relay mid-turn, and the next
|
|
10
|
+
// PreInvocation can be hours away. The relay publishes its own binding the way
|
|
11
|
+
// the Claude Code Channel does: under the session's lifecycle lock, after
|
|
12
|
+
// rereading ownership, so a queued start never publishes for a replaced or
|
|
13
|
+
// closed session.
|
|
14
|
+
export async function activateAntigravityRelay({ session, service, runtimeDir, dataHome,
|
|
15
|
+
adapter = createAntigravityAdapter(), deadlineAt = Date.now() + 5_000 }) {
|
|
16
|
+
if (typeof session.harnessSessionId !== "string") return null;
|
|
17
|
+
return withSessionLifecycle({ root: runtimeDir, sessionId: session.harnessSessionId,
|
|
18
|
+
clock: service.clock, deadlineAt }, async () => {
|
|
19
|
+
const { clock, ids } = service;
|
|
20
|
+
const store = await openFilesystemStore({ root: runtimeDir, clock, ids,
|
|
21
|
+
workspaceId: service.store.workspaceId, deadlineAt });
|
|
22
|
+
const current = createCoordinationService({ store, clock, ids });
|
|
23
|
+
const binding = await loadSessionBinding({ runtimeDir, harnessSessionId: session.harnessSessionId });
|
|
24
|
+
if (binding?.accSessionId !== session.sessionId || binding.generation !== session.generation
|
|
25
|
+
|| binding.clientPid !== session.clientPid) return null;
|
|
26
|
+
const located = await current.locateSession(session.sessionId);
|
|
27
|
+
if (located?.record.state !== "open" || located.record.generation !== session.generation) return null;
|
|
28
|
+
const { policy, policyStatus } = await readInstalledLivePolicyState({ dataHome,
|
|
29
|
+
adapterId: adapter.id });
|
|
30
|
+
if (policy === "off" || Date.now() >= deadlineAt) return null;
|
|
31
|
+
const result = await establishNativeBinding({ adapter,
|
|
32
|
+
event: { kind: "relayReady", sessionId: session.harnessSessionId },
|
|
33
|
+
hookBinding: binding, clientVersion: binding.clientVersion, platform: binding.platform,
|
|
34
|
+
livePolicy: policy, service: current, runtimeDir, clock, env: {},
|
|
35
|
+
timeoutMs: Math.max(1, Math.min(750, deadlineAt - Date.now())) });
|
|
36
|
+
await storeNativeAttempt({ runtimeDir, harnessSessionId: session.harnessSessionId,
|
|
37
|
+
accSessionId: session.sessionId, generation: session.generation, deadlineAt,
|
|
38
|
+
nativeAttempt: { at: clock.now(), event: "relayReady", state: result.state,
|
|
39
|
+
reasonCode: result.reasonCode, policy, policySource: "installation-record", policyStatus,
|
|
40
|
+
clientProcess: "identified" } }).catch(() => {});
|
|
41
|
+
return result;
|
|
42
|
+
});
|
|
43
|
+
}
|
|
@@ -52,6 +52,17 @@ it cannot create a session or advance receipts. Grok uses it to supply CLI owner
|
|
|
52
52
|
arguments after a terminal result. This does not certify general context or peer
|
|
53
53
|
delivery, and a tool such as `finish` can close the owner before the line arrives.
|
|
54
54
|
|
|
55
|
+
`continueTurnOutcome({ reason, payload })` is optional. A client whose end-of-turn hook can
|
|
56
|
+
hold a turn open implements it, and the runner's `turnEnd` handler calls it with the projected
|
|
57
|
+
peer context when - and only when - a peer body no invocation has shown yet is waiting. It
|
|
58
|
+
returns `{ stdout, stderr?, exitCode? }` in the client's own continuation shape, and prints
|
|
59
|
+
nothing to let the turn end. `payload` is the raw hook payload handed back unread, so the
|
|
60
|
+
adapter can apply its own ceiling from a counter the client supplies; nothing in core reads it.
|
|
61
|
+
An empty `stdout` records no offer, so the body stays queued for the next invocation. A
|
|
62
|
+
continuation costs the operator a model invocation, which is why an owner header or an
|
|
63
|
+
attention count is never a reason to call it. Antigravity CLI uses it for `Stop`, bounded to
|
|
64
|
+
one continuation per turn by the client's own `executionNum`.
|
|
65
|
+
|
|
55
66
|
`renderContextResult` is required wherever an adapter renders peer messages. It returns
|
|
56
67
|
`{ text, offeredMessageIds, includedAttentionIds }`, and the [receipt
|
|
57
68
|
lifecycle](PROTOCOL.md#receipt-lifecycle) advances only from those ids — never by searching
|
|
@@ -110,6 +121,20 @@ the false value and can never enable it.
|
|
|
110
121
|
shape for the installed client. Only an exact passing version/platform match remains true.
|
|
111
122
|
Unreadable, unknown, or mismatched clients degrade every uncertified row to false.
|
|
112
123
|
|
|
124
|
+
An adapter for a client that ships often may declare a floor per platform:
|
|
125
|
+
|
|
126
|
+
```js
|
|
127
|
+
certificationFloor: { "darwin-arm64": "1.2.7" },
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
A stable version at or above the floor, on that platform, is then judged by the floor
|
|
131
|
+
version's evidence for any capability it has no capture of its own for. A later capture
|
|
132
|
+
wins for its own version, capability by capability - a recorded failure turns that
|
|
133
|
+
capability off for that version and leaves the rest on the floor. Earlier versions,
|
|
134
|
+
prereleases and other platforms stay uncertified, and `defineAdapter` refuses a floor
|
|
135
|
+
that names a version with no passing evidence on its platform. Antigravity CLI declares
|
|
136
|
+
one; every other adapter certifies exact versions only.
|
|
137
|
+
|
|
113
138
|
The backing methods for delivery are `renderContextResult()` for `nextTurn`,
|
|
114
139
|
`offerMessage()` for `livePush`, and `routeReply()` for `replyRoute`.
|
|
115
140
|
|
|
@@ -198,6 +223,13 @@ return normalizedEvent({
|
|
|
198
223
|
Refuse an unrecognised payload. Inventing a session attaches the wrong one, or a new one
|
|
199
224
|
every hook, and looks like it is working.
|
|
200
225
|
|
|
226
|
+
`normalizeHook(payload, { args })` also receives the arguments the client's hook command
|
|
227
|
+
carried after the adapter id. Most clients name the event inside the payload and ignore this.
|
|
228
|
+
Antigravity CLI does not send one at all, and its `PreInvocation` and `PostInvocation` hand
|
|
229
|
+
over byte-identical envelopes - so for that client the registered command's own argument is
|
|
230
|
+
the only thing that knows which hook ran, and its install writes the event name into each
|
|
231
|
+
command. `args` is always an array; an adapter that does not need it may take one parameter.
|
|
232
|
+
|
|
201
233
|
## Measure response contracts
|
|
202
234
|
|
|
203
235
|
Measure them. Every client differs, and a wrong shape fails **silently**:
|
|
@@ -207,6 +239,7 @@ Measure them. Every client differs, and a wrong shape fails **silently**:
|
|
|
207
239
|
| Codex | exit 2 + stderr | plain stdout (`developer` message) |
|
|
208
240
|
| Claude Code | `hookSpecificOutput.permissionDecision` | same envelope |
|
|
209
241
|
| Gemini CLI | `{"decision":"block"}` | `hookSpecificOutput` envelope |
|
|
242
|
+
| Antigravity CLI | no tool event loads, so a deny is unreachable | `{"injectSteps":[{"ephemeralMessage"}]}` from `PreInvocation` |
|
|
210
243
|
| Grok | `{"decision":"deny","reason"}` (documented; deny not yet captured) | UserPromptSubmit stdout discarded; own identity only via PreToolUse after a terminal result, observed on 1.0.24 |
|
|
211
244
|
| Kimi Code | `hookSpecificOutput.permissionDecision` | plain stdout |
|
|
212
245
|
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -97,11 +97,13 @@ exposes and whether its lease is current, while recipient policy says whether it
|
|
|
97
97
|
turn.
|
|
98
98
|
|
|
99
99
|
Claude Code Channel has installed-client evidence on 2.1.258 and 2.1.260; Codex
|
|
100
|
-
LocalDaemon has it on 0.152.1 and 0.153.4.
|
|
100
|
+
LocalDaemon has it on 0.152.1 and 0.153.4; Antigravity CLI has it on 1.2.7 and later through a relay
|
|
101
|
+
the agent starts in its own shell. All three use a captured platform minimum,
|
|
101
102
|
current probe and exact session handshake. Codex preserves the ordinary client
|
|
102
103
|
launch and verifies its registered thread and workspace; native delivery owns no vendor
|
|
103
|
-
daemon lifecycle. Gemini CLI and Kimi Code have exact-version next-turn evidence only;
|
|
104
|
-
|
|
104
|
+
daemon lifecycle. Gemini CLI and Kimi Code have exact-version next-turn evidence only; Grok
|
|
105
|
+
and generic MCP use inbox polling. Antigravity CLI additionally attaches
|
|
106
|
+
a session only where the client reports an open workspace.
|
|
105
107
|
|
|
106
108
|
## Storage and workspace identity
|
|
107
109
|
|
package/docs/CAPABILITIES.md
CHANGED
|
@@ -17,7 +17,8 @@ Capability honesty separates four questions that are easy to collapse:
|
|
|
17
17
|
4. **Fallback** — what durable path remains when any earlier answer is no?
|
|
18
18
|
|
|
19
19
|
A source method or vendor documentation is not certification. Uncaptured hook versions and
|
|
20
|
-
unsupported platforms degrade to false
|
|
20
|
+
unsupported platforms degrade to false, except that an adapter may declare a captured version
|
|
21
|
+
as a floor for later stable releases on the same platform - Antigravity CLI does. Native minimum-based eligibility is separate. No weaker session inherits a stronger peer's capability.
|
|
21
22
|
|
|
22
23
|
Run `acc doctor` in the project when observed behavior differs from this page. It reports
|
|
23
24
|
the installed client version, platform, effective capability, and fallback instead of
|
|
@@ -25,34 +26,39 @@ assuming that a newer or differently packaged client behaves like a captured one
|
|
|
25
26
|
|
|
26
27
|
## Certified support
|
|
27
28
|
|
|
28
|
-
Passing evidence currently ships for these exact versions on `darwin-arm64
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
|
34
|
-
|
|
35
|
-
| `
|
|
36
|
-
| `
|
|
37
|
-
| `
|
|
38
|
-
| `
|
|
39
|
-
| `
|
|
40
|
-
| `
|
|
29
|
+
Passing evidence currently ships for these exact versions on `darwin-arm64`. Antigravity
|
|
30
|
+
CLI's column also covers every later stable release there: its adapter declares 1.2.7 as a
|
|
31
|
+
certification floor, so a newer version is judged by the 1.2.7 captures until one of its
|
|
32
|
+
own says otherwise.
|
|
33
|
+
|
|
34
|
+
| Capability | Antigravity 1.2.7 | Codex 0.147.0 | Claude Code 2.1.233 | Gemini CLI 0.57.0 | Grok 1.0.13 | Kimi 0.36.1 |
|
|
35
|
+
|---|---:|---:|---:|---:|---:|---:|
|
|
36
|
+
| `lifecycle.sessionStart` | yes | yes | yes | yes | no | yes |
|
|
37
|
+
| `lifecycle.sessionEnd` | no | yes | yes | yes | no | no |
|
|
38
|
+
| `lifecycle.heartbeat` | no | no | no | no | no | yes |
|
|
39
|
+
| `context.beforeTurnInjection` | yes | yes | yes | yes | no | yes |
|
|
40
|
+
| `guards.beforeWrite` | no | yes | yes | yes | no | yes |
|
|
41
|
+
| `guards.beforeShell` | no | no | yes | yes | no | yes |
|
|
42
|
+
| `delivery.nextTurn` | yes | yes | yes | yes | no | yes |
|
|
43
|
+
| `delivery.livePush` | yes | no | no | no | no | no |
|
|
44
|
+
| `delivery.replyRoute` | no | no | no | no | no | no |
|
|
41
45
|
|
|
42
46
|
Every other capability in the closed shape defaults to false, including session resume,
|
|
43
47
|
child sessions, startup or safe-point injection, and before-read guards.
|
|
44
48
|
|
|
45
49
|
The native rows remain `no` for the older exact hook versions in this matrix.
|
|
46
50
|
Separate installed-client captures establish Codex `livePush` on 0.152.1 and
|
|
47
|
-
0.153.4,
|
|
51
|
+
0.153.4, Claude Code `livePush` plus `replyRoute` on 2.1.258 and 2.1.260, and
|
|
52
|
+
Antigravity CLI `livePush` on 1.2.7 and later through a relay the agent starts in its own shell.
|
|
48
53
|
Native eligibility uses the captured platform minimum, a current feature probe,
|
|
49
54
|
and an exact per-session handshake. It is experimental and requires recipient
|
|
50
|
-
opt-in. Codex
|
|
55
|
+
opt-in. Codex and Antigravity CLI reply through `acc reply`; their native `replyRoute` remains false.
|
|
51
56
|
|
|
52
57
|
The limitations belong next to the adapters they affect:
|
|
53
58
|
|
|
54
59
|
| Adapter | Exact limitation and evidence |
|
|
55
60
|
|---|---|
|
|
61
|
+
| Antigravity CLI | 1.2.7 on darwin-arm64, captured in print mode, and later stable releases by certification floor. 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. ACC does not take that token, so live push and reply routing are 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; the operator approves that command 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. |
|
|
56
62
|
| Codex | Exact 0.147.0 next-turn context 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. Embedded or unreachable sessions keep their inbox. Native `replyRoute` remains false. |
|
|
57
63
|
| Claude Code | 2.1.233 next-turn delivery waits for the next user prompt. A 2.1.258 Channel capture proved idle offer, busy queue-after-turn, explicit reply, duplicate suppression, and durable fallback, so `delivery.livePush` and `delivery.replyRoute` are live capabilities behind the native contract (experimental, off until opted in; Claude's development-channel warning is vendor-owned and visible). |
|
|
58
64
|
| Gemini CLI | Only 0.57.0 has package-shipped next-turn certification. 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. |
|
package/docs/CONFIGURATION.md
CHANGED
|
@@ -194,6 +194,7 @@ that resolves inside a workspace.
|
|
|
194
194
|
| `ACC_MCP_WORKSPACE` | The project `acc-mcp` joins. Without it the server takes the directory the client launched it in, which is rarely the project |
|
|
195
195
|
| `ACC_NO_UPDATE_CHECK=1` | Disables update networking and background scheduling; manual recovery of an already downloaded update remains available |
|
|
196
196
|
| `ACC_PROBE_TIMEOUT_MS` | How long to wait for a client to print its version. Three seconds by default: generous on an idle machine, and not always enough on a busy one, where a client that overruns it is reported as not installed |
|
|
197
|
+
| `ACC_ANTIGRAVITY_HOOKS` | Where `acc install` registers Antigravity CLI hooks. `global`, the default, writes `~/.gemini/config/hooks.json`, which always loads and applies to every Antigravity session on the machine. `workspace` writes `<project>/.agents/hooks.json`, which is scoped to the project the command ran in and loads only while that project is an open Antigravity workspace - in print mode, only when it is passed with `--add-dir`. Any other value is refused by name rather than replaced by the default, and that client is skipped. The two cannot be combined: both files use the namespace `acc`, and a name in both is kept only once |
|
|
197
198
|
| `ACC_NATIVE_DELIVERY_POLICY` | Owned shell-bootstrap consent, currently used by Claude Code. The shim sets `off`, `actionable`, or `all`; missing/invalid values mean off for that route. Codex instead reads recorded installation consent, even when this variable is absent |
|
|
198
199
|
| `ACC_BYPASS=1` | Bypasses owned shell activation, currently Claude Code: no bootstrap check/native flags, and shim policy is unset. It does not disable Codex recorded opt-in; use `acc install --adapter codex --delivery off` for new Codex offers |
|
|
199
200
|
| `ACC_BOOTSTRAP_DEBUG=1` | Lets the internal `acc-bootstrap` check write one safe diagnostic line to stderr. Off, it is silent, and it never writes to stdout |
|
package/docs/GETTING_STARTED.md
CHANGED
|
@@ -132,16 +132,22 @@ Every message is recorded before ACC attempts faster delivery. Every participant
|
|
|
132
132
|
durable inbox, which is the universal recovery path.
|
|
133
133
|
|
|
134
134
|
On exact client versions and platforms with captured support, Codex, Claude Code, Gemini
|
|
135
|
-
CLI,
|
|
136
|
-
session. Grok, generic MCP clients, unknown versions, and unsupported
|
|
137
|
-
durable inbox instead.
|
|
135
|
+
CLI, Kimi Code and Antigravity CLI can receive a message at the next normal turn. That does
|
|
136
|
+
not wake an idle session. Grok, generic MCP clients, unknown versions, and unsupported
|
|
137
|
+
platforms use the durable inbox instead.
|
|
138
|
+
|
|
139
|
+
Antigravity CLI carries one extra condition: its hooks are given a project directory only
|
|
140
|
+
when the session has an open workspace. A session started without one attaches nothing, and
|
|
141
|
+
the client shows no hook output to say so - `acc doctor` names it.
|
|
138
142
|
|
|
139
143
|
Codex LocalDaemon and Claude Code Channel offer optional native delivery on
|
|
140
144
|
Apple Silicon macOS. They are experimental, can spend tokens, and queue messages
|
|
141
145
|
until a running turn finishes. Codex requires 0.152.1 or newer, LocalDaemon infrastructure,
|
|
142
146
|
recorded opt-in, and a verified session. Supported explicit setup can prepare a missing
|
|
143
147
|
service. Start the client with your normal command. A loaded daemon thread can receive
|
|
144
|
-
messages after its terminal exits.
|
|
148
|
+
messages after its terminal exits. Antigravity CLI 1.2.7 and later has one too: with delivery enabled,
|
|
149
|
+
ACC's context asks the agent once per conversation to start a relay from its own shell, and
|
|
150
|
+
you approve that command at the client's prompt.
|
|
145
151
|
[Capabilities](CAPABILITIES.md) explains policy, versions and fallback.
|
|
146
152
|
|
|
147
153
|
Delivery evidence is deliberately narrow: `queued -> offered -> retrieved -> acknowledged`.
|
package/docs/HOW_IT_WORKS.md
CHANGED
|
@@ -99,7 +99,7 @@ All recipients have the same durable record, but adapters expose different accel
|
|
|
99
99
|
- **Durable inbox:** universal recovery. `acc inbox` discovers bounded message headers;
|
|
100
100
|
`acc inbox --message <id>` retrieves one complete addressed message after selection
|
|
101
101
|
or compaction.
|
|
102
|
-
- **Next normal turn:** exact captured versions of Codex, Claude Code, Gemini CLI, and Kimi
|
|
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
105
|
- **Optional Claude Code channel:** supported Claude Code versions on Apple Silicon macOS
|
|
@@ -115,6 +115,12 @@ All recipients have the same durable record, but adapters expose different accel
|
|
|
115
115
|
and does not manage the vendor daemon during message delivery. Separately,
|
|
116
116
|
[confirmed update maintenance](UPGRADING.md#confirmed-client-service-maintenance) can restart it.
|
|
117
117
|
|
|
118
|
+
- **Optional Antigravity CLI relay:** on Apple Silicon macOS with 1.2.7 or later, the session
|
|
119
|
+
endpoint exists only in the agent's own shell, so ACC's context asks the agent once per
|
|
120
|
+
conversation to start a relay; the user approves that command. The relay keeps the endpoint
|
|
121
|
+
in memory, wakes an idle session with a fenced peer message, holds one for a busy session,
|
|
122
|
+
and ends with the client. It is experimental, off by default, and can spend tokens.
|
|
123
|
+
|
|
118
124
|
Grok, generic MCP, unsupported versions and uncaptured platforms use inbox polling.
|
|
119
125
|
[Capabilities](CAPABILITIES.md) lists evidence and fallback.
|
|
120
126
|
|
package/docs/TROUBLESHOOTING.md
CHANGED
|
@@ -214,6 +214,78 @@ trusted` and keeps going, and the default mode has no write or shell tool to gua
|
|
|
214
214
|
guard never fires and the mode you passed appears to have been ignored. Trust the folder,
|
|
215
215
|
or start the session somewhere trusted.
|
|
216
216
|
|
|
217
|
+
## Antigravity is installed and nothing happens
|
|
218
|
+
|
|
219
|
+
The most likely cause is that the session has no open workspace. Antigravity CLI gives its
|
|
220
|
+
hooks a project directory only through `workspacePaths`, and that array is empty unless the
|
|
221
|
+
session has one. The interactive TUI started in a project directory has one; a print-mode
|
|
222
|
+
`agy -p "..."` started in the same directory does not. The
|
|
223
|
+
hook then has no workspace to join, fails open as every ACC hook must, and this client shows
|
|
224
|
+
no hook output, so nothing anywhere says why.
|
|
225
|
+
|
|
226
|
+
Open the project as an Antigravity workspace, or pass it explicitly:
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
agy -p "..." --add-dir /path/to/project
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
The first TUI session in a folder you trusted at that same launch has no workspace either,
|
|
233
|
+
even with `--add-dir`; start the TUI again once the folder is trusted.
|
|
234
|
+
|
|
235
|
+
`acc doctor` names this state. Nothing else in the payload can substitute for it:
|
|
236
|
+
`transcriptPath` and `artifactDirectoryPath` both point inside the client's own
|
|
237
|
+
per-conversation directory, and the hook process does not inherit the directory the client
|
|
238
|
+
was started in.
|
|
239
|
+
|
|
240
|
+
If the session does have a workspace and ACC is still absent, check that the registration
|
|
241
|
+
actually loaded rather than that the file exists:
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
agy -p "/hooks" --output-format json
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
This client accepts a hook configuration it will not load and reports nothing. A file on
|
|
248
|
+
disk is not a registration: the Gemini CLI hook shape loads nothing here, an unsupported
|
|
249
|
+
event name is dropped out of an otherwise valid namespace, and one top-level key that is not
|
|
250
|
+
an integration namespace drops the whole file. The command above is the only answer that
|
|
251
|
+
counts.
|
|
252
|
+
|
|
253
|
+
The agent may see two ACC skills: `acc:acc`, which `acc install` puts there, and
|
|
254
|
+
`agents-can-communicate:acc`. The second is this client's own copy of ACC's Gemini CLI
|
|
255
|
+
extension, made on its first authenticated run into `~/.gemini/antigravity-cli/plugins/`. Its
|
|
256
|
+
skill loads, but none of its hooks do, and every command in it runs the Gemini CLI extension's
|
|
257
|
+
shim - so it works only while Gemini CLI is wired. `acc:acc` is the one to rely on; check what
|
|
258
|
+
the client actually loaded with:
|
|
259
|
+
|
|
260
|
+
```
|
|
261
|
+
agy -p "/skills" --output-format json
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
`agy plugin list` is not that check: it lists only plugins installed through
|
|
265
|
+
`agy plugin install`, and reports none while the imported skill above is loaded.
|
|
266
|
+
|
|
267
|
+
An agent that receives a peer message in print mode (`agy -p`) cannot answer it on its own.
|
|
268
|
+
It forms the right `acc reply` command from the skill, and print mode denies every command
|
|
269
|
+
because it cannot ask for approval; the client says so on stderr. The TUI asks instead.
|
|
270
|
+
ACC does not grant itself that permission. To let headless agents answer, allow the ACC
|
|
271
|
+
command yourself under `permissions.allow` in the client's settings, in the `command(...)`
|
|
272
|
+
form its message names.
|
|
273
|
+
|
|
274
|
+
## Antigravity never wakes while idle
|
|
275
|
+
|
|
276
|
+
Live delivery needs four things, and `acc doctor` shows each:
|
|
277
|
+
|
|
278
|
+
- the live policy is on: `acc install --adapter antigravity --delivery actionable` (or `all`);
|
|
279
|
+
- the session is interactive - print mode ends with its turn and never runs a relay;
|
|
280
|
+
- the session attached to ACC at all (see the section above);
|
|
281
|
+
- the agent started the relay. ACC's context asks once per conversation; if the command was
|
|
282
|
+
declined, or never approved at the permission prompt, nothing asks again. Ask the agent to
|
|
283
|
+
run `sh "~/.gemini/config/acc/acc-relay.sh" start`, or start a new conversation.
|
|
284
|
+
|
|
285
|
+
`acc doctor` reports how many relays are running and, per session, whether a live transport is
|
|
286
|
+
active. A relay ends with its client; nothing is left running after the TUI exits or after
|
|
287
|
+
`acc uninstall`.
|
|
288
|
+
|
|
217
289
|
## Grok shows no injected message
|
|
218
290
|
|
|
219
291
|
Grok discards UserPromptSubmit context. On the observed 1.0.24 client, run public
|