commonswarm 0.1.26 → 0.1.28
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/cswarm.cjs +492 -147
- package/package.json +1 -1
package/cswarm.cjs
CHANGED
|
@@ -28443,7 +28443,7 @@ function parseSignalRecord(value) {
|
|
|
28443
28443
|
throw new Error("signal read returned a malformed row");
|
|
28444
28444
|
}
|
|
28445
28445
|
const row = value;
|
|
28446
|
-
if (typeof row.from_kind !== "string" || !["user", "agent"].includes(row.from_kind) || typeof row.kind !== "string" || !SIGNAL_KINDS.has(row.kind) || typeof row.body !== "string" || row.body.length < 1 || row.body.length >
|
|
28446
|
+
if (typeof row.from_kind !== "string" || !["user", "agent"].includes(row.from_kind) || typeof row.kind !== "string" || !SIGNAL_KINDS.has(row.kind) || typeof row.body !== "string" || row.body.length < 1 || row.body.length > 8e3 || !(row.about === null || typeof row.about === "string" && row.about.length <= 500)) {
|
|
28447
28447
|
throw new Error("signal read returned malformed signal data");
|
|
28448
28448
|
}
|
|
28449
28449
|
let senderOwnerRelation = "unknown";
|
|
@@ -28550,12 +28550,12 @@ function parseRetryAfterMs(header, nowMs = Date.now()) {
|
|
|
28550
28550
|
if (!Number.isFinite(when)) return null;
|
|
28551
28551
|
return Math.max(0, Math.min(when - nowMs, SIGNAL_FOLLOW_BACKOFF_MAX_MS));
|
|
28552
28552
|
}
|
|
28553
|
-
function throwSignalHttp(response, body) {
|
|
28553
|
+
function throwSignalHttp(response, body, failure = "signal read failed") {
|
|
28554
28554
|
const status = response.status;
|
|
28555
28555
|
const retryAfterMs = parseRetryAfterMs(response.headers.get("retry-after"));
|
|
28556
28556
|
const envelope = parseServerErrorEnvelope(body);
|
|
28557
28557
|
const error = new Error(
|
|
28558
|
-
describeServerError(
|
|
28558
|
+
describeServerError(`${failure} (HTTP ${status})`, envelope)
|
|
28559
28559
|
);
|
|
28560
28560
|
plainHttpStatus.set(error, status);
|
|
28561
28561
|
plainHttpRetryAfterMs.set(error, retryAfterMs);
|
|
@@ -28912,7 +28912,7 @@ async function readAgentSignalDirectory(target2, token, workspaceId2, fetcherOrO
|
|
|
28912
28912
|
}
|
|
28913
28913
|
const { response, body } = result;
|
|
28914
28914
|
if (!response.ok) {
|
|
28915
|
-
|
|
28915
|
+
throwSignalHttp(response, body, "member read failed");
|
|
28916
28916
|
}
|
|
28917
28917
|
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
28918
28918
|
throw new Error("member read returned malformed JSON");
|
|
@@ -29130,6 +29130,37 @@ function postSignalTargets(recipient) {
|
|
|
29130
29130
|
};
|
|
29131
29131
|
}
|
|
29132
29132
|
var ASK_WAIT_TIMEOUT_MESSAGE = "Ask shared. No reply arrived before the wait ended; the ask remains live. Check for a reply with: cswarm inbox";
|
|
29133
|
+
function askFailureDetail(error) {
|
|
29134
|
+
const readHttp = followHttpDetails(error);
|
|
29135
|
+
if (readHttp !== null) {
|
|
29136
|
+
return {
|
|
29137
|
+
detail: describeServerError(
|
|
29138
|
+
`HTTP ${readHttp.status}`,
|
|
29139
|
+
followErrorEnvelope(error)
|
|
29140
|
+
),
|
|
29141
|
+
serverError: true
|
|
29142
|
+
};
|
|
29143
|
+
}
|
|
29144
|
+
if (error instanceof CommandHttpError) {
|
|
29145
|
+
return {
|
|
29146
|
+
detail: `HTTP ${error.status}; server detail: ${error.message.replace(/^signal read failed \(HTTP \d+\)(?:: )?/, "").slice(0, 240)}`,
|
|
29147
|
+
serverError: true
|
|
29148
|
+
};
|
|
29149
|
+
}
|
|
29150
|
+
return {
|
|
29151
|
+
detail: error instanceof Error ? error.message.slice(0, 300) : "unknown error",
|
|
29152
|
+
serverError: false
|
|
29153
|
+
};
|
|
29154
|
+
}
|
|
29155
|
+
function askCreateFailureMessage(workspaceId2, error) {
|
|
29156
|
+
const failure = askFailureDetail(error);
|
|
29157
|
+
const cause = failure.serverError ? `server error before it was confirmed: ${failure.detail}` : `request failure before it was confirmed: ${failure.detail}`;
|
|
29158
|
+
return `Your message may not have been posted (${cause}). Check with: cswarm feed --workspace-id ${workspaceId2} \u2014 and resend if it is not there.`;
|
|
29159
|
+
}
|
|
29160
|
+
function askReplyReadFailureMessage(workspaceId2, error) {
|
|
29161
|
+
const failure = askFailureDetail(error);
|
|
29162
|
+
return `Your message was posted, but its reply could not be fetched (${failure.detail}). Do not resend this ask. Check with: cswarm inbox --workspace-id ${workspaceId2}`;
|
|
29163
|
+
}
|
|
29133
29164
|
function renderSignals(signals, options) {
|
|
29134
29165
|
if (signals.length === 0) {
|
|
29135
29166
|
return [
|
|
@@ -29539,11 +29570,15 @@ var ACP_MAX_ACCUMULATED_TEXT_CHARS = 4194304;
|
|
|
29539
29570
|
var ACP_DEFAULT_REQUEST_TIMEOUT_MS = 12e4;
|
|
29540
29571
|
var ACP_VERSION_CHECK_TIMEOUT_MS = 5e3;
|
|
29541
29572
|
var ACP_CANARY_TIMEOUT_MS = 3e4;
|
|
29542
|
-
var
|
|
29543
|
-
var
|
|
29544
|
-
var
|
|
29573
|
+
var GROK_MIN_VERSION = "0.2.117";
|
|
29574
|
+
var GROK_LAST_MEASURED_VERSION = "0.2.117";
|
|
29575
|
+
var OPENCODE_MIN_VERSION = "1.18.10";
|
|
29576
|
+
var OPENCODE_LAST_MEASURED_VERSION = "1.18.10";
|
|
29577
|
+
var CLAUDE_ACP_MIN_VERSION = "0.64.2";
|
|
29578
|
+
var CLAUDE_ACP_LAST_MEASURED_VERSION = "0.64.2";
|
|
29545
29579
|
var CLAUDE_PERMISSION_MODE_ID = "default";
|
|
29546
|
-
var
|
|
29580
|
+
var CODEX_ACP_MIN_VERSION = "1.1.9";
|
|
29581
|
+
var CODEX_ACP_LAST_MEASURED_VERSION = "1.1.9";
|
|
29547
29582
|
var CODEX_PERMISSION_MODE_ID = "read-only";
|
|
29548
29583
|
var ACP_PROTOCOL_VERSION = 1;
|
|
29549
29584
|
var OPENCODE_FORCED_PERMISSION_TOOLS = [
|
|
@@ -29758,11 +29793,32 @@ var AcpTransportError = class extends AcpHostError {
|
|
|
29758
29793
|
cause;
|
|
29759
29794
|
};
|
|
29760
29795
|
var AcpVersionError = class extends AcpHostError {
|
|
29761
|
-
constructor(message) {
|
|
29762
|
-
super(
|
|
29796
|
+
constructor(message, code = "version_refused") {
|
|
29797
|
+
super(code, message);
|
|
29763
29798
|
this.name = "AcpVersionError";
|
|
29764
29799
|
}
|
|
29765
29800
|
};
|
|
29801
|
+
var AcpVersionParseError = class extends AcpVersionError {
|
|
29802
|
+
constructor(message) {
|
|
29803
|
+
super(message, "version_unparseable");
|
|
29804
|
+
this.name = "AcpVersionParseError";
|
|
29805
|
+
}
|
|
29806
|
+
};
|
|
29807
|
+
var AcpVersionBelowFloorError = class extends AcpVersionError {
|
|
29808
|
+
constructor(provider, minimum, actual) {
|
|
29809
|
+
super(
|
|
29810
|
+
`refusing ${provider} ${actual}; CommonSwarm requires ${minimum} or newer`,
|
|
29811
|
+
"version_below_floor"
|
|
29812
|
+
);
|
|
29813
|
+
this.provider = provider;
|
|
29814
|
+
this.minimum = minimum;
|
|
29815
|
+
this.actual = actual;
|
|
29816
|
+
this.name = "AcpVersionBelowFloorError";
|
|
29817
|
+
}
|
|
29818
|
+
provider;
|
|
29819
|
+
minimum;
|
|
29820
|
+
actual;
|
|
29821
|
+
};
|
|
29766
29822
|
var AcpPermissionCanaryError = class extends AcpHostError {
|
|
29767
29823
|
constructor(message) {
|
|
29768
29824
|
super("permission_canary_failed", message);
|
|
@@ -29800,11 +29856,26 @@ var AcpTransport = class extends import_node_events.EventEmitter {
|
|
|
29800
29856
|
this.writable = options.writable;
|
|
29801
29857
|
this.handlers = options.handlers ?? {};
|
|
29802
29858
|
this.requestTimeoutMs = options.requestTimeoutMs ?? ACP_DEFAULT_REQUEST_TIMEOUT_MS;
|
|
29859
|
+
const readableEndGraceMs = Math.max(0, options.readableEndGraceMs ?? 0);
|
|
29860
|
+
let readableEndTimer = null;
|
|
29803
29861
|
options.readable.on("data", (chunk) => {
|
|
29804
29862
|
this.onData(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
29805
29863
|
});
|
|
29806
29864
|
options.readable.on("end", () => {
|
|
29807
|
-
|
|
29865
|
+
const fail = () => {
|
|
29866
|
+
readableEndTimer = null;
|
|
29867
|
+
this.failAll(
|
|
29868
|
+
new AcpChildExitError(
|
|
29869
|
+
this.childExit?.code ?? null,
|
|
29870
|
+
this.childExit?.signal ?? null
|
|
29871
|
+
)
|
|
29872
|
+
);
|
|
29873
|
+
};
|
|
29874
|
+
if (readableEndGraceMs > 0 && options.onChildExit) {
|
|
29875
|
+
readableEndTimer = setTimeout(fail, readableEndGraceMs);
|
|
29876
|
+
} else {
|
|
29877
|
+
fail();
|
|
29878
|
+
}
|
|
29808
29879
|
});
|
|
29809
29880
|
options.readable.on("error", (err) => {
|
|
29810
29881
|
this.failAll(asAcpHostError(err));
|
|
@@ -29813,6 +29884,10 @@ var AcpTransport = class extends import_node_events.EventEmitter {
|
|
|
29813
29884
|
this.failAll(asAcpHostError(err));
|
|
29814
29885
|
});
|
|
29815
29886
|
options.onChildExit?.((code, signal) => {
|
|
29887
|
+
if (readableEndTimer) {
|
|
29888
|
+
clearTimeout(readableEndTimer);
|
|
29889
|
+
readableEndTimer = null;
|
|
29890
|
+
}
|
|
29816
29891
|
this.childExit = { code, signal };
|
|
29817
29892
|
this.failAll(new AcpChildExitError(code, signal));
|
|
29818
29893
|
});
|
|
@@ -30633,6 +30708,7 @@ function createBoundTransport(options) {
|
|
|
30633
30708
|
writable: options.writable,
|
|
30634
30709
|
requestTimeoutMs: options.requestTimeoutMs,
|
|
30635
30710
|
onChildExit: options.onChildExit,
|
|
30711
|
+
readableEndGraceMs: options.readableEndGraceMs,
|
|
30636
30712
|
handlers: {
|
|
30637
30713
|
onNotification: (method, params) => {
|
|
30638
30714
|
options.getSession()?.handleAgentNotification(method, params);
|
|
@@ -30648,6 +30724,98 @@ function createBoundTransport(options) {
|
|
|
30648
30724
|
});
|
|
30649
30725
|
}
|
|
30650
30726
|
|
|
30727
|
+
// src/host/version.ts
|
|
30728
|
+
var CORE_IDENTIFIER = "(?:0|[1-9]\\d*)";
|
|
30729
|
+
var PRERELEASE_IDENTIFIER = "(?:0|[1-9]\\d*|[A-Za-z-][0-9A-Za-z-]*)";
|
|
30730
|
+
var BUILD_IDENTIFIER = "[0-9A-Za-z-]+";
|
|
30731
|
+
var SEMVER_SOURCE = `${CORE_IDENTIFIER}\\.${CORE_IDENTIFIER}\\.${CORE_IDENTIFIER}(?:-${PRERELEASE_IDENTIFIER}(?:\\.${PRERELEASE_IDENTIFIER})*)?(?:\\+${BUILD_IDENTIFIER}(?:\\.${BUILD_IDENTIFIER})*)?`;
|
|
30732
|
+
var SEMVER_RE = new RegExp(`^${SEMVER_SOURCE}$`);
|
|
30733
|
+
function parseSemVer(value) {
|
|
30734
|
+
if (!SEMVER_RE.test(value)) return null;
|
|
30735
|
+
const withoutBuild = value.split("+", 1)[0];
|
|
30736
|
+
const dash = withoutBuild.indexOf("-");
|
|
30737
|
+
const coreText = dash === -1 ? withoutBuild : withoutBuild.slice(0, dash);
|
|
30738
|
+
const prereleaseText = dash === -1 ? null : withoutBuild.slice(dash + 1);
|
|
30739
|
+
const coreParts = coreText.split(".");
|
|
30740
|
+
if (coreParts.length !== 3) return null;
|
|
30741
|
+
return {
|
|
30742
|
+
core: [BigInt(coreParts[0]), BigInt(coreParts[1]), BigInt(coreParts[2])],
|
|
30743
|
+
prerelease: prereleaseText === null ? null : prereleaseText.split(".")
|
|
30744
|
+
};
|
|
30745
|
+
}
|
|
30746
|
+
function compareSemVer(left, right) {
|
|
30747
|
+
const a = parseSemVer(left);
|
|
30748
|
+
const b2 = parseSemVer(right);
|
|
30749
|
+
if (!a || !b2) {
|
|
30750
|
+
throw new AcpVersionParseError(
|
|
30751
|
+
`cannot compare invalid semantic versions: ${JSON.stringify(left)} and ${JSON.stringify(right)}`
|
|
30752
|
+
);
|
|
30753
|
+
}
|
|
30754
|
+
for (let index = 0; index < 3; index += 1) {
|
|
30755
|
+
if (a.core[index] < b2.core[index]) return -1;
|
|
30756
|
+
if (a.core[index] > b2.core[index]) return 1;
|
|
30757
|
+
}
|
|
30758
|
+
if (a.prerelease === null && b2.prerelease === null) return 0;
|
|
30759
|
+
if (a.prerelease === null) return 1;
|
|
30760
|
+
if (b2.prerelease === null) return -1;
|
|
30761
|
+
const length = Math.max(a.prerelease.length, b2.prerelease.length);
|
|
30762
|
+
for (let index = 0; index < length; index += 1) {
|
|
30763
|
+
const leftPart = a.prerelease[index];
|
|
30764
|
+
const rightPart = b2.prerelease[index];
|
|
30765
|
+
if (leftPart === void 0) return -1;
|
|
30766
|
+
if (rightPart === void 0) return 1;
|
|
30767
|
+
if (leftPart === rightPart) continue;
|
|
30768
|
+
const leftNumeric = /^\d+$/.test(leftPart);
|
|
30769
|
+
const rightNumeric = /^\d+$/.test(rightPart);
|
|
30770
|
+
if (leftNumeric && rightNumeric) {
|
|
30771
|
+
return BigInt(leftPart) < BigInt(rightPart) ? -1 : 1;
|
|
30772
|
+
}
|
|
30773
|
+
if (leftNumeric) return -1;
|
|
30774
|
+
if (rightNumeric) return 1;
|
|
30775
|
+
return leftPart < rightPart ? -1 : 1;
|
|
30776
|
+
}
|
|
30777
|
+
return 0;
|
|
30778
|
+
}
|
|
30779
|
+
function parseProviderVersionOutput(stdout, productPattern, allowBare = true) {
|
|
30780
|
+
const lines = stdout.split(/\r?\n/);
|
|
30781
|
+
for (const line of lines) {
|
|
30782
|
+
const pattern = new RegExp(productPattern.source, productPattern.flags.replace("g", ""));
|
|
30783
|
+
const product = pattern.exec(line);
|
|
30784
|
+
if (!product) continue;
|
|
30785
|
+
const after = line.slice(product.index + product[0].length);
|
|
30786
|
+
const afterMatch = new RegExp(
|
|
30787
|
+
`^\\s+(${SEMVER_SOURCE})(?=$|\\s|\\()`
|
|
30788
|
+
).exec(after);
|
|
30789
|
+
if (afterMatch?.[1]) return afterMatch[1];
|
|
30790
|
+
const before = line.slice(0, product.index);
|
|
30791
|
+
const beforeMatch = new RegExp(`(${SEMVER_SOURCE})\\s*\\($`).exec(before);
|
|
30792
|
+
if (beforeMatch?.[1]) return beforeMatch[1];
|
|
30793
|
+
}
|
|
30794
|
+
if (!allowBare) return null;
|
|
30795
|
+
for (const line of lines) {
|
|
30796
|
+
const trimmed = line.trim();
|
|
30797
|
+
const match = new RegExp(`^(${SEMVER_SOURCE})$`).exec(trimmed);
|
|
30798
|
+
if (match?.[1]) return match[1];
|
|
30799
|
+
}
|
|
30800
|
+
return null;
|
|
30801
|
+
}
|
|
30802
|
+
function assertProviderVersionFloor(options) {
|
|
30803
|
+
if (compareSemVer(options.version, options.minimumVersion) < 0) {
|
|
30804
|
+
throw new AcpVersionBelowFloorError(
|
|
30805
|
+
options.provider,
|
|
30806
|
+
options.minimumVersion,
|
|
30807
|
+
options.version
|
|
30808
|
+
);
|
|
30809
|
+
}
|
|
30810
|
+
if (compareSemVer(options.version, options.lastMeasuredVersion) > 0) {
|
|
30811
|
+
options.onNewerVersion?.({
|
|
30812
|
+
provider: options.provider,
|
|
30813
|
+
runningVersion: options.version,
|
|
30814
|
+
lastMeasuredVersion: options.lastMeasuredVersion
|
|
30815
|
+
});
|
|
30816
|
+
}
|
|
30817
|
+
}
|
|
30818
|
+
|
|
30651
30819
|
// src/host/opencode.ts
|
|
30652
30820
|
var OPENCODE_HOME_OWNER_FILE = ".cswarm-opencode-owner.json";
|
|
30653
30821
|
var MAX_OPENCODE_AUTH_BYTES = 256 * 1024;
|
|
@@ -30756,11 +30924,11 @@ async function releaseOpenCodeHome(home, instanceId) {
|
|
|
30756
30924
|
}
|
|
30757
30925
|
}
|
|
30758
30926
|
function parseOpenCodeVersionOutput(stdout) {
|
|
30759
|
-
|
|
30760
|
-
return m?.[1] ?? null;
|
|
30927
|
+
return parseProviderVersionOutput(stdout, /\bopencode\b/i);
|
|
30761
30928
|
}
|
|
30762
|
-
async function
|
|
30763
|
-
const
|
|
30929
|
+
async function assertOpenCodeVersionFloor(executable, options) {
|
|
30930
|
+
const minimumVersion = options?.minimumVersion ?? OPENCODE_MIN_VERSION;
|
|
30931
|
+
const lastMeasuredVersion = options?.lastMeasuredVersion ?? OPENCODE_LAST_MEASURED_VERSION;
|
|
30764
30932
|
const timeoutMs = options?.timeoutMs ?? ACP_VERSION_CHECK_TIMEOUT_MS;
|
|
30765
30933
|
const env = sanitizeChildEnv(options?.env ?? process.env);
|
|
30766
30934
|
const stdout = await new Promise((resolve, reject) => {
|
|
@@ -30783,15 +30951,17 @@ async function assertOpenCodeMeasuredVersion(executable, options) {
|
|
|
30783
30951
|
});
|
|
30784
30952
|
const version3 = parseOpenCodeVersionOutput(stdout);
|
|
30785
30953
|
if (!version3) {
|
|
30786
|
-
throw new
|
|
30954
|
+
throw new AcpVersionParseError(
|
|
30787
30955
|
`could not parse opencode version from: ${stdout.trim().slice(0, 200)}`
|
|
30788
30956
|
);
|
|
30789
30957
|
}
|
|
30790
|
-
|
|
30791
|
-
|
|
30792
|
-
|
|
30793
|
-
|
|
30794
|
-
|
|
30958
|
+
assertProviderVersionFloor({
|
|
30959
|
+
provider: "opencode",
|
|
30960
|
+
version: version3,
|
|
30961
|
+
minimumVersion,
|
|
30962
|
+
lastMeasuredVersion,
|
|
30963
|
+
...options?.onNewerVersion ? { onNewerVersion: options.onNewerVersion } : {}
|
|
30964
|
+
});
|
|
30795
30965
|
return version3;
|
|
30796
30966
|
}
|
|
30797
30967
|
function buildOpenCodeAcpArgs() {
|
|
@@ -31158,8 +31328,9 @@ async function openOpenCodeAcpSession(options) {
|
|
|
31158
31328
|
};
|
|
31159
31329
|
try {
|
|
31160
31330
|
if (!options.skipVersionCheck) {
|
|
31161
|
-
await
|
|
31162
|
-
env
|
|
31331
|
+
await assertOpenCodeVersionFloor(executable, {
|
|
31332
|
+
env,
|
|
31333
|
+
...options.onVersionNotice ? { onNewerVersion: options.onVersionNotice } : {}
|
|
31163
31334
|
});
|
|
31164
31335
|
}
|
|
31165
31336
|
if (!options.skipConfigProbe) {
|
|
@@ -31256,6 +31427,8 @@ var import_node_fs4 = require("node:fs");
|
|
|
31256
31427
|
var import_node_path6 = require("node:path");
|
|
31257
31428
|
var CHILD_EXIT_WAIT_MS2 = 3e3;
|
|
31258
31429
|
var CHILD_KILL_WAIT_MS2 = 1e3;
|
|
31430
|
+
var STDERR_EXIT_GRACE_MS = 100;
|
|
31431
|
+
var READABLE_END_GRACE_MS = STDERR_EXIT_GRACE_MS + 50;
|
|
31259
31432
|
var WINDOWS_NPM_SHIM_MAX_BYTES = 64 * 1024;
|
|
31260
31433
|
var WINDOWS_NPM_ENTRYPOINT = [
|
|
31261
31434
|
"node_modules",
|
|
@@ -31264,6 +31437,30 @@ var WINDOWS_NPM_ENTRYPOINT = [
|
|
|
31264
31437
|
"dist",
|
|
31265
31438
|
"index.js"
|
|
31266
31439
|
];
|
|
31440
|
+
function isPackagedClaudeBridge(executable) {
|
|
31441
|
+
const normalized = executable.replaceAll("\\", "/");
|
|
31442
|
+
return normalized.endsWith(
|
|
31443
|
+
"/node_modules/@agentclientprotocol/claude-agent-acp/dist/index.js"
|
|
31444
|
+
);
|
|
31445
|
+
}
|
|
31446
|
+
function resolvePackagedClaudeBridge(pathEnv, platform = process.platform) {
|
|
31447
|
+
const pathValue = pathEnv ?? process.env.PATH ?? "";
|
|
31448
|
+
const names = platform === "win32" ? ["claude-agent-acp.cmd"] : ["claude-agent-acp"];
|
|
31449
|
+
for (const dir of pathValue.split(import_node_path6.delimiter)) {
|
|
31450
|
+
if (!dir) continue;
|
|
31451
|
+
for (const name of names) {
|
|
31452
|
+
try {
|
|
31453
|
+
const candidate = resolvedClaudeCandidate((0, import_node_path6.join)(dir, name), platform);
|
|
31454
|
+
if (isPackagedClaudeBridge(candidate)) return candidate;
|
|
31455
|
+
} catch {
|
|
31456
|
+
}
|
|
31457
|
+
}
|
|
31458
|
+
}
|
|
31459
|
+
throw new AcpHostError(
|
|
31460
|
+
"executable_missing",
|
|
31461
|
+
"packaged claude-agent-acp executable not found; install @agentclientprotocol/claude-agent-acp@latest (minimum 0.64.2)"
|
|
31462
|
+
);
|
|
31463
|
+
}
|
|
31267
31464
|
function resolveWindowsNpmShim(shim) {
|
|
31268
31465
|
let source;
|
|
31269
31466
|
try {
|
|
@@ -31333,15 +31530,16 @@ function buildClaudeLaunch(executable, args, platform = process.platform) {
|
|
|
31333
31530
|
return platform === "win32" && (0, import_node_path6.extname)(executable).toLowerCase() === ".js" ? { command: process.execPath, args: [executable, ...args] } : { command: executable, args: [...args] };
|
|
31334
31531
|
}
|
|
31335
31532
|
function parseClaudeVersionOutput(stdout) {
|
|
31336
|
-
|
|
31337
|
-
return match?.[1] ?? null;
|
|
31533
|
+
return parseProviderVersionOutput(stdout, /\bclaude-agent-acp\b/i);
|
|
31338
31534
|
}
|
|
31339
|
-
|
|
31340
|
-
|
|
31535
|
+
function parseClaudeCodeVersionOutput(stdout) {
|
|
31536
|
+
return parseProviderVersionOutput(stdout, /\bClaude Code\b/i, false);
|
|
31537
|
+
}
|
|
31538
|
+
async function readClaudeVersionOutput(executable, options) {
|
|
31341
31539
|
const timeoutMs = options?.timeoutMs ?? ACP_VERSION_CHECK_TIMEOUT_MS;
|
|
31342
31540
|
const env = options?.env ?? sanitizeChildEnv(process.env);
|
|
31343
31541
|
const launch = buildClaudeLaunch(executable, ["--version"], options?.platform);
|
|
31344
|
-
|
|
31542
|
+
return await new Promise((resolve, reject) => {
|
|
31345
31543
|
(0, import_node_child_process4.execFile)(
|
|
31346
31544
|
launch.command,
|
|
31347
31545
|
launch.args,
|
|
@@ -31359,24 +31557,35 @@ async function assertClaudeMeasuredVersion(executable, options) {
|
|
|
31359
31557
|
}
|
|
31360
31558
|
);
|
|
31361
31559
|
});
|
|
31560
|
+
}
|
|
31561
|
+
async function assertClaudeVersionFloor(executable, options) {
|
|
31562
|
+
const minimumVersion = options?.minimumVersion ?? CLAUDE_ACP_MIN_VERSION;
|
|
31563
|
+
const lastMeasuredVersion = options?.lastMeasuredVersion ?? CLAUDE_ACP_LAST_MEASURED_VERSION;
|
|
31564
|
+
const stdout = await readClaudeVersionOutput(executable, options);
|
|
31362
31565
|
const version3 = parseClaudeVersionOutput(stdout);
|
|
31363
31566
|
if (!version3) {
|
|
31364
|
-
throw new
|
|
31567
|
+
throw new AcpVersionParseError(
|
|
31365
31568
|
`could not parse claude-agent-acp version from: ${stdout.trim().slice(0, 200)}`
|
|
31366
31569
|
);
|
|
31367
31570
|
}
|
|
31368
|
-
|
|
31369
|
-
|
|
31370
|
-
|
|
31371
|
-
|
|
31372
|
-
|
|
31571
|
+
assertProviderVersionFloor({
|
|
31572
|
+
provider: "claude-agent-acp",
|
|
31573
|
+
version: version3,
|
|
31574
|
+
minimumVersion,
|
|
31575
|
+
lastMeasuredVersion,
|
|
31576
|
+
...options?.onNewerVersion ? { onNewerVersion: options.onNewerVersion } : {}
|
|
31577
|
+
});
|
|
31373
31578
|
return version3;
|
|
31374
31579
|
}
|
|
31375
31580
|
function buildClaudeAcpArgs() {
|
|
31376
31581
|
return [];
|
|
31377
31582
|
}
|
|
31378
|
-
function buildClaudeChildEnv(parent) {
|
|
31379
|
-
|
|
31583
|
+
function buildClaudeChildEnv(parent, claudeCodeExecutable) {
|
|
31584
|
+
const env = sanitizeChildEnv(parent);
|
|
31585
|
+
if (claudeCodeExecutable) {
|
|
31586
|
+
env.CLAUDE_CODE_EXECUTABLE = claudeCodeExecutable;
|
|
31587
|
+
}
|
|
31588
|
+
return env;
|
|
31380
31589
|
}
|
|
31381
31590
|
function waitForChildExit2(child, timeoutMs) {
|
|
31382
31591
|
if (child.exitCode !== null || child.signalCode !== null) {
|
|
@@ -31419,13 +31628,56 @@ async function openClaudeAcpSession(options) {
|
|
|
31419
31628
|
);
|
|
31420
31629
|
}
|
|
31421
31630
|
const pathEnv = parentEnv.PATH;
|
|
31422
|
-
const
|
|
31423
|
-
|
|
31424
|
-
|
|
31425
|
-
|
|
31426
|
-
|
|
31427
|
-
|
|
31428
|
-
|
|
31631
|
+
const resolvedPathEnv = typeof pathEnv === "string" ? pathEnv : void 0;
|
|
31632
|
+
if (options.skipVersionCheck && options.executable) {
|
|
31633
|
+
throw new AcpHostError(
|
|
31634
|
+
"version_check_required",
|
|
31635
|
+
"skipVersionCheck cannot classify an explicit Claude executable"
|
|
31636
|
+
);
|
|
31637
|
+
}
|
|
31638
|
+
const requestedExecutable = options.executable ? resolveClaudeExecutable(options.executable, resolvedPathEnv) : null;
|
|
31639
|
+
const baseEnv = buildClaudeChildEnv(parentEnv);
|
|
31640
|
+
let executable;
|
|
31641
|
+
let env = baseEnv;
|
|
31642
|
+
let claudeCodeExecutable;
|
|
31643
|
+
if (requestedExecutable) {
|
|
31644
|
+
const output = await readClaudeVersionOutput(requestedExecutable, {
|
|
31645
|
+
env: baseEnv
|
|
31646
|
+
});
|
|
31647
|
+
const bridgeVersion = parseClaudeVersionOutput(output);
|
|
31648
|
+
if (bridgeVersion) {
|
|
31649
|
+
assertProviderVersionFloor({
|
|
31650
|
+
provider: "claude-agent-acp",
|
|
31651
|
+
version: bridgeVersion,
|
|
31652
|
+
minimumVersion: CLAUDE_ACP_MIN_VERSION,
|
|
31653
|
+
lastMeasuredVersion: CLAUDE_ACP_LAST_MEASURED_VERSION,
|
|
31654
|
+
...options.onVersionNotice ? { onNewerVersion: options.onVersionNotice } : {}
|
|
31655
|
+
});
|
|
31656
|
+
executable = requestedExecutable;
|
|
31657
|
+
} else if (parseClaudeCodeVersionOutput(output)) {
|
|
31658
|
+
claudeCodeExecutable = requestedExecutable;
|
|
31659
|
+
executable = resolvePackagedClaudeBridge(resolvedPathEnv);
|
|
31660
|
+
env = buildClaudeChildEnv(parentEnv, claudeCodeExecutable);
|
|
31661
|
+
await assertClaudeVersionFloor(executable, {
|
|
31662
|
+
env,
|
|
31663
|
+
...options.onVersionNotice ? { onNewerVersion: options.onVersionNotice } : {}
|
|
31664
|
+
});
|
|
31665
|
+
} else {
|
|
31666
|
+
throw new AcpVersionError(
|
|
31667
|
+
`could not identify Claude executable from: ${output.trim().slice(0, 200)}`
|
|
31668
|
+
);
|
|
31669
|
+
}
|
|
31670
|
+
} else {
|
|
31671
|
+
executable = requestedExecutable ?? resolveClaudeExecutable(
|
|
31672
|
+
"claude-agent-acp",
|
|
31673
|
+
resolvedPathEnv
|
|
31674
|
+
);
|
|
31675
|
+
if (!options.skipVersionCheck) {
|
|
31676
|
+
await assertClaudeVersionFloor(executable, {
|
|
31677
|
+
env: baseEnv,
|
|
31678
|
+
...options.onVersionNotice ? { onNewerVersion: options.onVersionNotice } : {}
|
|
31679
|
+
});
|
|
31680
|
+
}
|
|
31429
31681
|
}
|
|
31430
31682
|
if (options.signal?.aborted) {
|
|
31431
31683
|
throw new AcpHostError(
|
|
@@ -31474,25 +31726,33 @@ async function openClaudeAcpSession(options) {
|
|
|
31474
31726
|
throw new AcpHostError("spawn_failed", "child missing stdio pipes");
|
|
31475
31727
|
}
|
|
31476
31728
|
const stderrTail = attachStderrTailRing(child.stderr);
|
|
31477
|
-
if (options.onStderrTail) {
|
|
31478
|
-
const deliverTail = options.onStderrTail;
|
|
31479
|
-
let tailDelivered = false;
|
|
31480
|
-
const publishTail = () => {
|
|
31481
|
-
if (tailDelivered) return;
|
|
31482
|
-
tailDelivered = true;
|
|
31483
|
-
deliverTail(stderrTail.read());
|
|
31484
|
-
};
|
|
31485
|
-
child.once("exit", publishTail);
|
|
31486
|
-
child.once("close", publishTail);
|
|
31487
|
-
}
|
|
31488
31729
|
let sessionRef = null;
|
|
31489
31730
|
const transport = createBoundTransport({
|
|
31490
31731
|
readable: child.stdout,
|
|
31491
31732
|
writable: child.stdin,
|
|
31492
31733
|
requestTimeoutMs: options.requestTimeoutMs ?? ACP_DEFAULT_REQUEST_TIMEOUT_MS,
|
|
31734
|
+
readableEndGraceMs: READABLE_END_GRACE_MS,
|
|
31493
31735
|
getSession: () => sessionRef,
|
|
31494
31736
|
onChildExit: (handler) => {
|
|
31495
|
-
|
|
31737
|
+
const observeExit = (code, signal) => {
|
|
31738
|
+
let completed = false;
|
|
31739
|
+
let timer2 = null;
|
|
31740
|
+
const complete = () => {
|
|
31741
|
+
if (completed) return;
|
|
31742
|
+
completed = true;
|
|
31743
|
+
if (timer2) clearTimeout(timer2);
|
|
31744
|
+
child.removeListener("close", complete);
|
|
31745
|
+
options.onStderrTail?.(stderrTail.read());
|
|
31746
|
+
handler(code, signal);
|
|
31747
|
+
};
|
|
31748
|
+
child.once("close", complete);
|
|
31749
|
+
timer2 = setTimeout(complete, STDERR_EXIT_GRACE_MS);
|
|
31750
|
+
};
|
|
31751
|
+
if (child.exitCode !== null || child.signalCode !== null) {
|
|
31752
|
+
observeExit(child.exitCode, child.signalCode);
|
|
31753
|
+
} else {
|
|
31754
|
+
child.once("exit", observeExit);
|
|
31755
|
+
}
|
|
31496
31756
|
}
|
|
31497
31757
|
});
|
|
31498
31758
|
try {
|
|
@@ -31617,13 +31877,11 @@ function buildCodexLaunch(executable, args, platform = process.platform) {
|
|
|
31617
31877
|
return platform === "win32" && (0, import_node_path7.extname)(executable).toLowerCase() === ".js" ? { command: process.execPath, args: [executable, ...args] } : { command: executable, args: [...args] };
|
|
31618
31878
|
}
|
|
31619
31879
|
function parseCodexVersionOutput(stdout) {
|
|
31620
|
-
|
|
31621
|
-
/^@agentclientprotocol\/codex-acp (\d+\.\d+\.\d+)$/
|
|
31622
|
-
);
|
|
31623
|
-
return match?.[1] ?? null;
|
|
31880
|
+
return parseProviderVersionOutput(stdout, /@agentclientprotocol\/codex-acp\b/i);
|
|
31624
31881
|
}
|
|
31625
|
-
async function
|
|
31626
|
-
const
|
|
31882
|
+
async function assertCodexVersionFloor(executable, options) {
|
|
31883
|
+
const minimumVersion = options?.minimumVersion ?? CODEX_ACP_MIN_VERSION;
|
|
31884
|
+
const lastMeasuredVersion = options?.lastMeasuredVersion ?? CODEX_ACP_LAST_MEASURED_VERSION;
|
|
31627
31885
|
const timeoutMs = options?.timeoutMs ?? ACP_VERSION_CHECK_TIMEOUT_MS;
|
|
31628
31886
|
const env = options?.env ?? sanitizeChildEnv(process.env);
|
|
31629
31887
|
const launch = buildCodexLaunch(executable, ["--version"], options?.platform);
|
|
@@ -31647,15 +31905,17 @@ async function assertCodexMeasuredVersion(executable, options) {
|
|
|
31647
31905
|
});
|
|
31648
31906
|
const version3 = parseCodexVersionOutput(stdout);
|
|
31649
31907
|
if (!version3) {
|
|
31650
|
-
throw new
|
|
31908
|
+
throw new AcpVersionParseError(
|
|
31651
31909
|
`could not parse codex-acp version from: ${stdout.trim().slice(0, 200)}`
|
|
31652
31910
|
);
|
|
31653
31911
|
}
|
|
31654
|
-
|
|
31655
|
-
|
|
31656
|
-
|
|
31657
|
-
|
|
31658
|
-
|
|
31912
|
+
assertProviderVersionFloor({
|
|
31913
|
+
provider: "codex-acp",
|
|
31914
|
+
version: version3,
|
|
31915
|
+
minimumVersion,
|
|
31916
|
+
lastMeasuredVersion,
|
|
31917
|
+
...options?.onNewerVersion ? { onNewerVersion: options.onNewerVersion } : {}
|
|
31918
|
+
});
|
|
31659
31919
|
return version3;
|
|
31660
31920
|
}
|
|
31661
31921
|
function buildCodexAcpArgs() {
|
|
@@ -31711,7 +31971,10 @@ async function openCodexAcpSession(options) {
|
|
|
31711
31971
|
);
|
|
31712
31972
|
const env = buildCodexChildEnv(parentEnv);
|
|
31713
31973
|
if (!options.skipVersionCheck) {
|
|
31714
|
-
await
|
|
31974
|
+
await assertCodexVersionFloor(executable, {
|
|
31975
|
+
env,
|
|
31976
|
+
...options.onVersionNotice ? { onNewerVersion: options.onVersionNotice } : {}
|
|
31977
|
+
});
|
|
31715
31978
|
}
|
|
31716
31979
|
if (options.signal?.aborted) {
|
|
31717
31980
|
throw new AcpHostError(
|
|
@@ -32621,10 +32884,12 @@ function resolveGrokExecutable(executable = "grok") {
|
|
|
32621
32884
|
return executable;
|
|
32622
32885
|
}
|
|
32623
32886
|
function parseGrokVersionOutput(stdout) {
|
|
32624
|
-
|
|
32625
|
-
return m?.[1] ?? null;
|
|
32887
|
+
return parseProviderVersionOutput(stdout, /\bgrok\b/i);
|
|
32626
32888
|
}
|
|
32627
|
-
async function
|
|
32889
|
+
async function assertGrokVersionFloor(executable, options) {
|
|
32890
|
+
const minimumVersion = options?.minimumVersion ?? GROK_MIN_VERSION;
|
|
32891
|
+
const lastMeasuredVersion = options?.lastMeasuredVersion ?? GROK_LAST_MEASURED_VERSION;
|
|
32892
|
+
const timeoutMs = options?.timeoutMs ?? ACP_VERSION_CHECK_TIMEOUT_MS;
|
|
32628
32893
|
const stdout = await new Promise((resolve, reject) => {
|
|
32629
32894
|
(0, import_node_child_process6.execFile)(
|
|
32630
32895
|
executable,
|
|
@@ -32645,15 +32910,17 @@ async function assertGrokMeasuredVersion(executable, expected = GROK_MEASURED_VE
|
|
|
32645
32910
|
});
|
|
32646
32911
|
const version3 = parseGrokVersionOutput(stdout);
|
|
32647
32912
|
if (!version3) {
|
|
32648
|
-
throw new
|
|
32913
|
+
throw new AcpVersionParseError(
|
|
32649
32914
|
`could not parse grok version from: ${stdout.trim().slice(0, 200)}`
|
|
32650
32915
|
);
|
|
32651
32916
|
}
|
|
32652
|
-
|
|
32653
|
-
|
|
32654
|
-
|
|
32655
|
-
|
|
32656
|
-
|
|
32917
|
+
assertProviderVersionFloor({
|
|
32918
|
+
provider: "grok",
|
|
32919
|
+
version: version3,
|
|
32920
|
+
minimumVersion,
|
|
32921
|
+
lastMeasuredVersion,
|
|
32922
|
+
...options?.onNewerVersion ? { onNewerVersion: options.onNewerVersion } : {}
|
|
32923
|
+
});
|
|
32657
32924
|
return version3;
|
|
32658
32925
|
}
|
|
32659
32926
|
function buildGrokAcpArgs(options) {
|
|
@@ -32711,7 +32978,9 @@ async function terminateGrokChild(child) {
|
|
|
32711
32978
|
async function openGrokAcpSession(options) {
|
|
32712
32979
|
const executable = resolveGrokExecutable(options.executable ?? "grok");
|
|
32713
32980
|
if (!options.skipVersionCheck) {
|
|
32714
|
-
await
|
|
32981
|
+
await assertGrokVersionFloor(executable, {
|
|
32982
|
+
...options.onVersionNotice ? { onNewerVersion: options.onVersionNotice } : {}
|
|
32983
|
+
});
|
|
32715
32984
|
}
|
|
32716
32985
|
const args = buildGrokAcpArgs({
|
|
32717
32986
|
model: options.model,
|
|
@@ -32840,6 +33109,7 @@ var GrokListenerModel = class {
|
|
|
32840
33109
|
...this.options.model ? { model: this.options.model } : {},
|
|
32841
33110
|
...this.options.effort ? { effort: this.options.effort } : {},
|
|
32842
33111
|
...this.options.env ? { env: this.options.env } : {},
|
|
33112
|
+
...this.options.onVersionNotice ? { onVersionNotice: this.options.onVersionNotice } : {},
|
|
32843
33113
|
...this.options.onWorkerStderrTail ? { onStderrTail: this.options.onWorkerStderrTail } : {},
|
|
32844
33114
|
clientName: "cswarm-listener"
|
|
32845
33115
|
});
|
|
@@ -33248,6 +33518,7 @@ var OpenCodeListenerModel = class {
|
|
|
33248
33518
|
...this.options.executable ? { executable: this.options.executable } : {},
|
|
33249
33519
|
...this.options.model ? { model: this.options.model } : {},
|
|
33250
33520
|
...this.options.env ? { env: this.options.env } : {},
|
|
33521
|
+
...this.options.onVersionNotice ? { onVersionNotice: this.options.onVersionNotice } : {},
|
|
33251
33522
|
...this.options.allowMissingAuth === true ? { allowMissingAuth: true } : {},
|
|
33252
33523
|
...this.options.onWorkerStderrTail ? { onStderrTail: this.options.onWorkerStderrTail } : {},
|
|
33253
33524
|
clientName: "cswarm-listener"
|
|
@@ -33457,6 +33728,7 @@ var ClaudeListenerModel = class {
|
|
|
33457
33728
|
permissionCallback,
|
|
33458
33729
|
...this.options.executable ? { executable: this.options.executable } : {},
|
|
33459
33730
|
...this.options.env ? { env: this.options.env } : {},
|
|
33731
|
+
...this.options.onVersionNotice ? { onVersionNotice: this.options.onVersionNotice } : {},
|
|
33460
33732
|
signal: controller.signal,
|
|
33461
33733
|
...this.options.onWorkerStderrTail ? { onStderrTail: this.options.onWorkerStderrTail } : {},
|
|
33462
33734
|
clientName: "cswarm-listener"
|
|
@@ -33625,6 +33897,7 @@ var CodexListenerModel = class {
|
|
|
33625
33897
|
permissionCallback,
|
|
33626
33898
|
...this.options.executable ? { executable: this.options.executable } : {},
|
|
33627
33899
|
...this.options.env ? { env: this.options.env } : {},
|
|
33900
|
+
...this.options.onVersionNotice ? { onVersionNotice: this.options.onVersionNotice } : {},
|
|
33628
33901
|
signal: controller.signal,
|
|
33629
33902
|
...this.options.onWorkerStderrTail ? { onStderrTail: this.options.onWorkerStderrTail } : {},
|
|
33630
33903
|
clientName: "cswarm-listener"
|
|
@@ -35518,6 +35791,7 @@ var import_node_net = require("node:net");
|
|
|
35518
35791
|
var import_promises9 = require("node:fs/promises");
|
|
35519
35792
|
var import_node_path15 = require("node:path");
|
|
35520
35793
|
var UUID_RE13 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
35794
|
+
var SEMVER_RE2 = /^(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-(?:0|[1-9]\d*|[A-Za-z-][0-9A-Za-z-]*)(?:\.(?:0|[1-9]\d*|[A-Za-z-][0-9A-Za-z-]*))*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
35521
35795
|
var MAX_STATUS_BYTES = 16 * 1024;
|
|
35522
35796
|
var MAX_CONTROL_BYTES = 8 * 1024;
|
|
35523
35797
|
var CONTROL_TIMEOUT_MS = 2e3;
|
|
@@ -35564,6 +35838,8 @@ var STATUS_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
35564
35838
|
"stoppedAt",
|
|
35565
35839
|
"lastSignalId",
|
|
35566
35840
|
"lastErrorCode",
|
|
35841
|
+
"providerVersion",
|
|
35842
|
+
"providerLastMeasuredVersion",
|
|
35567
35843
|
"lastWorkerStderrTail",
|
|
35568
35844
|
"logPath",
|
|
35569
35845
|
"deliveryMode",
|
|
@@ -35623,7 +35899,7 @@ function parseStatus(raw) {
|
|
|
35623
35899
|
const nullableUuid2 = (candidate) => candidate === null || typeof candidate === "string" && UUID_RE13.test(candidate);
|
|
35624
35900
|
const nullableCount = (candidate) => candidate === null || typeof candidate === "number" && Number.isSafeInteger(candidate) && candidate >= 0;
|
|
35625
35901
|
const nullableTimestamp = (candidate) => candidate === null || typeof candidate === "string" && Number.isFinite(Date.parse(candidate));
|
|
35626
|
-
if (row.version !== 1 || typeof row.instanceId !== "string" || !UUID_RE13.test(row.instanceId) || row.provider !== "grok" && row.provider !== "opencode" && row.provider !== "claude" && row.provider !== "codex" || typeof row.profileId !== "string" || typeof row.workspaceId !== "string" || !UUID_RE13.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE13.test(row.principalId) || !Number.isSafeInteger(row.pid) || row.pid < 1 || typeof row.state !== "string" || !["starting", "ready", "stopping", "stopped", "failed"].includes(row.state) || typeof row.startedAt !== "string" || !Number.isFinite(Date.parse(row.startedAt)) || !(row.readyAt === null || typeof row.readyAt === "string" && Number.isFinite(Date.parse(row.readyAt))) || typeof row.updatedAt !== "string" || !Number.isFinite(Date.parse(row.updatedAt)) || !(row.stoppedAt === null || typeof row.stoppedAt === "string" && Number.isFinite(Date.parse(row.stoppedAt))) || !nullableUuid2(row.lastSignalId) || !(row.lastErrorCode === null || typeof row.lastErrorCode === "string" && /^[a-z0-9_-]{1,96}$/.test(row.lastErrorCode)) || !(row.lastWorkerStderrTail === void 0 || row.lastWorkerStderrTail === null || typeof row.lastWorkerStderrTail === "string" && row.lastWorkerStderrTail.length > 0 && row.lastWorkerStderrTail.length <= 2048 && !/swm_(?:agt|inv|cap)_/i.test(row.lastWorkerStderrTail)) || typeof row.logPath !== "string" || !(0, import_node_path15.isAbsolute)(row.logPath) || !(row.deliveryMode === void 0 || row.deliveryMode === null || typeof row.deliveryMode === "string" && STATUS_DELIVERY_MODES.has(row.deliveryMode)) || !(row.pendingDeliveryCount === void 0 || nullableCount(row.pendingDeliveryCount)) || !(row.lastTerminalDeliveryFailureCount === void 0 || nullableCount(row.lastTerminalDeliveryFailureCount)) || !(row.lastTerminalDeliveryFailureAt === void 0 || nullableTimestamp(row.lastTerminalDeliveryFailureAt)) || !(row.lastClaimAt === void 0 || nullableTimestamp(row.lastClaimAt)) || !(row.lastAckAt === void 0 || nullableTimestamp(row.lastAckAt)) || !(row.routeMode === void 0 || row.routeMode === "worker" || row.routeMode === "main" || row.routeMode === "split") || !(row.deferOverChars === void 0 || row.deferOverChars === null || typeof row.deferOverChars === "number" && Number.isSafeInteger(row.deferOverChars) && row.deferOverChars >= 1 && row.deferOverChars <= 1e4) || !(row.pendingForMainCount === void 0 || typeof row.pendingForMainCount === "number" && Number.isSafeInteger(row.pendingForMainCount) && row.pendingForMainCount >= 0) || !(row.droppedForMainCount === void 0 || typeof row.droppedForMainCount === "number" && Number.isSafeInteger(row.droppedForMainCount) && row.droppedForMainCount >= 0)) {
|
|
35902
|
+
if (row.version !== 1 || typeof row.instanceId !== "string" || !UUID_RE13.test(row.instanceId) || row.provider !== "grok" && row.provider !== "opencode" && row.provider !== "claude" && row.provider !== "codex" || typeof row.profileId !== "string" || typeof row.workspaceId !== "string" || !UUID_RE13.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE13.test(row.principalId) || !Number.isSafeInteger(row.pid) || row.pid < 1 || typeof row.state !== "string" || !["starting", "ready", "stopping", "stopped", "failed"].includes(row.state) || typeof row.startedAt !== "string" || !Number.isFinite(Date.parse(row.startedAt)) || !(row.readyAt === null || typeof row.readyAt === "string" && Number.isFinite(Date.parse(row.readyAt))) || typeof row.updatedAt !== "string" || !Number.isFinite(Date.parse(row.updatedAt)) || !(row.stoppedAt === null || typeof row.stoppedAt === "string" && Number.isFinite(Date.parse(row.stoppedAt))) || !nullableUuid2(row.lastSignalId) || !(row.lastErrorCode === null || typeof row.lastErrorCode === "string" && /^[a-z0-9_-]{1,96}$/.test(row.lastErrorCode)) || !(row.providerVersion === void 0 || row.providerVersion === null || typeof row.providerVersion === "string" && SEMVER_RE2.test(row.providerVersion)) || !(row.providerLastMeasuredVersion === void 0 || row.providerLastMeasuredVersion === null || typeof row.providerLastMeasuredVersion === "string" && SEMVER_RE2.test(row.providerLastMeasuredVersion)) || (row.providerVersion === null || row.providerVersion === void 0) !== (row.providerLastMeasuredVersion === null || row.providerLastMeasuredVersion === void 0) || !(row.lastWorkerStderrTail === void 0 || row.lastWorkerStderrTail === null || typeof row.lastWorkerStderrTail === "string" && row.lastWorkerStderrTail.length > 0 && row.lastWorkerStderrTail.length <= 2048 && !/swm_(?:agt|inv|cap)_/i.test(row.lastWorkerStderrTail)) || typeof row.logPath !== "string" || !(0, import_node_path15.isAbsolute)(row.logPath) || !(row.deliveryMode === void 0 || row.deliveryMode === null || typeof row.deliveryMode === "string" && STATUS_DELIVERY_MODES.has(row.deliveryMode)) || !(row.pendingDeliveryCount === void 0 || nullableCount(row.pendingDeliveryCount)) || !(row.lastTerminalDeliveryFailureCount === void 0 || nullableCount(row.lastTerminalDeliveryFailureCount)) || !(row.lastTerminalDeliveryFailureAt === void 0 || nullableTimestamp(row.lastTerminalDeliveryFailureAt)) || !(row.lastClaimAt === void 0 || nullableTimestamp(row.lastClaimAt)) || !(row.lastAckAt === void 0 || nullableTimestamp(row.lastAckAt)) || !(row.routeMode === void 0 || row.routeMode === "worker" || row.routeMode === "main" || row.routeMode === "split") || !(row.deferOverChars === void 0 || row.deferOverChars === null || typeof row.deferOverChars === "number" && Number.isSafeInteger(row.deferOverChars) && row.deferOverChars >= 1 && row.deferOverChars <= 1e4) || !(row.pendingForMainCount === void 0 || typeof row.pendingForMainCount === "number" && Number.isSafeInteger(row.pendingForMainCount) && row.pendingForMainCount >= 0) || !(row.droppedForMainCount === void 0 || typeof row.droppedForMainCount === "number" && Number.isSafeInteger(row.droppedForMainCount) && row.droppedForMainCount >= 0)) {
|
|
35627
35903
|
throw new Error("stored listener status is malformed");
|
|
35628
35904
|
}
|
|
35629
35905
|
const routeMode = row.routeMode ?? "worker";
|
|
@@ -35640,6 +35916,8 @@ function parseStatus(raw) {
|
|
|
35640
35916
|
lastClaimAt: row.lastClaimAt ?? null,
|
|
35641
35917
|
lastAckAt: row.lastAckAt ?? null,
|
|
35642
35918
|
lastWorkerStderrTail: row.lastWorkerStderrTail ?? null,
|
|
35919
|
+
providerVersion: row.providerVersion ?? null,
|
|
35920
|
+
providerLastMeasuredVersion: row.providerLastMeasuredVersion ?? null,
|
|
35643
35921
|
routeMode,
|
|
35644
35922
|
deferOverChars,
|
|
35645
35923
|
pendingForMainCount: row.pendingForMainCount ?? 0,
|
|
@@ -36051,6 +36329,8 @@ async function runListenerSupervisor(options) {
|
|
|
36051
36329
|
stoppedAt: null,
|
|
36052
36330
|
lastSignalId: null,
|
|
36053
36331
|
lastErrorCode: null,
|
|
36332
|
+
providerVersion: null,
|
|
36333
|
+
providerLastMeasuredVersion: null,
|
|
36054
36334
|
lastWorkerStderrTail: null,
|
|
36055
36335
|
deliveryMode: null,
|
|
36056
36336
|
pendingDeliveryCount: null,
|
|
@@ -36120,10 +36400,13 @@ async function runListenerSupervisor(options) {
|
|
|
36120
36400
|
};
|
|
36121
36401
|
const onEvent = (event) => {
|
|
36122
36402
|
if (event.type === "ready") {
|
|
36403
|
+
const versionNotice = options.getProviderVersionNotice?.() ?? null;
|
|
36123
36404
|
transition("ready", {
|
|
36124
36405
|
readyAt: event.ts,
|
|
36125
36406
|
lastErrorCode: null,
|
|
36126
|
-
lastWorkerStderrTail: null
|
|
36407
|
+
lastWorkerStderrTail: null,
|
|
36408
|
+
providerVersion: versionNotice?.runningVersion ?? null,
|
|
36409
|
+
providerLastMeasuredVersion: versionNotice?.lastMeasuredVersion ?? null
|
|
36127
36410
|
});
|
|
36128
36411
|
log({ ts: event.ts, event: "listener_ready" });
|
|
36129
36412
|
return;
|
|
@@ -36321,7 +36604,9 @@ async function runListenerSupervisor(options) {
|
|
|
36321
36604
|
transition("starting", {
|
|
36322
36605
|
readyAt: null,
|
|
36323
36606
|
lastErrorCode: restartCode,
|
|
36324
|
-
lastWorkerStderrTail: restartStderrTail
|
|
36607
|
+
lastWorkerStderrTail: restartStderrTail,
|
|
36608
|
+
providerVersion: null,
|
|
36609
|
+
providerLastMeasuredVersion: null
|
|
36325
36610
|
});
|
|
36326
36611
|
await restartSleep(delayMs, controller.signal);
|
|
36327
36612
|
if (controller.signal.aborted) {
|
|
@@ -37850,8 +38135,8 @@ var ACCEPTED_AGENT_CREDENTIAL_MESSAGES = [
|
|
|
37850
38135
|
AGENT_CREDENTIAL_MESSAGE_D088
|
|
37851
38136
|
];
|
|
37852
38137
|
function packageVersion() {
|
|
37853
|
-
if ("0.1.
|
|
37854
|
-
return "0.1.
|
|
38138
|
+
if ("0.1.28".length > 0) {
|
|
38139
|
+
return "0.1.28";
|
|
37855
38140
|
}
|
|
37856
38141
|
try {
|
|
37857
38142
|
const value = JSON.parse(
|
|
@@ -37967,8 +38252,8 @@ Usage:
|
|
|
37967
38252
|
cswarm status [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--json]
|
|
37968
38253
|
cswarm members [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--agent-token-stdin] [--json]
|
|
37969
38254
|
cswarm working-on "<what>" [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--about <ref>] [--until <dur>] [--json]
|
|
37970
|
-
cswarm note "<text>" [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--to <member|agent>] [--about <ref>] [--until <dur>] [--json]
|
|
37971
|
-
cswarm ask "<text>" [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--to <member|agent>] [--about <ref>] [--until <dur>] [--wait <seconds>] [--json]
|
|
38255
|
+
cswarm note "<text>" [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--to <member|agent>] [--about <ref>] [--until <dur>] [--json] # text: 1..8000 characters
|
|
38256
|
+
cswarm ask "<text>" [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--to <member|agent>] [--about <ref>] [--until <dur>] [--wait <seconds>] [--json] # text: 1..8000 characters
|
|
37972
38257
|
cswarm reply <signal-id> "<text>" [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--until <dur>] [--json]
|
|
37973
38258
|
cswarm feed [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--about <ref>] [--kind <kind>] [--since <timestamp>] [--limit <n>] [--include-stale] [--json]
|
|
37974
38259
|
cswarm inbox [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--kind <kind>] [--about <ref>] [--since <timestamp>] [--limit <n>] [--include-stale] [--wait <seconds>] [--json]
|
|
@@ -38034,7 +38319,7 @@ Signals (intention sharing) accept the same credential selection. Agent mode
|
|
|
38034
38319
|
never opens a browser or infers a human's saved workspace. Durations use a whole
|
|
38035
38320
|
number plus m, h, or d (for example 90m, 24h, or 7d) and are capped at 30d.
|
|
38036
38321
|
Place -- before signal text that itself begins with -- to stop option parsing.
|
|
38037
|
-
Signal text is at most
|
|
38322
|
+
Signal text is at most 8000 characters and --about at most 500; a longer body is
|
|
38038
38323
|
refused locally before any network call, so compose within the limit.
|
|
38039
38324
|
|
|
38040
38325
|
listen start --turn-budget bounds ONE worker prompt turn (default 10m): how long
|
|
@@ -39518,13 +39803,18 @@ function resolveTurnBudgetOrDefer(configuredBudgetMs, credentialExpiresAt, nowMs
|
|
|
39518
39803
|
}
|
|
39519
39804
|
return clampTurnBudgetToCredential(configuredBudgetMs, credentialExpiresAt, nowMs);
|
|
39520
39805
|
}
|
|
39521
|
-
var SIGNAL_BODY_MAX =
|
|
39806
|
+
var SIGNAL_BODY_MAX = 8e3;
|
|
39522
39807
|
var SIGNAL_ABOUT_MAX = 500;
|
|
39523
39808
|
function signalText(value, label) {
|
|
39524
39809
|
const maximum = label === "body" ? SIGNAL_BODY_MAX : SIGNAL_ABOUT_MAX;
|
|
39525
39810
|
if (value.length < (label === "body" ? 1 : 0) || value.length > maximum) {
|
|
39811
|
+
if (label === "body") {
|
|
39812
|
+
throw new Error(
|
|
39813
|
+
`signal text is ${value.length} characters; the maximum is ${maximum}`
|
|
39814
|
+
);
|
|
39815
|
+
}
|
|
39526
39816
|
throw new Error(
|
|
39527
|
-
|
|
39817
|
+
`--about must be at most ${maximum} characters`
|
|
39528
39818
|
);
|
|
39529
39819
|
}
|
|
39530
39820
|
return value;
|
|
@@ -39666,10 +39956,25 @@ async function runPostSignal(args, kind) {
|
|
|
39666
39956
|
validateHumanWorkspace: true
|
|
39667
39957
|
});
|
|
39668
39958
|
const toSelector = allowTo ? args.optional("to") : void 0;
|
|
39669
|
-
|
|
39670
|
-
|
|
39671
|
-
|
|
39672
|
-
|
|
39959
|
+
let recipient = null;
|
|
39960
|
+
if (toSelector !== void 0) {
|
|
39961
|
+
let directory;
|
|
39962
|
+
try {
|
|
39963
|
+
directory = await signalDirectory(
|
|
39964
|
+
cloud,
|
|
39965
|
+
credential.selectedWorkspace,
|
|
39966
|
+
credential
|
|
39967
|
+
);
|
|
39968
|
+
} catch (error) {
|
|
39969
|
+
if (kind === "ask") {
|
|
39970
|
+
throw new Error(
|
|
39971
|
+
askCreateFailureMessage(credential.selectedWorkspace, error)
|
|
39972
|
+
);
|
|
39973
|
+
}
|
|
39974
|
+
throw error;
|
|
39975
|
+
}
|
|
39976
|
+
recipient = resolveSignalRecipient(toSelector, directory);
|
|
39977
|
+
}
|
|
39673
39978
|
if (waitSeconds !== void 0 && recipient === null) {
|
|
39674
39979
|
throw new Error(
|
|
39675
39980
|
"ask --wait requires --to with a direct member or agent recipient"
|
|
@@ -39684,21 +39989,38 @@ async function runPostSignal(args, kind) {
|
|
|
39684
39989
|
about: args.optional("about") === void 0 ? null : signalText(args.required("about"), "about"),
|
|
39685
39990
|
...untilMs2 === void 0 ? {} : { until_ms: untilMs2 }
|
|
39686
39991
|
};
|
|
39687
|
-
|
|
39992
|
+
let result;
|
|
39993
|
+
try {
|
|
39994
|
+
result = await postSignalCommand(cloud, credential, command2);
|
|
39995
|
+
} catch (error) {
|
|
39996
|
+
if (kind === "ask") {
|
|
39997
|
+
throw new Error(
|
|
39998
|
+
askCreateFailureMessage(credential.selectedWorkspace, error)
|
|
39999
|
+
);
|
|
40000
|
+
}
|
|
40001
|
+
throw error;
|
|
40002
|
+
}
|
|
39688
40003
|
const signal = result.response.signal;
|
|
39689
40004
|
if (waitSeconds !== void 0) {
|
|
39690
40005
|
const credentialForRead = signalCredentialOf(credential);
|
|
39691
40006
|
const deadlineMs = waitDeadlineMs(waitSeconds);
|
|
39692
|
-
|
|
39693
|
-
|
|
39694
|
-
|
|
39695
|
-
|
|
39696
|
-
|
|
39697
|
-
|
|
39698
|
-
|
|
39699
|
-
|
|
39700
|
-
|
|
39701
|
-
|
|
40007
|
+
let waitResult;
|
|
40008
|
+
try {
|
|
40009
|
+
waitResult = await pollForSignals({
|
|
40010
|
+
deadlineMs,
|
|
40011
|
+
read: () => readSignals(cloud, credentialForRead, {
|
|
40012
|
+
workspaceId: credential.selectedWorkspace,
|
|
40013
|
+
inbox: true,
|
|
40014
|
+
in_reply_to: signal.id,
|
|
40015
|
+
includeStale: false,
|
|
40016
|
+
limit: 1
|
|
40017
|
+
}, { deadlineMs })
|
|
40018
|
+
});
|
|
40019
|
+
} catch (error) {
|
|
40020
|
+
throw new Error(
|
|
40021
|
+
askReplyReadFailureMessage(credential.selectedWorkspace, error)
|
|
40022
|
+
);
|
|
40023
|
+
}
|
|
39702
40024
|
const reply = waitResult.signals[0] ?? null;
|
|
39703
40025
|
if (args.has("json")) {
|
|
39704
40026
|
printJson(askWaitJsonPayload(signal, reply, waitResult.timedOut));
|
|
@@ -40153,7 +40475,7 @@ function listenerModelLabel(provider) {
|
|
|
40153
40475
|
}
|
|
40154
40476
|
function listenerProvider(args) {
|
|
40155
40477
|
const provider = args.optional("provider");
|
|
40156
|
-
const hints = "supported providers: grok \u2014 install Grok CLI 0.2.117 and run grok login; opencode \u2014 install OpenCode 1.18.10 and authenticate it; claude \u2014 npm install -g @agentclientprotocol/claude-agent-acp@0.64.2; codex \u2014 npm install -g @agentclientprotocol/codex-acp@1.1.9. You can use working-on, note, ask, and feed now; detached live receipt needs one of these adapters";
|
|
40478
|
+
const hints = "supported providers: grok \u2014 install Grok CLI 0.2.117 or newer and run grok login; opencode \u2014 install OpenCode 1.18.10 or newer and authenticate it; claude \u2014 npm install -g @agentclientprotocol/claude-agent-acp@latest (minimum 0.64.2); codex \u2014 npm install -g @agentclientprotocol/codex-acp@latest (minimum 1.1.9). You can use working-on, note, ask, and feed now; detached live receipt needs one of these adapters";
|
|
40157
40479
|
if (provider === void 0) {
|
|
40158
40480
|
throw new Error(`--provider is required; ${hints}`);
|
|
40159
40481
|
}
|
|
@@ -40214,7 +40536,7 @@ function listenerHostLimits(provider) {
|
|
|
40214
40536
|
};
|
|
40215
40537
|
}
|
|
40216
40538
|
if (provider === "claude") {
|
|
40217
|
-
const host_configuration2 = "The Claude worker uses the operator-selected cwd and the normal Claude Code home through claude-agent-acp 0.64.2. Keychain/OAuth auth was measured; ANTHROPIC_API_KEY is stripped by the listener environment sanitizer.";
|
|
40539
|
+
const host_configuration2 = "The Claude worker uses the operator-selected cwd and the normal Claude Code home through claude-agent-acp 0.64.2 or newer. Keychain/OAuth auth was measured; ANTHROPIC_API_KEY is stripped by the listener environment sanitizer.";
|
|
40218
40540
|
const deny_canary_scope2 = "The deny canary proves host reject + correlated terminal deny only.";
|
|
40219
40541
|
const steady_allow_unproven2 = "The deny canary does not prove steady-state --permissions allow behavior.";
|
|
40220
40542
|
const cross_owner_context2 = "All sender relations reach that same worker and local context; each prompt carries sender and operator provenance.";
|
|
@@ -40238,7 +40560,7 @@ function listenerHostLimits(provider) {
|
|
|
40238
40560
|
};
|
|
40239
40561
|
}
|
|
40240
40562
|
if (provider === "codex") {
|
|
40241
|
-
const host_configuration2 = "The Codex worker uses the operator-selected cwd and normal ChatGPT/Codex auth through codex-acp 1.1.9. CommonSwarm explicitly selects read-only mode after every session/new; API-key variables are stripped by the listener environment sanitizer.";
|
|
40563
|
+
const host_configuration2 = "The Codex worker uses the operator-selected cwd and normal ChatGPT/Codex auth through codex-acp 1.1.9 or newer. CommonSwarm explicitly selects read-only mode after every session/new; API-key variables are stripped by the listener environment sanitizer.";
|
|
40242
40564
|
const deny_canary_scope2 = "The deny canary proves host reject + correlated terminal deny only.";
|
|
40243
40565
|
const steady_allow_unproven2 = "The deny canary does not prove steady-state --permissions allow behavior.";
|
|
40244
40566
|
const cross_owner_context2 = "All sender relations reach that same worker and local context; each prompt carries sender and operator provenance.";
|
|
@@ -40327,6 +40649,11 @@ function renderListenerStatus(status) {
|
|
|
40327
40649
|
lines.push(` ${line}`);
|
|
40328
40650
|
}
|
|
40329
40651
|
}
|
|
40652
|
+
if (status.providerVersion && status.providerLastMeasuredVersion) {
|
|
40653
|
+
lines.push(
|
|
40654
|
+
`Provider version ${status.providerVersion} is newer than the last measured version ${status.providerLastMeasuredVersion}. It is unverified but allowed because the startup permission canary passed. Next: verify this provider release with CommonSwarm and update the last-measured version.`
|
|
40655
|
+
);
|
|
40656
|
+
}
|
|
40330
40657
|
if (status.deliveryMode === "durable_claim") {
|
|
40331
40658
|
lines.push("Delivery mode: durable claim and acknowledgement.");
|
|
40332
40659
|
} else if (status.deliveryMode === "cursor_fallback") {
|
|
@@ -40369,29 +40696,35 @@ function renderListenerStatus(status) {
|
|
|
40369
40696
|
return lines.join("\n");
|
|
40370
40697
|
}
|
|
40371
40698
|
function listenerFailureMessage(code, provider) {
|
|
40372
|
-
if (code === "
|
|
40699
|
+
if (code === "version_below_floor") {
|
|
40373
40700
|
if (provider === "codex") {
|
|
40374
|
-
return "the Codex listener requires codex-acp 1.1.9
|
|
40701
|
+
return "the Codex listener requires codex-acp 1.1.9 or newer; update the bridge, then retry";
|
|
40375
40702
|
}
|
|
40376
40703
|
if (provider === "claude") {
|
|
40377
|
-
return "the Claude listener requires claude-agent-acp 0.64.2
|
|
40704
|
+
return "the Claude listener requires claude-agent-acp 0.64.2 or newer; update the bridge, then retry";
|
|
40378
40705
|
}
|
|
40379
40706
|
if (provider === "opencode") {
|
|
40380
|
-
return "the OpenCode listener requires OpenCode 1.18.10
|
|
40707
|
+
return "the OpenCode listener requires OpenCode 1.18.10 or newer; update OpenCode, then retry";
|
|
40381
40708
|
}
|
|
40382
|
-
return "the Grok listener requires Grok 0.2.117
|
|
40709
|
+
return "the Grok listener requires Grok 0.2.117 or newer; update Grok, confirm grok login, then retry";
|
|
40710
|
+
}
|
|
40711
|
+
if (code === "version_unparseable") {
|
|
40712
|
+
return `the ${provider ?? "provider"} version output was not valid semantic version data, so startup stopped. Next: run the provider's --version command, then update or reinstall it`;
|
|
40713
|
+
}
|
|
40714
|
+
if (code === "version_refused") {
|
|
40715
|
+
return `the ${provider ?? "provider"} version check could not run, so startup stopped. Next: run the provider's --version command and fix that error, then retry`;
|
|
40383
40716
|
}
|
|
40384
40717
|
if (code === "executable_missing" && provider === "claude") {
|
|
40385
|
-
return "claude-agent-acp is not installed; run npm install -g @agentclientprotocol/claude-agent-acp@0.64.2, then retry";
|
|
40718
|
+
return "claude-agent-acp is not installed; run npm install -g @agentclientprotocol/claude-agent-acp@latest (minimum 0.64.2), then retry";
|
|
40386
40719
|
}
|
|
40387
40720
|
if (code === "executable_missing" && provider === "codex") {
|
|
40388
|
-
return "codex-acp is not installed; run npm install -g @agentclientprotocol/codex-acp@1.1.9, then retry";
|
|
40721
|
+
return "codex-acp is not installed; run npm install -g @agentclientprotocol/codex-acp@latest (minimum 1.1.9), then retry";
|
|
40389
40722
|
}
|
|
40390
40723
|
if (code === "permission_mode_unavailable" && provider === "claude") {
|
|
40391
|
-
return "the Claude bridge does not expose the required manual permission mode; reinstall claude-agent-acp
|
|
40724
|
+
return "the Claude bridge does not expose the required manual permission mode; update or reinstall claude-agent-acp, then retry";
|
|
40392
40725
|
}
|
|
40393
40726
|
if (code === "permission_mode_unavailable" && provider === "codex") {
|
|
40394
|
-
return "the Codex bridge does not expose the required read-only permission mode; reinstall codex-acp
|
|
40727
|
+
return "the Codex bridge does not expose the required read-only permission mode; update or reinstall codex-acp, then retry";
|
|
40395
40728
|
}
|
|
40396
40729
|
if (provider === "claude" && (code === "rpc_error" || code === "child_exit" || code === "timeout")) {
|
|
40397
40730
|
return `the Claude bridge could not start (${code}); confirm Claude Code keychain/OAuth sign-in and network access, then retry. ANTHROPIC_API_KEY is not forwarded to detached listeners`;
|
|
@@ -40443,7 +40776,7 @@ function resolveDetachedClaudeExecutable(executable = "claude-agent-acp", pathEn
|
|
|
40443
40776
|
if ((0, import_node_path19.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
|
|
40444
40777
|
const detail = error instanceof Error ? error.message : code;
|
|
40445
40778
|
throw new Error(
|
|
40446
|
-
`could not use --claude-executable: ${detail};
|
|
40779
|
+
`could not use --claude-executable: ${detail}; install the current bridge with npm install -g @agentclientprotocol/claude-agent-acp@latest if this path should be replaced`
|
|
40447
40780
|
);
|
|
40448
40781
|
}
|
|
40449
40782
|
throw new Error(listenerFailureMessage(code, "claude"));
|
|
@@ -40460,7 +40793,7 @@ function resolveDetachedCodexExecutable(executable = "codex-acp", pathEnv = proc
|
|
|
40460
40793
|
if ((0, import_node_path19.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
|
|
40461
40794
|
const detail = error instanceof Error ? error.message : code;
|
|
40462
40795
|
throw new Error(
|
|
40463
|
-
`could not use --codex-executable: ${detail};
|
|
40796
|
+
`could not use --codex-executable: ${detail}; install the current bridge with npm install -g @agentclientprotocol/codex-acp@latest if this path should be replaced`
|
|
40464
40797
|
);
|
|
40465
40798
|
}
|
|
40466
40799
|
throw new Error(listenerFailureMessage(code, "codex"));
|
|
@@ -40564,6 +40897,10 @@ async function runConfiguredListener(options) {
|
|
|
40564
40897
|
};
|
|
40565
40898
|
let lastWorkerStderrTail = null;
|
|
40566
40899
|
let workerStderrGeneration = 0;
|
|
40900
|
+
let providerVersionNotice = null;
|
|
40901
|
+
const onVersionNotice = (notice) => {
|
|
40902
|
+
providerVersionNotice = notice;
|
|
40903
|
+
};
|
|
40567
40904
|
const newWorkerStderrTailSink = () => {
|
|
40568
40905
|
const generation = ++workerStderrGeneration;
|
|
40569
40906
|
lastWorkerStderrTail = null;
|
|
@@ -40572,34 +40909,41 @@ async function runConfiguredListener(options) {
|
|
|
40572
40909
|
lastWorkerStderrTail = tail.length > 0 ? tail : null;
|
|
40573
40910
|
};
|
|
40574
40911
|
};
|
|
40575
|
-
const newModel = () =>
|
|
40576
|
-
|
|
40577
|
-
|
|
40578
|
-
|
|
40579
|
-
|
|
40580
|
-
|
|
40581
|
-
|
|
40582
|
-
|
|
40583
|
-
|
|
40584
|
-
|
|
40585
|
-
|
|
40586
|
-
|
|
40587
|
-
|
|
40588
|
-
|
|
40589
|
-
|
|
40590
|
-
|
|
40591
|
-
|
|
40592
|
-
|
|
40593
|
-
|
|
40594
|
-
|
|
40595
|
-
|
|
40596
|
-
|
|
40597
|
-
|
|
40598
|
-
|
|
40599
|
-
|
|
40600
|
-
|
|
40601
|
-
|
|
40602
|
-
|
|
40912
|
+
const newModel = () => {
|
|
40913
|
+
providerVersionNotice = null;
|
|
40914
|
+
return options.provider === "opencode" ? new OpenCodeListenerModel({
|
|
40915
|
+
cwd: options.cwd,
|
|
40916
|
+
permissionMode: options.permissionMode,
|
|
40917
|
+
promptTimeoutMs: resolveTurnBudgetMs,
|
|
40918
|
+
onWorkerStderrTail: newWorkerStderrTailSink(),
|
|
40919
|
+
onVersionNotice,
|
|
40920
|
+
...options.model ? { model: options.model } : {},
|
|
40921
|
+
...options.opencodeExecutable ? { executable: options.opencodeExecutable } : options.executable ? { executable: options.executable } : {}
|
|
40922
|
+
}) : options.provider === "claude" ? new ClaudeListenerModel({
|
|
40923
|
+
cwd: options.cwd,
|
|
40924
|
+
permissionMode: options.permissionMode,
|
|
40925
|
+
promptTimeoutMs: resolveTurnBudgetMs,
|
|
40926
|
+
onWorkerStderrTail: newWorkerStderrTailSink(),
|
|
40927
|
+
onVersionNotice,
|
|
40928
|
+
...options.claudeExecutable ? { executable: options.claudeExecutable } : options.executable ? { executable: options.executable } : {}
|
|
40929
|
+
}) : options.provider === "codex" ? new CodexListenerModel({
|
|
40930
|
+
cwd: options.cwd,
|
|
40931
|
+
permissionMode: options.permissionMode,
|
|
40932
|
+
promptTimeoutMs: resolveTurnBudgetMs,
|
|
40933
|
+
onWorkerStderrTail: newWorkerStderrTailSink(),
|
|
40934
|
+
onVersionNotice,
|
|
40935
|
+
...options.codexExecutable ? { executable: options.codexExecutable } : options.executable ? { executable: options.executable } : {}
|
|
40936
|
+
}) : new GrokListenerModel({
|
|
40937
|
+
cwd: options.cwd,
|
|
40938
|
+
permissionMode: options.permissionMode,
|
|
40939
|
+
promptTimeoutMs: resolveTurnBudgetMs,
|
|
40940
|
+
onWorkerStderrTail: newWorkerStderrTailSink(),
|
|
40941
|
+
onVersionNotice,
|
|
40942
|
+
...options.model ? { model: options.model } : {},
|
|
40943
|
+
...options.effort ? { effort: options.effort } : {},
|
|
40944
|
+
...options.executable ? { executable: options.executable } : {}
|
|
40945
|
+
});
|
|
40946
|
+
};
|
|
40603
40947
|
const onProcessSignal = () => {
|
|
40604
40948
|
void stopListener(paths);
|
|
40605
40949
|
};
|
|
@@ -40623,6 +40967,7 @@ async function runConfiguredListener(options) {
|
|
|
40623
40967
|
// The bound a timeout event reports: the last turn's clamped budget when
|
|
40624
40968
|
// one has run, else the configured cap.
|
|
40625
40969
|
getTurnBudgetMs: () => lastAppliedTurnBudgetMs ?? turnBudgetMs,
|
|
40970
|
+
getProviderVersionNotice: () => providerVersionNotice,
|
|
40626
40971
|
takeWorkerStderrTail: () => {
|
|
40627
40972
|
const tail = lastWorkerStderrTail;
|
|
40628
40973
|
lastWorkerStderrTail = null;
|
|
@@ -40841,8 +41186,8 @@ async function runListenStart(args) {
|
|
|
40841
41186
|
` : "";
|
|
40842
41187
|
const workerAudience = routing.routeMode === "main" ? "Directed asks do not reach that worker." : routing.routeMode === "split" ? "Only asks at or below the split threshold reach that worker, with sender and operator provenance in the prompt." : "Every sender reaches that worker with sender and operator provenance in the prompt.";
|
|
40843
41188
|
const hostNote = provider === "opencode" ? `The OpenCode worker uses one private auth/config home and your selected project cwd. ${workerAudience} Tool requests are approved one at a time by default, when the worker asks and the host offers a one-time approval; --permissions deny refuses them. The deny canary does not cover steady-state allow.
|
|
40844
|
-
` : provider === "claude" ? `The Claude worker uses your selected cwd and normal Claude Code keychain/OAuth state through claude-agent-acp 0.64.2. ${workerAudience}
|
|
40845
|
-
` : provider === "codex" ? `The Codex worker uses your selected cwd and normal ChatGPT/Codex auth through codex-acp 1.1.9. CommonSwarm selects read-only mode before its deny canary. ${workerAudience}
|
|
41189
|
+
` : provider === "claude" ? `The Claude worker uses your selected cwd and normal Claude Code keychain/OAuth state through claude-agent-acp 0.64.2 or newer. ${workerAudience}
|
|
41190
|
+
` : provider === "codex" ? `The Codex worker uses your selected cwd and normal ChatGPT/Codex auth through codex-acp 1.1.9 or newer. CommonSwarm selects read-only mode before its deny canary. ${workerAudience}
|
|
40846
41191
|
` : `The Grok worker uses your selected cwd and local Grok configuration, including user and cmux hooks. ${workerAudience}
|
|
40847
41192
|
`;
|
|
40848
41193
|
process.stdout.write(
|