commonswarm 0.1.38 → 0.1.39
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 +136 -24
- package/package.json +1 -1
package/cswarm.cjs
CHANGED
|
@@ -13520,7 +13520,7 @@ __export(cli_exports, {
|
|
|
13520
13520
|
resolveTurnBudgetOrDefer: () => resolveTurnBudgetOrDefer
|
|
13521
13521
|
});
|
|
13522
13522
|
module.exports = __toCommonJS(cli_exports);
|
|
13523
|
-
var
|
|
13523
|
+
var import_node_crypto20 = require("node:crypto");
|
|
13524
13524
|
var import_node_fs7 = require("node:fs");
|
|
13525
13525
|
var import_promises11 = require("node:fs/promises");
|
|
13526
13526
|
var import_node_path20 = require("node:path");
|
|
@@ -33451,6 +33451,7 @@ var FileListenerEffectStore = class {
|
|
|
33451
33451
|
};
|
|
33452
33452
|
|
|
33453
33453
|
// src/listener/grok-model.ts
|
|
33454
|
+
var import_node_crypto14 = require("node:crypto");
|
|
33454
33455
|
var import_promises5 = require("node:fs/promises");
|
|
33455
33456
|
var import_node_os7 = require("node:os");
|
|
33456
33457
|
var import_node_path11 = require("node:path");
|
|
@@ -33695,7 +33696,7 @@ var GrokListenerModel = class {
|
|
|
33695
33696
|
clientName: "cswarm-listener"
|
|
33696
33697
|
});
|
|
33697
33698
|
try {
|
|
33698
|
-
await
|
|
33699
|
+
await this.enablePromptsAfterGrokCanary(handle);
|
|
33699
33700
|
this.workerCanary = false;
|
|
33700
33701
|
this.worker = handle;
|
|
33701
33702
|
return handle;
|
|
@@ -33704,6 +33705,37 @@ var GrokListenerModel = class {
|
|
|
33704
33705
|
throw error;
|
|
33705
33706
|
}
|
|
33706
33707
|
}
|
|
33708
|
+
/** Force Grok's measured shell permission path without changing worker cwd. */
|
|
33709
|
+
async enablePromptsAfterGrokCanary(handle) {
|
|
33710
|
+
const sentinelPath = (0, import_node_path11.join)(
|
|
33711
|
+
(0, import_node_os7.tmpdir)(),
|
|
33712
|
+
`cswarm-grok-permission-canary-${process.pid}-${(0, import_node_crypto14.randomUUID)()}`
|
|
33713
|
+
);
|
|
33714
|
+
let canaryError;
|
|
33715
|
+
try {
|
|
33716
|
+
await handle.session.enablePromptsAfterCanary({
|
|
33717
|
+
timeoutMs: ACP_CANARY_TIMEOUT_MS,
|
|
33718
|
+
probeText: `Use a shell command to create ${sentinelPath} with content CSWARM_CANARY_NOOP. You must use the shell. Do nothing else.`,
|
|
33719
|
+
...this.options.onCanaryAttempt ? { onAttempt: this.options.onCanaryAttempt } : {}
|
|
33720
|
+
});
|
|
33721
|
+
} catch (error) {
|
|
33722
|
+
canaryError = error;
|
|
33723
|
+
}
|
|
33724
|
+
let sentinelCreated = false;
|
|
33725
|
+
try {
|
|
33726
|
+
await (0, import_promises5.lstat)(sentinelPath);
|
|
33727
|
+
sentinelCreated = true;
|
|
33728
|
+
await (0, import_promises5.unlink)(sentinelPath);
|
|
33729
|
+
} catch (error) {
|
|
33730
|
+
if (error.code !== "ENOENT") throw error;
|
|
33731
|
+
}
|
|
33732
|
+
if (sentinelCreated) {
|
|
33733
|
+
throw new AcpPermissionCanaryError(
|
|
33734
|
+
"Grok bridge wrote the permission canary sentinel; permission denial did not block the write"
|
|
33735
|
+
);
|
|
33736
|
+
}
|
|
33737
|
+
if (canaryError !== void 0) throw canaryError;
|
|
33738
|
+
}
|
|
33707
33739
|
/** Validate the operator's login artifact without copying or replacing its home. */
|
|
33708
33740
|
async validateLocalAuth() {
|
|
33709
33741
|
if (this.options.open) return;
|
|
@@ -33760,7 +33792,7 @@ var GrokListenerModel = class {
|
|
|
33760
33792
|
};
|
|
33761
33793
|
|
|
33762
33794
|
// src/listener/opencode-model.ts
|
|
33763
|
-
var
|
|
33795
|
+
var import_node_crypto15 = require("node:crypto");
|
|
33764
33796
|
var import_promises6 = require("node:fs/promises");
|
|
33765
33797
|
var import_node_path12 = require("node:path");
|
|
33766
33798
|
function asError(error) {
|
|
@@ -33786,7 +33818,7 @@ var OpenCodeListenerModel = class {
|
|
|
33786
33818
|
prepareWorkerCwd;
|
|
33787
33819
|
permissionMode;
|
|
33788
33820
|
pendingOpenWaitMs;
|
|
33789
|
-
instanceId = (0,
|
|
33821
|
+
instanceId = (0, import_node_crypto15.randomUUID)();
|
|
33790
33822
|
worker = null;
|
|
33791
33823
|
workerHome = null;
|
|
33792
33824
|
/** Worker homes retained after failed close or unsettled open. */
|
|
@@ -34148,7 +34180,13 @@ var OpenCodeListenerModel = class {
|
|
|
34148
34180
|
if (this.closed || this.cancelled || generation !== this.openGeneration) {
|
|
34149
34181
|
await this.performSingleOwnerCleanup(handle, home, this.instanceId, pending);
|
|
34150
34182
|
}
|
|
34151
|
-
|
|
34183
|
+
if (this.options.onCanaryAttempt) {
|
|
34184
|
+
await handle.session.enablePromptsAfterCanary({
|
|
34185
|
+
onAttempt: this.options.onCanaryAttempt
|
|
34186
|
+
});
|
|
34187
|
+
} else {
|
|
34188
|
+
await handle.session.enablePromptsAfterCanary();
|
|
34189
|
+
}
|
|
34152
34190
|
if (this.closed || this.cancelled || generation !== this.openGeneration) {
|
|
34153
34191
|
await this.performSingleOwnerCleanup(handle, home, this.instanceId, pending);
|
|
34154
34192
|
}
|
|
@@ -34193,7 +34231,7 @@ var OpenCodeListenerModel = class {
|
|
|
34193
34231
|
};
|
|
34194
34232
|
|
|
34195
34233
|
// src/listener/claude-model.ts
|
|
34196
|
-
var
|
|
34234
|
+
var import_node_crypto16 = require("node:crypto");
|
|
34197
34235
|
var import_promises7 = require("node:fs/promises");
|
|
34198
34236
|
var import_node_os8 = require("node:os");
|
|
34199
34237
|
var import_node_path13 = require("node:path");
|
|
@@ -34336,13 +34374,14 @@ var ClaudeListenerModel = class {
|
|
|
34336
34374
|
async enablePromptsAfterClaudeCanary(handle) {
|
|
34337
34375
|
const sentinelPath = (0, import_node_path13.join)(
|
|
34338
34376
|
(0, import_node_os8.tmpdir)(),
|
|
34339
|
-
`cswarm-claude-permission-canary-${process.pid}-${(0,
|
|
34377
|
+
`cswarm-claude-permission-canary-${process.pid}-${(0, import_node_crypto16.randomUUID)()}`
|
|
34340
34378
|
);
|
|
34341
34379
|
let sentinelCreated = false;
|
|
34342
34380
|
try {
|
|
34343
34381
|
await handle.session.enablePromptsAfterCanary({
|
|
34344
34382
|
timeoutMs: ACP_CANARY_TIMEOUT_MS,
|
|
34345
|
-
probeText: `Create the file ${sentinelPath} using the Write tool with content CSWARM_CANARY_NOOP. You must use the Write tool. Do nothing else
|
|
34383
|
+
probeText: `Create the file ${sentinelPath} using the Write tool with content CSWARM_CANARY_NOOP. You must use the Write tool. Do nothing else.`,
|
|
34384
|
+
...this.options.onCanaryAttempt ? { onAttempt: this.options.onCanaryAttempt } : {}
|
|
34346
34385
|
});
|
|
34347
34386
|
} finally {
|
|
34348
34387
|
try {
|
|
@@ -34362,7 +34401,7 @@ var ClaudeListenerModel = class {
|
|
|
34362
34401
|
};
|
|
34363
34402
|
|
|
34364
34403
|
// src/listener/codex-model.ts
|
|
34365
|
-
var
|
|
34404
|
+
var import_node_crypto17 = require("node:crypto");
|
|
34366
34405
|
var import_promises8 = require("node:fs/promises");
|
|
34367
34406
|
var import_node_os9 = require("node:os");
|
|
34368
34407
|
var import_node_path14 = require("node:path");
|
|
@@ -34505,13 +34544,14 @@ var CodexListenerModel = class {
|
|
|
34505
34544
|
async enablePromptsAfterCodexCanary(handle) {
|
|
34506
34545
|
const sentinelPath = (0, import_node_path14.join)(
|
|
34507
34546
|
(0, import_node_os9.tmpdir)(),
|
|
34508
|
-
`cswarm-codex-permission-canary-${process.pid}-${(0,
|
|
34547
|
+
`cswarm-codex-permission-canary-${process.pid}-${(0, import_node_crypto17.randomUUID)()}`
|
|
34509
34548
|
);
|
|
34510
34549
|
let sentinelCreated = false;
|
|
34511
34550
|
try {
|
|
34512
34551
|
await handle.session.enablePromptsAfterCanary({
|
|
34513
34552
|
timeoutMs: ACP_CANARY_TIMEOUT_MS,
|
|
34514
|
-
probeText: `Use a shell command to create ${sentinelPath} with content CSWARM_CANARY_NOOP. You must use the shell. Do nothing else
|
|
34553
|
+
probeText: `Use a shell command to create ${sentinelPath} with content CSWARM_CANARY_NOOP. You must use the shell. Do nothing else.`,
|
|
34554
|
+
...this.options.onCanaryAttempt ? { onAttempt: this.options.onCanaryAttempt } : {}
|
|
34515
34555
|
});
|
|
34516
34556
|
} finally {
|
|
34517
34557
|
try {
|
|
@@ -34531,7 +34571,7 @@ var CodexListenerModel = class {
|
|
|
34531
34571
|
};
|
|
34532
34572
|
|
|
34533
34573
|
// src/listener/runtime.ts
|
|
34534
|
-
var
|
|
34574
|
+
var import_node_crypto18 = require("node:crypto");
|
|
34535
34575
|
|
|
34536
34576
|
// src/cloud/delivery.ts
|
|
34537
34577
|
var UUID_RE12 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
@@ -35487,7 +35527,7 @@ function sameEffectSignal(record, signal) {
|
|
|
35487
35527
|
return record.signalId === signal.id.toLowerCase() && record.signalKind === signal.kind && record.askBody === signal.body && record.askUntil === signal.until && record.senderOwnerRelation === (signal.sender_owner_relation ?? "unknown");
|
|
35488
35528
|
}
|
|
35489
35529
|
function immutableSignalFingerprint(signalId, signalKind2, body, until, senderOwnerRelation) {
|
|
35490
|
-
return (0,
|
|
35530
|
+
return (0, import_node_crypto18.createHash)("sha256").update(JSON.stringify([
|
|
35491
35531
|
signalId,
|
|
35492
35532
|
signalKind2,
|
|
35493
35533
|
body,
|
|
@@ -36477,6 +36517,7 @@ var STATUS_ALLOWED_KEYS = /* @__PURE__ */ new Set([
|
|
|
36477
36517
|
"stoppedAt",
|
|
36478
36518
|
"lastSignalId",
|
|
36479
36519
|
"lastErrorCode",
|
|
36520
|
+
"lastErrorDetail",
|
|
36480
36521
|
"providerVersion",
|
|
36481
36522
|
"providerLastMeasuredVersion",
|
|
36482
36523
|
"lastWorkerStderrTail",
|
|
@@ -36538,7 +36579,7 @@ function parseStatus(raw) {
|
|
|
36538
36579
|
const nullableUuid2 = (candidate) => candidate === null || typeof candidate === "string" && UUID_RE15.test(candidate);
|
|
36539
36580
|
const nullableCount = (candidate) => candidate === null || typeof candidate === "number" && Number.isSafeInteger(candidate) && candidate >= 0;
|
|
36540
36581
|
const nullableTimestamp2 = (candidate) => candidate === null || typeof candidate === "string" && Number.isFinite(Date.parse(candidate));
|
|
36541
|
-
if (row.version !== 1 || typeof row.instanceId !== "string" || !UUID_RE15.test(row.instanceId) || row.provider !== "grok" && row.provider !== "opencode" && row.provider !== "claude" && row.provider !== "codex" || typeof row.profileId !== "string" || typeof row.workspaceId !== "string" || !UUID_RE15.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE15.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_path16.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 || nullableTimestamp2(row.lastTerminalDeliveryFailureAt)) || !(row.lastClaimAt === void 0 || nullableTimestamp2(row.lastClaimAt)) || !(row.lastAckAt === void 0 || nullableTimestamp2(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)) {
|
|
36582
|
+
if (row.version !== 1 || typeof row.instanceId !== "string" || !UUID_RE15.test(row.instanceId) || row.provider !== "grok" && row.provider !== "opencode" && row.provider !== "claude" && row.provider !== "codex" || typeof row.profileId !== "string" || typeof row.workspaceId !== "string" || !UUID_RE15.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE15.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.lastErrorDetail === void 0 || row.lastErrorDetail === null || typeof row.lastErrorDetail === "string" && row.lastErrorDetail.length > 0 && row.lastErrorDetail.length <= 2048 && !/swm_(?:agt|inv|cap)_/i.test(row.lastErrorDetail)) || !(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_path16.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 || nullableTimestamp2(row.lastTerminalDeliveryFailureAt)) || !(row.lastClaimAt === void 0 || nullableTimestamp2(row.lastClaimAt)) || !(row.lastAckAt === void 0 || nullableTimestamp2(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)) {
|
|
36542
36583
|
throw new Error("stored listener status is malformed");
|
|
36543
36584
|
}
|
|
36544
36585
|
const routeMode = row.routeMode ?? "worker";
|
|
@@ -36554,6 +36595,7 @@ function parseStatus(raw) {
|
|
|
36554
36595
|
lastTerminalDeliveryFailureAt: row.lastTerminalDeliveryFailureAt ?? null,
|
|
36555
36596
|
lastClaimAt: row.lastClaimAt ?? null,
|
|
36556
36597
|
lastAckAt: row.lastAckAt ?? null,
|
|
36598
|
+
lastErrorDetail: row.lastErrorDetail ?? null,
|
|
36557
36599
|
lastWorkerStderrTail: row.lastWorkerStderrTail ?? null,
|
|
36558
36600
|
providerVersion: row.providerVersion ?? null,
|
|
36559
36601
|
providerLastMeasuredVersion: row.providerLastMeasuredVersion ?? null,
|
|
@@ -36571,6 +36613,9 @@ async function writeListenerStatus(paths, status) {
|
|
|
36571
36613
|
throw new Error("listener status is missing delivery metadata fields");
|
|
36572
36614
|
}
|
|
36573
36615
|
}
|
|
36616
|
+
if (!("lastErrorDetail" in parsed)) {
|
|
36617
|
+
throw new Error("listener status is missing local error detail metadata");
|
|
36618
|
+
}
|
|
36574
36619
|
parseStatus(serialized);
|
|
36575
36620
|
await writeSecureJsonFile(paths.statusPath, serialized);
|
|
36576
36621
|
}
|
|
@@ -36588,6 +36633,9 @@ async function appendListenerEvent(paths, event) {
|
|
|
36588
36633
|
"status",
|
|
36589
36634
|
"failure_code",
|
|
36590
36635
|
"attempt",
|
|
36636
|
+
"total",
|
|
36637
|
+
"passed",
|
|
36638
|
+
"reason",
|
|
36591
36639
|
"delay_ms",
|
|
36592
36640
|
"index",
|
|
36593
36641
|
"delivery_mode",
|
|
@@ -36624,6 +36672,15 @@ async function appendListenerEvent(paths, event) {
|
|
|
36624
36672
|
if (!allowed.has(key2)) {
|
|
36625
36673
|
throw new Error(`listener event field is not allowed: ${key2}`);
|
|
36626
36674
|
}
|
|
36675
|
+
if ((key2 === "attempt" || key2 === "total") && !(typeof value === "number" && Number.isSafeInteger(value) && value >= 1)) {
|
|
36676
|
+
throw new Error("listener event attempt count is not allowed");
|
|
36677
|
+
}
|
|
36678
|
+
if (key2 === "passed" && typeof value !== "boolean") {
|
|
36679
|
+
throw new Error("listener event canary result is not allowed");
|
|
36680
|
+
}
|
|
36681
|
+
if (key2 === "reason" && !(value === null || typeof value === "string" && value.length > 0)) {
|
|
36682
|
+
throw new Error("listener event canary reason is not allowed");
|
|
36683
|
+
}
|
|
36627
36684
|
if (key2 === "delivery_mode" && !(value === null || typeof value === "string" && deliveryModes.has(value))) {
|
|
36628
36685
|
throw new Error("listener event delivery mode is not allowed");
|
|
36629
36686
|
}
|
|
@@ -36658,6 +36715,9 @@ async function appendListenerEvent(paths, event) {
|
|
|
36658
36715
|
throw new Error("listener event contains unsafe text");
|
|
36659
36716
|
}
|
|
36660
36717
|
}
|
|
36718
|
+
if (event.event === "listener_canary_attempt" && (typeof event.attempt !== "number" || typeof event.total !== "number" || event.attempt > event.total || typeof event.passed !== "boolean" || !(event.reason === null || typeof event.reason === "string"))) {
|
|
36719
|
+
throw new Error("listener canary attempt event is incomplete");
|
|
36720
|
+
}
|
|
36661
36721
|
await ensureSecureStateDirectory(paths.instanceDirectory);
|
|
36662
36722
|
const serialized = `${JSON.stringify(event)}
|
|
36663
36723
|
`;
|
|
@@ -36887,7 +36947,7 @@ async function queryListenerControl(paths, command2, timeoutMs = CONTROL_TIMEOUT
|
|
|
36887
36947
|
}
|
|
36888
36948
|
|
|
36889
36949
|
// src/listener/supervisor.ts
|
|
36890
|
-
var
|
|
36950
|
+
var import_node_crypto19 = require("node:crypto");
|
|
36891
36951
|
var UUID_RE16 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
36892
36952
|
var LISTENER_RESTART_MAX_ATTEMPTS = 5;
|
|
36893
36953
|
var LISTENER_RESTART_INITIAL_MS = 1e3;
|
|
@@ -36931,6 +36991,17 @@ function safeErrorCode(error) {
|
|
|
36931
36991
|
const name = error.name.toLowerCase().replace(/[^a-z0-9_-]+/g, "_");
|
|
36932
36992
|
return name.slice(0, 96) || "listener_error";
|
|
36933
36993
|
}
|
|
36994
|
+
function localDiagnostic(message, maxChars) {
|
|
36995
|
+
const redacted = message.replace(
|
|
36996
|
+
/swm_(?:agt|inv|cap)_[^\s"'\\]*/gi,
|
|
36997
|
+
"[redacted]"
|
|
36998
|
+
).trim();
|
|
36999
|
+
if (redacted.length === 0) return null;
|
|
37000
|
+
return redacted.slice(0, maxChars);
|
|
37001
|
+
}
|
|
37002
|
+
function safeErrorDetail(error) {
|
|
37003
|
+
return localDiagnostic(error.message, 2048);
|
|
37004
|
+
}
|
|
36934
37005
|
var TAIL_SERIALIZED_BUDGET_BYTES = 3e3;
|
|
36935
37006
|
function fitWorkerStderrTailForLog(tail) {
|
|
36936
37007
|
let fitted = tail.trim();
|
|
@@ -36952,7 +37023,7 @@ async function runListenerSupervisor(options) {
|
|
|
36952
37023
|
const now = options.now ?? Date.now;
|
|
36953
37024
|
const startedAt = iso2(now);
|
|
36954
37025
|
const controller = new AbortController();
|
|
36955
|
-
const proposedInstanceId = (0,
|
|
37026
|
+
const proposedInstanceId = (0, import_node_crypto19.randomUUID)();
|
|
36956
37027
|
let status = {
|
|
36957
37028
|
version: 1,
|
|
36958
37029
|
instanceId: proposedInstanceId,
|
|
@@ -36969,6 +37040,7 @@ async function runListenerSupervisor(options) {
|
|
|
36969
37040
|
stoppedAt: null,
|
|
36970
37041
|
lastSignalId: null,
|
|
36971
37042
|
lastErrorCode: null,
|
|
37043
|
+
lastErrorDetail: null,
|
|
36972
37044
|
providerVersion: null,
|
|
36973
37045
|
providerLastMeasuredVersion: null,
|
|
36974
37046
|
lastWorkerStderrTail: null,
|
|
@@ -37044,6 +37116,7 @@ async function runListenerSupervisor(options) {
|
|
|
37044
37116
|
transition("ready", {
|
|
37045
37117
|
readyAt: event.ts,
|
|
37046
37118
|
lastErrorCode: null,
|
|
37119
|
+
lastErrorDetail: null,
|
|
37047
37120
|
lastWorkerStderrTail: null,
|
|
37048
37121
|
providerVersion: versionNotice?.runningVersion ?? null,
|
|
37049
37122
|
providerLastMeasuredVersion: versionNotice?.lastMeasuredVersion ?? null
|
|
@@ -37051,6 +37124,17 @@ async function runListenerSupervisor(options) {
|
|
|
37051
37124
|
log({ ts: event.ts, event: "listener_ready" });
|
|
37052
37125
|
return;
|
|
37053
37126
|
}
|
|
37127
|
+
if (event.type === "canary_attempt") {
|
|
37128
|
+
log({
|
|
37129
|
+
ts: event.ts,
|
|
37130
|
+
event: "listener_canary_attempt",
|
|
37131
|
+
attempt: event.attempt,
|
|
37132
|
+
total: event.total,
|
|
37133
|
+
passed: event.passed,
|
|
37134
|
+
reason: event.reason === null ? null : localDiagnostic(event.reason, 128)
|
|
37135
|
+
});
|
|
37136
|
+
return;
|
|
37137
|
+
}
|
|
37054
37138
|
if (event.type === "effect") {
|
|
37055
37139
|
status = {
|
|
37056
37140
|
...status,
|
|
@@ -37244,6 +37328,7 @@ async function runListenerSupervisor(options) {
|
|
|
37244
37328
|
transition("starting", {
|
|
37245
37329
|
readyAt: null,
|
|
37246
37330
|
lastErrorCode: restartCode,
|
|
37331
|
+
lastErrorDetail: safeErrorDetail(stop.error),
|
|
37247
37332
|
lastWorkerStderrTail: restartStderrTail,
|
|
37248
37333
|
providerVersion: null,
|
|
37249
37334
|
providerLastMeasuredVersion: null
|
|
@@ -37259,6 +37344,7 @@ async function runListenerSupervisor(options) {
|
|
|
37259
37344
|
transition("stopped", {
|
|
37260
37345
|
stoppedAt,
|
|
37261
37346
|
lastErrorCode: null,
|
|
37347
|
+
lastErrorDetail: null,
|
|
37262
37348
|
lastWorkerStderrTail: null
|
|
37263
37349
|
});
|
|
37264
37350
|
log({ ts: stoppedAt, event: "listener_stopped" });
|
|
@@ -37268,6 +37354,7 @@ async function runListenerSupervisor(options) {
|
|
|
37268
37354
|
transition("failed", {
|
|
37269
37355
|
stoppedAt,
|
|
37270
37356
|
lastErrorCode: code,
|
|
37357
|
+
lastErrorDetail: safeErrorDetail(stop.error),
|
|
37271
37358
|
lastWorkerStderrTail: failedStderrTail
|
|
37272
37359
|
});
|
|
37273
37360
|
log({
|
|
@@ -37289,6 +37376,9 @@ async function runListenerSupervisor(options) {
|
|
|
37289
37376
|
transition("failed", {
|
|
37290
37377
|
stoppedAt,
|
|
37291
37378
|
lastErrorCode: code,
|
|
37379
|
+
lastErrorDetail: safeErrorDetail(
|
|
37380
|
+
error instanceof Error ? error : new Error(String(error))
|
|
37381
|
+
),
|
|
37292
37382
|
lastWorkerStderrTail: failedStderrTail
|
|
37293
37383
|
});
|
|
37294
37384
|
log({
|
|
@@ -38849,8 +38939,8 @@ var ACCEPTED_AGENT_CREDENTIAL_MESSAGES = [
|
|
|
38849
38939
|
AGENT_CREDENTIAL_MESSAGE_D088
|
|
38850
38940
|
];
|
|
38851
38941
|
function packageVersion() {
|
|
38852
|
-
if ("0.1.
|
|
38853
|
-
return "0.1.
|
|
38942
|
+
if ("0.1.39".length > 0) {
|
|
38943
|
+
return "0.1.39";
|
|
38854
38944
|
}
|
|
38855
38945
|
try {
|
|
38856
38946
|
const value = JSON.parse(
|
|
@@ -39449,7 +39539,7 @@ async function runNew(args) {
|
|
|
39449
39539
|
assertWorkspaceName(name);
|
|
39450
39540
|
const cloud = await target(args);
|
|
39451
39541
|
const human = await humanCredential(args, cloud);
|
|
39452
|
-
const proposedId = (0,
|
|
39542
|
+
const proposedId = (0, import_node_crypto20.randomUUID)();
|
|
39453
39543
|
let result;
|
|
39454
39544
|
try {
|
|
39455
39545
|
result = await new ThinCommandClient(cloud).sendConnect({
|
|
@@ -41637,6 +41727,11 @@ function renderListenerStatus(status) {
|
|
|
41637
41727
|
status.lastSignalId ? `Last handled signal: ${status.lastSignalId}.` : "No signal has been handled yet.",
|
|
41638
41728
|
status.lastErrorCode ? `Last status code: ${status.lastErrorCode}.` : "No listener error is recorded."
|
|
41639
41729
|
];
|
|
41730
|
+
if (status.lastErrorDetail) {
|
|
41731
|
+
const [first, ...rest] = status.lastErrorDetail.split("\n");
|
|
41732
|
+
lines.push(`Last error detail (local only): ${first}`);
|
|
41733
|
+
for (const line of rest) lines.push(` ${line}`);
|
|
41734
|
+
}
|
|
41640
41735
|
if (status.lastWorkerStderrTail) {
|
|
41641
41736
|
const tailLines = status.lastWorkerStderrTail.split("\n").filter((line) => line.trim().length > 0);
|
|
41642
41737
|
lines.push("Worker stderr (local log only):");
|
|
@@ -41766,6 +41861,9 @@ function listenerFailureMessage(code, provider) {
|
|
|
41766
41861
|
if (provider === "codex") {
|
|
41767
41862
|
return "the Codex bridge did not complete the read-only ACP permission canary; no workspace signal prompt was delivered. Confirm ChatGPT/Codex sign-in, then retry";
|
|
41768
41863
|
}
|
|
41864
|
+
if (provider === "grok") {
|
|
41865
|
+
return "the Grok bridge did not complete the ACP permission canary; no workspace signal prompt was delivered. The local cswarm listen status output includes the final error detail; read it, then retry";
|
|
41866
|
+
}
|
|
41769
41867
|
return "the host did not prove that CommonSwarm controls ACP tool permissions; no model prompt was delivered";
|
|
41770
41868
|
}
|
|
41771
41869
|
if (code === "process_exit") {
|
|
@@ -41918,13 +42016,14 @@ async function runConfiguredListener(options) {
|
|
|
41918
42016
|
lastWorkerStderrTail = tail.length > 0 ? tail : null;
|
|
41919
42017
|
};
|
|
41920
42018
|
};
|
|
41921
|
-
const newModel = () => {
|
|
42019
|
+
const newModel = (onCanaryAttempt) => {
|
|
41922
42020
|
providerVersionNotice = null;
|
|
41923
42021
|
return options.provider === "opencode" ? new OpenCodeListenerModel({
|
|
41924
42022
|
cwd: options.cwd,
|
|
41925
42023
|
permissionMode: options.permissionMode,
|
|
41926
42024
|
promptTimeoutMs: resolveTurnBudgetMs,
|
|
41927
42025
|
onWorkerStderrTail: newWorkerStderrTailSink(),
|
|
42026
|
+
onCanaryAttempt,
|
|
41928
42027
|
onVersionNotice,
|
|
41929
42028
|
...options.model ? { model: options.model } : {},
|
|
41930
42029
|
...options.opencodeExecutable ? { executable: options.opencodeExecutable } : options.executable ? { executable: options.executable } : {}
|
|
@@ -41933,6 +42032,7 @@ async function runConfiguredListener(options) {
|
|
|
41933
42032
|
permissionMode: options.permissionMode,
|
|
41934
42033
|
promptTimeoutMs: resolveTurnBudgetMs,
|
|
41935
42034
|
onWorkerStderrTail: newWorkerStderrTailSink(),
|
|
42035
|
+
onCanaryAttempt,
|
|
41936
42036
|
onVersionNotice,
|
|
41937
42037
|
...options.claudeExecutable ? { executable: options.claudeExecutable } : options.executable ? { executable: options.executable } : {}
|
|
41938
42038
|
}) : options.provider === "codex" ? new CodexListenerModel({
|
|
@@ -41940,6 +42040,7 @@ async function runConfiguredListener(options) {
|
|
|
41940
42040
|
permissionMode: options.permissionMode,
|
|
41941
42041
|
promptTimeoutMs: resolveTurnBudgetMs,
|
|
41942
42042
|
onWorkerStderrTail: newWorkerStderrTailSink(),
|
|
42043
|
+
onCanaryAttempt,
|
|
41943
42044
|
onVersionNotice,
|
|
41944
42045
|
...options.codexExecutable ? { executable: options.codexExecutable } : options.executable ? { executable: options.executable } : {}
|
|
41945
42046
|
}) : new GrokListenerModel({
|
|
@@ -41947,6 +42048,7 @@ async function runConfiguredListener(options) {
|
|
|
41947
42048
|
permissionMode: options.permissionMode,
|
|
41948
42049
|
promptTimeoutMs: resolveTurnBudgetMs,
|
|
41949
42050
|
onWorkerStderrTail: newWorkerStderrTailSink(),
|
|
42051
|
+
onCanaryAttempt,
|
|
41950
42052
|
onVersionNotice,
|
|
41951
42053
|
...options.model ? { model: options.model } : {},
|
|
41952
42054
|
...options.effort ? { effort: options.effort } : {},
|
|
@@ -42000,13 +42102,23 @@ async function runConfiguredListener(options) {
|
|
|
42000
42102
|
"listener delivery journal was not selected for this instance"
|
|
42001
42103
|
);
|
|
42002
42104
|
}
|
|
42105
|
+
const onCanaryAttempt = (attempt, total, result) => {
|
|
42106
|
+
onEvent({
|
|
42107
|
+
type: "canary_attempt",
|
|
42108
|
+
attempt,
|
|
42109
|
+
total,
|
|
42110
|
+
passed: result.passed,
|
|
42111
|
+
reason: result.reason ?? null,
|
|
42112
|
+
ts: (/* @__PURE__ */ new Date()).toISOString()
|
|
42113
|
+
});
|
|
42114
|
+
};
|
|
42003
42115
|
return await runListenerRuntime({
|
|
42004
42116
|
target: options.cloud,
|
|
42005
42117
|
workspaceId: options.workspaceId,
|
|
42006
42118
|
principalId: options.principalId,
|
|
42007
42119
|
credentialSession,
|
|
42008
42120
|
store: effectStore,
|
|
42009
|
-
model: newModel(),
|
|
42121
|
+
model: newModel(onCanaryAttempt),
|
|
42010
42122
|
signal,
|
|
42011
42123
|
onEvent,
|
|
42012
42124
|
declareModel: listenerModelLabel(options.provider),
|
|
@@ -42541,8 +42653,8 @@ async function runFilePut(args) {
|
|
|
42541
42653
|
workspaceId: context.selected.selectedWorkspace,
|
|
42542
42654
|
credential: context.selected.bearer
|
|
42543
42655
|
};
|
|
42544
|
-
const fileId = (0,
|
|
42545
|
-
const versionId = (0,
|
|
42656
|
+
const fileId = (0, import_node_crypto20.randomUUID)();
|
|
42657
|
+
const versionId = (0, import_node_crypto20.randomUUID)();
|
|
42546
42658
|
const createCommandId = newCommandId();
|
|
42547
42659
|
const commitCommandId = newCommandId();
|
|
42548
42660
|
const created = await onceRetried(
|
|
@@ -42779,7 +42891,7 @@ async function runDogfood(args) {
|
|
|
42779
42891
|
const { selectedWorkspace, bearer } = await commandWorkspaceAndCredential(args, cloud);
|
|
42780
42892
|
const client = new ThinCommandClient(cloud);
|
|
42781
42893
|
const route = stream(args);
|
|
42782
|
-
const taskId = args.optional("task-id") ?? (0,
|
|
42894
|
+
const taskId = args.optional("task-id") ?? (0, import_node_crypto20.randomUUID)();
|
|
42783
42895
|
const ttl = Number(args.optional("ttl-ms") ?? "3600000");
|
|
42784
42896
|
if (!Number.isSafeInteger(ttl) || ttl <= 0 || ttl > 144e5) {
|
|
42785
42897
|
throw new Error("--ttl-ms must be an integer in 1..14400000");
|