commonswarm 0.1.34 → 0.1.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/cswarm.cjs +464 -179
  2. package/package.json +1 -1
package/cswarm.cjs CHANGED
@@ -4381,8 +4381,8 @@ var require_RealtimeChannel = __commonJS({
4381
4381
  }
4382
4382
  /** @internal */
4383
4383
  _notThisChannelEvent(event, ref) {
4384
- const { close, error, leave, join: join17 } = constants_1.CHANNEL_EVENTS;
4385
- const events = [close, error, leave, join17];
4384
+ const { close, error, leave, join: join18 } = constants_1.CHANNEL_EVENTS;
4385
+ const events = [close, error, leave, join18];
4386
4386
  return ref && events.includes(event) && ref !== this.joinPush.ref;
4387
4387
  }
4388
4388
  /** @internal */
@@ -13523,7 +13523,7 @@ module.exports = __toCommonJS(cli_exports);
13523
13523
  var import_node_crypto19 = require("node:crypto");
13524
13524
  var import_node_fs7 = require("node:fs");
13525
13525
  var import_promises11 = require("node:fs/promises");
13526
- var import_node_path19 = require("node:path");
13526
+ var import_node_path20 = require("node:path");
13527
13527
  var import_promises12 = require("node:readline/promises");
13528
13528
 
13529
13529
  // src/cloud/auth.ts
@@ -29571,8 +29571,195 @@ async function runInboxFollow(options) {
29571
29571
  }
29572
29572
  }
29573
29573
 
29574
- // src/cloud/delivery-receipts.ts
29574
+ // src/cloud/arrival-watch.ts
29575
+ var import_node_os4 = require("node:os");
29576
+ var import_node_path4 = require("node:path");
29575
29577
  var UUID_RE8 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
