agents-can-communicate 0.5.3 → 0.5.5
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 +8 -5
- package/docs/ARCHITECTURE.md +6 -1
- package/docs/CLI.md +7 -4
- package/docs/CONFIGURATION.md +7 -3
- package/docs/GETTING_STARTED.md +12 -3
- package/docs/TROUBLESHOOTING.md +25 -9
- package/docs/UPGRADING.md +39 -10
- 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-codex/src/adapter.mjs +5 -2
- package/node_modules/@agents-can-communicate/adapter-codex/src/app-server-client.mjs +2 -1
- package/node_modules/@agents-can-communicate/adapter-codex/src/install.mjs +1 -1
- package/node_modules/@agents-can-communicate/adapter-codex/src/live-permissions.mjs +37 -12
- package/node_modules/@agents-can-communicate/adapter-codex/src/maintenance-host.mjs +1 -1
- package/node_modules/@agents-can-communicate/adapter-codex/src/native-delivery.mjs +2 -1
- package/node_modules/@agents-can-communicate/adapter-codex/src/service-setup.mjs +135 -0
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/gemini-extension.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-gemini-cli/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-grok/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-kimi/package.json +1 -1
- package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
- package/node_modules/@agents-can-communicate/cli/package.json +1 -1
- package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +10 -5
- package/node_modules/@agents-can-communicate/cli/src/help.mjs +3 -0
- package/node_modules/@agents-can-communicate/cli/src/install-command.mjs +15 -71
- package/node_modules/@agents-can-communicate/cli/src/install-delivery-consent.mjs +152 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/generation-files.mjs +25 -0
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/generation.mjs +1 -22
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/launchers.mjs +1 -1
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/leases.mjs +2 -2
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/refresh.mjs +6 -1
- package/node_modules/@agents-can-communicate/cli/src/managed-runtime/state.mjs +23 -1
- package/node_modules/@agents-can-communicate/cli/src/native-delivery-status.mjs +22 -5
- package/node_modules/@agents-can-communicate/core/package.json +1 -1
- 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/installer/package.json +1 -1
- package/node_modules/@agents-can-communicate/installer/src/apply.mjs +6 -2
- package/node_modules/@agents-can-communicate/installer/src/detect.mjs +11 -0
- package/node_modules/@agents-can-communicate/installer/src/ownership.mjs +6 -1
- package/node_modules/@agents-can-communicate/installer/src/plan.mjs +10 -2
- package/node_modules/@agents-can-communicate/installer/src/service-setup.mjs +30 -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/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applyServiceSetup } from "./service-setup.mjs";
|
|
1
2
|
import { applyNativeActivation, deactivateNative } from "./native-activation.mjs";
|
|
2
3
|
import { finalizeRemoval, missingArtifactParents, recordInstall,
|
|
3
4
|
removeEmptyOwnedDirectories, removeOwnedArtifacts } from "./ownership.mjs";
|
|
@@ -68,7 +69,8 @@ export async function applyPlan({ plan, adapters, context, dataHome, dryRun = fa
|
|
|
68
69
|
await recordInstall({ dataHome, adapterId: adapter.id,
|
|
69
70
|
version: operation.clientVersion ?? null, accVersion,
|
|
70
71
|
artifacts: operation.artifacts, createdDirectories,
|
|
71
|
-
deliveryPolicy: operation.livePolicy,
|
|
72
|
+
deliveryPolicy: operation.livePolicy, deliveryDecision: operation.deliveryDecision,
|
|
73
|
+
nativeActivation: native });
|
|
72
74
|
results.operations.push({ ...operation, applied: true, appendedRcBlock,
|
|
73
75
|
needsAction: outcome.needsAction ?? [],
|
|
74
76
|
changes: outcome.changes ?? [], diagnostics: [
|
|
@@ -77,6 +79,8 @@ export async function applyPlan({ plan, adapters, context, dataHome, dryRun = fa
|
|
|
77
79
|
...(outcome.diagnostics ?? []),
|
|
78
80
|
...notes,
|
|
79
81
|
] });
|
|
82
|
+
await applyServiceSetup({ adapter, context: installContext,
|
|
83
|
+
operation: results.operations.at(-1), results });
|
|
80
84
|
} else {
|
|
81
85
|
// Config ownership can veto removal. Ask before teardown or recorded
|
|
82
86
|
// artifact deletion; an adapter-local check would run after those writes.
|
|
@@ -131,7 +135,7 @@ function describeTeardown(report) {
|
|
|
131
135
|
for (const service of report.services) {
|
|
132
136
|
lines.push(service.outcome === "stopped" ? `stopped the ${service.serviceId} service`
|
|
133
137
|
: `retained the ${service.serviceId} service (${service.outcome === "retained_pre_existing"
|
|
134
|
-
? "it
|
|
138
|
+
? "it was reused at activation" : "no vendor teardown exists"})`);
|
|
135
139
|
}
|
|
136
140
|
return lines;
|
|
137
141
|
}
|
|
@@ -145,6 +145,17 @@ export async function detectInstallation({ adapters, context, probe = spawnProbe
|
|
|
145
145
|
: unsupported(adapter.nativeDelivery === undefined
|
|
146
146
|
? "native_delivery_unsupported" : "version_unavailable");
|
|
147
147
|
|
|
148
|
+
if (entry.present && typeof adapter.inspectNativeServiceSetup === "function") {
|
|
149
|
+
try {
|
|
150
|
+
entry.nativeServiceSetup = await withTimeout(Promise.resolve().then(() =>
|
|
151
|
+
adapter.inspectNativeServiceSetup({ ...context, platform, clientVersion: entry.version })),
|
|
152
|
+
probeTimeoutMs, `${adapter.id} service setup probe`);
|
|
153
|
+
} catch {
|
|
154
|
+
entry.nativeServiceSetup = { state: "blocked", reasonCode: "service_inspection_failed",
|
|
155
|
+
diagnostic: `${adapter.displayName} service preparation could not be inspected; check the vendor service and retry install` };
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
148
159
|
try {
|
|
149
160
|
const detected = await adapter.detect({ ...context, clientVersion: entry.version,
|
|
150
161
|
platform, nativeDelivery: entry.nativeDelivery });
|
|
@@ -110,7 +110,8 @@ async function saveOwnership({ dataHome, record }) {
|
|
|
110
110
|
* runtime, and leaves the bundle inside the client exactly where it was.
|
|
111
111
|
*/
|
|
112
112
|
export async function recordInstall({ dataHome, adapterId, version, accVersion = null,
|
|
113
|
-
artifacts, createdDirectories = [], deliveryPolicy,
|
|
113
|
+
artifacts, createdDirectories = [], deliveryPolicy, deliveryDecision,
|
|
114
|
+
nativeActivation = null }) {
|
|
114
115
|
const stamped = await Promise.all(artifacts.map(async artifact => ({
|
|
115
116
|
path: artifact.path,
|
|
116
117
|
kind: artifact.kind ?? "file",
|
|
@@ -120,6 +121,7 @@ export async function recordInstall({ dataHome, adapterId, version, accVersion =
|
|
|
120
121
|
})));
|
|
121
122
|
const record = await loadOwnership({ dataHome });
|
|
122
123
|
const previous = record.installs.find(install => install.adapterId === adapterId);
|
|
124
|
+
const retainedDeliveryDecision = deliveryDecision ?? previous?.deliveryDecision;
|
|
123
125
|
const directories = [...new Set([
|
|
124
126
|
...(previous?.createdDirectories ?? []), ...createdDirectories,
|
|
125
127
|
])].sort((left, right) => left.split(path.sep).length - right.split(path.sep).length
|
|
@@ -129,6 +131,9 @@ export async function recordInstall({ dataHome, adapterId, version, accVersion =
|
|
|
129
131
|
{ adapterId, version, accVersion, artifacts: stamped,
|
|
130
132
|
...(directories.length === 0 ? {} : { createdDirectories: directories }),
|
|
131
133
|
...(deliveryPolicy === undefined ? {} : { deliveryPolicy }),
|
|
134
|
+
...(retainedDeliveryDecision === undefined ? {} : {
|
|
135
|
+
deliveryDecision: retainedDeliveryDecision,
|
|
136
|
+
}),
|
|
132
137
|
// Present only for a consented native activation. A record without it
|
|
133
138
|
// - every 0.2 install - reads as live policy off and is never rewritten
|
|
134
139
|
// merely to add the field.
|
|
@@ -14,7 +14,7 @@ import { LIVE_POLICIES, describeActivation, describeDeactivation, planActivation
|
|
|
14
14
|
*/
|
|
15
15
|
export function planInstallation({ adapters, detected, context, action = "install",
|
|
16
16
|
recorded = [], accVersion = null, allowDowngrade = false, requested = [],
|
|
17
|
-
deliveryByAdapter = {} }) {
|
|
17
|
+
deliveryByAdapter = {}, deliveryDecisionByAdapter = {}, allowServiceSetup = false }) {
|
|
18
18
|
if (!["install", "uninstall"].includes(action)) {
|
|
19
19
|
throw new AccError(EXIT.USAGE, `unknown installation action: ${action}`, { action });
|
|
20
20
|
}
|
|
@@ -104,6 +104,9 @@ export function planInstallation({ adapters, detected, context, action = "instal
|
|
|
104
104
|
// and so what will be removed. Asking the adapter instead would describe an
|
|
105
105
|
// install for a machine this one no longer is.
|
|
106
106
|
const delivery = deliveryByAdapter[entry.adapterId] ?? "off";
|
|
107
|
+
const deliveryDecision = deliveryDecisionByAdapter[entry.adapterId]
|
|
108
|
+
?? recordedById.get(entry.adapterId)?.deliveryDecision
|
|
109
|
+
?? { source: "legacy-unknown", completeSetup: false };
|
|
107
110
|
const native = entry.nativeDelivery ?? null;
|
|
108
111
|
const liveDeliverySupported = native?.state === "eligible"
|
|
109
112
|
&& native.activationPlan?.eligible === true;
|
|
@@ -122,8 +125,10 @@ export function planInstallation({ adapters, detected, context, action = "instal
|
|
|
122
125
|
? describeInstallDelivery(entry, delivery, effectiveLivePolicy) : null;
|
|
123
126
|
const installContext = { ...context, requestedLivePolicy: delivery,
|
|
124
127
|
livePolicy: configuredLivePolicy, clientVersion: entry.version, platform: entry.platform };
|
|
128
|
+
const nativeServiceSetup = action === "install" && allowServiceSetup && delivery !== "off"
|
|
129
|
+
&& deliveryDecision.completeSetup === true ? entry.nativeServiceSetup : undefined;
|
|
125
130
|
const setupNotes = action === "install" && delivery !== "off"
|
|
126
|
-
? [entry.outgoingDelivery?.setup, entry.nativeSetup].filter(note => typeof note === "string") : [];
|
|
131
|
+
? [entry.outgoingDelivery?.setup, nativeServiceSetup ? null : entry.nativeSetup].filter(note => typeof note === "string") : [];
|
|
127
132
|
// A consented activation that this run keeps, activates, or takes back.
|
|
128
133
|
// Only an explicit off or an uninstall removes one; an absent record never
|
|
129
134
|
// creates one.
|
|
@@ -154,11 +159,13 @@ export function planInstallation({ adapters, detected, context, action = "instal
|
|
|
154
159
|
alreadyInstalled: entry.installed === true,
|
|
155
160
|
livePolicy: delivery,
|
|
156
161
|
effectiveLivePolicy,
|
|
162
|
+
...(action === "install" ? { deliveryDecision } : {}),
|
|
157
163
|
...(retainedActivation ? { configuredLivePolicy, retainedNativeActivation: retainedActivation } : {}),
|
|
158
164
|
...(deliveryDiagnostic === null ? {} : { deliveryDiagnostic }),
|
|
159
165
|
...(deliverySummary === null ? {} : { deliverySummary }),
|
|
160
166
|
...(setupNotes.length ? { setupNotes } : {}),
|
|
161
167
|
...(nativeActivation === null ? {} : { nativeActivation }),
|
|
168
|
+
...(nativeServiceSetup ? { nativeServiceSetup } : {}),
|
|
162
169
|
...(deactivation === null ? {} : { deactivation }),
|
|
163
170
|
artifacts,
|
|
164
171
|
// Said in the operator's terms, not in paths: which files ACC creates
|
|
@@ -169,6 +176,7 @@ export function planInstallation({ adapters, detected, context, action = "instal
|
|
|
169
176
|
...(deliverySummary === null ? [] : [deliverySummary]),
|
|
170
177
|
...(retainedActivation ? ["keep existing native delivery setup; current readiness is unverified"] : []),
|
|
171
178
|
...setupNotes,
|
|
179
|
+
...(nativeServiceSetup ? [nativeServiceSetup.diagnostic] : []),
|
|
172
180
|
...artifacts.filter(a => a.kind === "tree")
|
|
173
181
|
.map(a => `${action === "install" ? "create" : "remove"} ${a.path}`),
|
|
174
182
|
...artifacts.filter(a => a.kind === "merge")
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Invoked only after adapter configuration and ownership/consent persistence.
|
|
2
|
+
// A failed service command must not erase the successful adapter operation.
|
|
3
|
+
export async function applyServiceSetup({ adapter, context, operation, results }) {
|
|
4
|
+
const plan = operation.nativeServiceSetup;
|
|
5
|
+
if (!plan || operation.livePolicy === "off" || operation.deliveryDecision?.completeSetup !== true) return;
|
|
6
|
+
let setup = plan;
|
|
7
|
+
if (["needed", "ready"].includes(plan.state)) {
|
|
8
|
+
try {
|
|
9
|
+
setup = await adapter.prepareNativeServiceSetup({ context, plan });
|
|
10
|
+
if (!setup || !["ready", "failed", "blocked"].includes(setup.state)) throw new Error("invalid setup result");
|
|
11
|
+
} catch {
|
|
12
|
+
setup = { state: "failed", started: false, reasonCode: "service_setup_failed",
|
|
13
|
+
diagnostic: `${adapter.displayName} service preparation failed; check the vendor service and retry acc install` };
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
operation.nativeServiceSetup = setup;
|
|
17
|
+
if (setup.state === "ready") {
|
|
18
|
+
const stale = new Set([operation.deliverySummary, operation.deliveryDiagnostic, plan.diagnostic]);
|
|
19
|
+
operation.summary = (operation.summary ?? []).filter(line => !stale.has(line));
|
|
20
|
+
operation.summary.push(setup.diagnostic);
|
|
21
|
+
operation.diagnostics = (operation.diagnostics ?? []).filter(line => !stale.has(line));
|
|
22
|
+
operation.deliverySummary = setup.diagnostic;
|
|
23
|
+
operation.deliveryDiagnostic = setup.diagnostic;
|
|
24
|
+
} else {
|
|
25
|
+
operation.needsAction.push(setup.diagnostic);
|
|
26
|
+
if (setup.state === "failed") results.failed.push({ adapterId: operation.adapterId,
|
|
27
|
+
error: setup.diagnostic, reasonCode: setup.reasonCode });
|
|
28
|
+
}
|
|
29
|
+
operation.diagnostics.push(setup.diagnostic);
|
|
30
|
+
}
|