commonswarm 0.1.28 → 0.1.30

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 +227 -165
  2. package/package.json +1 -1
package/cswarm.cjs CHANGED
@@ -22125,6 +22125,8 @@ var WORKSPACE_NAME_MAX_LENGTH = 80;
22125
22125
  var CAPABILITY_MIN_TTL_MS = 6e4;
22126
22126
  var CAPABILITY_MAX_TTL_MS = 7 * 24 * 60 * 60 * 1e3;
22127
22127
  var SIGNAL_REQUEST_TIMEOUT_MS = 3e4;
22128
+ var SIGNAL_WRITE_MAX_ATTEMPTS = 3;
22129
+ var SIGNAL_WRITE_RETRY_BASE_MS = 500;
22128
22130
  var CommandTransportError = class extends Error {
22129
22131
  constructor(message) {
22130
22132
  super(message);
@@ -22380,6 +22382,27 @@ async function raceSignalDeadline(work, deadline, callerAbort) {
22380
22382
  }
22381
22383
  return await Promise.race(arms);
22382
22384
  }
22385
+ function signalRetryDelayMs(retry, baseMs, random) {
22386
+ const exponential = baseMs * 2 ** (retry - 1);
22387
+ const jitter = 0.5 + Math.min(1, Math.max(0, random()));
22388
+ return Math.round(exponential * jitter);
22389
+ }
22390
+ async function waitForSignalRetry(delayMs, deadline, callerAbort) {
22391
+ if (delayMs === 0) return "elapsed";
22392
+ let timer2;
22393
+ const elapsed = new Promise((resolve) => {
22394
+ timer2 = setTimeout(() => resolve("elapsed"), delayMs);
22395
+ });
22396
+ try {
22397
+ const outcome = await raceSignalDeadline(elapsed, deadline, callerAbort);
22398
+ if (outcome.kind === "value") return outcome.value;
22399
+ if (outcome.kind === "callerAbort") return "callerAbort";
22400
+ if (outcome.kind === "deadline") return "deadline";
22401
+ throw outcome.error;
22402
+ } finally {
22403
+ if (timer2 !== void 0) clearTimeout(timer2);
22404
+ }
22405
+ }
22383
22406
  async function declareAgentModel(target2, request, fetcher = fetch) {
22384
22407
  const controller = new AbortController();
22385
22408
  const timer2 = setTimeout(() => controller.abort(), 3e4);
@@ -22416,12 +22439,14 @@ async function declareAgentModel(target2, request, fetcher = fetch) {
22416
22439
  return { httpStatus: response.status };
22417
22440
  }
22418
22441
  var ThinCommandClient = class {
22419
- constructor(target2, fetcher = fetch) {
22442
+ constructor(target2, fetcher = fetch, options = {}) {
22420
22443
  this.target = target2;
22421
22444
  this.fetcher = fetcher;
22445
+ this.options = options;
22422
22446
  }
22423
22447
  target;
22424
22448
  fetcher;
22449
+ options;
22425
22450
  projections = /* @__PURE__ */ new Map();
22426
22451
  projection(taskId) {
22427
22452
  return this.projections.get(taskId) ?? null;
@@ -22681,10 +22706,12 @@ var ThinCommandClient = class {
22681
22706
  const callerAbort = new Promise((resolve) => {
22682
22707
  releaseCallerAbort = resolve;
22683
22708
  });
22709
+ let deadlineReached = false;
22684
22710
  const timer2 = setTimeout(() => {
22711
+ deadlineReached = true;
22685
22712
  releaseDeadline?.();
22686
22713
  controller.abort();
22687
- }, SIGNAL_REQUEST_TIMEOUT_MS);
22714
+ }, this.options.signalRequestTimeoutMs ?? SIGNAL_REQUEST_TIMEOUT_MS);
22688
22715
  const onCallerAbort = () => {
22689
22716
  releaseCallerAbort?.();
22690
22717
  controller.abort();
@@ -22695,90 +22722,117 @@ var ThinCommandClient = class {
22695
22722
  controller.abort();
22696
22723
  }
22697
22724
  try {
22698
- let fetchWork;
22699
- try {
22700
- fetchWork = Promise.resolve(
22701
- this.fetcher(commandEndpoint(this.target), {
22702
- method: "POST",
22703
- headers: {
22704
- authorization: `Bearer ${request.credential}`,
22705
- apikey: this.target.anonKey,
22706
- "content-type": "application/json"
22707
- },
22708
- body: JSON.stringify({
22709
- command_id: commandId,
22710
- client_version: CLIENT_PROTOCOL_VERSION,
22711
- workspace_id: request.workspaceId,
22712
- stream: { kind: "workspace" },
22713
- command: command2
22714
- }),
22715
- signal: controller.signal
22716
- })
22717
- );
22718
- } catch (error) {
22719
- fetchWork = Promise.reject(error);
22720
- }
22721
- const fetchOutcome = await raceSignalDeadline(
22722
- fetchWork,
22723
- deadline,
22724
- callerSignal === void 0 ? void 0 : callerAbort
22725
- );
22726
- if (fetchOutcome.kind === "callerAbort") {
22727
- throw signalAbortError();
22728
- }
22729
- if (fetchOutcome.kind === "deadline") {
22730
- throw new CommandTransportError("signal request timed out");
22731
- }
22732
- if (fetchOutcome.kind === "error") {
22733
- throw new CommandTransportError(
22734
- "signal request failed before a response"
22735
- );
22736
- }
22737
- const response = fetchOutcome.value;
22738
- const bodyOutcome = await raceSignalDeadline(
22739
- parsedJson(response),
22740
- deadline,
22741
- callerSignal === void 0 ? void 0 : callerAbort
22742
- );
22743
- if (bodyOutcome.kind === "callerAbort") {
22744
- throw signalAbortError();
22745
- }
22746
- if (bodyOutcome.kind === "deadline") {
22747
- throw new CommandTransportError("signal request timed out");
22748
- }
22749
- if (bodyOutcome.kind === "error") {
22750
- if (response.status >= 400) {
22751
- throw new CommandHttpError(
22752
- response.status,
22753
- `signal failed (HTTP ${response.status})`
22754
- );
22755
- }
22756
- throw bodyOutcome.error;
22757
- }
22758
- const raw = bodyOutcome.value;
22759
- if (!response.ok) {
22760
- const error = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
22761
- throw new CommandHttpError(
22762
- response.status,
22763
- typeof error.message === "string" ? error.message : `signal failed (HTTP ${response.status}): ${typeof error.error === "string" ? error.error : "unknown_error"}`
22764
- );
22765
- }
22766
- const body = responseBody(raw);
22767
- if (body.status !== "accepted" || body.signal === void 0) {
22768
- throw new Error("signal endpoint accepted without a signal receipt");
22769
- }
22770
- if (body.min_client_version !== void 0) {
22771
- const order = compareVersion(CLIENT_PROTOCOL_VERSION, body.min_client_version);
22772
- if (order === null) {
22773
- throw new Error("server returned a malformed min_client_version");
22725
+ for (let attempt = 1; attempt <= SIGNAL_WRITE_MAX_ATTEMPTS; attempt += 1) {
22726
+ if (callerSignal?.aborted) throw signalAbortError();
22727
+ if (deadlineReached) {
22728
+ throw new CommandTransportError("signal request timed out");
22774
22729
  }
22775
- if (order < 0) {
22776
- throw new Error(
22777
- `client upgrade required (minimum ${body.min_client_version})`
22730
+ try {
22731
+ let fetchWork;
22732
+ try {
22733
+ fetchWork = Promise.resolve(
22734
+ this.fetcher(commandEndpoint(this.target), {
22735
+ method: "POST",
22736
+ headers: {
22737
+ authorization: `Bearer ${request.credential}`,
22738
+ apikey: this.target.anonKey,
22739
+ "content-type": "application/json"
22740
+ },
22741
+ body: JSON.stringify({
22742
+ // One id is minted outside the loop. Every retry is a replay.
22743
+ command_id: commandId,
22744
+ client_version: CLIENT_PROTOCOL_VERSION,
22745
+ workspace_id: request.workspaceId,
22746
+ stream: { kind: "workspace" },
22747
+ command: command2
22748
+ }),
22749
+ signal: controller.signal
22750
+ })
22751
+ );
22752
+ } catch (error) {
22753
+ fetchWork = Promise.reject(error);
22754
+ }
22755
+ const fetchOutcome = await raceSignalDeadline(
22756
+ fetchWork,
22757
+ deadline,
22758
+ callerSignal === void 0 ? void 0 : callerAbort
22778
22759
  );
22760
+ if (fetchOutcome.kind === "callerAbort") throw signalAbortError();
22761
+ if (fetchOutcome.kind === "deadline") {
22762
+ throw new CommandTransportError("signal request timed out");
22763
+ }
22764
+ if (fetchOutcome.kind === "error") {
22765
+ throw new CommandTransportError(
22766
+ "signal request failed before a response"
22767
+ );
22768
+ }
22769
+ const response = fetchOutcome.value;
22770
+ const bodyOutcome = await raceSignalDeadline(
22771
+ parsedJson(response),
22772
+ deadline,
22773
+ callerSignal === void 0 ? void 0 : callerAbort
22774
+ );
22775
+ if (bodyOutcome.kind === "callerAbort") throw signalAbortError();
22776
+ if (bodyOutcome.kind === "deadline") {
22777
+ throw new CommandTransportError("signal request timed out");
22778
+ }
22779
+ if (bodyOutcome.kind === "error") {
22780
+ if (response.status >= 400) {
22781
+ throw new CommandHttpError(
22782
+ response.status,
22783
+ `signal failed (HTTP ${response.status})`
22784
+ );
22785
+ }
22786
+ throw bodyOutcome.error;
22787
+ }
22788
+ const raw = bodyOutcome.value;
22789
+ if (!response.ok) {
22790
+ const error = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
22791
+ throw new CommandHttpError(
22792
+ response.status,
22793
+ typeof error.message === "string" ? error.message : `signal failed (HTTP ${response.status}): ${typeof error.error === "string" ? error.error : "unknown_error"}`
22794
+ );
22795
+ }
22796
+ const body = responseBody(raw);
22797
+ if (body.status !== "accepted" || body.signal === void 0) {
22798
+ throw new Error("signal endpoint accepted without a signal receipt");
22799
+ }
22800
+ if (body.min_client_version !== void 0) {
22801
+ const order = compareVersion(CLIENT_PROTOCOL_VERSION, body.min_client_version);
22802
+ if (order === null) {
22803
+ throw new Error("server returned a malformed min_client_version");
22804
+ }
22805
+ if (order < 0) {
22806
+ throw new Error(
22807
+ `client upgrade required (minimum ${body.min_client_version})`
22808
+ );
22809
+ }
22810
+ }
22811
+ return {
22812
+ httpStatus: response.status,
22813
+ response: body,
22814
+ attempts: attempt,
22815
+ retried: attempt > 1
22816
+ };
22817
+ } catch (error) {
22818
+ const transient = error instanceof CommandTransportError || error instanceof CommandHttpError && error.status >= 500;
22819
+ if (!transient || attempt === SIGNAL_WRITE_MAX_ATTEMPTS) throw error;
22820
+ const waitOutcome = await waitForSignalRetry(
22821
+ signalRetryDelayMs(
22822
+ attempt,
22823
+ this.options.signalRetryBaseMs ?? SIGNAL_WRITE_RETRY_BASE_MS,
22824
+ this.options.signalRetryRandom ?? Math.random
22825
+ ),
22826
+ deadline,
22827
+ callerSignal === void 0 ? void 0 : callerAbort
22828
+ );
22829
+ if (waitOutcome === "callerAbort") throw signalAbortError();
22830
+ if (waitOutcome === "deadline") {
22831
+ throw new CommandTransportError("signal request timed out");
22832
+ }
22779
22833
  }
22780
22834
  }
22781
- return { httpStatus: response.status, response: body };
22835
+ throw new Error("signal retry loop ended without an outcome");
22782
22836
  } finally {
22783
22837
  clearTimeout(timer2);
22784
22838
  callerSignal?.removeEventListener("abort", onCallerAbort);
@@ -28337,6 +28391,8 @@ function describeServerError(prefix, envelope) {
28337
28391
  // src/cloud/signals.ts
28338
28392
  var UUID_RE7 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
28339
28393
  var SIGNAL_KINDS = /* @__PURE__ */ new Set(["working-on", "note", "ask"]);
28394
+ var SIGNAL_BODY_DISPLAY_MAX = 8e3;
28395
+ var SIGNAL_ABOUT_DISPLAY_MAX = 500;
28340
28396
  var SIGNAL_READ_TIMEOUT_MS = 3e4;
28341
28397
  var SignalReadTimeoutError = class extends Error {
28342
28398
  constructor(message = "signal read timed out") {
@@ -28443,7 +28499,7 @@ function parseSignalRecord(value) {
28443
28499
  throw new Error("signal read returned a malformed row");
28444
28500
  }
28445
28501
  const row = value;
28446
- if (typeof row.from_kind !== "string" || !["user", "agent"].includes(row.from_kind) || typeof row.kind !== "string" || !SIGNAL_KINDS.has(row.kind) || typeof row.body !== "string" || row.body.length < 1 || row.body.length > 8e3 || !(row.about === null || typeof row.about === "string" && row.about.length <= 500)) {
28502
+ if (typeof row.from_kind !== "string" || !["user", "agent"].includes(row.from_kind) || typeof row.kind !== "string" || !SIGNAL_KINDS.has(row.kind) || typeof row.body !== "string" || row.body.length < 1 || !(row.about === null || typeof row.about === "string")) {
28447
28503
  throw new Error("signal read returned malformed signal data");
28448
28504
  }
28449
28505
  let senderOwnerRelation = "unknown";
@@ -29175,13 +29231,27 @@ function renderSignals(signals, options) {
29175
29231
  const authorName = signal.from_kind === "agent" ? options.authors?.agents.get(signal.from) : options.authors?.users.get(signal.from);
29176
29232
  const author = authorName === void 0 ? `${authorKind} ${signal.from}` : `${authorKind} ${authorName} (${signal.from})${signal.from_kind === "user" && options.authors?.currentUserId === signal.from ? " \u2014 you" : ""}`;
29177
29233
  const expired = Date.parse(signal.until) <= now ? " (expired)" : "";
29178
- const about = signal.about === null ? "" : ` about ${JSON.stringify(signal.about)}`;
29234
+ const aboutClipped = signal.about !== null && signal.about.length > SIGNAL_ABOUT_DISPLAY_MAX;
29235
+ const displayedAbout = aboutClipped ? signal.about.slice(0, SIGNAL_ABOUT_DISPLAY_MAX) : signal.about;
29236
+ const about = displayedAbout === null ? "" : ` about ${JSON.stringify(displayedAbout)}`;
29179
29237
  const replyTo = (signal.in_reply_to ?? null) === null ? "" : ` \u2014 in reply to ${signal.in_reply_to}`;
29180
29238
  const replyable = signal.kind === "ask";
29181
29239
  const idHint = replyable ? ` \u2014 reply with: cswarm reply ${signal.id}` : "";
29240
+ const bodyClipped = signal.body.length > SIGNAL_BODY_DISPLAY_MAX;
29241
+ const displayedBody = bodyClipped ? signal.body.slice(0, SIGNAL_BODY_DISPLAY_MAX) : signal.body;
29182
29242
  lines.push(
29183
- `- [${signal.kind}] ${author} \u2014 ${relativeAge(signal.created_at, now)} \u2014 ${relativeExpiry(signal.until, now)}${expired}${about}${replyTo}: ${JSON.stringify(signal.body)}${idHint}`
29243
+ `- [${signal.kind}] ${author} \u2014 ${relativeAge(signal.created_at, now)} \u2014 ${relativeExpiry(signal.until, now)}${expired}${about}${replyTo}: ${JSON.stringify(displayedBody)}${idHint}`
29184
29244
  );
29245
+ if (bodyClipped) {
29246
+ lines.push(
29247
+ ` WARNING: Body clipped for display. Showing ${SIGNAL_BODY_DISPLAY_MAX} of ${signal.body.length} characters. Use --json to read the full body.`
29248
+ );
29249
+ }
29250
+ if (aboutClipped) {
29251
+ lines.push(
29252
+ ` WARNING: About reference clipped for display. Showing ${SIGNAL_ABOUT_DISPLAY_MAX} of ${signal.about.length} characters. Use --json to read the full reference.`
29253
+ );
29254
+ }
29185
29255
  }
29186
29256
  return lines.join("\n");
29187
29257
  }
@@ -29508,6 +29578,8 @@ var import_node_crypto12 = require("node:crypto");
29508
29578
  // src/host/stderr-tail.ts
29509
29579
  var RING_CAPACITY_BYTES = 4096;
29510
29580
  var TAIL_MAX_CHARS = 2048;
29581
+ var STDERR_EXIT_GRACE_MS = 100;
29582
+ var STDERR_READABLE_END_GRACE_MS = STDERR_EXIT_GRACE_MS + 50;
29511
29583
  var EXOTIC_SEPARATORS = "\\u00a0\\u1680\\u2000-\\u200d\\u2028\\u2029\\u202a-\\u202e\\u2060\\u2066-\\u2069\\u202f\\u205f\\u3000\\ufeff";
29512
29584
  var SEPARATOR_CLASS_SOURCE = "\\t\\n\\x0b\\f\\r " + EXOTIC_SEPARATORS;
29513
29585
  var ANSI_ESCAPE_GLOBAL_RE2 = new RegExp("\\u001b\\[[0-?]*[ -\\/]*[@-~]", "g");
@@ -29555,6 +29627,34 @@ function attachStderrTailRing(stderr) {
29555
29627
  }
29556
29628
  };
29557
29629
  }
29630
+ function attachStderrTailExitObserver(child, onStderrTail) {
29631
+ const stderrTail = attachStderrTailRing(child.stderr);
29632
+ return (handler) => {
29633
+ const observeExit = (code, signal) => {
29634
+ let completed = false;
29635
+ let timer2 = null;
29636
+ const complete = () => {
29637
+ if (completed) return;
29638
+ completed = true;
29639
+ if (timer2) clearTimeout(timer2);
29640
+ child.removeListener("close", complete);
29641
+ try {
29642
+ onStderrTail?.(stderrTail.read());
29643
+ } finally {
29644
+ handler(code, signal);
29645
+ }
29646
+ };
29647
+ child.once("close", complete);
29648
+ timer2 = setTimeout(complete, STDERR_EXIT_GRACE_MS);
29649
+ timer2.unref();
29650
+ };
29651
+ if (child.exitCode !== null || child.signalCode !== null) {
29652
+ observeExit(child.exitCode, child.signalCode);
29653
+ } else {
29654
+ child.once("exit", observeExit);
29655
+ }
29656
+ };
29657
+ }
29558
29658
 
29559
29659
  // src/host/opencode.ts
29560
29660
  var import_node_fs3 = require("node:fs");
@@ -31351,27 +31451,18 @@ async function openOpenCodeAcpSession(options) {
31351
31451
  await disposeHome();
31352
31452
  throw new AcpHostError("spawn_failed", "child missing stdio pipes");
31353
31453
  }
31354
- const stderrTail = attachStderrTailRing(child.stderr);
31355
- if (options.onStderrTail) {
31356
- const deliverTail = options.onStderrTail;
31357
- let tailDelivered = false;
31358
- const publishTail = () => {
31359
- if (tailDelivered) return;
31360
- tailDelivered = true;
31361
- deliverTail(stderrTail.read());
31362
- };
31363
- child.once("exit", publishTail);
31364
- child.once("close", publishTail);
31365
- }
31454
+ const observeStderrTailOnExit = attachStderrTailExitObserver(
31455
+ child,
31456
+ options.onStderrTail
31457
+ );
31366
31458
  let sessionRef = null;
31367
31459
  const transport = createBoundTransport({
31368
31460
  readable: child.stdout,
31369
31461
  writable: child.stdin,
31370
31462
  requestTimeoutMs: options.requestTimeoutMs ?? ACP_DEFAULT_REQUEST_TIMEOUT_MS,
31463
+ readableEndGraceMs: STDERR_READABLE_END_GRACE_MS,
31371
31464
  getSession: () => sessionRef,
31372
- onChildExit: (handler) => {
31373
- child.on("exit", (code, signal) => handler(code, signal));
31374
- }
31465
+ onChildExit: observeStderrTailOnExit
31375
31466
  });
31376
31467
  try {
31377
31468
  const session = await AcpHostSession.connect({
@@ -31427,8 +31518,6 @@ var import_node_fs4 = require("node:fs");
31427
31518
  var import_node_path6 = require("node:path");
31428
31519
  var CHILD_EXIT_WAIT_MS2 = 3e3;
31429
31520
  var CHILD_KILL_WAIT_MS2 = 1e3;
31430
- var STDERR_EXIT_GRACE_MS = 100;
31431
- var READABLE_END_GRACE_MS = STDERR_EXIT_GRACE_MS + 50;
31432
31521
  var WINDOWS_NPM_SHIM_MAX_BYTES = 64 * 1024;
31433
31522
  var WINDOWS_NPM_ENTRYPOINT = [
31434
31523
  "node_modules",
@@ -31725,35 +31814,18 @@ async function openClaudeAcpSession(options) {
31725
31814
  await terminateClaudeChild(child);
31726
31815
  throw new AcpHostError("spawn_failed", "child missing stdio pipes");
31727
31816
  }
31728
- const stderrTail = attachStderrTailRing(child.stderr);
31817
+ const observeStderrTailOnExit = attachStderrTailExitObserver(
31818
+ child,
31819
+ options.onStderrTail
31820
+ );
31729
31821
  let sessionRef = null;
31730
31822
  const transport = createBoundTransport({
31731
31823
  readable: child.stdout,
31732
31824
  writable: child.stdin,
31733
31825
  requestTimeoutMs: options.requestTimeoutMs ?? ACP_DEFAULT_REQUEST_TIMEOUT_MS,
31734
- readableEndGraceMs: READABLE_END_GRACE_MS,
31826
+ readableEndGraceMs: STDERR_READABLE_END_GRACE_MS,
31735
31827
  getSession: () => sessionRef,
31736
- onChildExit: (handler) => {
31737
- const observeExit = (code, signal) => {
31738
- let completed = false;
31739
- let timer2 = null;
31740
- const complete = () => {
31741
- if (completed) return;
31742
- completed = true;
31743
- if (timer2) clearTimeout(timer2);
31744
- child.removeListener("close", complete);
31745
- options.onStderrTail?.(stderrTail.read());
31746
- handler(code, signal);
31747
- };
31748
- child.once("close", complete);
31749
- timer2 = setTimeout(complete, STDERR_EXIT_GRACE_MS);
31750
- };
31751
- if (child.exitCode !== null || child.signalCode !== null) {
31752
- observeExit(child.exitCode, child.signalCode);
31753
- } else {
31754
- child.once("exit", observeExit);
31755
- }
31756
- }
31828
+ onChildExit: observeStderrTailOnExit
31757
31829
  });
31758
31830
  try {
31759
31831
  const session = await Promise.race([
@@ -32022,27 +32094,18 @@ async function openCodexAcpSession(options) {
32022
32094
  await terminateCodexChild(child);
32023
32095
  throw new AcpHostError("spawn_failed", "child missing stdio pipes");
32024
32096
  }
32025
- const stderrTail = attachStderrTailRing(child.stderr);
32026
- if (options.onStderrTail) {
32027
- const deliverTail = options.onStderrTail;
32028
- let tailDelivered = false;
32029
- const publishTail = () => {
32030
- if (tailDelivered) return;
32031
- tailDelivered = true;
32032
- deliverTail(stderrTail.read());
32033
- };
32034
- child.once("exit", publishTail);
32035
- child.once("close", publishTail);
32036
- }
32097
+ const observeStderrTailOnExit = attachStderrTailExitObserver(
32098
+ child,
32099
+ options.onStderrTail
32100
+ );
32037
32101
  let sessionRef = null;
32038
32102
  const transport = createBoundTransport({
32039
32103
  readable: child.stdout,
32040
32104
  writable: child.stdin,
32041
32105
  requestTimeoutMs: options.requestTimeoutMs ?? ACP_DEFAULT_REQUEST_TIMEOUT_MS,
32106
+ readableEndGraceMs: STDERR_READABLE_END_GRACE_MS,
32042
32107
  getSession: () => sessionRef,
32043
- onChildExit: (handler) => {
32044
- child.on("exit", (code, signal) => handler(code, signal));
32045
- }
32108
+ onChildExit: observeStderrTailOnExit
32046
32109
  });
32047
32110
  try {
32048
32111
  const session = await Promise.race([
@@ -32571,7 +32634,7 @@ var import_node_path8 = require("node:path");
32571
32634
  var import_node_util = require("node:util");
32572
32635
  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;
32573
32636
  var COMMAND_ID_RE2 = /^[A-Za-z0-9_-]{8,72}$/;
32574
- var MAX_EFFECT_BYTES = 32 * 1024;
32637
+ var MAX_EFFECT_BYTES = 1024 * 1024;
32575
32638
  var STATES = /* @__PURE__ */ new Set([
32576
32639
  "received",
32577
32640
  "prompting",
@@ -32653,7 +32716,7 @@ function parseListenerEffectRecord(raw, expectedId) {
32653
32716
  return parseV2Record(row);
32654
32717
  }
32655
32718
  function upcastV1Ask(row) {
32656
- if (row.effectOrdinal !== 0 || typeof row.commandId !== "string" || !COMMAND_ID_RE2.test(row.commandId) || typeof row.askBody !== "string" || row.askBody.length < 1 || row.askBody.length > 2e3 || 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))) {
32719
+ 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))) {
32657
32720
  throw new Error("stored listener effect is malformed");
32658
32721
  }
32659
32722
  if (row.replySignalId !== null && !UUID_RE9.test(row.replySignalId)) {
@@ -32680,7 +32743,7 @@ function upcastV1Ask(row) {
32680
32743
  }
32681
32744
  function parseV2Record(row) {
32682
32745
  const signalKind2 = row.signalKind;
32683
- if (typeof signalKind2 !== "string" || !SIGNAL_KINDS2.has(signalKind2) || row.effectOrdinal !== 0 || typeof row.askBody !== "string" || row.askBody.length < 1 || row.askBody.length > 2e3 || 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))) {
32746
+ if (typeof signalKind2 !== "string" || !SIGNAL_KINDS2.has(signalKind2) || row.effectOrdinal !== 0 || 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))) {
32684
32747
  throw new Error("stored listener effect is malformed");
32685
32748
  }
32686
32749
  if (signalKind2 === "note") {
@@ -32722,7 +32785,7 @@ function newObservedNoteRecord(input) {
32722
32785
  if (!UUID_RE9.test(input.signalId)) {
32723
32786
  throw new Error("listener note signal id must be a UUID");
32724
32787
  }
32725
- if (input.body.length < 1 || input.body.length > 2e3) {
32788
+ if (input.body.length < 1) {
32726
32789
  throw new Error("listener note body is invalid");
32727
32790
  }
32728
32791
  if (!Number.isFinite(Date.parse(input.until))) {
@@ -32996,27 +33059,18 @@ async function openGrokAcpSession(options) {
32996
33059
  child.kill("SIGKILL");
32997
33060
  throw new AcpHostError("spawn_failed", "child missing stdio pipes");
32998
33061
  }
32999
- const stderrTail = attachStderrTailRing(child.stderr);
33000
- if (options.onStderrTail) {
33001
- const deliverTail = options.onStderrTail;
33002
- let tailDelivered = false;
33003
- const publishTail = () => {
33004
- if (tailDelivered) return;
33005
- tailDelivered = true;
33006
- deliverTail(stderrTail.read());
33007
- };
33008
- child.once("exit", publishTail);
33009
- child.once("close", publishTail);
33010
- }
33062
+ const observeStderrTailOnExit = attachStderrTailExitObserver(
33063
+ child,
33064
+ options.onStderrTail
33065
+ );
33011
33066
  let sessionRef = null;
33012
33067
  const transport = createBoundTransport({
33013
33068
  readable: child.stdout,
33014
33069
  writable: child.stdin,
33015
33070
  requestTimeoutMs: options.requestTimeoutMs ?? ACP_DEFAULT_REQUEST_TIMEOUT_MS,
33071
+ readableEndGraceMs: STDERR_READABLE_END_GRACE_MS,
33016
33072
  getSession: () => sessionRef,
33017
- onChildExit: (handler) => {
33018
- child.on("exit", (code, signal) => handler(code, signal));
33019
- }
33073
+ onChildExit: observeStderrTailOnExit
33020
33074
  });
33021
33075
  try {
33022
33076
  const session = await AcpHostSession.connect({
@@ -34556,7 +34610,7 @@ function parseEntry(value) {
34556
34610
  if (Object.keys(row).some((key2) => !allowed.has(key2))) {
34557
34611
  throw new Error("stored pending-for-main entry is malformed");
34558
34612
  }
34559
- if (typeof row.signalId !== "string" || !UUID_RE11.test(row.signalId) || typeof row.workspaceId !== "string" || !UUID_RE11.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE11.test(row.principalId) || typeof row.fromId !== "string" || !UUID_RE11.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 || row.body.length > 2e3 || !checkedTimestamp2(row.createdAt) || !checkedTimestamp2(row.queuedAt)) {
34613
+ if (typeof row.signalId !== "string" || !UUID_RE11.test(row.signalId) || typeof row.workspaceId !== "string" || !UUID_RE11.test(row.workspaceId) || typeof row.principalId !== "string" || !UUID_RE11.test(row.principalId) || typeof row.fromId !== "string" || !UUID_RE11.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)) {
34560
34614
  throw new Error("stored pending-for-main entry is malformed");
34561
34615
  }
34562
34616
  return {
@@ -38135,8 +38189,8 @@ var ACCEPTED_AGENT_CREDENTIAL_MESSAGES = [
38135
38189
  AGENT_CREDENTIAL_MESSAGE_D088
38136
38190
  ];
38137
38191
  function packageVersion() {
38138
- if ("0.1.28".length > 0) {
38139
- return "0.1.28";
38192
+ if ("0.1.30".length > 0) {
38193
+ return "0.1.30";
38140
38194
  }
38141
38195
  try {
38142
38196
  const value = JSON.parse(
@@ -40023,7 +40077,11 @@ async function runPostSignal(args, kind) {
40023
40077
  }
40024
40078
  const reply = waitResult.signals[0] ?? null;
40025
40079
  if (args.has("json")) {
40026
- printJson(askWaitJsonPayload(signal, reply, waitResult.timedOut));
40080
+ printJson({
40081
+ ...askWaitJsonPayload(signal, reply, waitResult.timedOut),
40082
+ retried: result.retried,
40083
+ attempts: result.attempts
40084
+ });
40027
40085
  return;
40028
40086
  }
40029
40087
  const authors2 = await settleSignalAuthorLabels(
@@ -40060,7 +40118,9 @@ ${renderSignals([signal, reply], {
40060
40118
  printJson({
40061
40119
  status: result.response.status,
40062
40120
  message: "Signal shared. It is immutable, tenancy-scoped, and will quietly expire at its horizon.",
40063
- signal
40121
+ signal,
40122
+ retried: result.retried,
40123
+ attempts: result.attempts
40064
40124
  });
40065
40125
  return;
40066
40126
  }
@@ -40150,7 +40210,9 @@ async function runReply(args) {
40150
40210
  printJson({
40151
40211
  status: result.response.status,
40152
40212
  message: "Reply shared. It is immutable, tenancy-scoped, and will quietly expire at its horizon.",
40153
- signal
40213
+ signal,
40214
+ retried: result.retried,
40215
+ attempts: result.attempts
40154
40216
  });
40155
40217
  return;
40156
40218
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "commonswarm",
3
- "version": "0.1.28",
3
+ "version": "0.1.30",
4
4
  "description": "CommonSwarm CLI — coordination for teams where people and AI agents work side by side.",
5
5
  "bin": {
6
6
  "cswarm": "cswarm.cjs"