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.
Files changed (46) hide show
  1. package/README.md +8 -5
  2. package/docs/ARCHITECTURE.md +6 -1
  3. package/docs/CLI.md +7 -4
  4. package/docs/CONFIGURATION.md +7 -3
  5. package/docs/GETTING_STARTED.md +12 -3
  6. package/docs/TROUBLESHOOTING.md +25 -9
  7. package/docs/UPGRADING.md +39 -10
  8. package/node_modules/@agents-can-communicate/adapter-claude-code/package.json +1 -1
  9. package/node_modules/@agents-can-communicate/adapter-codex/package.json +1 -1
  10. package/node_modules/@agents-can-communicate/adapter-codex/src/adapter.mjs +5 -2
  11. package/node_modules/@agents-can-communicate/adapter-codex/src/app-server-client.mjs +2 -1
  12. package/node_modules/@agents-can-communicate/adapter-codex/src/install.mjs +1 -1
  13. package/node_modules/@agents-can-communicate/adapter-codex/src/live-permissions.mjs +37 -12
  14. package/node_modules/@agents-can-communicate/adapter-codex/src/maintenance-host.mjs +1 -1
  15. package/node_modules/@agents-can-communicate/adapter-codex/src/native-delivery.mjs +2 -1
  16. package/node_modules/@agents-can-communicate/adapter-codex/src/service-setup.mjs +135 -0
  17. package/node_modules/@agents-can-communicate/adapter-gemini-cli/extension/gemini-extension.json +1 -1
  18. package/node_modules/@agents-can-communicate/adapter-gemini-cli/package.json +1 -1
  19. package/node_modules/@agents-can-communicate/adapter-grok/package.json +1 -1
  20. package/node_modules/@agents-can-communicate/adapter-kimi/package.json +1 -1
  21. package/node_modules/@agents-can-communicate/adapter-sdk/package.json +1 -1
  22. package/node_modules/@agents-can-communicate/cli/package.json +1 -1
  23. package/node_modules/@agents-can-communicate/cli/src/doctor-command.mjs +10 -5
  24. package/node_modules/@agents-can-communicate/cli/src/help.mjs +3 -0
  25. package/node_modules/@agents-can-communicate/cli/src/install-command.mjs +15 -71
  26. package/node_modules/@agents-can-communicate/cli/src/install-delivery-consent.mjs +152 -0
  27. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/generation-files.mjs +25 -0
  28. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/generation.mjs +1 -22
  29. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/launchers.mjs +1 -1
  30. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/leases.mjs +2 -2
  31. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/refresh.mjs +6 -1
  32. package/node_modules/@agents-can-communicate/cli/src/managed-runtime/state.mjs +23 -1
  33. package/node_modules/@agents-can-communicate/cli/src/native-delivery-status.mjs +22 -5
  34. package/node_modules/@agents-can-communicate/core/package.json +1 -1
  35. package/node_modules/@agents-can-communicate/delivery-router/package.json +1 -1
  36. package/node_modules/@agents-can-communicate/hook-runner/package.json +1 -1
  37. package/node_modules/@agents-can-communicate/installer/package.json +1 -1
  38. package/node_modules/@agents-can-communicate/installer/src/apply.mjs +6 -2
  39. package/node_modules/@agents-can-communicate/installer/src/detect.mjs +11 -0
  40. package/node_modules/@agents-can-communicate/installer/src/ownership.mjs +6 -1
  41. package/node_modules/@agents-can-communicate/installer/src/plan.mjs +10 -2
  42. package/node_modules/@agents-can-communicate/installer/src/service-setup.mjs +30 -0
  43. package/node_modules/@agents-can-communicate/mcp-server/package.json +1 -1
  44. package/node_modules/@agents-can-communicate/protocol/package.json +1 -1
  45. package/node_modules/@agents-can-communicate/storage-filesystem/package.json +1 -1
  46. 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, nativeActivation: native });
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 existed before ACC" : "no vendor teardown exists"})`);
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, nativeActivation = null }) {
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
+ }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/mcp-server",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/protocol",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agents-can-communicate/storage-filesystem",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "private": true,
5
5
  "type": "module",
6
6
  "exports": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agents-can-communicate",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "accManagedUpdateProtocol": 2,
5
5
  "accStoreVersion": 6,
6
6
  "type": "module",