29578
+ var CURSOR_MAX_BYTES = 4 * 1024;
29579
+ var ARRIVAL_SNIPPET_MAX = 180;
29580
+ var ARRIVAL_WATCH_POLL_MS = 25e3;
29581
+ function stateRoot() {
29582
+ return process.env.XDG_STATE_HOME ? (0, import_node_path4.join)(process.env.XDG_STATE_HOME, "cswarm", "arrival-cursors") : (0, import_node_path4.join)((0, import_node_os4.homedir)(), ".cswarm", "arrival-cursors");
29583
+ }
29584
+ function arrivalCursorPath(target2, workspaceId2, principalId, root = stateRoot()) {
29585
+ return (0, import_node_path4.join)(
29586
+ root,
29587
+ `${target2.profileId}-${workspaceId2.toLowerCase()}-${principalId.toLowerCase()}.json`
29588
+ );
29589
+ }
29590
+ function parseCursor(raw, workspaceId2, principalId) {
29591
+ let value;
29592
+ try {
29593
+ value = JSON.parse(raw);
29594
+ } catch {
29595
+ throw new Error("stored arrival cursor is malformed");
29596
+ }
29597
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
29598
+ throw new Error("stored arrival cursor is malformed");
29599
+ }
29600
+ const row = value;
29601
+ const keys = Object.keys(row).sort();
29602
+ const cursor = row.cursor;
29603
+ if (keys.join(",") !== "cursor,principal_id,version,workspace_id" || row.version !== 1 || row.workspace_id !== workspaceId2.toLowerCase() || row.principal_id !== principalId.toLowerCase() || !(cursor === null || typeof cursor === "object" && !Array.isArray(cursor) && Object.keys(cursor).sort().join(",") === "created_at,id" && typeof cursor.created_at === "string" && Number.isFinite(Date.parse(cursor.created_at)) && typeof cursor.id === "string" && UUID_RE8.test(cursor.id))) {
29604
+ throw new Error("stored arrival cursor is malformed");
29605
+ }
29606
+ if (cursor === null) return null;
29607
+ return {
29608
+ created_at: cursor.created_at,
29609
+ id: cursor.id.toLowerCase()
29610
+ };
29611
+ }
29612
+ function fileArrivalCursorStore(options) {
29613
+ const workspaceId2 = options.workspaceId.toLowerCase();
29614
+ const principalId = options.principalId.toLowerCase();
29615
+ if (!UUID_RE8.test(workspaceId2) || !UUID_RE8.test(principalId)) {
29616
+ throw new Error("arrival cursor identity must use workspace and principal UUIDs");
29617
+ }
29618
+ const location2 = arrivalCursorPath(
29619
+ options.target,
29620
+ workspaceId2,
29621
+ principalId,
29622
+ options.stateDirectory
29623
+ );
29624
+ return {
29625
+ location: location2,
29626
+ async read() {
29627
+ const raw = await readSecureJsonFile(location2, CURSOR_MAX_BYTES);
29628
+ return raw === null ? void 0 : parseCursor(raw, workspaceId2, principalId);
29629
+ },
29630
+ async write(cursor) {
29631
+ const record = {
29632
+ version: 1,
29633
+ workspace_id: workspaceId2,
29634
+ principal_id: principalId,
29635
+ cursor
29636
+ };
29637
+ await writeSecureJsonFile(location2, JSON.stringify(record));
29638
+ }
29639
+ };
29640
+ }
29641
+ function arrivalSnippet(body) {
29642
+ const oneLine = body.replace(/[\u0000-\u001f\u007f-\u009f]/g, " ").replace(/\s+/g, " ").trim();
29643
+ if (oneLine.length <= ARRIVAL_SNIPPET_MAX) return oneLine;
29644
+ return `${oneLine.slice(0, ARRIVAL_SNIPPET_MAX - 1).trimEnd()}\u2026`;
29645
+ }
29646
+ function arrivalReplyCommand(signalId, workspaceId2, target2) {
29647
+ return `cswarm reply ${signalId} "<answer>" --agent-token-stdin --url ${target2.url} --anon-key ${target2.anonKey} --workspace-id ${workspaceId2}`;
29648
+ }
29649
+ function arrivalNotification(signal, workspaceId2, target2) {
29650
+ return {
29651
+ type: "arrival",
29652
+ workspace_id: workspaceId2,
29653
+ signal_id: signal.id,
29654
+ sender: signal.from,
29655
+ sender_kind: signal.from_kind,
29656
+ kind: signal.kind,
29657
+ snippet: arrivalSnippet(signal.body),
29658
+ reply_command: arrivalReplyCommand(signal.id, workspaceId2, target2)
29659
+ };
29660
+ }
29661
+ function formatArrivalNotification(notification) {
29662
+ return `CommonSwarm from ${notification.sender_kind} ${notification.sender}: ${notification.snippet} \u2014 reply: ${notification.reply_command}`;
29663
+ }
29664
+ function cursorOf(signal) {
29665
+ return { created_at: signal.created_at, id: signal.id };
29666
+ }
29667
+ function assertCursorPage(page) {
29668
+ if (!page.capabilities.cursorAfter || page.legacyCursorFallback) {
29669
+ throw new Error(
29670
+ "arrival watch needs a read service with durable cursor support"
29671
+ );
29672
+ }
29673
+ }
29674
+ async function runArrivalWatch(options) {
29675
+ const pollMs = options.pollMs ?? ARRIVAL_WATCH_POLL_MS;
29676
+ const random = options.random ?? Math.random;
29677
+ let cursor = await options.store.read();
29678
+ let baseline = cursor === void 0;
29679
+ let attempt = 0;
29680
+ const cancelled = () => options.signal?.aborted === true;
29681
+ const wait = async (ms) => {
29682
+ if (options.sleep) {
29683
+ await options.sleep(ms);
29684
+ return;
29685
+ }
29686
+ await new Promise((resolve) => {
29687
+ let timer2;
29688
+ const finish = () => {
29689
+ if (timer2 !== void 0) clearTimeout(timer2);
29690
+ options.signal?.removeEventListener("abort", finish);
29691
+ resolve();
29692
+ };
29693
+ if (cancelled() || ms <= 0) {
29694
+ resolve();
29695
+ return;
29696
+ }
29697
+ options.signal?.addEventListener("abort", finish, { once: true });
29698
+ timer2 = setTimeout(finish, ms);
29699
+ });
29700
+ };
29701
+ while (!cancelled()) {
29702
+ try {
29703
+ const page = await options.readPage({
29704
+ after: cursor ?? null,
29705
+ baseline,
29706
+ limit: baseline ? 1 : SIGNAL_FOLLOW_PAGE_LIMIT
29707
+ });
29708
+ assertCursorPage(page);
29709
+ if (page.signals.some(
29710
+ (row) => row.workspace_id !== options.workspaceId || row.to_agent !== options.principalId
29711
+ )) {
29712
+ throw new Error(
29713
+ "arrival read returned a message directed to another workspace or agent"
29714
+ );
29715
+ }
29716
+ attempt = 0;
29717
+ if (baseline) {
29718
+ if (page.rawCount > 0 && page.nextCursor === null) {
29719
+ throw new Error("arrival baseline returned no safe terminal cursor");
29720
+ }
29721
+ cursor = page.nextCursor;
29722
+ await options.store.write(cursor);
29723
+ baseline = false;
29724
+ if (cancelled()) break;
29725
+ await wait(pollMs);
29726
+ continue;
29727
+ }
29728
+ for (const row of page.signals) {
29729
+ if (cancelled()) break;
29730
+ await options.emit(row);
29731
+ cursor = cursorOf(row);
29732
+ await options.store.write(cursor);
29733
+ }
29734
+ if (cancelled()) break;
29735
+ const fullPage = page.rawCount >= SIGNAL_FOLLOW_PAGE_LIMIT;
29736
+ await wait(fullPage ? 0 : pollMs);
29737
+ } catch (error) {
29738
+ if (cancelled()) break;
29739
+ const http = followHttpDetails(error);
29740
+ const retryable = isRetryableFollowError(error) || http?.status === 429 || http !== null && http.status >= 500;
29741
+ if (!retryable) {
29742
+ return {
29743
+ reason: "error",
29744
+ error: error instanceof Error ? error : new Error(String(error))
29745
+ };
29746
+ }
29747
+ attempt += 1;
29748
+ const delayMs = nextFollowBackoffMs(
29749
+ attempt,
29750
+ http?.retryAfterMs ?? null,
29751
+ random
29752
+ );
29753
+ const typed = error instanceof Error ? error : new Error(String(error));
29754
+ options.onRetry?.(typed, delayMs);
29755
+ await wait(delayMs);
29756
+ }
29757
+ }
29758
+ return { reason: "cancelled" };
29759
+ }
29760
+
29761
+ // src/cloud/delivery-receipts.ts
29762
+ var UUID_RE9 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
29576
29763
  var DeliveryReceiptReadError = class extends Error {
29577
29764
  constructor(code, message, status = null) {
29578
29765
  super(message);
@@ -29591,7 +29778,7 @@ var ACK_OUTCOMES = /* @__PURE__ */ new Set([
29591
29778
  "failed_terminal"
29592
29779
  ]);
29593
29780
  function uuid3(value, field) {
29594
- if (typeof value !== "string" || !UUID_RE8.test(value)) {
29781
+ if (typeof value !== "string" || !UUID_RE9.test(value)) {
29595
29782
  throw new DeliveryReceiptReadError(
29596
29783
  "protocol",
29597
29784
  `delivery receipt returned a malformed ${field}`
@@ -29980,8 +30167,8 @@ function attachStderrTailExitObserver(child, onStderrTail) {
29980
30167
  // src/host/opencode.ts
29981
30168
  var import_node_fs3 = require("node:fs");
29982
30169
  var import_promises4 = require("node:fs/promises");
29983
- var import_node_os4 = require("node:os");
29984
- var import_node_path5 = require("node:path");
30170
+ var import_node_os5 = require("node:os");
30171
+ var import_node_path6 = require("node:path");
29985
30172
 
29986
30173
  // src/host/bounds.ts
29987
30174
  var ACP_MAX_LINE_BYTES = 1048576;
@@ -30063,7 +30250,7 @@ function sanitizeChildEnv(parent = process.env) {
30063
30250
 
30064
30251
  // src/host/session.ts
30065
30252
  var import_node_fs2 = require("node:fs");
30066
- var import_node_path4 = require("node:path");
30253
+ var import_node_path5 = require("node:path");
30067
30254
 
30068
30255
  // src/host/permission.ts
30069
30256
  function allowOnceOrDeny(request) {
@@ -30544,7 +30731,7 @@ function assertAbsoluteExistingCwd(cwd) {
30544
30731
  if (!cwd || typeof cwd !== "string") {
30545
30732
  throw new AcpProtocolError("cwd is required", "invalid_cwd");
30546
30733
  }
30547
- if (!(0, import_node_path4.isAbsolute)(cwd)) {
30734
+ if (!(0, import_node_path5.isAbsolute)(cwd)) {
30548
30735
  throw new AcpProtocolError("cwd must be an absolute path", "invalid_cwd");
30549
30736
  }
30550
30737
  let st;
@@ -31254,8 +31441,8 @@ function isProcessAlive(pid) {
31254
31441
  }
31255
31442
  }
31256
31443
  function resolveOpenCodeExecutable(executable = "opencode", pathEnv) {
31257
- if ((0, import_node_path5.isAbsolute)(executable) || executable.includes("/")) {
31258
- const abs = (0, import_node_path5.resolve)(executable);
31444
+ if ((0, import_node_path6.isAbsolute)(executable) || executable.includes("/")) {
31445
+ const abs = (0, import_node_path6.resolve)(executable);
31259
31446
  try {
31260
31447
  (0, import_node_fs3.accessSync)(abs, import_node_fs3.constants.X_OK);
31261
31448
  } catch {
@@ -31273,7 +31460,7 @@ function resolveOpenCodeExecutable(executable = "opencode", pathEnv) {
31273
31460
  const pathValue = pathEnv ?? process.env.PATH ?? "";
31274
31461
  for (const dir of pathValue.split(":")) {
31275
31462
  if (!dir) continue;
31276
- const candidate = (0, import_node_path5.join)(dir, executable);
31463
+ const candidate = (0, import_node_path6.join)(dir, executable);
31277
31464
  try {
31278
31465
  (0, import_node_fs3.accessSync)(candidate, import_node_fs3.constants.X_OK);
31279
31466
  try {
@@ -31305,7 +31492,7 @@ function buildOpenCodeHomeOwner(options) {
31305
31492
  };
31306
31493
  }
31307
31494
  async function writeOpenCodeHomeOwner(home, owner) {
31308
- const path = (0, import_node_path5.join)(home, OPENCODE_HOME_OWNER_FILE);
31495
+ const path = (0, import_node_path6.join)(home, OPENCODE_HOME_OWNER_FILE);
31309
31496
  await (0, import_promises4.writeFile)(path, `${JSON.stringify(owner)}
31310
31497
  `, {
31311
31498
  flag: "wx",
@@ -31314,7 +31501,7 @@ async function writeOpenCodeHomeOwner(home, owner) {
31314
31501
  await (0, import_promises4.chmod)(path, 384);
31315
31502
  }
31316
31503
  async function readOpenCodeHomeOwner(home) {
31317
- const path = (0, import_node_path5.join)(home, OPENCODE_HOME_OWNER_FILE);
31504
+ const path = (0, import_node_path6.join)(home, OPENCODE_HOME_OWNER_FILE);
31318
31505
  let raw;
31319
31506
  try {
31320
31507
  raw = await (0, import_promises4.readFile)(path, "utf8");
@@ -31332,7 +31519,7 @@ async function readOpenCodeHomeOwner(home) {
31332
31519
  }
31333
31520
  }
31334
31521
  async function releaseOpenCodeHome(home, instanceId) {
31335
- if (!(0, import_node_path5.isAbsolute)(home)) return;
31522
+ if (!(0, import_node_path6.isAbsolute)(home)) return;
31336
31523
  const owner = await readOpenCodeHomeOwner(home);
31337
31524
  if (owner && owner.instanceId !== instanceId) {
31338
31525
  return;
@@ -31457,15 +31644,15 @@ async function readValidatedOpenCodeAuth(sourceAuthPath, options) {
31457
31644
  }
31458
31645
  function resolveOpenCodeAuthSourcePath(parent = process.env) {
31459
31646
  const xdgData = parent.XDG_DATA_HOME;
31460
- if (typeof xdgData === "string" && (0, import_node_path5.isAbsolute)(xdgData)) {
31461
- return (0, import_node_path5.join)(xdgData, "opencode", "auth.json");
31647
+ if (typeof xdgData === "string" && (0, import_node_path6.isAbsolute)(xdgData)) {
31648
+ return (0, import_node_path6.join)(xdgData, "opencode", "auth.json");
31462
31649
  }
31463
- const home = parent.HOME ?? (0, import_node_os4.homedir)();
31464
- return (0, import_node_path5.join)(home, ".local", "share", "opencode", "auth.json");
31650
+ const home = parent.HOME ?? (0, import_node_os5.homedir)();
31651
+ return (0, import_node_path6.join)(home, ".local", "share", "opencode", "auth.json");
31465
31652
  }
31466
31653
  async function prepareOpenCodeIsolatedHome(options) {
31467
- const home = options.home ?? await (0, import_promises4.mkdtemp)((0, import_node_path5.join)((0, import_node_os4.tmpdir)(), OPENCODE_HOME_PREFIX));
31468
- if (!(0, import_node_path5.isAbsolute)(home)) {
31654
+ const home = options.home ?? await (0, import_promises4.mkdtemp)((0, import_node_path6.join)((0, import_node_os5.tmpdir)(), OPENCODE_HOME_PREFIX));
31655
+ if (!(0, import_node_path6.isAbsolute)(home)) {
31469
31656
  throw new AcpHostError(
31470
31657
  "isolated_home_invalid",
31471
31658
  "isolated OpenCode home must be absolute"
@@ -31473,21 +31660,21 @@ async function prepareOpenCodeIsolatedHome(options) {
31473
31660
  }
31474
31661
  await (0, import_promises4.chmod)(home, 448);
31475
31662
  try {
31476
- const xdgConfig = (0, import_node_path5.join)(home, "xdg-config");
31477
- const xdgData = (0, import_node_path5.join)(home, "xdg-data");
31478
- const xdgCache = (0, import_node_path5.join)(home, "xdg-cache");
31479
- const xdgState = (0, import_node_path5.join)(home, "xdg-state");
31663
+ const xdgConfig = (0, import_node_path6.join)(home, "xdg-config");
31664
+ const xdgData = (0, import_node_path6.join)(home, "xdg-data");
31665
+ const xdgCache = (0, import_node_path6.join)(home, "xdg-cache");
31666
+ const xdgState = (0, import_node_path6.join)(home, "xdg-state");
31480
31667
  for (const dir of [xdgConfig, xdgData, xdgCache, xdgState]) {
31481
31668
  await (0, import_promises4.mkdir)(dir, { recursive: true, mode: 448 });
31482
31669
  await (0, import_promises4.chmod)(dir, 448);
31483
31670
  }
31484
- const configDir = (0, import_node_path5.join)(xdgConfig, "opencode");
31485
- const dataDir = (0, import_node_path5.join)(xdgData, "opencode");
31671
+ const configDir = (0, import_node_path6.join)(xdgConfig, "opencode");
31672
+ const dataDir = (0, import_node_path6.join)(xdgData, "opencode");
31486
31673
  await (0, import_promises4.mkdir)(configDir, { recursive: true, mode: 448 });
31487
31674
  await (0, import_promises4.mkdir)(dataDir, { recursive: true, mode: 448 });
31488
31675
  await (0, import_promises4.chmod)(configDir, 448);
31489
31676
  await (0, import_promises4.chmod)(dataDir, 448);
31490
- const configPath = (0, import_node_path5.join)(configDir, "opencode.json");
31677
+ const configPath = (0, import_node_path6.join)(configDir, "opencode.json");
31491
31678
  await (0, import_promises4.writeFile)(
31492
31679
  configPath,
31493
31680
  buildOpenCodeSafeConfigJson(
@@ -31501,7 +31688,7 @@ async function prepareOpenCodeIsolatedHome(options) {
31501
31688
  allowMissing: options.allowMissingAuth === true
31502
31689
  });
31503
31690
  if (authBytes) {
31504
- const destAuth = (0, import_node_path5.join)(dataDir, "auth.json");
31691
+ const destAuth = (0, import_node_path6.join)(dataDir, "auth.json");
31505
31692
  await (0, import_promises4.writeFile)(destAuth, authBytes, { flag: "wx", mode: 384 });
31506
31693
  await (0, import_promises4.chmod)(destAuth, 384);
31507
31694
  }
@@ -31516,7 +31703,7 @@ async function prepareOpenCodeIsolatedHome(options) {
31516
31703
  }
31517
31704
  }
31518
31705
  function buildOpenCodeChildEnv(parent, home) {
31519
- if (!(0, import_node_path5.isAbsolute)(home)) {
31706
+ if (!(0, import_node_path6.isAbsolute)(home)) {
31520
31707
  throw new AcpHostError(
31521
31708
  "isolated_home_invalid",
31522
31709
  "isolated OpenCode home must be absolute"
@@ -31526,20 +31713,20 @@ function buildOpenCodeChildEnv(parent, home) {
31526
31713
  return {
31527
31714
  ...base,
31528
31715
  HOME: home,
31529
- XDG_CONFIG_HOME: (0, import_node_path5.join)(home, "xdg-config"),
31530
- XDG_DATA_HOME: (0, import_node_path5.join)(home, "xdg-data"),
31531
- XDG_CACHE_HOME: (0, import_node_path5.join)(home, "xdg-cache"),
31532
- XDG_STATE_HOME: (0, import_node_path5.join)(home, "xdg-state"),
31716
+ XDG_CONFIG_HOME: (0, import_node_path6.join)(home, "xdg-config"),
31717
+ XDG_DATA_HOME: (0, import_node_path6.join)(home, "xdg-data"),
31718
+ XDG_CACHE_HOME: (0, import_node_path6.join)(home, "xdg-cache"),
31719
+ XDG_STATE_HOME: (0, import_node_path6.join)(home, "xdg-state"),
31533
31720
  // Measured 1.18.10: private home alone still merges project opencode.json.
31534
31721
  OPENCODE_DISABLE_PROJECT_CONFIG: "1"
31535
31722
  };
31536
31723
  }
31537
31724
  async function assertOpenCodeEffectiveConfig(options) {
31538
- const hostile = await (0, import_promises4.mkdtemp)((0, import_node_path5.join)((0, import_node_os4.tmpdir)(), "cswarm-opencode-hostile-"));
31725
+ const hostile = await (0, import_promises4.mkdtemp)((0, import_node_path6.join)((0, import_node_os5.tmpdir)(), "cswarm-opencode-hostile-"));
31539
31726
  try {
31540
31727
  await (0, import_promises4.chmod)(hostile, 448);
31541
31728
  await (0, import_promises4.writeFile)(
31542
- (0, import_node_path5.join)(hostile, "opencode.json"),
31729
+ (0, import_node_path6.join)(hostile, "opencode.json"),
31543
31730
  `${JSON.stringify({
31544
31731
  permission: {
31545
31732
  bash: "allow",
@@ -31647,7 +31834,7 @@ async function sweepStaleOpenCodeHomes(options) {
31647
31834
  const maxAgeMs = options?.maxAgeMs ?? STALE_HOME_MAX_AGE_MS;
31648
31835
  const now = options?.now ?? Date.now();
31649
31836
  const alive = options?.isAlive ?? isProcessAlive;
31650
- const root = options?.root ?? (0, import_node_os4.tmpdir)();
31837
+ const root = options?.root ?? (0, import_node_os5.tmpdir)();
31651
31838
  const selfUid = typeof process.getuid === "function" ? process.getuid() : null;
31652
31839
  let removed = 0;
31653
31840
  let entries;
@@ -31658,7 +31845,7 @@ async function sweepStaleOpenCodeHomes(options) {
31658
31845
  }
31659
31846
  for (const name of entries) {
31660
31847
  if (!name.startsWith(OPENCODE_HOME_PREFIX)) continue;
31661
- const full = (0, import_node_path5.join)(root, name);
31848
+ const full = (0, import_node_path6.join)(root, name);
31662
31849
  try {
31663
31850
  const st = await (0, import_promises4.lstat)(full);
31664
31851
  if (!st.isDirectory() || st.isSymbolicLink()) continue;
@@ -31836,7 +32023,7 @@ async function openOpenCodeAcpSession(options) {
31836
32023
  // src/host/claude.ts
31837
32024
  var import_node_child_process4 = require("node:child_process");
31838
32025
  var import_node_fs4 = require("node:fs");
31839
- var import_node_path6 = require("node:path");
32026
+ var import_node_path7 = require("node:path");
31840
32027
  var CHILD_EXIT_WAIT_MS2 = 3e3;
31841
32028
  var CHILD_KILL_WAIT_MS2 = 1e3;
31842
32029
  var WINDOWS_NPM_SHIM_MAX_BYTES = 64 * 1024;
@@ -31856,11 +32043,11 @@ function isPackagedClaudeBridge(executable) {
31856
32043
  function resolvePackagedClaudeBridge(pathEnv, platform = process.platform) {
31857
32044
  const pathValue = pathEnv ?? process.env.PATH ?? "";
31858
32045
  const names = platform === "win32" ? ["claude-agent-acp.cmd"] : ["claude-agent-acp"];
31859
- for (const dir of pathValue.split(import_node_path6.delimiter)) {
32046
+ for (const dir of pathValue.split(import_node_path7.delimiter)) {
31860
32047
  if (!dir) continue;
31861
32048
  for (const name of names) {
31862
32049
  try {
31863
- const candidate = resolvedClaudeCandidate((0, import_node_path6.join)(dir, name), platform);
32050
+ const candidate = resolvedClaudeCandidate((0, import_node_path7.join)(dir, name), platform);
31864
32051
  if (isPackagedClaudeBridge(candidate)) return candidate;
31865
32052
  } catch {
31866
32053
  }
@@ -31889,7 +32076,7 @@ function resolveWindowsNpmShim(shim) {
31889
32076
  `unrecognized claude-agent-acp npm shim: ${shim}`
31890
32077
  );
31891
32078
  }
31892
- const target2 = (0, import_node_path6.join)((0, import_node_path6.dirname)(shim), ...WINDOWS_NPM_ENTRYPOINT);
32079
+ const target2 = (0, import_node_path7.join)((0, import_node_path7.dirname)(shim), ...WINDOWS_NPM_ENTRYPOINT);
31893
32080
  try {
31894
32081
  (0, import_node_fs4.accessSync)(target2, import_node_fs4.constants.R_OK);
31895
32082
  return (0, import_node_fs4.realpathSync)(target2);
@@ -31903,12 +32090,12 @@ function resolveWindowsNpmShim(shim) {
31903
32090
  function resolvedClaudeCandidate(candidate, platform) {
31904
32091
  (0, import_node_fs4.accessSync)(candidate, import_node_fs4.constants.X_OK);
31905
32092
  const real = (0, import_node_fs4.realpathSync)(candidate);
31906
- return platform === "win32" && (0, import_node_path6.extname)(real).toLowerCase() === ".cmd" ? resolveWindowsNpmShim(real) : real;
32093
+ return platform === "win32" && (0, import_node_path7.extname)(real).toLowerCase() === ".cmd" ? resolveWindowsNpmShim(real) : real;
31907
32094
  }
31908
32095
  function resolveClaudeExecutable(executable = "claude-agent-acp", pathEnv, platform = process.platform) {
31909
- if ((0, import_node_path6.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
31910
- const abs = (0, import_node_path6.resolve)(executable);
31911
- const candidates = platform === "win32" && (0, import_node_path6.extname)(abs) === "" ? [`${abs}.cmd`] : [abs];
32096
+ if ((0, import_node_path7.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
32097
+ const abs = (0, import_node_path7.resolve)(executable);
32098
+ const candidates = platform === "win32" && (0, import_node_path7.extname)(abs) === "" ? [`${abs}.cmd`] : [abs];
31912
32099
  for (const candidate of candidates) {
31913
32100
  try {
31914
32101
  return resolvedClaudeCandidate(candidate, platform);
@@ -31919,11 +32106,11 @@ function resolveClaudeExecutable(executable = "claude-agent-acp", pathEnv, platf
31919
32106
  throw new AcpHostError("executable_missing", `not executable: ${abs}`);
31920
32107
  }
31921
32108
  const pathValue = pathEnv ?? process.env.PATH ?? "";
31922
- const names = platform === "win32" && (0, import_node_path6.extname)(executable) === "" ? [`${executable}.cmd`] : [executable];
31923
- for (const dir of pathValue.split(import_node_path6.delimiter)) {
32109
+ const names = platform === "win32" && (0, import_node_path7.extname)(executable) === "" ? [`${executable}.cmd`] : [executable];
32110
+ for (const dir of pathValue.split(import_node_path7.delimiter)) {
31924
32111
  if (!dir) continue;
31925
32112
  for (const name of names) {
31926
- const candidate = (0, import_node_path6.join)(dir, name);
32113
+ const candidate = (0, import_node_path7.join)(dir, name);
31927
32114
  try {
31928
32115
  return resolvedClaudeCandidate(candidate, platform);
31929
32116
  } catch (error) {
@@ -31937,7 +32124,7 @@ function resolveClaudeExecutable(executable = "claude-agent-acp", pathEnv, platf
31937
32124
  );
31938
32125
  }
31939
32126
  function buildClaudeLaunch(executable, args, platform = process.platform) {
31940
- return platform === "win32" && (0, import_node_path6.extname)(executable).toLowerCase() === ".js" ? { command: process.execPath, args: [executable, ...args] } : { command: executable, args: [...args] };
32127
+ return platform === "win32" && (0, import_node_path7.extname)(executable).toLowerCase() === ".js" ? { command: process.execPath, args: [executable, ...args] } : { command: executable, args: [...args] };
31941
32128
  }
31942
32129
  function parseClaudeVersionOutput(stdout) {
31943
32130
  return parseProviderVersionOutput(stdout, /\bclaude-agent-acp\b/i);
@@ -32190,7 +32377,7 @@ async function openClaudeAcpSession(options) {
32190
32377
  // src/host/codex.ts
32191
32378
  var import_node_child_process5 = require("node:child_process");
32192
32379
  var import_node_fs5 = require("node:fs");
32193
- var import_node_path7 = require("node:path");
32380
+ var import_node_path8 = require("node:path");
32194
32381
  var CHILD_EXIT_WAIT_MS3 = 3e3;
32195
32382
  var CHILD_KILL_WAIT_MS3 = 1e3;
32196
32383
  var WINDOWS_NPM_SHIM_MAX_BYTES2 = 64 * 1024;
@@ -32219,7 +32406,7 @@ function resolveWindowsNpmShim2(shim) {
32219
32406
  `unrecognized codex-acp npm shim: ${shim}`
32220
32407
  );
32221
32408
  }
32222
- const target2 = (0, import_node_path7.join)((0, import_node_path7.dirname)(shim), ...WINDOWS_NPM_ENTRYPOINT2);
32409
+ const target2 = (0, import_node_path8.join)((0, import_node_path8.dirname)(shim), ...WINDOWS_NPM_ENTRYPOINT2);
32223
32410
  try {
32224
32411
  (0, import_node_fs5.accessSync)(target2, import_node_fs5.constants.R_OK);
32225
32412
  return (0, import_node_fs5.realpathSync)(target2);
@@ -32233,12 +32420,12 @@ function resolveWindowsNpmShim2(shim) {
32233
32420
  function resolvedCodexCandidate(candidate, platform) {
32234
32421
  (0, import_node_fs5.accessSync)(candidate, import_node_fs5.constants.X_OK);
32235
32422
  const real = (0, import_node_fs5.realpathSync)(candidate);
32236
- return platform === "win32" && (0, import_node_path7.extname)(real).toLowerCase() === ".cmd" ? resolveWindowsNpmShim2(real) : real;
32423
+ return platform === "win32" && (0, import_node_path8.extname)(real).toLowerCase() === ".cmd" ? resolveWindowsNpmShim2(real) : real;
32237
32424
  }
32238
32425
  function resolveCodexExecutable(executable = "codex-acp", pathEnv, platform = process.platform) {
32239
- if ((0, import_node_path7.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
32240
- const abs = (0, import_node_path7.resolve)(executable);
32241
- const candidates = platform === "win32" && (0, import_node_path7.extname)(abs) === "" ? [`${abs}.cmd`] : [abs];
32426
+ if ((0, import_node_path8.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
32427
+ const abs = (0, import_node_path8.resolve)(executable);
32428
+ const candidates = platform === "win32" && (0, import_node_path8.extname)(abs) === "" ? [`${abs}.cmd`] : [abs];
32242
32429
  for (const candidate of candidates) {
32243
32430
  try {
32244
32431
  return resolvedCodexCandidate(candidate, platform);
@@ -32249,11 +32436,11 @@ function resolveCodexExecutable(executable = "codex-acp", pathEnv, platform = pr
32249
32436
  throw new AcpHostError("executable_missing", `not executable: ${abs}`);
32250
32437
  }
32251
32438
  const pathValue = pathEnv ?? process.env.PATH ?? "";
32252
- const names = platform === "win32" && (0, import_node_path7.extname)(executable) === "" ? [`${executable}.cmd`] : [executable];
32253
- for (const dir of pathValue.split(import_node_path7.delimiter)) {
32439
+ const names = platform === "win32" && (0, import_node_path8.extname)(executable) === "" ? [`${executable}.cmd`] : [executable];
32440
+ for (const dir of pathValue.split(import_node_path8.delimiter)) {
32254
32441
  if (!dir) continue;
32255
32442
  for (const name of names) {
32256
- const candidate = (0, import_node_path7.join)(dir, name);
32443
+ const candidate = (0, import_node_path8.join)(dir, name);
32257
32444
  try {
32258
32445
  return resolvedCodexCandidate(candidate, platform);
32259
32446
  } catch (error) {
@@ -32267,7 +32454,7 @@ function resolveCodexExecutable(executable = "codex-acp", pathEnv, platform = pr
32267
32454
  );
32268
32455
  }
32269
32456
  function buildCodexLaunch(executable, args, platform = process.platform) {
32270
- return platform === "win32" && (0, import_node_path7.extname)(executable).toLowerCase() === ".js" ? { command: process.execPath, args: [executable, ...args] } : { command: executable, args: [...args] };
32457
+ return platform === "win32" && (0, import_node_path8.extname)(executable).toLowerCase() === ".js" ? { command: process.execPath, args: [executable, ...args] } : { command: executable, args: [...args] };
32271
32458
  }
32272
32459
  function parseCodexVersionOutput(stdout) {
32273
32460
  return parseProviderVersionOutput(stdout, /@agentclientprotocol\/codex-acp\b/i);
@@ -32481,7 +32668,7 @@ async function resolveBudgetAndPrompt(session, prompt, budget) {
32481
32668
  }
32482
32669
 
32483
32670
  // src/listener/engine.ts
32484
- var UUID_RE9 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
32671
+ var UUID_RE10 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
32485
32672
  var TERMINAL_STATES = /* @__PURE__ */ new Set(["done", "expired", "failed"]);
32486
32673
  var REPLY_MAX_CODE_UNITS = 2e3;
32487
32674
  var TRUNCATION_SUFFIX = "\n[Reply truncated by CommonSwarm]";
@@ -32489,7 +32676,7 @@ var UNSAFE_CONTROLS_RE = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u
32489
32676
  var LISTENER_MAX_PROMPT_ATTEMPTS = 3;
32490
32677
  var LISTENER_MAX_POST_ATTEMPTS = 5;
32491
32678
  function listenerReplyCommandId(signalId, effectOrdinal = 0) {
32492
- if (!UUID_RE9.test(signalId)) {
32679
+ if (!UUID_RE10.test(signalId)) {
32493
32680
  throw new Error("listener signal id must be a UUID");
32494
32681
  }
32495
32682
  if (!Number.isSafeInteger(effectOrdinal) || effectOrdinal < 0) {
@@ -32950,10 +33137,10 @@ var ListenerEngine = class {
32950
33137
 
32951
33138
  // src/listener/file-store.ts
32952
33139
  var import_node_crypto13 = require("node:crypto");
32953
- var import_node_os5 = require("node:os");
32954
- var import_node_path8 = require("node:path");
33140
+ var import_node_os6 = require("node:os");
33141
+ var import_node_path9 = require("node:path");
32955
33142
  var import_node_util = require("node:util");
32956
- var UUID_RE10 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
33143
+ var UUID_RE11 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
32957
33144
  var COMMAND_ID_RE2 = /^[A-Za-z0-9_-]{8,72}$/;
32958
33145
  var MAX_EFFECT_BYTES = 1024 * 1024;
32959
33146
  var STATES = /* @__PURE__ */ new Set([
@@ -32988,10 +33175,10 @@ var V1_EFFECT_KEYS = /* @__PURE__ */ new Set([
32988
33175
  ]);
32989
33176
  var V2_EFFECT_KEYS = /* @__PURE__ */ new Set([...V1_EFFECT_KEYS, "signalKind"]);
32990
33177
  function defaultListenerStateDirectory() {
32991
- return process.env.XDG_STATE_HOME ? (0, import_node_path8.join)(process.env.XDG_STATE_HOME, "cswarm", "listeners") : (0, import_node_path8.join)((0, import_node_os5.homedir)(), ".cswarm", "listeners");
33178
+ return process.env.XDG_STATE_HOME ? (0, import_node_path9.join)(process.env.XDG_STATE_HOME, "cswarm", "listeners") : (0, import_node_path9.join)((0, import_node_os6.homedir)(), ".cswarm", "listeners");
32992
33179
  }
32993
33180
  function listenerInstanceKey(input) {
32994
- if (!UUID_RE10.test(input.workspaceId) || !UUID_RE10.test(input.principalId)) {
33181
+ if (!UUID_RE11.test(input.workspaceId) || !UUID_RE11.test(input.principalId)) {
32995
33182
  throw new Error("listener workspace and principal ids must be UUIDs");
32996
33183
  }
32997
33184
  if (!input.profileId || input.profileId.includes("\0")) {
@@ -33023,7 +33210,7 @@ function parseListenerEffectRecord(raw, expectedId) {
33023
33210
  throw new Error("stored listener effect is malformed");
33024
33211
  }
33025
33212
  const row = value;
33026
- if (typeof row.version !== "number" || row.version !== 1 && row.version !== 2 || typeof row.signalId !== "string" || row.signalId.toLowerCase() !== expectedId || !UUID_RE10.test(row.signalId)) {
33213
+ if (typeof row.version !== "number" || row.version !== 1 && row.version !== 2 || typeof row.signalId !== "string" || row.signalId.toLowerCase() !== expectedId || !UUID_RE11.test(row.signalId)) {
33027
33214
  throw new Error("stored listener effect is malformed");
33028
33215
  }
33029
33216
  if (row.version === 1) {
@@ -33040,7 +33227,7 @@ function upcastV1Ask(row) {
33040
33227
  if (row.effectOrdinal !== 0 || typeof row.commandId !== "string" || !COMMAND_ID_RE2.test(row.commandId) || typeof row.askBody !== "string" || row.askBody.length < 1 || typeof row.askUntil !== "string" || !Number.isFinite(Date.parse(row.askUntil)) || typeof row.senderOwnerRelation !== "string" || !RELATIONS.has(row.senderOwnerRelation) || typeof row.state !== "string" || !STATES.has(row.state) || !integer(row.promptAttempts) || !integer(row.postAttempts) || !nullableString(row.replyBody, 2e3) || typeof row.replyTruncated !== "boolean" || !nullableString(row.replySignalId, 64) || !nullableString(row.failureCode, 96) || typeof row.updatedAt !== "string" || !Number.isFinite(Date.parse(row.updatedAt))) {
33041
33228
  throw new Error("stored listener effect is malformed");
33042
33229
  }
33043
- if (row.replySignalId !== null && !UUID_RE10.test(row.replySignalId)) {
33230
+ if (row.replySignalId !== null && !UUID_RE11.test(row.replySignalId)) {
33044
33231
  throw new Error("stored listener effect is malformed");
33045
33232
  }
33046
33233
  return {
@@ -33079,7 +33266,7 @@ function parseV2Record(row) {
33079
33266
  if (typeof row.commandId !== "string" || !COMMAND_ID_RE2.test(row.commandId) || row.state === "observed") {
33080
33267
  throw new Error("stored listener effect is malformed");
33081
33268
  }
33082
- if (row.replySignalId !== null && !UUID_RE10.test(row.replySignalId)) {
33269
+ if (row.replySignalId !== null && !UUID_RE11.test(row.replySignalId)) {
33083
33270
  throw new Error("stored listener effect is malformed");
33084
33271
  }
33085
33272
  }
@@ -33103,7 +33290,7 @@ function parseV2Record(row) {
33103
33290
  };
33104
33291
  }
33105
33292
  function newObservedNoteRecord(input) {
33106
- if (!UUID_RE10.test(input.signalId)) {
33293
+ if (!UUID_RE11.test(input.signalId)) {
33107
33294
  throw new Error("listener note signal id must be a UUID");
33108
33295
  }
33109
33296
  if (input.body.length < 1) {
@@ -33210,16 +33397,16 @@ var FileListenerEffectStore = class {
33210
33397
  effectsDirectory;
33211
33398
  constructor(options) {
33212
33399
  const root = options.stateDirectory ?? defaultListenerStateDirectory();
33213
- if (!(0, import_node_path8.isAbsolute)(root)) {
33400
+ if (!(0, import_node_path9.isAbsolute)(root)) {
33214
33401
  throw new Error("listener state directory must be absolute");
33215
33402
  }
33216
- this.instanceDirectory = (0, import_node_path8.join)(root, listenerInstanceKey(options));
33217
- this.effectsDirectory = (0, import_node_path8.join)(this.instanceDirectory, "effects");
33403
+ this.instanceDirectory = (0, import_node_path9.join)(root, listenerInstanceKey(options));
33404
+ this.effectsDirectory = (0, import_node_path9.join)(this.instanceDirectory, "effects");
33218
33405
  }
33219
33406
  async read(signalId) {
33220
33407
  const id = this.checkedId(signalId);
33221
33408
  const raw = await readSecureJsonFile(
33222
- (0, import_node_path8.join)(this.effectsDirectory, `${id}.json`),
33409
+ (0, import_node_path9.join)(this.effectsDirectory, `${id}.json`),
33223
33410
  MAX_EFFECT_BYTES
33224
33411
  );
33225
33412
  return raw === null ? null : parseListenerEffectRecord(raw, id);
@@ -33232,12 +33419,12 @@ var FileListenerEffectStore = class {
33232
33419
  throw new Error("listener effect is too large");
33233
33420
  }
33234
33421
  await writeSecureJsonFile(
33235
- (0, import_node_path8.join)(this.effectsDirectory, `${id}.json`),
33422
+ (0, import_node_path9.join)(this.effectsDirectory, `${id}.json`),
33236
33423
  serialized
33237
33424
  );
33238
33425
  }
33239
33426
  checkedId(signalId) {
33240
- if (!UUID_RE10.test(signalId)) {
33427
+ if (!UUID_RE11.test(signalId)) {
33241
33428
  throw new Error("listener signal id must be a UUID");
33242
33429
  }
33243
33430
  return signalId.toLowerCase();
@@ -33246,18 +33433,18 @@ var FileListenerEffectStore = class {
33246
33433
 
33247
33434
  // src/listener/grok-model.ts
33248
33435
  var import_promises5 = require("node:fs/promises");
33249
- var import_node_os6 = require("node:os");
33250
- var import_node_path10 = require("node:path");
33436
+ var import_node_os7 = require("node:os");
33437
+ var import_node_path11 = require("node:path");
33251
33438
 
33252
33439
  // src/host/grok.ts
33253
33440
  var import_node_child_process6 = require("node:child_process");
33254
33441
  var import_node_fs6 = require("node:fs");
33255
- var import_node_path9 = require("node:path");
33442
+ var import_node_path10 = require("node:path");
33256
33443
  var CHILD_EXIT_WAIT_MS4 = 3e3;
33257
33444
  var CHILD_KILL_WAIT_MS4 = 1e3;
33258
33445
  function resolveGrokExecutable(executable = "grok") {
33259
- if ((0, import_node_path9.isAbsolute)(executable) || executable.includes("/")) {
33260
- const abs = (0, import_node_path9.resolve)(executable);
33446
+ if ((0, import_node_path10.isAbsolute)(executable) || executable.includes("/")) {
33447
+ const abs = (0, import_node_path10.resolve)(executable);
33261
33448
  try {
33262
33449
  (0, import_node_fs6.accessSync)(abs, import_node_fs6.constants.X_OK);
33263
33450
  } catch {
@@ -33502,11 +33689,11 @@ var GrokListenerModel = class {
33502
33689
  async validateLocalAuth() {
33503
33690
  if (this.options.open) return;
33504
33691
  const parent = this.options.env ?? process.env;
33505
- const sourceHome = parent.GROK_HOME ?? (0, import_node_path10.join)(parent.HOME ?? (0, import_node_os6.homedir)(), ".grok");
33506
- if (!(0, import_node_path10.isAbsolute)(sourceHome)) {
33692
+ const sourceHome = parent.GROK_HOME ?? (0, import_node_path11.join)(parent.HOME ?? (0, import_node_os7.homedir)(), ".grok");
33693
+ if (!(0, import_node_path11.isAbsolute)(sourceHome)) {
33507
33694
  throw new Error("Grok home must be an absolute path");
33508
33695
  }
33509
- const sourceAuth = (0, import_node_path10.join)(sourceHome, "auth.json");
33696
+ const sourceAuth = (0, import_node_path11.join)(sourceHome, "auth.json");
33510
33697
  let info;
33511
33698
  try {
33512
33699
  info = await (0, import_promises5.lstat)(sourceAuth);
@@ -33556,7 +33743,7 @@ var GrokListenerModel = class {
33556
33743
  // src/listener/opencode-model.ts
33557
33744
  var import_node_crypto14 = require("node:crypto");
33558
33745
  var import_promises6 = require("node:fs/promises");
33559
- var import_node_path11 = require("node:path");
33746
+ var import_node_path12 = require("node:path");
33560
33747
  function asError(error) {
33561
33748
  return error instanceof Error ? error : new Error(String(error));
33562
33749
  }
@@ -33567,7 +33754,7 @@ var OpenCodeListenerModel = class {
33567
33754
  this.openSession = options.open ?? openOpenCodeAcpSession;
33568
33755
  this.prepareHome = options.prepareHome ?? prepareOpenCodeIsolatedHome;
33569
33756
  this.prepareWorkerCwd = options.prepareWorkerCwd ?? (async (home) => {
33570
- const cwd = await (0, import_promises6.mkdtemp)((0, import_node_path11.join)(home, "canary-cwd-"));
33757
+ const cwd = await (0, import_promises6.mkdtemp)((0, import_node_path12.join)(home, "canary-cwd-"));
33571
33758
  await (0, import_promises6.chmod)(cwd, 448);
33572
33759
  return cwd;
33573
33760
  });
@@ -33989,8 +34176,8 @@ var OpenCodeListenerModel = class {
33989
34176
  // src/listener/claude-model.ts
33990
34177
  var import_node_crypto15 = require("node:crypto");
33991
34178
  var import_promises7 = require("node:fs/promises");
33992
- var import_node_os7 = require("node:os");
33993
- var import_node_path12 = require("node:path");
34179
+ var import_node_os8 = require("node:os");
34180
+ var import_node_path13 = require("node:path");
33994
34181
  var ClaudeListenerClosedDuringOpen = class extends Error {
33995
34182
  constructor() {
33996
34183
  super("listener model closed while the Claude worker was opening");
@@ -34128,8 +34315,8 @@ var ClaudeListenerModel = class {
34128
34315
  }
34129
34316
  /** Force Claude's measured Write permission path without changing worker cwd. */
34130
34317
  async enablePromptsAfterClaudeCanary(handle) {
34131
- const sentinelPath = (0, import_node_path12.join)(
34132
- (0, import_node_os7.tmpdir)(),
34318
+ const sentinelPath = (0, import_node_path13.join)(
34319
+ (0, import_node_os8.tmpdir)(),
34133
34320
  `cswarm-claude-permission-canary-${process.pid}-${(0, import_node_crypto15.randomUUID)()}`
34134
34321
  );
34135
34322
  let sentinelCreated = false;
@@ -34158,8 +34345,8 @@ var ClaudeListenerModel = class {
34158
34345
  // src/listener/codex-model.ts
34159
34346
  var import_node_crypto16 = require("node:crypto");
34160
34347
  var import_promises8 = require("node:fs/promises");
34161
- var import_node_os8 = require("node:os");
34162
- var import_node_path13 = require("node:path");
34348
+ var import_node_os9 = require("node:os");
34349
+ var import_node_path14 = require("node:path");
34163
34350
  var CodexListenerClosedDuringOpen = class extends Error {
34164
34351
  constructor() {
34165
34352
  super("listener model closed while the Codex worker was opening");
@@ -34297,8 +34484,8 @@ var CodexListenerModel = class {
34297
34484
  }
34298
34485
  /** Force Codex's measured shell permission path without changing worker cwd. */
34299
34486
  async enablePromptsAfterCodexCanary(handle) {
34300
- const sentinelPath = (0, import_node_path13.join)(
34301
- (0, import_node_os8.tmpdir)(),
34487
+ const sentinelPath = (0, import_node_path14.join)(
34488
+ (0, import_node_os9.tmpdir)(),
34302
34489
  `cswarm-codex-permission-canary-${process.pid}-${(0, import_node_crypto16.randomUUID)()}`
34303
34490
  );
34304
34491
  let sentinelCreated = false;
@@ -34328,7 +34515,7 @@ var CodexListenerModel = class {
34328
34515
  var import_node_crypto17 = require("node:crypto");
34329
34516
 
34330
34517
  // src/cloud/delivery.ts
34331
- var UUID_RE11 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
34518
+ 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;
34332
34519
  var RFC3339_TIMESTAMP_RE = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})(?:\.\d+)?(?:Z|([+-]\d{2}):(\d{2}))$/i;
34333
34520
  var DELIVERY_KINDS = /* @__PURE__ */ new Set(["ask", "note"]);
34334
34521
  var SENDER_OWNER_RELATIONS2 = /* @__PURE__ */ new Set([
@@ -34415,7 +34602,7 @@ var DeliveryProtocolError = class extends Error {
34415
34602
  }
34416
34603
  };
34417
34604
  function checkedUuid3(value, field) {
34418
- if (typeof value !== "string" || !UUID_RE11.test(value)) {
34605
+ if (typeof value !== "string" || !UUID_RE12.test(value)) {
34419
34606
  throw new DeliveryProtocolError(
34420
34607
  `delivery response returned a malformed ${field}`
34421
34608
  );
@@ -34526,7 +34713,7 @@ function checkedClaimCapabilities(value) {
34526
34713
  }
34527
34714
  function checkedOptionalUuidArray(value, field) {
34528
34715
  if (value === void 0) return;
34529
- if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || !UUID_RE11.test(item))) {
34716
+ if (!Array.isArray(value) || value.some((item) => typeof item !== "string" || !UUID_RE12.test(item))) {
34530
34717
  throw new DeliveryProtocolError(
34531
34718
  `delivery response returned a malformed ${field}`
34532
34719
  );
@@ -34673,7 +34860,7 @@ function checkedCommandId(value) {
34673
34860
  return value;
34674
34861
  }
34675
34862
  function checkedUuidRequest(value, field) {
34676
- if (!UUID_RE11.test(value)) {
34863
+ if (!UUID_RE12.test(value)) {
34677
34864
  throw new Error(`${field} must be a UUID for an agent delivery command`);
34678
34865
  }
34679
34866
  }
@@ -34909,8 +35096,8 @@ var DeliveryCommandClient = class {
34909
35096
  };
34910
35097
 
34911
35098
  // src/listener/main-routing.ts
34912
- var import_node_path14 = require("node:path");
34913
- 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;
35099
+ var import_node_path15 = require("node:path");
35100
+ 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;
34914
35101
  var MAX_QUEUE_BYTES = 1024 * 1024;
34915
35102
  var QUEUE_FILE = "pending-for-main.json";
34916
35103
  var QUEUE_LOCK = "pending-for-main";
@@ -34965,7 +35152,7 @@ function parseEntry(value) {
34965
35152
  if (Object.keys(row).some((key2) => !allowed.has(key2))) {
34966
35153
  throw new Error("stored pending-for-main entry is malformed");
34967
35154
  }
34968
- if (typeof row.signalId !== "string" || !UUID_RE12.test(row.signalId) || typeof row.workspaceId !== "string" || !UUID_RE12.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE12.test(row.principalId) || typeof row.fromId !== "string" || !UUID_RE12.test(row.fromId) || row.fromKind !== "user" && row.fromKind !== "agent" || !(row.kind === void 0 || row.kind === "ask" || row.kind === "note") || !(row.senderName === null || typeof row.senderName === "string" && row.senderName.length <= 200) || typeof row.body !== "string" || row.body.length < 1 || !checkedTimestamp2(row.createdAt) || !checkedTimestamp2(row.queuedAt) || !(row.observationPending === void 0 || row.observationPending === true)) {
35155
+ if (typeof row.signalId !== "string" || !UUID_RE13.test(row.signalId) || typeof row.workspaceId !== "string" || !UUID_RE13.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE13.test(row.principalId) || typeof row.fromId !== "string" || !UUID_RE13.test(row.fromId) || row.fromKind !== "user" && row.fromKind !== "agent" || !(row.kind === void 0 || row.kind === "ask" || row.kind === "note") || !(row.senderName === null || typeof row.senderName === "string" && row.senderName.length <= 200) || typeof row.body !== "string" || row.body.length < 1 || !checkedTimestamp2(row.createdAt) || !checkedTimestamp2(row.queuedAt) || !(row.observationPending === void 0 || row.observationPending === true)) {
34969
35156
  throw new Error("stored pending-for-main entry is malformed");
34970
35157
  }
34971
35158
  return {
@@ -35008,11 +35195,11 @@ var FilePendingMainQueue = class {
35008
35195
  path;
35009
35196
  directory;
35010
35197
  constructor(instanceDirectory) {
35011
- if (!(0, import_node_path14.isAbsolute)(instanceDirectory)) {
35198
+ if (!(0, import_node_path15.isAbsolute)(instanceDirectory)) {
35012
35199
  throw new Error("pending-for-main directory must be absolute");
35013
35200
  }
35014
35201
  this.directory = instanceDirectory;
35015
- this.path = (0, import_node_path14.join)(instanceDirectory, QUEUE_FILE);
35202
+ this.path = (0, import_node_path15.join)(instanceDirectory, QUEUE_FILE);
35016
35203
  }
35017
35204
  async readUnlocked() {
35018
35205
  const raw = await readSecureJsonFile(this.path, MAX_QUEUE_BYTES);
@@ -35104,7 +35291,7 @@ var LISTENER_REPLY_ONLY_MINIMUM_MS = SIGNAL_REQUEST_TIMEOUT_MS + LISTENER_ACK_ON
35104
35291
  var LISTENER_PROMPT_START_MINIMUM_MS = SIGNAL_READ_TIMEOUT_MS + ACP_DEFAULT_REQUEST_TIMEOUT_MS + LISTENER_REPLY_ONLY_MINIMUM_MS;
35105
35292
  var LISTENER_DELIVERY_RETRY_INITIAL_MS = 500;
35106
35293
  var LISTENER_DELIVERY_RETRY_MAX_MS = 3e4;
35107
- 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;
35294
+ var UUID_RE14 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
35108
35295
  var ListenerCapabilityError = class extends Error {
35109
35296
  code;
35110
35297
  constructor(code, message) {
@@ -35382,7 +35569,7 @@ async function runListenerRuntime(options) {
35382
35569
  new Error("listener instance id and delivery journal must be configured together")
35383
35570
  );
35384
35571
  }
35385
- if (hasInstanceId && !UUID_RE13.test(options.listenerInstanceId)) {
35572
+ if (hasInstanceId && !UUID_RE14.test(options.listenerInstanceId)) {
35386
35573
  return await closeBeforeStart(
35387
35574
  options.model,
35388
35575
  new Error("listener instance id must be a UUID")
@@ -36222,8 +36409,8 @@ async function runListenerRuntime(options) {
36222
36409
  // src/listener/control.ts
36223
36410
  var import_node_net = require("node:net");
36224
36411
  var import_promises9 = require("node:fs/promises");
36225
- var import_node_path15 = require("node:path");
36226
- var UUID_RE14 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
36412
+ var import_node_path16 = require("node:path");
36413
+ var UUID_RE15 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
36227
36414
  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-]+)*)?$/;
36228
36415
  var MAX_STATUS_BYTES = 16 * 1024;
36229
36416
  var MAX_CONTROL_BYTES = 8 * 1024;
@@ -36238,19 +36425,19 @@ var ListenerAlreadyRunningError = class extends Error {
36238
36425
  };
36239
36426
  function listenerPaths(options) {
36240
36427
  const root = options.stateDirectory ?? defaultListenerStateDirectory();
36241
- if (!(0, import_node_path15.isAbsolute)(root)) {
36428
+ if (!(0, import_node_path16.isAbsolute)(root)) {
36242
36429
  throw new Error("listener state directory must be absolute");
36243
36430
  }
36244
36431
  const key2 = listenerInstanceKey(options);
36245
- const instanceDirectory = (0, import_node_path15.join)(root, key2);
36432
+ const instanceDirectory = (0, import_node_path16.join)(root, key2);
36246
36433
  const uid2 = typeof process.getuid === "function" ? process.getuid() : process.pid;
36247
- const controlDirectory = process.platform === "win32" ? "" : (0, import_node_path15.join)("/tmp", `cswarm-control-${uid2}`);
36248
- const socketPath = process.platform === "win32" ? `\\\\.\\pipe\\cswarm-${key2}` : (0, import_node_path15.join)(controlDirectory, `${key2.slice(0, 32)}.sock`);
36434
+ const controlDirectory = process.platform === "win32" ? "" : (0, import_node_path16.join)("/tmp", `cswarm-control-${uid2}`);
36435
+ const socketPath = process.platform === "win32" ? `\\\\.\\pipe\\cswarm-${key2}` : (0, import_node_path16.join)(controlDirectory, `${key2.slice(0, 32)}.sock`);
36249
36436
  return {
36250
36437
  key: key2,
36251
36438
  instanceDirectory,
36252
- statusPath: (0, import_node_path15.join)(instanceDirectory, "status.json"),
36253
- logPath: (0, import_node_path15.join)(instanceDirectory, "events.ndjson"),
36439
+ statusPath: (0, import_node_path16.join)(instanceDirectory, "status.json"),
36440
+ logPath: (0, import_node_path16.join)(instanceDirectory, "events.ndjson"),
36254
36441
  socketPath
36255
36442
  };
36256
36443
  }
@@ -36329,10 +36516,10 @@ function parseStatus(raw) {
36329
36516
  throw new Error("stored listener status is malformed");
36330
36517
  }
36331
36518
  }
36332
- const nullableUuid2 = (candidate) => candidate === null || typeof candidate === "string" && UUID_RE14.test(candidate);
36519
+ const nullableUuid2 = (candidate) => candidate === null || typeof candidate === "string" && UUID_RE15.test(candidate);
36333
36520
  const nullableCount = (candidate) => candidate === null || typeof candidate === "number" && Number.isSafeInteger(candidate) && candidate >= 0;
36334
36521
  const nullableTimestamp2 = (candidate) => candidate === null || typeof candidate === "string" && Number.isFinite(Date.parse(candidate));
36335
- if (row.version !== 1 || typeof row.instanceId !== "string" || !UUID_RE14.test(row.instanceId) || row.provider !== "grok" && row.provider !== "opencode" && row.provider !== "claude" && row.provider !== "codex" || typeof row.profileId !== "string" || typeof row.workspaceId !== "string" || !UUID_RE14.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE14.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 || 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)) {
36522
+ 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)) {
36336
36523
  throw new Error("stored listener status is malformed");
36337
36524
  }
36338
36525
  const routeMode = row.routeMode ?? "worker";
@@ -36506,7 +36693,7 @@ function writeResponse(socket, response) {
36506
36693
  }
36507
36694
  async function startupLock(paths) {
36508
36695
  await ensureSecureStateDirectory(paths.instanceDirectory);
36509
- const lockPath = (0, import_node_path15.join)(paths.instanceDirectory, "starting.lock");
36696
+ const lockPath = (0, import_node_path16.join)(paths.instanceDirectory, "starting.lock");
36510
36697
  const deadline = Date.now() + START_LOCK_WAIT_MS;
36511
36698
  while (Date.now() < deadline) {
36512
36699
  let handle;
@@ -36547,7 +36734,7 @@ async function startupLock(paths) {
36547
36734
  async function prepareSocket(paths) {
36548
36735
  if (process.platform !== "win32") {
36549
36736
  const uid2 = typeof process.getuid === "function" ? process.getuid() : process.pid;
36550
- const directory = (0, import_node_path15.join)("/tmp", `cswarm-control-${uid2}`);
36737
+ const directory = (0, import_node_path16.join)("/tmp", `cswarm-control-${uid2}`);
36551
36738
  await ensureSecureStateDirectory(directory);
36552
36739
  }
36553
36740
  try {
@@ -36682,7 +36869,7 @@ async function queryListenerControl(paths, command2, timeoutMs = CONTROL_TIMEOUT
36682
36869
 
36683
36870
  // src/listener/supervisor.ts
36684
36871
  var import_node_crypto18 = require("node:crypto");
36685
- var UUID_RE15 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
36872
+ 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;
36686
36873
  var LISTENER_RESTART_MAX_ATTEMPTS = 5;
36687
36874
  var LISTENER_RESTART_INITIAL_MS = 1e3;
36688
36875
  var LISTENER_RESTART_MAX_MS = 6e4;
@@ -36811,7 +36998,7 @@ async function runListenerSupervisor(options) {
36811
36998
  // before the socket can answer, before any status/event persistence.
36812
36999
  initialize: prepare ? async () => {
36813
37000
  const selected = await prepare(proposedInstanceId);
36814
- if (!selected || typeof selected !== "object" || typeof selected.instanceId !== "string" || !UUID_RE15.test(selected.instanceId)) {
37001
+ if (!selected || typeof selected !== "object" || typeof selected.instanceId !== "string" || !UUID_RE16.test(selected.instanceId)) {
36815
37002
  throw new Error("listener prepare returned an invalid instance id");
36816
37003
  }
36817
37004
  status = { ...status, instanceId: selected.instanceId };
@@ -37167,9 +37354,9 @@ async function waitForListenerReady(paths, options = {}) {
37167
37354
  }
37168
37355
 
37169
37356
  // src/listener/delivery-journal.ts
37170
- var import_node_path16 = require("node:path");
37357
+ var import_node_path17 = require("node:path");
37171
37358
  var import_node_util2 = require("node:util");
37172
- 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}$/;
37359
+ var UUID_RE17 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
37173
37360
  var COMMAND_ID_RE3 = /^[A-Za-z0-9_-]{8,72}$/;
37174
37361
  var SIGNAL_FINGERPRINT_RE = /^[0-9a-f]{64}$/;
37175
37362
  var MAX_JOURNAL_BYTES = 8192;
@@ -37264,7 +37451,7 @@ var ALLOWED_ERROR_CODES = /* @__PURE__ */ new Set([
37264
37451
  "credential_unavailable"
37265
37452
  ]);
37266
37453
  function claimCommandId(listenerInstanceId, claimOrdinal) {
37267
- if (!UUID_RE16.test(listenerInstanceId)) {
37454
+ if (!UUID_RE17.test(listenerInstanceId)) {
37268
37455
  throw new Error("stored delivery journal is malformed");
37269
37456
  }
37270
37457
  if (!Number.isSafeInteger(claimOrdinal) || claimOrdinal < 0) {
@@ -37279,7 +37466,7 @@ function claimCommandId(listenerInstanceId, claimOrdinal) {
37279
37466
  return id;
37280
37467
  }
37281
37468
  function ackCommandId(leaseId) {
37282
- if (!UUID_RE16.test(leaseId)) {
37469
+ if (!UUID_RE17.test(leaseId)) {
37283
37470
  throw new Error("stored delivery journal is malformed");
37284
37471
  }
37285
37472
  const cleanLease = leaseId.toLowerCase().replace(/-/g, "");
@@ -37362,19 +37549,19 @@ function parseJournalRecord(raw, expectedWorkspaceId, expectedPrincipalId) {
37362
37549
  if (row.version !== 1) {
37363
37550
  throw new Error("stored delivery journal is malformed");
37364
37551
  }
37365
- if (typeof row.workspaceId !== "string" || !UUID_RE16.test(row.workspaceId) || row.workspaceId !== row.workspaceId.toLowerCase()) {
37552
+ if (typeof row.workspaceId !== "string" || !UUID_RE17.test(row.workspaceId) || row.workspaceId !== row.workspaceId.toLowerCase()) {
37366
37553
  throw new Error("stored delivery journal is malformed");
37367
37554
  }
37368
37555
  if (expectedWorkspaceId && row.workspaceId !== expectedWorkspaceId.toLowerCase()) {
37369
37556
  throw new Error("stored delivery journal is malformed");
37370
37557
  }
37371
- if (typeof row.principalId !== "string" || !UUID_RE16.test(row.principalId) || row.principalId !== row.principalId.toLowerCase()) {
37558
+ if (typeof row.principalId !== "string" || !UUID_RE17.test(row.principalId) || row.principalId !== row.principalId.toLowerCase()) {
37372
37559
  throw new Error("stored delivery journal is malformed");
37373
37560
  }
37374
37561
  if (expectedPrincipalId && row.principalId !== expectedPrincipalId.toLowerCase()) {
37375
37562
  throw new Error("stored delivery journal is malformed");
37376
37563
  }
37377
- if (typeof row.listenerInstanceId !== "string" || !UUID_RE16.test(row.listenerInstanceId) || row.listenerInstanceId !== row.listenerInstanceId.toLowerCase()) {
37564
+ if (typeof row.listenerInstanceId !== "string" || !UUID_RE17.test(row.listenerInstanceId) || row.listenerInstanceId !== row.listenerInstanceId.toLowerCase()) {
37378
37565
  throw new Error("stored delivery journal is malformed");
37379
37566
  }
37380
37567
  if (!Number.isSafeInteger(row.nextClaimOrdinal) || row.nextClaimOrdinal < 0) {
@@ -37438,10 +37625,10 @@ function parseJournalRecord(raw, expectedWorkspaceId, expectedPrincipalId) {
37438
37625
  if (active.claimLastAttemptAt === null) {
37439
37626
  throw new Error("stored delivery journal is malformed");
37440
37627
  }
37441
- if (typeof active.signalId !== "string" || !UUID_RE16.test(active.signalId) || active.signalId !== active.signalId.toLowerCase()) {
37628
+ if (typeof active.signalId !== "string" || !UUID_RE17.test(active.signalId) || active.signalId !== active.signalId.toLowerCase()) {
37442
37629
  throw new Error("stored delivery journal is malformed");
37443
37630
  }
37444
- if (typeof active.leaseId !== "string" || !UUID_RE16.test(active.leaseId) || active.leaseId !== active.leaseId.toLowerCase()) {
37631
+ if (typeof active.leaseId !== "string" || !UUID_RE17.test(active.leaseId) || active.leaseId !== active.leaseId.toLowerCase()) {
37445
37632
  throw new Error("stored delivery journal is malformed");
37446
37633
  }
37447
37634
  if (!isValidIsoTimestamp(active.leasedUntil) || Date.parse(active.leasedUntil) <= Date.parse(active.claimCreatedAt)) {
@@ -37513,7 +37700,7 @@ var FileListenerDeliveryJournal = class {
37513
37700
  ["profileId", "workspaceId", "principalId"],
37514
37701
  "delivery journal configuration rejected"
37515
37702
  );
37516
- if (typeof options.profileId !== "string" || !options.profileId || options.profileId.includes("\0") || typeof options.workspaceId !== "string" || !UUID_RE16.test(options.workspaceId) || typeof options.principalId !== "string" || !UUID_RE16.test(options.principalId)) {
37703
+ if (typeof options.profileId !== "string" || !options.profileId || options.profileId.includes("\0") || typeof options.workspaceId !== "string" || !UUID_RE17.test(options.workspaceId) || typeof options.principalId !== "string" || !UUID_RE17.test(options.principalId)) {
37517
37704
  throw new Error("delivery journal configuration rejected");
37518
37705
  }
37519
37706
  if (options.stateDirectory !== void 0) {
@@ -37528,11 +37715,11 @@ var FileListenerDeliveryJournal = class {
37528
37715
  stateDirectory: options.stateDirectory
37529
37716
  });
37530
37717
  const root = this.options.stateDirectory ?? defaultListenerStateDirectory();
37531
- if (!(0, import_node_path16.isAbsolute)(root)) {
37718
+ if (!(0, import_node_path17.isAbsolute)(root)) {
37532
37719
  throw new Error("delivery journal configuration rejected");
37533
37720
  }
37534
- this.instanceDirectory = (0, import_node_path16.join)(root, listenerInstanceKey(this.options));
37535
- this.journalPath = (0, import_node_path16.join)(this.instanceDirectory, "delivery-journal.json");
37721
+ this.instanceDirectory = (0, import_node_path17.join)(root, listenerInstanceKey(this.options));
37722
+ this.journalPath = (0, import_node_path17.join)(this.instanceDirectory, "delivery-journal.json");
37536
37723
  }
37537
37724
  async readRecordUnlocked() {
37538
37725
  let raw;
@@ -37634,7 +37821,7 @@ var FileListenerDeliveryJournal = class {
37634
37821
  ["signalId", "leaseId", "leasedUntil"],
37635
37822
  "delivery journal mutation rejected"
37636
37823
  );
37637
- if (typeof input.signalId !== "string" || !UUID_RE16.test(input.signalId) || typeof input.leaseId !== "string" || !UUID_RE16.test(input.leaseId) || !isValidIsoTimestamp(input.leasedUntil) || input.signalFingerprint !== void 0 && (typeof input.signalFingerprint !== "string" || !SIGNAL_FINGERPRINT_RE.test(input.signalFingerprint))) {
37824
+ if (typeof input.signalId !== "string" || !UUID_RE17.test(input.signalId) || typeof input.leaseId !== "string" || !UUID_RE17.test(input.leaseId) || !isValidIsoTimestamp(input.leasedUntil) || input.signalFingerprint !== void 0 && (typeof input.signalFingerprint !== "string" || !SIGNAL_FINGERPRINT_RE.test(input.signalFingerprint))) {
37638
37825
  throw new Error("delivery journal mutation rejected");
37639
37826
  }
37640
37827
  const canonicalSignalId = input.signalId.toLowerCase();
@@ -37766,7 +37953,7 @@ async function openListenerDeliveryJournal(options) {
37766
37953
  ["profileId", "workspaceId", "principalId", "proposedListenerInstanceId"],
37767
37954
  "delivery journal configuration rejected"
37768
37955
  );
37769
- if (typeof options.profileId !== "string" || !options.profileId || options.profileId.includes("\0") || typeof options.workspaceId !== "string" || !UUID_RE16.test(options.workspaceId) || typeof options.principalId !== "string" || !UUID_RE16.test(options.principalId) || typeof options.proposedListenerInstanceId !== "string" || !UUID_RE16.test(options.proposedListenerInstanceId)) {
37956
+ if (typeof options.profileId !== "string" || !options.profileId || options.profileId.includes("\0") || typeof options.workspaceId !== "string" || !UUID_RE17.test(options.workspaceId) || typeof options.principalId !== "string" || !UUID_RE17.test(options.principalId) || typeof options.proposedListenerInstanceId !== "string" || !UUID_RE17.test(options.proposedListenerInstanceId)) {
37770
37957
  throw new Error("delivery journal configuration rejected");
37771
37958
  }
37772
37959
  if (options.stateDirectory !== void 0) {
@@ -37861,9 +38048,9 @@ async function openListenerDeliveryJournal(options) {
37861
38048
 
37862
38049
  // src/listener/detach.ts
37863
38050
  var import_node_child_process7 = require("node:child_process");
37864
- var import_node_path17 = require("node:path");
38051
+ var import_node_path18 = require("node:path");
37865
38052
  function isNativeAbsolutePath(value, platform = process.platform) {
37866
- return platform === "win32" ? import_node_path17.win32.isAbsolute(value) : import_node_path17.posix.isAbsolute(value);
38053
+ return platform === "win32" ? import_node_path18.win32.isAbsolute(value) : import_node_path18.posix.isAbsolute(value);
37867
38054
  }
37868
38055
  function listenerNodeExecArgv(values2) {
37869
38056
  const safe = [];
@@ -37980,8 +38167,8 @@ async function spawnDetachedListener(options) {
37980
38167
 
37981
38168
  // src/listener/hook.ts
37982
38169
  var import_promises10 = require("node:fs/promises");
37983
- var import_node_path18 = require("node:path");
37984
- var UUID_RE17 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
38170
+ var import_node_path19 = require("node:path");
38171
+ var UUID_RE18 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
37985
38172
  var TOKEN_RE = /^swm_agt_[A-Za-z0-9_-]{43}$/;
37986
38173
  var INSTANCE_KEY_RE = /^[0-9a-f]{64}$/;
37987
38174
  var MAX_HOOK_CREDENTIAL_BYTES = 8 * 1024;
@@ -38022,7 +38209,7 @@ function parseListenerCredential(raw) {
38022
38209
  "principalId",
38023
38210
  "credential",
38024
38211
  "updatedAt"
38025
- ]) || row.version !== 1 || typeof row.profileId !== "string" || !/^[0-9a-f]{24}$/.test(row.profileId) || typeof row.targetUrl !== "string" || typeof row.anonKey !== "string" || row.anonKey.length < 1 || row.anonKey.length > 4096 || typeof row.workspaceId !== "string" || !UUID_RE17.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE17.test(row.principalId) || typeof row.credential !== "string" || !TOKEN_RE.test(row.credential) || typeof row.updatedAt !== "string" || !Number.isFinite(Date.parse(row.updatedAt))) {
38212
+ ]) || row.version !== 1 || typeof row.profileId !== "string" || !/^[0-9a-f]{24}$/.test(row.profileId) || typeof row.targetUrl !== "string" || typeof row.anonKey !== "string" || row.anonKey.length < 1 || row.anonKey.length > 4096 || typeof row.workspaceId !== "string" || !UUID_RE18.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE18.test(row.principalId) || typeof row.credential !== "string" || !TOKEN_RE.test(row.credential) || typeof row.updatedAt !== "string" || !Number.isFinite(Date.parse(row.updatedAt))) {
38026
38213
  throw new Error("stored listener hook credential is malformed");
38027
38214
  }
38028
38215
  const target2 = cloudTarget(row.targetUrl, row.anonKey);
@@ -38041,7 +38228,7 @@ function parseListenerCredential(raw) {
38041
38228
  };
38042
38229
  }
38043
38230
  async function writeListenerCredentialState(instanceDirectory, input) {
38044
- if (!(0, import_node_path18.isAbsolute)(instanceDirectory)) {
38231
+ if (!(0, import_node_path19.isAbsolute)(instanceDirectory)) {
38045
38232
  throw new Error("listener hook state directory must be absolute");
38046
38233
  }
38047
38234
  const record = parseListenerCredential(JSON.stringify({
@@ -38055,16 +38242,16 @@ async function writeListenerCredentialState(instanceDirectory, input) {
38055
38242
  updatedAt: new Date(input.now ?? Date.now()).toISOString()
38056
38243
  }));
38057
38244
  await writeSecureJsonFile(
38058
- (0, import_node_path18.join)(instanceDirectory, LISTENER_CREDENTIAL_FILE),
38245
+ (0, import_node_path19.join)(instanceDirectory, LISTENER_CREDENTIAL_FILE),
38059
38246
  JSON.stringify(record)
38060
38247
  );
38061
38248
  await deleteSecureJsonFile(
38062
- (0, import_node_path18.join)(instanceDirectory, RETIRED_HOOK_CREDENTIAL_FILE)
38249
+ (0, import_node_path19.join)(instanceDirectory, RETIRED_HOOK_CREDENTIAL_FILE)
38063
38250
  ).catch(() => void 0);
38064
38251
  }
38065
38252
  async function readListenerCredentialState(instanceDirectory) {
38066
38253
  const raw = await readSecureJsonFile(
38067
- (0, import_node_path18.join)(instanceDirectory, LISTENER_CREDENTIAL_FILE),
38254
+ (0, import_node_path19.join)(instanceDirectory, LISTENER_CREDENTIAL_FILE),
38068
38255
  MAX_HOOK_CREDENTIAL_BYTES
38069
38256
  );
38070
38257
  return raw === null ? null : parseListenerCredential(raw);
@@ -38082,7 +38269,7 @@ function parseSurface(raw) {
38082
38269
  const row = value;
38083
38270
  if (Object.keys(row).some(
38084
38271
  (key2) => key2 !== "version" && key2 !== "surfacedSignalIds" && key2 !== "reportedDroppedCount" && key2 !== "credentialFailureReported"
38085
- ) || row.version !== 1 || !Array.isArray(row.surfacedSignalIds) || row.surfacedSignalIds.length > HOOK_SURFACED_IDS_MAX || row.surfacedSignalIds.some((id) => typeof id !== "string" || !UUID_RE17.test(id)) || !(row.reportedDroppedCount === void 0 || typeof row.reportedDroppedCount === "number" && Number.isSafeInteger(row.reportedDroppedCount) && row.reportedDroppedCount >= 0) || !(row.credentialFailureReported === void 0 || typeof row.credentialFailureReported === "boolean")) {
38272
+ ) || row.version !== 1 || !Array.isArray(row.surfacedSignalIds) || row.surfacedSignalIds.length > HOOK_SURFACED_IDS_MAX || row.surfacedSignalIds.some((id) => typeof id !== "string" || !UUID_RE18.test(id)) || !(row.reportedDroppedCount === void 0 || typeof row.reportedDroppedCount === "number" && Number.isSafeInteger(row.reportedDroppedCount) && row.reportedDroppedCount >= 0) || !(row.credentialFailureReported === void 0 || typeof row.credentialFailureReported === "boolean")) {
38086
38273
  throw new Error("stored listener hook surface state is malformed");
38087
38274
  }
38088
38275
  const ids = row.surfacedSignalIds.map((id) => String(id).toLowerCase());
@@ -38099,10 +38286,10 @@ function parseSurface(raw) {
38099
38286
  var FileHookSurfaceStore = class {
38100
38287
  constructor(instanceDirectory) {
38101
38288
  this.instanceDirectory = instanceDirectory;
38102
- if (!(0, import_node_path18.isAbsolute)(instanceDirectory)) {
38289
+ if (!(0, import_node_path19.isAbsolute)(instanceDirectory)) {
38103
38290
  throw new Error("listener hook surface directory must be absolute");
38104
38291
  }
38105
- this.path = (0, import_node_path18.join)(instanceDirectory, HOOK_SURFACE_FILE);
38292
+ this.path = (0, import_node_path19.join)(instanceDirectory, HOOK_SURFACE_FILE);
38106
38293
  }
38107
38294
  instanceDirectory;
38108
38295
  path;
@@ -38119,7 +38306,7 @@ var FileHookSurfaceStore = class {
38119
38306
  const unseen = [];
38120
38307
  for (const item of items) {
38121
38308
  const signalId = item.signalId.toLowerCase();
38122
- if (!UUID_RE17.test(signalId) || seen.has(signalId)) continue;
38309
+ if (!UUID_RE18.test(signalId) || seen.has(signalId)) continue;
38123
38310
  seen.add(signalId);
38124
38311
  unseen.push(item);
38125
38312
  }
@@ -38142,7 +38329,7 @@ var FileHookSurfaceStore = class {
38142
38329
  const seen = new Set(state.surfacedSignalIds);
38143
38330
  for (const signalId of options.signalIds ?? []) {
38144
38331
  const checked = signalId.toLowerCase();
38145
- if (UUID_RE17.test(checked)) seen.add(checked);
38332
+ if (UUID_RE18.test(checked)) seen.add(checked);
38146
38333
  }
38147
38334
  await writeSecureJsonFile(
38148
38335
  this.path,
@@ -38181,7 +38368,7 @@ function parseGlobalState(raw) {
38181
38368
  }
38182
38369
  async function reserveCheck(stateDirectory2, cooldownMs, now) {
38183
38370
  return await withFileLock(stateDirectory2, GLOBAL_STATE_LOCK, async () => {
38184
- const path = (0, import_node_path18.join)(stateDirectory2, GLOBAL_STATE_FILE);
38371
+ const path = (0, import_node_path19.join)(stateDirectory2, GLOBAL_STATE_FILE);
38185
38372
  const raw = await readSecureJsonFile(path, MAX_GLOBAL_STATE_BYTES);
38186
38373
  const previous = raw === null ? null : parseGlobalState(raw);
38187
38374
  if (previous !== null && now - previous.lastCheckAt < cooldownMs) return false;
@@ -38201,8 +38388,8 @@ async function statusContext(stateDirectory2, key2, instanceDirectory) {
38201
38388
  const provisional = {
38202
38389
  key: key2,
38203
38390
  instanceDirectory,
38204
- statusPath: (0, import_node_path18.join)(instanceDirectory, "status.json"),
38205
- logPath: (0, import_node_path18.join)(instanceDirectory, "events.ndjson"),
38391
+ statusPath: (0, import_node_path19.join)(instanceDirectory, "status.json"),
38392
+ logPath: (0, import_node_path19.join)(instanceDirectory, "events.ndjson"),
38206
38393
  socketPath: ""
38207
38394
  };
38208
38395
  const status = await readListenerStatus(provisional).catch(() => null);
@@ -38238,7 +38425,7 @@ async function discoverContexts(stateDirectory2, isListenerLive = listenerIsLive
38238
38425
  const contexts = [];
38239
38426
  for (const entry of entries) {
38240
38427
  if (!entry.isDirectory() || !INSTANCE_KEY_RE.test(entry.name)) continue;
38241
- const instanceDirectory = (0, import_node_path18.join)(stateDirectory2, entry.name);
38428
+ const instanceDirectory = (0, import_node_path19.join)(stateDirectory2, entry.name);
38242
38429
  const storedStatus = await statusContext(
38243
38430
  stateDirectory2,
38244
38431
  entry.name,
@@ -38257,7 +38444,7 @@ async function discoverContexts(stateDirectory2, isListenerLive = listenerIsLive
38257
38444
  continue;
38258
38445
  }
38259
38446
  await deleteSecureJsonFile(
38260
- (0, import_node_path18.join)(instanceDirectory, RETIRED_HOOK_CREDENTIAL_FILE)
38447
+ (0, import_node_path19.join)(instanceDirectory, RETIRED_HOOK_CREDENTIAL_FILE)
38261
38448
  ).catch(() => void 0);
38262
38449
  try {
38263
38450
  const credential = await readListenerCredentialState(instanceDirectory);
@@ -38408,7 +38595,7 @@ async function recordQueuedObservations(check, signalIds, options, now) {
38408
38595
  async function checkListenerHooks(options) {
38409
38596
  try {
38410
38597
  const stateDirectory2 = options.stateDirectory ?? defaultListenerStateDirectory();
38411
- if (!(0, import_node_path18.isAbsolute)(stateDirectory2)) return "";
38598
+ if (!(0, import_node_path19.isAbsolute)(stateDirectory2)) return "";
38412
38599
  const now = options.now ?? Date.now;
38413
38600
  const cooldownSeconds = options.cooldownSeconds ?? HOOK_DEFAULT_COOLDOWN_SECONDS;
38414
38601
  if (!Number.isSafeInteger(cooldownSeconds) || cooldownSeconds < 0 || cooldownSeconds > 86400) {
@@ -38589,6 +38776,7 @@ var KNOWN_FLAGS = /* @__PURE__ */ new Set([
38589
38776
  "name",
38590
38777
  "ndjson",
38591
38778
  "no-browser",
38779
+ "notify",
38592
38780
  "opencode-executable",
38593
38781
  "out",
38594
38782
  "permissions",
@@ -38628,11 +38816,12 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
38628
38816
  "link-stdin",
38629
38817
  "local",
38630
38818
  "ndjson",
38819
+ "notify",
38631
38820
  "no-browser",
38632
38821
  "reveal-anon-key",
38633
38822
  "write"
38634
38823
  ]);
38635
- var UUID_RE18 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
38824
+ var UUID_RE19 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
38636
38825
  var AGENT_CREDENTIAL_MESSAGE = "Agent credential minted. It is bound to this task and run so the agent's work stays scoped and attributable.";
38637
38826
  var AGENT_CREDENTIAL_MESSAGE_D088 = "Agent credential minted. It is bound to this run, so the agent's work is attributable to it.";
38638
38827
  var ACCEPTED_AGENT_CREDENTIAL_MESSAGES = [
@@ -38640,8 +38829,8 @@ var ACCEPTED_AGENT_CREDENTIAL_MESSAGES = [
38640
38829
  AGENT_CREDENTIAL_MESSAGE_D088
38641
38830
  ];
38642
38831
  function packageVersion() {
38643
- if ("0.1.34".length > 0) {
38644
- return "0.1.34";
38832
+ if ("0.1.35".length > 0) {
38833
+ return "0.1.35";
38645
38834
  }
38646
38835
  try {
38647
38836
  const value = JSON.parse(
@@ -38763,6 +38952,7 @@ Usage:
38763
38952
  cswarm receipt <signal-id> --agent-token-stdin [--url <url> --anon-key <key>] --workspace-id <uuid> [--json]
38764
38953
  cswarm feed [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--about <ref>] [--kind <kind>] [--since <timestamp>] [--limit <n>] [--include-stale] [--json]
38765
38954
  cswarm inbox [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--kind <kind>] [--about <ref>] [--since <timestamp>] [--limit <n>] [--include-stale] [--wait <seconds>] [--json]
38955
+ cswarm inbox --notify --agent-token-stdin [--url <url> --anon-key <key>] --workspace-id <uuid> [--json]
38766
38956
  cswarm inbox --follow --ndjson [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--kind <kind>] [--about <ref>] [--since <timestamp>] [--limit <n>] [--include-stale]
38767
38957
  cswarm file put <local-path> [--name <name>] [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--agent-token-stdin] [--json]
38768
38958
  cswarm file ls [--include-tombstoned] [--url <url> --anon-key <key>] [--workspace-id <uuid>] [--agent-token-stdin] [--json]
@@ -38808,6 +38998,7 @@ Credential selection for command/dogfood:
38808
38998
  JSON artifact, because it needs a field a bare secret does not carry:
38809
38999
  members reads only -- either form
38810
39000
  receipt reads only -- either form
39001
+ inbox --notify persists a per-agent cursor -- needs principal_id
38811
39002
  file put, file ls, file get, file rm, file restore
38812
39003
  read and command, nothing persisted -- either form
38813
39004
  feedback command only, nothing persisted -- either form
@@ -38977,7 +39168,7 @@ function parsedAgentCredential(value) {
38977
39168
  const withExpiry = [...requiredKeys, "expires_at"].sort();
38978
39169
  const actualKeys = Object.keys(artifact).sort();
38979
39170
  const shape = actualKeys.length === requiredKeys.length ? requiredKeys : withExpiry;
38980
- if (actualKeys.length !== shape.length || !actualKeys.every((key2, index) => key2 === shape[index]) || !ACCEPTED_AGENT_CREDENTIAL_MESSAGES.includes(artifact.message) || artifact.status !== "accepted" || typeof artifact.principal_id !== "string" || !UUID_RE18.test(artifact.principal_id) || typeof artifact.token_id !== "string" || !UUID_RE18.test(artifact.token_id) || typeof artifact.run_id !== "string" || !UUID_RE18.test(artifact.run_id) || typeof artifact.agent_token !== "string") {
39171
+ if (actualKeys.length !== shape.length || !actualKeys.every((key2, index) => key2 === shape[index]) || !ACCEPTED_AGENT_CREDENTIAL_MESSAGES.includes(artifact.message) || artifact.status !== "accepted" || typeof artifact.principal_id !== "string" || !UUID_RE19.test(artifact.principal_id) || typeof artifact.token_id !== "string" || !UUID_RE19.test(artifact.token_id) || typeof artifact.run_id !== "string" || !UUID_RE19.test(artifact.run_id) || typeof artifact.agent_token !== "string") {
38981
39172
  throw new Error("agent credential JSON is malformed");
38982
39173
  }
38983
39174
  let expiresAt = null;
@@ -39215,7 +39406,7 @@ async function runNew(args) {
39215
39406
  project: {
39216
39407
  workspace_id: created,
39217
39408
  name,
39218
- stream_id: typeof response.stream_id === "string" && UUID_RE18.test(response.stream_id) ? response.stream_id : null
39409
+ stream_id: typeof response.stream_id === "string" && UUID_RE19.test(response.stream_id) ? response.stream_id : null
39219
39410
  }
39220
39411
  });
39221
39412
  return;
@@ -39989,7 +40180,7 @@ async function runLinkNew(args) {
39989
40180
  2
39990
40181
  );
39991
40182
  const taskId = args.required("task-id");
39992
- if (!UUID_RE18.test(taskId)) {
40183
+ if (!UUID_RE19.test(taskId)) {
39993
40184
  throw new Error("--task-id must be the work item's UUID");
39994
40185
  }
39995
40186
  const site = capabilitySiteOrigin(
@@ -40049,7 +40240,7 @@ async function runLinkRevoke(args) {
40049
40240
  2
40050
40241
  );
40051
40242
  const capabilityId = args.required("capability-id");
40052
- if (!UUID_RE18.test(capabilityId)) {
40243
+ if (!UUID_RE19.test(capabilityId)) {
40053
40244
  throw new Error(
40054
40245
  "--capability-id must be the id printed when the link was created"
40055
40246
  );
@@ -40628,7 +40819,7 @@ async function runReply(args) {
40628
40819
  "json"
40629
40820
  ], 3);
40630
40821
  const signalId = args.positionals[1];
40631
- if (signalId === void 0 || !UUID_RE18.test(signalId)) {
40822
+ if (signalId === void 0 || !UUID_RE19.test(signalId)) {
40632
40823
  throw new Error("reply requires the signal UUID being answered");
40633
40824
  }
40634
40825
  const body = args.positionals[2];
@@ -40770,18 +40961,29 @@ async function runMembers(args) {
40770
40961
  process.stdout.write(renderRoster(directory, memberNames));
40771
40962
  }
40772
40963
  async function runSignalRead(args, inbox) {
40773
- args.assertShape([
40964
+ const notify = inbox && args.has("notify");
40965
+ args.assertShape(notify ? [
40966
+ ...TARGET_FLAGS,
40967
+ "workspace-id",
40968
+ ...CREDENTIAL_FLAGS,
40969
+ "notify",
40970
+ "json"
40971
+ ] : [
40774
40972
  ...TARGET_FLAGS,
40775
40973
  "workspace-id",
40776
40974
  ...CREDENTIAL_FLAGS,
40777
40975
  "about",
40778
40976
  "kind",
40779
- ...inbox ? ["wait", "follow", "ndjson"] : [],
40977
+ ...inbox ? ["wait", "follow", "ndjson", "notify"] : [],
40780
40978
  "since",
40781
40979
  "limit",
40782
40980
  "include-stale",
40783
40981
  "json"
40784
40982
  ], 1);
40983
+ if (notify) {
40984
+ await runInboxNotifyCommand(args);
40985
+ return;
40986
+ }
40785
40987
  if (inbox && args.has("follow")) {
40786
40988
  if (!args.has("ndjson")) {
40787
40989
  throw new Error("inbox --follow requires --ndjson");
@@ -40858,6 +41060,89 @@ async function runSignalRead(args, inbox) {
40858
41060
  })}
40859
41061
  `);
40860
41062
  }
41063
+ async function writeMonitorLine(line) {
41064
+ await new Promise((resolve, reject) => {
41065
+ process.stdout.write(`${line}
41066
+ `, (error) => {
41067
+ if (error) reject(error);
41068
+ else resolve();
41069
+ });
41070
+ });
41071
+ }
41072
+ async function runInboxNotifyCommand(args) {
41073
+ if (!args.has("agent-token-stdin")) {
41074
+ throw new Error(
41075
+ "inbox --notify is for one agent; provide its JSON credential with --agent-token-stdin"
41076
+ );
41077
+ }
41078
+ const cloud = await target(args);
41079
+ const selected = await commandWorkspaceAndCredential(args, cloud, {
41080
+ validateHumanWorkspace: true
41081
+ });
41082
+ const principalId = selected.agent?.principalId ?? null;
41083
+ if (selected.kind !== "agent" || principalId === null) {
41084
+ throw new Error(
41085
+ "inbox --notify needs the full JSON agent credential so its durable cursor is tied to one agent"
41086
+ );
41087
+ }
41088
+ const controller = new AbortController();
41089
+ const stop = () => controller.abort();
41090
+ process.on("SIGINT", stop);
41091
+ process.on("SIGTERM", stop);
41092
+ try {
41093
+ const cursorStore = fileArrivalCursorStore({
41094
+ target: cloud,
41095
+ workspaceId: selected.selectedWorkspace,
41096
+ principalId
41097
+ });
41098
+ const result = await runArrivalWatch({
41099
+ workspaceId: selected.selectedWorkspace,
41100
+ principalId,
41101
+ store: cursorStore,
41102
+ signal: controller.signal,
41103
+ readPage: async ({ after, baseline, limit }) => {
41104
+ const token = selected.session ? await selected.session.bearer() : selected.bearer;
41105
+ return await readAgentSignalPage(
41106
+ cloud,
41107
+ { kind: "agent", token },
41108
+ {
41109
+ workspaceId: selected.selectedWorkspace,
41110
+ inbox: true,
41111
+ limit,
41112
+ includeStale: false,
41113
+ ...baseline ? {} : {
41114
+ ascending: true,
41115
+ ...after === null ? {} : { after }
41116
+ }
41117
+ },
41118
+ { signal: controller.signal }
41119
+ );
41120
+ },
41121
+ emit: async (signal) => {
41122
+ const notification = arrivalNotification(
41123
+ signal,
41124
+ selected.selectedWorkspace,
41125
+ cloud
41126
+ );
41127
+ await writeMonitorLine(
41128
+ args.has("json") ? JSON.stringify(notification) : formatArrivalNotification(notification)
41129
+ );
41130
+ },
41131
+ onRetry: (_error, delayMs) => {
41132
+ process.stderr.write(
41133
+ `cswarm: arrival read failed; still watching and retrying in ${delayMs}ms.
41134
+ `
41135
+ );
41136
+ }
41137
+ });
41138
+ if (result.reason === "error") {
41139
+ throw result.error ?? new Error("arrival watch stopped");
41140
+ }
41141
+ } finally {
41142
+ process.off("SIGINT", stop);
41143
+ process.off("SIGTERM", stop);
41144
+ }
41145
+ }
40861
41146
  async function runReceipt(args) {
40862
41147
  args.assertShape([
40863
41148
  ...TARGET_FLAGS,
@@ -40866,7 +41151,7 @@ async function runReceipt(args) {
40866
41151
  "json"
40867
41152
  ], 2);
40868
41153
  const signalId = args.positionals[1];
40869
- if (!UUID_RE18.test(signalId)) {
41154
+ if (!UUID_RE19.test(signalId)) {
40870
41155
  throw new Error("signal-id must be a UUID");
40871
41156
  }
40872
41157
  if (!args.has("agent-token-stdin")) {
@@ -41004,7 +41289,7 @@ async function runInboxFollowCommand(args) {
41004
41289
  }
41005
41290
  }
41006
41291
  function listenerUuid(value, flag) {
41007
- if (!value || !UUID_RE18.test(value)) {
41292
+ if (!value || !UUID_RE19.test(value)) {
41008
41293
  throw new Error(`--${flag} must be a UUID`);
41009
41294
  }
41010
41295
  return value.toLowerCase();
@@ -41017,7 +41302,7 @@ function listenerPermissionMode(value) {
41017
41302
  function listenerStateDirectory(args) {
41018
41303
  const value = args.optional("state-dir");
41019
41304
  if (value === void 0) return void 0;
41020
- if (!(0, import_node_path19.isAbsolute)(value)) {
41305
+ if (!(0, import_node_path20.isAbsolute)(value)) {
41021
41306
  throw new Error("--state-dir must be an absolute path");
41022
41307
  }
41023
41308
  return value;
@@ -41348,7 +41633,7 @@ function resolveDetachedClaudeExecutable(executable = "claude-agent-acp", pathEn
41348
41633
  } catch (error) {
41349
41634
  const code = error.code;
41350
41635
  if (typeof code === "string") {
41351
- if ((0, import_node_path19.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
41636
+ if ((0, import_node_path20.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
41352
41637
  const detail = error instanceof Error ? error.message : code;
41353
41638
  throw new Error(
41354
41639
  `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`
@@ -41365,7 +41650,7 @@ function resolveDetachedCodexExecutable(executable = "codex-acp", pathEnv = proc
41365
41650
  } catch (error) {
41366
41651
  const code = error.code;
41367
41652
  if (typeof code === "string") {
41368
- if ((0, import_node_path19.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
41653
+ if ((0, import_node_path20.isAbsolute)(executable) || executable.includes("/") || executable.includes("\\")) {
41369
41654
  const detail = error instanceof Error ? error.message : code;
41370
41655
  throw new Error(
41371
41656
  `could not use --codex-executable: ${detail}; install the current bridge with npm install -g @agentclientprotocol/codex-acp@latest if this path should be replaced`
@@ -41632,7 +41917,7 @@ async function runListenStart(args) {
41632
41917
  assertDurableListenerCredential(agent);
41633
41918
  const principalId = agent.principalId;
41634
41919
  const cwd = args.optional("cwd") ?? process.cwd();
41635
- if (!(0, import_node_path19.isAbsolute)(cwd)) throw new Error("--cwd must be an absolute path");
41920
+ if (!(0, import_node_path20.isAbsolute)(cwd)) throw new Error("--cwd must be an absolute path");
41636
41921
  const permissionMode = listenerPermissionMode(args.optional("permissions"));
41637
41922
  const stateDirectory2 = listenerStateDirectory(args);
41638
41923
  const paths = listenerPaths({
@@ -41669,7 +41954,7 @@ async function runListenStart(args) {
41669
41954
  });
41670
41955
  } else {
41671
41956
  const entrypoint = process.argv[1];
41672
- if (!entrypoint || !(0, import_node_path19.isAbsolute)(entrypoint)) {
41957
+ if (!entrypoint || !(0, import_node_path20.isAbsolute)(entrypoint)) {
41673
41958
  throw new Error("cannot locate the cswarm executable for detached start");
41674
41959
  }
41675
41960
  const artifact = JSON.stringify(agentCredentialArtifact({
@@ -41807,7 +42092,7 @@ async function runListenSupervisor(args) {
41807
42092
  const agent = await stdinCredential();
41808
42093
  assertDurableListenerCredential(agent, principalId);
41809
42094
  const cwd = args.required("cwd");
41810
- if (!(0, import_node_path19.isAbsolute)(cwd)) throw new Error("--cwd must be an absolute path");
42095
+ if (!(0, import_node_path20.isAbsolute)(cwd)) throw new Error("--cwd must be an absolute path");
41811
42096
  const status = await runConfiguredListener({
41812
42097
  cloud,
41813
42098
  workspaceId: workspaceId2,
@@ -41909,7 +42194,7 @@ function claudeUserPromptHookSnippet() {
41909
42194
  };
41910
42195
  }
41911
42196
  function projectClaudeSettingsPath() {
41912
- return (0, import_node_path19.join)(process.cwd(), ".claude", "settings.json");
42197
+ return (0, import_node_path20.join)(process.cwd(), ".claude", "settings.json");
41913
42198
  }
41914
42199
  function readProjectSettings(path) {
41915
42200
  let raw;
@@ -42021,7 +42306,7 @@ async function runHook(args) {
42021
42306
  const path = projectClaudeSettingsPath();
42022
42307
  const settings = readProjectSettings(path);
42023
42308
  const updated = command2 === "install" ? installClaudeHook(settings) : uninstallClaudeHook(settings);
42024
- (0, import_node_fs7.mkdirSync)((0, import_node_path19.dirname)(path), { recursive: true });
42309
+ (0, import_node_fs7.mkdirSync)((0, import_node_path20.dirname)(path), { recursive: true });
42025
42310
  (0, import_node_fs7.writeFileSync)(path, `${JSON.stringify(updated, null, 2)}
42026
42311
  `, {
42027
42312
  encoding: "utf8",
@@ -42067,7 +42352,7 @@ async function fileRows(context) {
42067
42352
  );
42068
42353
  }
42069
42354
  async function resolveFileSelector(context, selector) {
42070
- if (UUID_RE18.test(selector)) return selector.toLowerCase();
42355
+ if (UUID_RE19.test(selector)) return selector.toLowerCase();
42071
42356
  const rows3 = await fileRows(context);
42072
42357
  const match = rows3.find(
42073
42358
  (row) => row.name.toLowerCase() === selector.toLowerCase()
@@ -42089,7 +42374,7 @@ async function runFilePut(args) {
42089
42374
  } catch {
42090
42375
  throw new Error(`could not read ${localPath}; check the path and permissions`);
42091
42376
  }
42092
- const name = args.optional("name") ?? (0, import_node_path19.basename)(localPath);
42377
+ const name = args.optional("name") ?? (0, import_node_path20.basename)(localPath);
42093
42378
  if (bytes.byteLength > FILE_MAX_VERSION_BYTES) {
42094
42379
  throw new Error(
42095
42380
  `this file is ${formatFileSize(bytes.byteLength)}; the per-file limit is ${formatFileSize(FILE_MAX_VERSION_BYTES)}, so the upload was not started`
@@ -42191,7 +42476,7 @@ async function runFileGet(args) {
42191
42476
  credential: context.selected.bearer
42192
42477
  };
42193
42478
  const grant = await fileDownloadUrl(send, { fileId, versionN });
42194
- const destination = args.optional("out") ?? (0, import_node_path19.basename)(grant.name);
42479
+ const destination = args.optional("out") ?? (0, import_node_path20.basename)(grant.name);
42195
42480
  const bytes = await getObject(context.cloud, grant.download_path);
42196
42481
  writeDestination(destination, bytes, args.has("force"), import_node_fs7.writeFileSync);
42197
42482
  if (args.has("json")) {
@@ -42407,7 +42692,7 @@ async function runSeed(args) {
42407
42692
  throw new Error("DATABASE_URL is required for the fixture bridge");
42408
42693
  }
42409
42694
  const tokenOut = process.env.SEED_TOKEN_OUT;
42410
- if (!tokenOut || !(0, import_node_path19.isAbsolute)(tokenOut)) {
42695
+ if (!tokenOut || !(0, import_node_path20.isAbsolute)(tokenOut)) {
42411
42696
  throw new Error("SEED_TOKEN_OUT must be an absolute path");
42412
42697
  }
42413
42698
  const tokenFile = await (0, import_promises11.open)(tokenOut, "wx", 384).catch((error) => {