@wrongstack/core 0.301.0 → 0.302.2

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 (44) hide show
  1. package/dist/agent-status-tracker.d.ts +6 -2
  2. package/dist/chronicle/index.js +1836 -1645
  3. package/dist/chronicle/metrics-store.d.ts +14 -0
  4. package/dist/chronicle/project-server-protocol.d.ts +13 -0
  5. package/dist/chronicle/project-server.js +1759 -1583
  6. package/dist/chronicle/rollup-adapter.d.ts +2 -0
  7. package/dist/chronicle/sqlite-journal.d.ts +59 -0
  8. package/dist/coordination/index.js +791 -249
  9. package/dist/coordination/mail-tools.d.ts +2 -2
  10. package/dist/core/continue-intent.d.ts +2 -0
  11. package/dist/core/conversation-state.d.ts +5 -0
  12. package/dist/core/index.js +120 -19
  13. package/dist/defaults/index.js +928 -374
  14. package/dist/execution/index.js +28 -11
  15. package/dist/index.d.ts +3 -1
  16. package/dist/index.js +8763 -6781
  17. package/dist/infrastructure/index.js +722 -672
  18. package/dist/kernel/events/memory-events.d.ts +62 -0
  19. package/dist/plugin/index.js +2154 -1979
  20. package/dist/session-catalog/client.d.ts +62 -0
  21. package/dist/session-catalog/endpoint.d.ts +6 -0
  22. package/dist/session-catalog/index.d.ts +6 -0
  23. package/dist/session-catalog/index.js +1978 -0
  24. package/dist/session-catalog/project-server.d.ts +3 -0
  25. package/dist/session-catalog/project-server.js +1838 -0
  26. package/dist/session-catalog/protocol.d.ts +275 -0
  27. package/dist/session-catalog/registry.d.ts +59 -0
  28. package/dist/session-catalog/store.d.ts +55 -0
  29. package/dist/session-registry-types.d.ts +17 -0
  30. package/dist/session-registry.d.ts +1 -1
  31. package/dist/storage/index.d.ts +42 -38
  32. package/dist/storage/index.js +14279 -13393
  33. package/dist/storage/session-event-bridge.d.ts +2 -2
  34. package/dist/storage/session-store.d.ts +6 -0
  35. package/dist/tools/index.js +8 -2
  36. package/dist/types/context-evidence.d.ts +2 -0
  37. package/dist/types/messages.d.ts +8 -0
  38. package/dist/types/session.d.ts +19 -0
  39. package/dist/utils/context-evidence.d.ts +13 -1
  40. package/dist/utils/index.js +26 -2
  41. package/instructions/system-lite.md +11 -2
  42. package/instructions/system-pro.md +14 -0
  43. package/instructions/system.md +14 -0
  44. package/package.json +7 -3
@@ -224,7 +224,7 @@ var InMemoryAgentBridge = class {
224
224
  });
225
225
  }
226
226
  this.inflightGuards.add(correlationId);
227
- return new Promise((resolve14, reject) => {
227
+ return new Promise((resolve16, reject) => {
228
228
  const timer = setTimeout(() => {
229
229
  this.inflightGuards.delete(correlationId);
230
230
  this.pendingRequests.delete(correlationId);
@@ -243,7 +243,7 @@ var InMemoryAgentBridge = class {
243
243
  return;
244
244
  }
245
245
  this.pendingRequests.set(correlationId, {
246
- resolve: resolve14,
246
+ resolve: resolve16,
247
247
  reject,
248
248
  timer
249
249
  });
@@ -592,13 +592,13 @@ var SubagentBudget = class _SubagentBudget {
592
592
  if (!bus?.hasListenerFor("budget.threshold_reached")) {
593
593
  return Promise.resolve("stop");
594
594
  }
595
- return new Promise((resolve14) => {
595
+ return new Promise((resolve16) => {
596
596
  let resolved = false;
597
597
  const respond = (d) => {
598
598
  if (resolved) return;
599
599
  resolved = true;
600
600
  clearTimeout(fallback);
601
- resolve14(d);
601
+ resolve16(d);
602
602
  };
603
603
  const fallback = setTimeout(() => respond("stop"), _SubagentBudget.DECISION_TIMEOUT_MS);
604
604
  const sessionId = this.currentSessionId();
@@ -6265,13 +6265,13 @@ var BrainDecisionQueue = class {
6265
6265
  options: request.options,
6266
6266
  rationale: "Decision escalated to human authority."
6267
6267
  };
6268
- const pending = new Promise((resolve14) => {
6269
- const entry = { request, resolve: resolve14 };
6268
+ const pending = new Promise((resolve16) => {
6269
+ const entry = { request, resolve: resolve16 };
6270
6270
  if (this.opts.timeoutMs && this.opts.timeoutMs > 0) {
6271
6271
  entry.timer = setTimeout(() => {
6272
6272
  this.pending.delete(request.id);
6273
6273
  markDecisionTier(request, "terminal");
6274
- resolve14(
6274
+ resolve16(
6275
6275
  this.opts.onTimeout?.(request) ?? {
6276
6276
  type: "deny",
6277
6277
  reason: "Brain human decision timed out."
@@ -7050,26 +7050,26 @@ var BrainMonitor = class {
7050
7050
  trackFileChurn(toolName, ok, input) {
7051
7051
  if (!this.signals.fileChurn) return;
7052
7052
  if (!ok || !this.fileEditTools.has(toolName.toLowerCase())) return;
7053
- const path34 = editedPath(input);
7054
- if (!path34) return;
7053
+ const path36 = editedPath(input);
7054
+ if (!path36) return;
7055
7055
  const now = Date.now();
7056
- const stamps = (this.editTimestamps.get(path34) ?? []).filter(
7056
+ const stamps = (this.editTimestamps.get(path36) ?? []).filter(
7057
7057
  (t) => now - t <= this.fileChurnWindowMs
7058
7058
  );
7059
7059
  stamps.push(now);
7060
7060
  if (stamps.length >= this.fileChurnThreshold) {
7061
- this.editTimestamps.delete(path34);
7061
+ this.editTimestamps.delete(path36);
7062
7062
  void this.engage("file_churn", {
7063
- question: `The file "${path34}" has been edited ${stamps.length} times within ${Math.round(this.fileChurnWindowMs / 6e4)} minutes \u2014 the agent may be oscillating (edit/revert loop) instead of converging. Should it be steered?`,
7063
+ question: `The file "${path36}" has been edited ${stamps.length} times within ${Math.round(this.fileChurnWindowMs / 6e4)} minutes \u2014 the agent may be oscillating (edit/revert loop) instead of converging. Should it be steered?`,
7064
7064
  context: [
7065
- `File: ${path34}`,
7065
+ `File: ${path36}`,
7066
7066
  `Edits in window: ${stamps.length}`,
7067
7067
  `Window: ${Math.round(this.fileChurnWindowMs / 1e3)}s`
7068
7068
  ].join("\n")
7069
7069
  });
7070
7070
  return;
7071
7071
  }
7072
- this.editTimestamps.set(path34, stamps);
7072
+ this.editTimestamps.set(path36, stamps);
7073
7073
  }
7074
7074
  async engage(kind, input) {
7075
7075
  const last = this.lastEngagedAt.get(kind) ?? 0;
@@ -8998,7 +8998,7 @@ async function gitOtherWorktrees(cwd, signal) {
8998
8998
  return branches.slice(1);
8999
8999
  }
9000
9000
  function runGit(args, cwd, signal) {
9001
- return new Promise((resolve14, reject) => {
9001
+ return new Promise((resolve16, reject) => {
9002
9002
  let stdout = "";
9003
9003
  let stderr = "";
9004
9004
  const child = spawn("git", args, {
@@ -9017,7 +9017,7 @@ function runGit(args, cwd, signal) {
9017
9017
  });
9018
9018
  child.on("error", (err) => reject(err));
9019
9019
  child.on("close", (code) => {
9020
- if (code === 0) resolve14(stdout);
9020
+ if (code === 0) resolve16(stdout);
9021
9021
  else reject(new Error(stderr || `git ${args[0]} exited ${code}`));
9022
9022
  });
9023
9023
  });
@@ -9516,7 +9516,7 @@ function createDelegateTool(opts) {
9516
9516
  };
9517
9517
  }
9518
9518
  async function awaitDelegateAttempt(director, subagentId, taskId, timeoutMs, abortSignal) {
9519
- return new Promise((resolve14) => {
9519
+ return new Promise((resolve16) => {
9520
9520
  let settled = false;
9521
9521
  let timer;
9522
9522
  let offAbort = () => {
@@ -9529,7 +9529,7 @@ async function awaitDelegateAttempt(director, subagentId, taskId, timeoutMs, abo
9529
9529
  offIter();
9530
9530
  offProgress();
9531
9531
  offAbort();
9532
- resolve14(value);
9532
+ resolve16(value);
9533
9533
  };
9534
9534
  const arm = () => {
9535
9535
  if (timer) clearTimeout(timer);
@@ -9894,7 +9894,7 @@ function attachDepWatcherBridge(opts) {
9894
9894
  }
9895
9895
 
9896
9896
  // src/coordination/director.ts
9897
- import { randomUUID as randomUUID13 } from "node:crypto";
9897
+ import { randomUUID as randomUUID14 } from "node:crypto";
9898
9898
  import * as fsp19 from "node:fs/promises";
9899
9899
 
9900
9900
  // src/core/instruction-template.ts
@@ -10746,10 +10746,10 @@ var DirectorTaskRegistry = class _DirectorTaskRegistry {
10746
10746
  pending: taskIds.filter((id) => !done.has(id))
10747
10747
  });
10748
10748
  }
10749
- return new Promise((resolve14) => {
10749
+ return new Promise((resolve16) => {
10750
10750
  const entry = {
10751
10751
  ids: new Set(taskIds),
10752
- resolve: (result) => resolve14({
10752
+ resolve: (result) => resolve16({
10753
10753
  completed: [result],
10754
10754
  pending: taskIds.filter((id) => id !== result.taskId)
10755
10755
  })
@@ -10757,7 +10757,7 @@ var DirectorTaskRegistry = class _DirectorTaskRegistry {
10757
10757
  if (opts?.timeoutMs !== void 0) {
10758
10758
  entry.timer = setTimeout(() => {
10759
10759
  this.anyWaiters.delete(entry);
10760
- resolve14({ completed: [], pending: [...taskIds], timedOut: true });
10760
+ resolve16({ completed: [], pending: [...taskIds], timedOut: true });
10761
10761
  }, opts.timeoutMs);
10762
10762
  }
10763
10763
  this.anyWaiters.add(entry);
@@ -10875,11 +10875,11 @@ ${JSON.stringify(result.result, null, 2)}
10875
10875
  this.makeStoppedResult(taskId, "director", `Unknown task id "${taskId}" \u2014 never assigned`)
10876
10876
  );
10877
10877
  }
10878
- let resolve14;
10878
+ let resolve16;
10879
10879
  const promise = new Promise((done) => {
10880
- resolve14 = done;
10880
+ resolve16 = done;
10881
10881
  });
10882
- this.taskWaiters.set(taskId, { promise, resolve: resolve14 });
10882
+ this.taskWaiters.set(taskId, { promise, resolve: resolve16 });
10883
10883
  return promise;
10884
10884
  }
10885
10885
  recordAssignment(task) {
@@ -12769,11 +12769,394 @@ function rosterSummaryFromConfigs(roster) {
12769
12769
 
12770
12770
  // src/coordination/director-session.ts
12771
12771
  import * as fsp18 from "node:fs/promises";
12772
- import * as path24 from "node:path";
12772
+ import * as path26 from "node:path";
12773
12773
 
12774
12774
  // src/storage/session-store.ts
12775
+ import { randomUUID as randomUUID12 } from "node:crypto";
12775
12776
  import * as fsp17 from "node:fs/promises";
12776
- import * as path23 from "node:path";
12777
+ import * as path25 from "node:path";
12778
+
12779
+ // src/session-catalog/client.ts
12780
+ import { spawn as spawn2 } from "node:child_process";
12781
+ import * as fs3 from "node:fs";
12782
+ import * as net from "node:net";
12783
+ import * as path15 from "node:path";
12784
+ import { fileURLToPath as fileURLToPath3 } from "node:url";
12785
+
12786
+ // src/session-catalog/endpoint.ts
12787
+ import { createHash as createHash2 } from "node:crypto";
12788
+ import * as os2 from "node:os";
12789
+ import * as path14 from "node:path";
12790
+
12791
+ // src/session-catalog/protocol.ts
12792
+ var SESSION_CATALOG_PROTOCOL_VERSION = 1;
12793
+ var SESSION_CATALOG_MAX_FRAME_CHARS = 4 * 1024 * 1024;
12794
+ function encodeSessionCatalogMessage(message) {
12795
+ return `${JSON.stringify(message)}
12796
+ `;
12797
+ }
12798
+
12799
+ // src/session-catalog/endpoint.ts
12800
+ var SESSION_CATALOG_METADATA_FILE = ".session-catalog-server.json";
12801
+ function normalizedPath(value) {
12802
+ const resolved = path14.resolve(value);
12803
+ return process.platform === "win32" ? resolved.toLowerCase() : resolved;
12804
+ }
12805
+ function sessionCatalogProjectServerKey(projectDir) {
12806
+ return createHash2("sha256").update(normalizedPath(projectDir)).digest("hex").slice(0, 24);
12807
+ }
12808
+ function sessionCatalogProjectServerEndpoint(projectDir) {
12809
+ const key = sessionCatalogProjectServerKey(projectDir);
12810
+ if (process.platform === "win32") {
12811
+ return `\\\\.\\pipe\\wrongstack-session-catalog-v${SESSION_CATALOG_PROTOCOL_VERSION}-${key}`;
12812
+ }
12813
+ return path14.join(os2.tmpdir(), `wssc-v${SESSION_CATALOG_PROTOCOL_VERSION}`, `${key}.sock`);
12814
+ }
12815
+ function sessionCatalogProjectServerMetadataPath(projectDir) {
12816
+ return path14.join(projectDir, SESSION_CATALOG_METADATA_FILE);
12817
+ }
12818
+
12819
+ // src/session-catalog/client.ts
12820
+ var CONNECT_TIMEOUT_MS = 750;
12821
+ var START_TIMEOUT_MS = 1e4;
12822
+ var CALL_TIMEOUT_MS = 3e4;
12823
+ var MAX_PENDING_REQUESTS = 1024;
12824
+ var MAX_EVENT_LISTENERS = 64;
12825
+ function locateServer(moduleUrl, exists) {
12826
+ for (const candidate of [
12827
+ "./project-server.js",
12828
+ "../session-catalog/project-server.js",
12829
+ "./session-catalog/project-server.js",
12830
+ "../../dist/session-catalog/project-server.js"
12831
+ ]) {
12832
+ try {
12833
+ const url = new URL(candidate, moduleUrl);
12834
+ if (url.protocol === "file:" && exists(fileURLToPath3(url))) return url;
12835
+ } catch {
12836
+ }
12837
+ }
12838
+ return null;
12839
+ }
12840
+ function resolveSessionCatalogDaemonAvailability(moduleUrl = import.meta.url, exists = fs3.existsSync) {
12841
+ if (process.env["WRONGSTACK_SESSION_CATALOG_INLINE"] || process.env["WRONGSTACK_SESSION_CATALOG_SERVER"] === "0")
12842
+ return { kind: "inline-requested" };
12843
+ const url = locateServer(moduleUrl, exists);
12844
+ return url ? { kind: "available", url } : { kind: "missing-build" };
12845
+ }
12846
+ function resolveSessionCatalogProjectServerUrl(moduleUrl = import.meta.url, exists = fs3.existsSync) {
12847
+ const availability = resolveSessionCatalogDaemonAvailability(moduleUrl, exists);
12848
+ return availability.kind === "available" ? availability.url : null;
12849
+ }
12850
+ function normalize2(value) {
12851
+ const resolved = path15.resolve(value);
12852
+ return process.platform === "win32" ? resolved.toLowerCase() : resolved;
12853
+ }
12854
+ function delay(ms) {
12855
+ return new Promise((resolve16) => setTimeout(resolve16, ms));
12856
+ }
12857
+ var SessionCatalogProjectClient = class {
12858
+ constructor(options) {
12859
+ this.options = options;
12860
+ this.endpoint = sessionCatalogProjectServerEndpoint(options.projectDir);
12861
+ }
12862
+ options;
12863
+ endpoint;
12864
+ socket = null;
12865
+ info = null;
12866
+ buffer = "";
12867
+ connecting = null;
12868
+ connectResolve = null;
12869
+ connectReject = null;
12870
+ authToken;
12871
+ nextId = 1;
12872
+ pending = /* @__PURE__ */ new Map();
12873
+ eventListeners = /* @__PURE__ */ new Set();
12874
+ reconnectTimer;
12875
+ explicitlyClosed = false;
12876
+ async call(op, args, options = {}) {
12877
+ await this.ensureConnected(true);
12878
+ return this.request({ type: "request", op, args }, options.timeoutMs ?? CALL_TIMEOUT_MS);
12879
+ }
12880
+ /**
12881
+ * Call an already-running project daemon without starting one.
12882
+ *
12883
+ * Cross-project discovery must use this path: observing another project is
12884
+ * never sufficient authority to wake that project's IPC owner.
12885
+ */
12886
+ async callExisting(op, args, options = {}) {
12887
+ await this.ensureConnected(false);
12888
+ return this.request({ type: "request", op, args }, options.timeoutMs ?? CALL_TIMEOUT_MS);
12889
+ }
12890
+ ping() {
12891
+ return this.call("ping", {}, { timeoutMs: 3e3 });
12892
+ }
12893
+ async subscribe(listener) {
12894
+ if (!this.eventListeners.has(listener) && this.eventListeners.size >= MAX_EVENT_LISTENERS) {
12895
+ throw new Error(`Session Catalog listener limit reached (${MAX_EVENT_LISTENERS})`);
12896
+ }
12897
+ this.explicitlyClosed = false;
12898
+ this.eventListeners.add(listener);
12899
+ try {
12900
+ await this.call("subscribe", {});
12901
+ } catch (error) {
12902
+ this.eventListeners.delete(listener);
12903
+ throw error;
12904
+ }
12905
+ return async () => {
12906
+ this.eventListeners.delete(listener);
12907
+ if (this.eventListeners.size === 0)
12908
+ await this.callExisting("unsubscribe", {}).catch(() => void 0);
12909
+ };
12910
+ }
12911
+ async shutdown(reason) {
12912
+ try {
12913
+ await this.ensureConnected(false);
12914
+ } catch {
12915
+ return { stopped: false };
12916
+ }
12917
+ const result = await this.request({ type: "shutdown", ...reason !== void 0 ? { reason } : {} }, 5e3).catch(
12918
+ () => ({ stopped: false })
12919
+ );
12920
+ if (result.stopped) {
12921
+ const metadataPath = sessionCatalogProjectServerMetadataPath(this.options.projectDir);
12922
+ const deadline = Date.now() + 5e3;
12923
+ while (fs3.existsSync(metadataPath) && Date.now() < deadline) await delay(20);
12924
+ if (result.pid && result.pid !== process.pid) {
12925
+ while (Date.now() < deadline) {
12926
+ try {
12927
+ process.kill(result.pid, 0);
12928
+ await delay(20);
12929
+ } catch {
12930
+ break;
12931
+ }
12932
+ }
12933
+ }
12934
+ }
12935
+ return result;
12936
+ }
12937
+ async close() {
12938
+ this.explicitlyClosed = true;
12939
+ if (this.reconnectTimer) clearTimeout(this.reconnectTimer);
12940
+ this.reconnectTimer = void 0;
12941
+ const socket = this.socket;
12942
+ this.socket = null;
12943
+ this.info = null;
12944
+ if (socket && !socket.destroyed)
12945
+ await new Promise((resolve16) => {
12946
+ socket.once("close", resolve16);
12947
+ socket.end();
12948
+ });
12949
+ }
12950
+ async ensureConnected(spawnIfMissing) {
12951
+ if (this.socket && !this.socket.destroyed && this.info) return;
12952
+ if (this.connecting) return this.connecting;
12953
+ this.connecting = this.connectWithElection(spawnIfMissing).finally(() => {
12954
+ this.connecting = null;
12955
+ });
12956
+ return this.connecting;
12957
+ }
12958
+ async connectWithElection(spawnIfMissing) {
12959
+ const deadline = Date.now() + (spawnIfMissing ? START_TIMEOUT_MS : CONNECT_TIMEOUT_MS);
12960
+ let spawned = false;
12961
+ let lastError = new Error("Session Catalog project server unavailable");
12962
+ while (Date.now() < deadline) {
12963
+ try {
12964
+ await this.connectOnce();
12965
+ return;
12966
+ } catch (error) {
12967
+ lastError = error;
12968
+ }
12969
+ if (!spawnIfMissing) break;
12970
+ if (!spawned) {
12971
+ this.spawnDetached();
12972
+ spawned = true;
12973
+ }
12974
+ await delay(75);
12975
+ }
12976
+ throw lastError;
12977
+ }
12978
+ connectOnce() {
12979
+ this.socket?.destroy();
12980
+ this.socket = null;
12981
+ this.info = null;
12982
+ this.authToken = void 0;
12983
+ this.buffer = "";
12984
+ return new Promise((resolve16, reject) => {
12985
+ const socket = net.createConnection(this.endpoint);
12986
+ this.socket = socket;
12987
+ socket.setEncoding("utf8");
12988
+ const timer = setTimeout(() => {
12989
+ reject(new Error("Session Catalog handshake timed out"));
12990
+ socket.destroy();
12991
+ }, CONNECT_TIMEOUT_MS);
12992
+ timer.unref?.();
12993
+ this.connectResolve = () => {
12994
+ clearTimeout(timer);
12995
+ this.connectResolve = null;
12996
+ this.connectReject = null;
12997
+ resolve16();
12998
+ };
12999
+ this.connectReject = (error) => {
13000
+ clearTimeout(timer);
13001
+ this.connectResolve = null;
13002
+ this.connectReject = null;
13003
+ reject(error);
13004
+ };
13005
+ socket.on("data", (chunk) => this.onData(socket, chunk));
13006
+ socket.on("error", (error) => {
13007
+ if (!this.info) this.connectReject?.(error);
13008
+ });
13009
+ socket.on("close", () => this.onClose(socket));
13010
+ });
13011
+ }
13012
+ currentAuthToken() {
13013
+ if (this.authToken === void 0) {
13014
+ try {
13015
+ const parsed = JSON.parse(
13016
+ fs3.readFileSync(sessionCatalogProjectServerMetadataPath(this.options.projectDir), "utf8")
13017
+ );
13018
+ if (typeof parsed.authToken === "string" && parsed.authToken)
13019
+ this.authToken = parsed.authToken;
13020
+ } catch {
13021
+ }
13022
+ }
13023
+ return this.authToken;
13024
+ }
13025
+ request(message, timeoutMs) {
13026
+ const socket = this.socket;
13027
+ if (!socket || socket.destroyed)
13028
+ return Promise.reject(new Error("Session Catalog connection is unavailable"));
13029
+ const id = this.nextId++;
13030
+ if (this.pending.size >= MAX_PENDING_REQUESTS) {
13031
+ return Promise.reject(
13032
+ new Error(`Session Catalog pending request limit reached (${MAX_PENDING_REQUESTS})`)
13033
+ );
13034
+ }
13035
+ const encoded = encodeSessionCatalogMessage({
13036
+ ...message,
13037
+ id,
13038
+ authToken: this.currentAuthToken()
13039
+ });
13040
+ if (encoded.length > SESSION_CATALOG_MAX_FRAME_CHARS)
13041
+ return Promise.reject(new Error("Session Catalog request exceeded frame limit"));
13042
+ return new Promise((resolve16, reject) => {
13043
+ const timer = setTimeout(() => {
13044
+ const pending = this.pending.get(id);
13045
+ if (!pending) return;
13046
+ this.pending.delete(id);
13047
+ pending.reject(
13048
+ new Error(
13049
+ `Session Catalog ${message.type === "request" ? message.op : message.type} timed out`
13050
+ )
13051
+ );
13052
+ }, timeoutMs);
13053
+ timer.unref?.();
13054
+ this.pending.set(id, { resolve: resolve16, reject, timer });
13055
+ socket.write(encoded);
13056
+ });
13057
+ }
13058
+ onData(socket, chunk) {
13059
+ if (socket !== this.socket) return;
13060
+ this.buffer += chunk;
13061
+ if (this.buffer.length > SESSION_CATALOG_MAX_FRAME_CHARS) {
13062
+ socket.destroy(new Error("Session Catalog response exceeded frame limit"));
13063
+ return;
13064
+ }
13065
+ while (true) {
13066
+ const newline = this.buffer.indexOf("\n");
13067
+ if (newline < 0) return;
13068
+ const line = this.buffer.slice(0, newline);
13069
+ this.buffer = this.buffer.slice(newline + 1);
13070
+ if (!line) continue;
13071
+ try {
13072
+ this.onMessage(JSON.parse(line));
13073
+ } catch {
13074
+ socket.destroy(new Error("Invalid Session Catalog response"));
13075
+ return;
13076
+ }
13077
+ }
13078
+ }
13079
+ onMessage(message) {
13080
+ if (message.type === "hello") {
13081
+ if (message.protocolVersion !== SESSION_CATALOG_PROTOCOL_VERSION) {
13082
+ this.connectReject?.(
13083
+ new Error(
13084
+ `Session Catalog protocol mismatch: client=${SESSION_CATALOG_PROTOCOL_VERSION}, server=${message.protocolVersion}`
13085
+ )
13086
+ );
13087
+ this.socket?.destroy();
13088
+ return;
13089
+ }
13090
+ if (normalize2(message.projectDir) !== normalize2(this.options.projectDir) || normalize2(message.projectRoot) !== normalize2(this.options.projectRoot)) {
13091
+ this.connectReject?.(new Error("Session Catalog project identity mismatch"));
13092
+ this.socket?.destroy();
13093
+ return;
13094
+ }
13095
+ this.info = message;
13096
+ this.connectResolve?.();
13097
+ return;
13098
+ }
13099
+ if (message.type === "event") {
13100
+ for (const listener of this.eventListeners) {
13101
+ try {
13102
+ listener(message.event);
13103
+ } catch {
13104
+ }
13105
+ }
13106
+ return;
13107
+ }
13108
+ const pending = this.pending.get(message.id);
13109
+ if (!pending) return;
13110
+ this.pending.delete(message.id);
13111
+ clearTimeout(pending.timer);
13112
+ if (message.ok) pending.resolve(message.result);
13113
+ else {
13114
+ const error = new Error(message.error);
13115
+ if (message.errorName) error.name = message.errorName;
13116
+ pending.reject(error);
13117
+ }
13118
+ }
13119
+ onClose(socket) {
13120
+ if (socket !== this.socket) return;
13121
+ this.socket = null;
13122
+ this.info = null;
13123
+ this.authToken = void 0;
13124
+ const error = new Error("Session Catalog connection closed");
13125
+ this.connectReject?.(error);
13126
+ this.connectResolve = null;
13127
+ this.connectReject = null;
13128
+ for (const pending of this.pending.values()) {
13129
+ clearTimeout(pending.timer);
13130
+ pending.reject(error);
13131
+ }
13132
+ this.pending.clear();
13133
+ this.scheduleSubscriptionReconnect();
13134
+ }
13135
+ scheduleSubscriptionReconnect() {
13136
+ if (this.explicitlyClosed || this.eventListeners.size === 0 || this.reconnectTimer) return;
13137
+ this.reconnectTimer = setTimeout(() => {
13138
+ this.reconnectTimer = void 0;
13139
+ void this.call("subscribe", {}).catch(() => this.scheduleSubscriptionReconnect());
13140
+ }, 250);
13141
+ this.reconnectTimer.unref?.();
13142
+ }
13143
+ spawnDetached() {
13144
+ const url = resolveSessionCatalogProjectServerUrl();
13145
+ if (!url) throw new Error("Built Session Catalog project server is unavailable");
13146
+ const child = spawn2(
13147
+ process.execPath,
13148
+ [
13149
+ fileURLToPath3(url),
13150
+ "--project-dir",
13151
+ this.options.projectDir,
13152
+ "--project-root",
13153
+ this.options.projectRoot
13154
+ ],
13155
+ { detached: true, stdio: "ignore", windowsHide: true, env: process.env }
13156
+ );
13157
+ child.unref();
13158
+ }
13159
+ };
12777
13160
 
12778
13161
  // src/utils/message-invariants.ts
12779
13162
  function repairToolUseAdjacency(messages) {
@@ -12910,14 +13293,14 @@ function ulid(seedTime = Date.now()) {
12910
13293
  }
12911
13294
 
12912
13295
  // src/utils/session-scoped-path.ts
12913
- import * as path14 from "node:path";
13296
+ import * as path16 from "node:path";
12914
13297
  function sessionScopedPath(dir, sessionId, suffix) {
12915
13298
  if (!sessionId || sessionId.includes("\\") || sessionId.includes("..")) {
12916
13299
  throw invalid(sessionId);
12917
13300
  }
12918
- const resolved = path14.resolve(dir, `${sessionId}${suffix}`);
12919
- const rel = path14.relative(path14.resolve(dir), resolved);
12920
- if (rel.startsWith("..") || path14.isAbsolute(rel)) {
13301
+ const resolved = path16.resolve(dir, `${sessionId}${suffix}`);
13302
+ const rel = path16.relative(path16.resolve(dir), resolved);
13303
+ if (rel.startsWith("..") || path16.isAbsolute(rel)) {
12921
13304
  throw invalid(sessionId);
12922
13305
  }
12923
13306
  return resolved;
@@ -12939,7 +13322,7 @@ function truncate3(s, max) {
12939
13322
  // src/storage/file-session-writer.ts
12940
13323
  import { closeSync, createReadStream as createReadStream2, fsyncSync, openSync, writeSync } from "node:fs";
12941
13324
  import * as fsp7 from "node:fs/promises";
12942
- import * as path15 from "node:path";
13325
+ import * as path17 from "node:path";
12943
13326
  import { createInterface as createInterface2 } from "node:readline";
12944
13327
 
12945
13328
  // src/storage/session-workspace-checkpoints.ts
@@ -13205,7 +13588,7 @@ var FileSessionWriter = class _FileSessionWriter {
13205
13588
  this.meta = meta;
13206
13589
  this.events = events;
13207
13590
  this.resumed = opts.resumed ?? false;
13208
- this.manifestFile = opts.dir ? path15.join(opts.dir, `${path15.basename(id)}.summary.json`) : "";
13591
+ this.manifestFile = opts.dir ? path17.join(opts.dir, `${path17.basename(id)}.summary.json`) : "";
13209
13592
  this.filePath = opts.filePath ?? "";
13210
13593
  this.secretScrubber = opts.secretScrubber;
13211
13594
  this.checkpointCas = opts.checkpointCas;
@@ -14094,10 +14477,10 @@ var FileSessionWriter = class _FileSessionWriter {
14094
14477
  };
14095
14478
 
14096
14479
  // src/storage/session-checkpoint-cas.ts
14097
- import { spawn as spawn2 } from "node:child_process";
14098
- import { createHash as createHash2, randomUUID as randomUUID11 } from "node:crypto";
14480
+ import { spawn as spawn3 } from "node:child_process";
14481
+ import { createHash as createHash3, randomUUID as randomUUID11 } from "node:crypto";
14099
14482
  import * as fsp8 from "node:fs/promises";
14100
- import * as path16 from "node:path";
14483
+ import * as path18 from "node:path";
14101
14484
 
14102
14485
  // src/storage/storage-concurrency.ts
14103
14486
  async function mapWithConcurrency(items, concurrency, mapper) {
@@ -14125,16 +14508,16 @@ var MAX_GIT_OUTPUT = 16 * 1024 * 1024;
14125
14508
  var MAX_BLOB_BYTES = 64 * 1024 * 1024;
14126
14509
  var MAX_CHECKPOINT_BYTES = 512 * 1024 * 1024;
14127
14510
  function sha256(content) {
14128
- return createHash2("sha256").update(content).digest("hex");
14511
+ return createHash3("sha256").update(content).digest("hex");
14129
14512
  }
14130
14513
  function isInside(root, target) {
14131
- const relative4 = path16.relative(root, target);
14132
- return relative4 === "" || !relative4.startsWith("..") && !path16.isAbsolute(relative4);
14514
+ const relative4 = path18.relative(root, target);
14515
+ return relative4 === "" || !relative4.startsWith("..") && !path18.isAbsolute(relative4);
14133
14516
  }
14134
14517
  function normalizeRelative(input) {
14135
- if (!input || path16.isAbsolute(input)) return null;
14518
+ if (!input || path18.isAbsolute(input)) return null;
14136
14519
  const normalized = input.replace(/\\/g, "/").replace(/^\.\//, "");
14137
- const resolved = path16.posix.normalize(normalized);
14520
+ const resolved = path18.posix.normalize(normalized);
14138
14521
  if (!resolved || resolved === "." || resolved === ".." || resolved.startsWith("../")) return null;
14139
14522
  return resolved;
14140
14523
  }
@@ -14149,8 +14532,8 @@ var SessionCheckpointCas = class {
14149
14532
  projectRoot;
14150
14533
  runGit;
14151
14534
  constructor(opts) {
14152
- this.rootDir = path16.resolve(opts.rootDir);
14153
- this.projectRoot = path16.resolve(opts.projectRoot);
14535
+ this.rootDir = path18.resolve(opts.rootDir);
14536
+ this.projectRoot = path18.resolve(opts.projectRoot);
14154
14537
  this.runGit = opts.runGit ?? defaultRunGit;
14155
14538
  }
14156
14539
  async capture(_sessionId, _promptIndex) {
@@ -14175,7 +14558,7 @@ var SessionCheckpointCas = class {
14175
14558
  relativePaths,
14176
14559
  CAPTURE_CONCURRENCY,
14177
14560
  async (relative4) => {
14178
- const absolute = path16.resolve(this.projectRoot, ...relative4.split("/"));
14561
+ const absolute = path18.resolve(this.projectRoot, ...relative4.split("/"));
14179
14562
  if (!isInside(this.projectRoot, absolute)) {
14180
14563
  unresolved.push({ path: relative4, reason: "path escapes project root" });
14181
14564
  return null;
@@ -14184,8 +14567,8 @@ var SessionCheckpointCas = class {
14184
14567
  const stat10 = await fsp8.lstat(absolute);
14185
14568
  if (stat10.isSymbolicLink()) {
14186
14569
  const linkTarget = await fsp8.readlink(absolute);
14187
- const resolvedLink = path16.resolve(path16.dirname(absolute), linkTarget);
14188
- if (path16.isAbsolute(linkTarget) || !isInside(this.projectRoot, resolvedLink)) {
14570
+ const resolvedLink = path18.resolve(path18.dirname(absolute), linkTarget);
14571
+ if (path18.isAbsolute(linkTarget) || !isInside(this.projectRoot, resolvedLink)) {
14189
14572
  unresolved.push({
14190
14573
  path: relative4,
14191
14574
  reason: "symlink target escapes project root"
@@ -14247,7 +14630,7 @@ var SessionCheckpointCas = class {
14247
14630
  };
14248
14631
  }
14249
14632
  async materialize(checkpoint, targetRoot) {
14250
- const target = path16.resolve(targetRoot);
14633
+ const target = path18.resolve(targetRoot);
14251
14634
  if (target === this.projectRoot) {
14252
14635
  throw new Error("Refusing to materialize a workspace checkpoint over the parent project root");
14253
14636
  }
@@ -14287,10 +14670,10 @@ var SessionCheckpointCas = class {
14287
14670
  try {
14288
14671
  const output = await this.safeOutputPath(target, realTarget, entry.path);
14289
14672
  if (entry.state === "symlink") {
14290
- if (path16.isAbsolute(entry.linkTarget)) {
14673
+ if (path18.isAbsolute(entry.linkTarget)) {
14291
14674
  throw new Error("absolute symlink target refused");
14292
14675
  }
14293
- const resolvedLink = path16.resolve(path16.dirname(output), entry.linkTarget);
14676
+ const resolvedLink = path18.resolve(path18.dirname(output), entry.linkTarget);
14294
14677
  if (!isInside(target, resolvedLink)) throw new Error("symlink target escapes checkpoint root");
14295
14678
  }
14296
14679
  prepared.push({
@@ -14318,7 +14701,7 @@ var SessionCheckpointCas = class {
14318
14701
  await fsp8.unlink(output).catch((err) => {
14319
14702
  if (err.code !== "ENOENT") throw err;
14320
14703
  });
14321
- await fsp8.mkdir(path16.dirname(output), { recursive: true });
14704
+ await fsp8.mkdir(path18.dirname(output), { recursive: true });
14322
14705
  await fsp8.symlink(entry.linkTarget, output);
14323
14706
  writtenFiles.push(entry.path);
14324
14707
  continue;
@@ -14335,15 +14718,15 @@ var SessionCheckpointCas = class {
14335
14718
  }
14336
14719
  objectPath(hash) {
14337
14720
  if (!HASH_RE.test(hash)) throw new Error(`Invalid CAS object hash: ${hash}`);
14338
- return path16.join(this.rootDir, "objects", hash.slice(0, 2), hash.slice(2));
14721
+ return path18.join(this.rootDir, "objects", hash.slice(0, 2), hash.slice(2));
14339
14722
  }
14340
14723
  manifestPath(hash) {
14341
14724
  if (!HASH_RE.test(hash)) throw new Error(`Invalid checkpoint manifest hash: ${hash}`);
14342
- return path16.join(this.rootDir, "manifests", `${hash}.json`);
14725
+ return path18.join(this.rootDir, "manifests", `${hash}.json`);
14343
14726
  }
14344
14727
  async putBlob(hash, content) {
14345
14728
  const target = this.objectPath(hash);
14346
- await fsp8.mkdir(path16.dirname(target), { recursive: true });
14729
+ await fsp8.mkdir(path18.dirname(target), { recursive: true });
14347
14730
  try {
14348
14731
  const existing = await fsp8.readFile(target);
14349
14732
  if (sha256(existing) !== hash) throw new Error(`Corrupt CAS object collision: ${hash}`);
@@ -14351,9 +14734,9 @@ var SessionCheckpointCas = class {
14351
14734
  } catch (err) {
14352
14735
  if (err.code !== "ENOENT") throw err;
14353
14736
  }
14354
- const temp = path16.join(
14355
- path16.dirname(target),
14356
- `.${path16.basename(target)}.${process.pid}.${randomUUID11()}.tmp`
14737
+ const temp = path18.join(
14738
+ path18.dirname(target),
14739
+ `.${path18.basename(target)}.${process.pid}.${randomUUID11()}.tmp`
14357
14740
  );
14358
14741
  let handle;
14359
14742
  try {
@@ -14414,7 +14797,7 @@ var SessionCheckpointCas = class {
14414
14797
  async safeOutputPath(target, realTarget, relative4) {
14415
14798
  const normalized = normalizeRelative(relative4);
14416
14799
  if (!normalized) throw new Error("invalid relative path");
14417
- const output = path16.resolve(target, ...normalized.split("/"));
14800
+ const output = path18.resolve(target, ...normalized.split("/"));
14418
14801
  if (!isInside(target, output)) throw new Error("path escapes checkpoint target");
14419
14802
  let probe = output;
14420
14803
  for (; ; ) {
@@ -14424,7 +14807,7 @@ var SessionCheckpointCas = class {
14424
14807
  return output;
14425
14808
  } catch (err) {
14426
14809
  if (err.code !== "ENOENT") throw err;
14427
- const parent = path16.dirname(probe);
14810
+ const parent = path18.dirname(probe);
14428
14811
  if (parent === probe) throw err;
14429
14812
  probe = parent;
14430
14813
  }
@@ -14432,14 +14815,14 @@ var SessionCheckpointCas = class {
14432
14815
  }
14433
14816
  };
14434
14817
  function defaultRunGit(args, cwd) {
14435
- return new Promise((resolve14) => {
14818
+ return new Promise((resolve16) => {
14436
14819
  const stdoutChunks = [];
14437
14820
  const stderrChunks = [];
14438
14821
  let stdoutBytes = 0;
14439
14822
  let stderrBytes = 0;
14440
14823
  let stdoutTruncated = false;
14441
14824
  let stderrTruncated = false;
14442
- const child = spawn2("git", args, {
14825
+ const child = spawn3("git", args, {
14443
14826
  cwd,
14444
14827
  env: buildChildEnv(),
14445
14828
  stdio: ["ignore", "pipe", "pipe"],
@@ -14475,8 +14858,8 @@ function defaultRunGit(args, cwd) {
14475
14858
  stdoutTruncated,
14476
14859
  stderrTruncated
14477
14860
  });
14478
- child.on("error", (err) => resolve14(result(1, err.message)));
14479
- child.on("close", (code) => resolve14(result(code ?? 1)));
14861
+ child.on("error", (err) => resolve16(result(1, err.message)));
14862
+ child.on("close", (code) => resolve16(result(code ?? 1)));
14480
14863
  });
14481
14864
  }
14482
14865
 
@@ -14488,13 +14871,13 @@ function generateSessionId(startedAt, _model) {
14488
14871
  }
14489
14872
 
14490
14873
  // src/storage/session-id-resolver.ts
14491
- import * as path17 from "node:path";
14874
+ import * as path19 from "node:path";
14492
14875
  function resolveSessionId(query, candidateIds) {
14493
14876
  const normalized = query.trim();
14494
14877
  if (!normalized) return { status: "missing", query: normalized };
14495
14878
  const uniqueIds = [...new Set(candidateIds)];
14496
14879
  if (uniqueIds.includes(normalized)) return { status: "resolved", id: normalized };
14497
- const leaf = (id) => path17.posix.basename(id.replace(/\\/g, "/"));
14880
+ const leaf = (id) => path19.posix.basename(id.replace(/\\/g, "/"));
14498
14881
  const exactLeafMatches = uniqueIds.filter((id) => leaf(id) === normalized);
14499
14882
  if (exactLeafMatches.length === 1) {
14500
14883
  return { status: "resolved", id: exactLeafMatches[0] };
@@ -14543,15 +14926,15 @@ function scrubPersistedSessionSummary(summary, scrubber2) {
14543
14926
  }
14544
14927
 
14545
14928
  // src/storage/session-resume-validation.ts
14546
- import { createHash as createHash3 } from "node:crypto";
14929
+ import { createHash as createHash4 } from "node:crypto";
14547
14930
  import * as fsp9 from "node:fs/promises";
14548
- import * as path18 from "node:path";
14931
+ import * as path20 from "node:path";
14549
14932
  var MAX_REVALIDATE_BYTES = 5 * 1024 * 1024;
14550
14933
  var VALIDATION_CONCURRENCY = 8;
14551
14934
  var NOTICE_PATH_LIMIT = 20;
14552
14935
  function isInside2(root, target) {
14553
- const relative4 = path18.relative(root, target);
14554
- return relative4 === "" || !relative4.startsWith("..") && !path18.isAbsolute(relative4);
14936
+ const relative4 = path20.relative(root, target);
14937
+ return relative4 === "" || !relative4.startsWith("..") && !path20.isAbsolute(relative4);
14555
14938
  }
14556
14939
  function errno(err) {
14557
14940
  return err && typeof err === "object" && "code" in err ? String(err.code) : void 0;
@@ -14562,7 +14945,7 @@ function latestObservations(events, projectRoot) {
14562
14945
  if (event.type !== "file_observation" || typeof event.path !== "string" || event.path.length === 0 || typeof event.hash !== "string" || !/^[a-f\d]{64}$/i.test(event.hash)) {
14563
14946
  continue;
14564
14947
  }
14565
- const normalized = path18.resolve(projectRoot, event.path);
14948
+ const normalized = path20.resolve(projectRoot, event.path);
14566
14949
  latest.set(normalized, {
14567
14950
  path: normalized,
14568
14951
  hash: event.hash.toLowerCase(),
@@ -14611,7 +14994,7 @@ async function validateOne(observation, lexicalRoot, realRoot) {
14611
14994
  };
14612
14995
  }
14613
14996
  const content = await fsp9.readFile(realFile, "utf8");
14614
- const actualHash = createHash3("sha256").update(content, "utf8").digest("hex");
14997
+ const actualHash = createHash4("sha256").update(content, "utf8").digest("hex");
14615
14998
  if (actualHash === observation.hash) return null;
14616
14999
  return { ...base, status: "modified", actualHash };
14617
15000
  } catch (err) {
@@ -14620,7 +15003,7 @@ async function validateOne(observation, lexicalRoot, realRoot) {
14620
15003
  }
14621
15004
  }
14622
15005
  async function validateResumeFileObservations(events, projectRoot) {
14623
- const lexicalRoot = path18.resolve(projectRoot);
15006
+ const lexicalRoot = path20.resolve(projectRoot);
14624
15007
  const realRoot = await fsp9.realpath(lexicalRoot).catch(() => lexicalRoot);
14625
15008
  const observations = latestObservations(events, lexicalRoot);
14626
15009
  const results = await mapWithConcurrency(
@@ -14636,9 +15019,9 @@ async function validateResumeFileObservations(events, projectRoot) {
14636
15019
  }
14637
15020
  function formatResumeValidationNotice(validation, projectRoot) {
14638
15021
  if (validation.staleFiles.length === 0) return null;
14639
- const root = path18.resolve(projectRoot);
15022
+ const root = path20.resolve(projectRoot);
14640
15023
  const shown = validation.staleFiles.slice(0, NOTICE_PATH_LIMIT).map((entry) => {
14641
- const relative4 = path18.relative(root, entry.path);
15024
+ const relative4 = path20.relative(root, entry.path);
14642
15025
  const display = isInside2(root, entry.path) ? relative4 || "." : entry.path;
14643
15026
  return `- ${JSON.stringify(display)} [${entry.status}]`;
14644
15027
  });
@@ -14663,22 +15046,22 @@ function formatInterruptedToolNotice(pendingToolUseCount) {
14663
15046
 
14664
15047
  // src/storage/session-store/delete-session-artifacts.ts
14665
15048
  import * as fsp10 from "node:fs/promises";
14666
- import * as path20 from "node:path";
15049
+ import * as path22 from "node:path";
14667
15050
 
14668
15051
  // src/storage/session-store/paths.ts
14669
- import * as path19 from "node:path";
15052
+ import * as path21 from "node:path";
14670
15053
  function sessionPath(storeDir, id, ext) {
14671
15054
  return sessionScopedPath(storeDir, id, ext);
14672
15055
  }
14673
15056
  function shardManifestPath(storeDir, shardKey) {
14674
- return shardKey ? path19.join(storeDir, shardKey, "_manifest.json") : path19.join(storeDir, "_manifest.json");
15057
+ return shardKey ? path21.join(storeDir, shardKey, "_manifest.json") : path21.join(storeDir, "_manifest.json");
14675
15058
  }
14676
15059
  function shardKeyForSessionId(id) {
14677
- const dirName = path19.dirname(id);
15060
+ const dirName = path21.dirname(id);
14678
15061
  return dirName === "." ? "" : dirName;
14679
15062
  }
14680
15063
  async function ensureShardDir(storeDir, id) {
14681
- const dirPath = path19.dirname(sessionScopedPath(storeDir, id, ""));
15064
+ const dirPath = path21.dirname(sessionScopedPath(storeDir, id, ""));
14682
15065
  await ensureDir(dirPath);
14683
15066
  return dirPath;
14684
15067
  }
@@ -14689,9 +15072,9 @@ async function deleteSessionArtifacts({
14689
15072
  id,
14690
15073
  jsonlPath
14691
15074
  }) {
14692
- const shardDir = path20.dirname(jsonlPath);
14693
- const base = path20.basename(id);
14694
- const sessDir = path20.join(shardDir, base);
15075
+ const shardDir = path22.dirname(jsonlPath);
15076
+ const base = path22.basename(id);
15077
+ const sessDir = path22.join(shardDir, base);
14695
15078
  const deletions = [
14696
15079
  fsp10.unlink(jsonlPath),
14697
15080
  fsp10.unlink(sessionPath(rootDir, id, ".summary.json")),
@@ -14750,7 +15133,7 @@ function isSessionJsonlFileName(name) {
14750
15133
 
14751
15134
  // src/storage/session-store/directory-session-files.ts
14752
15135
  import * as fsp11 from "node:fs/promises";
14753
- import * as path21 from "node:path";
15136
+ import * as path23 from "node:path";
14754
15137
  function sessionIdForFile(prefix, name) {
14755
15138
  const base = name.replace(/\.jsonl$/, "");
14756
15139
  return prefix ? `${prefix}/${base}` : base;
@@ -14772,12 +15155,12 @@ async function collectSessionFiles(dir, prefix = "", depth = 0) {
14772
15155
  if (entry.isDirectory()) {
14773
15156
  dirEntries.push(entry);
14774
15157
  } else if (entry.isFile() && isSessionJsonlFileName(entry.name)) {
14775
- files.push({ id: sessionIdForFile(prefix, entry.name), filePath: path21.join(dir, entry.name) });
15158
+ files.push({ id: sessionIdForFile(prefix, entry.name), filePath: path23.join(dir, entry.name) });
14776
15159
  }
14777
15160
  }
14778
15161
  const childFileArrays = await Promise.all(
14779
15162
  dirEntries.map(
14780
- (entry) => collectSessionFiles(path21.join(dir, entry.name), childPrefixFor(entry, prefix, depth), depth + 1)
15163
+ (entry) => collectSessionFiles(path23.join(dir, entry.name), childPrefixFor(entry, prefix, depth), depth + 1)
14781
15164
  )
14782
15165
  );
14783
15166
  return [...childFileArrays.flat(), ...files];
@@ -14801,7 +15184,7 @@ async function collectSessionIds(dir, prefix = "", depth = 0) {
14801
15184
  }
14802
15185
  const childIdArrays = await Promise.all(
14803
15186
  dirEntries.map(
14804
- (entry) => collectSessionIds(path21.join(dir, entry.name), childPrefixFor(entry, prefix, depth), depth + 1)
15187
+ (entry) => collectSessionIds(path23.join(dir, entry.name), childPrefixFor(entry, prefix, depth), depth + 1)
14805
15188
  )
14806
15189
  );
14807
15190
  return [...childIdArrays.flat(), ...fileIds];
@@ -14843,7 +15226,7 @@ function emitSessionStoreError(events, sessionId, filePath, operation, error, re
14843
15226
  }
14844
15227
 
14845
15228
  // src/storage/session-store/fork-session.ts
14846
- import { createHash as createHash4 } from "node:crypto";
15229
+ import { createHash as createHash5 } from "node:crypto";
14847
15230
 
14848
15231
  // src/storage/session-store/replay.ts
14849
15232
  function isReplayableMessage(value) {
@@ -14915,7 +15298,7 @@ async function forkSession(host, id, opts = {}) {
14915
15298
  }
14916
15299
  const parentPrefix = parent.events.slice(0, boundary + 1);
14917
15300
  const workspaceCheckpoint = targetCheckpoint?.workspaceCheckpoint;
14918
- const checkpointHash = createHash4("sha256").update(parentPrefix.map((event) => JSON.stringify(event)).join("\n") + "\n", "utf8").digest("hex");
15301
+ const checkpointHash = createHash5("sha256").update(parentPrefix.map((event) => JSON.stringify(event)).join("\n") + "\n", "utf8").digest("hex");
14919
15302
  const inherited = parentPrefix.filter(inheritsIntoFork);
14920
15303
  const writer = await host.create({
14921
15304
  id: "",
@@ -15258,6 +15641,16 @@ function replaySessionEvent(params) {
15258
15641
  } else {
15259
15642
  emitDamaged(params, "Ignored malformed messages_replaced event");
15260
15643
  }
15644
+ } else if (ev.type === "messages_dropped" && ev.version === 1) {
15645
+ if (exactJournalActive && Number.isInteger(ev.count) && ev.count > 0) {
15646
+ messages.splice(0, Math.min(ev.count, messages.length));
15647
+ openToolUses.clear();
15648
+ for (const current of messages) trackMessageToolState(current, openToolUses);
15649
+ } else if (!exactJournalActive) {
15650
+ emitDamaged(params, "Ignored messages_dropped event outside the exact journal");
15651
+ } else {
15652
+ emitDamaged(params, `Ignored malformed messages_dropped event (count ${String(ev.count)})`);
15653
+ }
15261
15654
  } else if (ev.type === "context_snapshot") {
15262
15655
  if (!applyContextSnapshot(messages, openToolUses, ev.messages)) {
15263
15656
  emitDamaged(params, "Ignored malformed context_snapshot event");
@@ -15312,7 +15705,7 @@ function emitDamaged(params, detail) {
15312
15705
 
15313
15706
  // src/storage/session-store/prune-helpers.ts
15314
15707
  import * as fsp13 from "node:fs/promises";
15315
- import * as path22 from "node:path";
15708
+ import * as path24 from "node:path";
15316
15709
  function isPrunableSessionJsonl(name) {
15317
15710
  return name.endsWith(".jsonl") && name !== "_index.jsonl" && name !== "_mailbox.jsonl" && !name.endsWith(".replay.jsonl") && !name.endsWith(".audit.jsonl");
15318
15711
  }
@@ -15320,7 +15713,7 @@ async function pruneSessionFiles(storeDir, maxAgeDays, deleteSession) {
15320
15713
  const cutoff = Date.now() - maxAgeDays * 864e5;
15321
15714
  let deleted = 0;
15322
15715
  const pruneFile = async (dir, name, prefix) => {
15323
- const jsonlPath = path22.join(dir, name);
15716
+ const jsonlPath = path24.join(dir, name);
15324
15717
  try {
15325
15718
  const stat10 = await fsp13.stat(jsonlPath);
15326
15719
  if (stat10.mtimeMs >= cutoff) return;
@@ -15339,7 +15732,7 @@ async function pruneSessionFiles(storeDir, maxAgeDays, deleteSession) {
15339
15732
  continue;
15340
15733
  }
15341
15734
  if (!entry.isDirectory()) continue;
15342
- const dateDir = path22.join(storeDir, entry.name);
15735
+ const dateDir = path24.join(storeDir, entry.name);
15343
15736
  const files = await fsp13.readdir(dateDir, { withFileTypes: true }).catch(() => []);
15344
15737
  for (const file of files) {
15345
15738
  if (!file.isFile() || !isPrunableSessionJsonl(file.name)) continue;
@@ -15348,7 +15741,7 @@ async function pruneSessionFiles(storeDir, maxAgeDays, deleteSession) {
15348
15741
  }
15349
15742
  for (const entry of entries) {
15350
15743
  if (!entry.isDirectory()) continue;
15351
- const dateDir = path22.join(storeDir, entry.name);
15744
+ const dateDir = path24.join(storeDir, entry.name);
15352
15745
  try {
15353
15746
  const remaining = await fsp13.readdir(dateDir);
15354
15747
  if (remaining.length === 0) {
@@ -15681,6 +16074,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
15681
16074
  logger;
15682
16075
  onAppend;
15683
16076
  onAppendBatch;
16077
+ /** Present in built production output; source-only tests retain the local compatibility path. */
16078
+ catalogClient;
16079
+ maintenanceHolderId = randomUUID12();
15684
16080
  /**
15685
16081
  * In-memory cache for load() results, keyed by session ID. The cache is
15686
16082
  * invalidated when the file's mtimeMs or size changes (indicating the
@@ -15698,9 +16094,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
15698
16094
  static LIST_SCAN_CONCURRENCY = 32;
15699
16095
  constructor(opts) {
15700
16096
  this.dir = opts.dir;
15701
- this.projectRoot = opts.projectRoot ? path23.resolve(opts.projectRoot) : void 0;
16097
+ this.projectRoot = opts.projectRoot ? path25.resolve(opts.projectRoot) : void 0;
15702
16098
  this.checkpointCas = this.projectRoot ? new SessionCheckpointCas({
15703
- rootDir: path23.join(this.dir, "_cas"),
16099
+ rootDir: path25.join(this.dir, "_cas"),
15704
16100
  projectRoot: this.projectRoot
15705
16101
  }) : void 0;
15706
16102
  this.events = opts.events;
@@ -15709,6 +16105,11 @@ var DefaultSessionStore = class _DefaultSessionStore {
15709
16105
  this.logger = opts.logger;
15710
16106
  this.onAppend = opts.onAppend;
15711
16107
  this.onAppendBatch = opts.onAppendBatch;
16108
+ const builtRuntime = import.meta.url.includes("/dist/");
16109
+ this.catalogClient = this.projectRoot && (builtRuntime || process.env["WRONGSTACK_SESSION_CATALOG_FORCE"] === "1") && resolveSessionCatalogProjectServerUrl() ? new SessionCatalogProjectClient({
16110
+ projectDir: path25.dirname(this.dir),
16111
+ projectRoot: this.projectRoot
16112
+ }) : void 0;
15712
16113
  }
15713
16114
  /**
15714
16115
  * Emit a structured warning. Uses the configured Logger when available;
@@ -15731,10 +16132,14 @@ var DefaultSessionStore = class _DefaultSessionStore {
15731
16132
  clearLoadCache(sessionId) {
15732
16133
  this.loadCache.clear(sessionId);
15733
16134
  }
16135
+ async dispose() {
16136
+ await this.catalogClient?.close();
16137
+ this.clearLoadCache();
16138
+ }
15734
16139
  // ── Storage event helpers ───────────────────────────────────────────────────
15735
16140
  /** Absolute path to the session index file. */
15736
16141
  get indexFile() {
15737
- return path23.join(this.dir, "_index.jsonl");
16142
+ return path25.join(this.dir, "_index.jsonl");
15738
16143
  }
15739
16144
  /** Join session ID to its absolute path within the store directory. */
15740
16145
  sessionPath(id, ext) {
@@ -15792,8 +16197,23 @@ var DefaultSessionStore = class _DefaultSessionStore {
15792
16197
  if (!current) return null;
15793
16198
  return current.name === void 0 ? {} : { name: sessionContentText(this.secretScrubber.scrub(current.name)) };
15794
16199
  },
15795
- onClose: (s) => this.appendToIndex(s)
16200
+ onClose: (s) => this.persistCatalogSummary(s)
15796
16201
  });
16202
+ if (this.catalogClient) {
16203
+ await this.catalogClient.call("upsert_summary", {
16204
+ summary: {
16205
+ id,
16206
+ title: meta.title ?? "",
16207
+ startedAt,
16208
+ model: meta.model ?? "",
16209
+ provider: meta.provider ?? "",
16210
+ tokenTotal: 0,
16211
+ lastActivityAt: startedAt
16212
+ },
16213
+ transcriptRelativePath: `${id}.jsonl`,
16214
+ summaryRelativePath: `${id}.summary.json`
16215
+ });
16216
+ }
15797
16217
  emitSessionStoreWrite(this.events, id, file, "create", "success", Date.now() - t0);
15798
16218
  return writer;
15799
16219
  } catch (err) {
@@ -15823,6 +16243,9 @@ var DefaultSessionStore = class _DefaultSessionStore {
15823
16243
  return materializeCheckpoint(this.checkpointCas, checkpoint, targetRoot);
15824
16244
  }
15825
16245
  async resolveId(query) {
16246
+ if (this.catalogClient) {
16247
+ return this.catalogClient.call("resolve_id", { query });
16248
+ }
15826
16249
  const normalized = query.trim();
15827
16250
  if (!normalized) throw new Error("Session not found: (empty query)");
15828
16251
  if (normalized) {
@@ -15929,7 +16352,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
15929
16352
  // Shard directory (sessions/<date>/) — must match create() so the
15930
16353
  // .summary.json sidecar lands next to the JSONL instead of the
15931
16354
  // sessions root (where summaryFor() would never find it).
15932
- dir: path23.dirname(file),
16355
+ dir: path25.dirname(file),
15933
16356
  filePath: file,
15934
16357
  secretScrubber: this.secretScrubber,
15935
16358
  checkpointCas: this.checkpointCas,
@@ -15940,7 +16363,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
15940
16363
  if (!current) return null;
15941
16364
  return current.name === void 0 ? {} : { name: sessionContentText(this.secretScrubber.scrub(current.name)) };
15942
16365
  },
15943
- onClose: (s) => this.appendToIndex(s)
16366
+ onClose: (s) => this.persistCatalogSummary(s)
15944
16367
  }
15945
16368
  );
15946
16369
  emitSessionStoreWrite(this.events, canonicalId, file, "resume", "success", Date.now() - t0);
@@ -16053,6 +16476,10 @@ var DefaultSessionStore = class _DefaultSessionStore {
16053
16476
  });
16054
16477
  }
16055
16478
  async list(limit = 20) {
16479
+ if (this.catalogClient) {
16480
+ const records = await this.catalogClient.call("list_catalog", { limit });
16481
+ return this.scrubSummaries(records);
16482
+ }
16056
16483
  try {
16057
16484
  const indexed = await this.readIndex();
16058
16485
  if (indexed.length > 0) {
@@ -16075,6 +16502,13 @@ var DefaultSessionStore = class _DefaultSessionStore {
16075
16502
  */
16076
16503
  async listFiltered(criteria) {
16077
16504
  const limit = criteria.limit ?? 100;
16505
+ if (this.catalogClient) {
16506
+ const records = await this.catalogClient.call("list_catalog", {
16507
+ limit: Math.min(1e3, Math.max(limit, 100)),
16508
+ ...criteria.titleContains ? { search: criteria.titleContains } : {}
16509
+ });
16510
+ return this.scrubSummaries(records).filter((summary) => matchesSessionFilter(summary, criteria)).slice(0, limit);
16511
+ }
16078
16512
  try {
16079
16513
  const indexed = await this.readIndex();
16080
16514
  if (indexed.length === 0) {
@@ -16124,6 +16558,18 @@ var DefaultSessionStore = class _DefaultSessionStore {
16124
16558
  await this.appendToIndexStrict(summary).catch(() => {
16125
16559
  });
16126
16560
  }
16561
+ /** Final summary boundary: daemon is authoritative when available. */
16562
+ async persistCatalogSummary(summary) {
16563
+ if (!this.catalogClient) {
16564
+ await this.appendToIndex(summary);
16565
+ return;
16566
+ }
16567
+ await this.catalogClient.call("upsert_summary", {
16568
+ summary,
16569
+ transcriptRelativePath: `${summary.id}.jsonl`,
16570
+ summaryRelativePath: `${summary.id}.summary.json`
16571
+ });
16572
+ }
16127
16573
  /** Append a tombstone entry for a deleted session. */
16128
16574
  async writeTombstone(id) {
16129
16575
  try {
@@ -16233,6 +16679,10 @@ var DefaultSessionStore = class _DefaultSessionStore {
16233
16679
  * fresh _index.jsonl. Useful after manual cleanup or index corruption.
16234
16680
  */
16235
16681
  async rebuildIndex() {
16682
+ if (this.catalogClient) {
16683
+ const result = await this.catalogClient.call("rebuild_catalog", {}, { timeoutMs: 12e4 });
16684
+ return result.indexed;
16685
+ }
16236
16686
  const ids = await this.collectSessionIds(this.dir);
16237
16687
  const summaries = await Promise.all(
16238
16688
  ids.map((id) => this.summaryFor(id).catch(() => null))
@@ -16302,7 +16752,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
16302
16752
  });
16303
16753
  }
16304
16754
  async collectSessionFilesInShard(shardKey) {
16305
- const dir = shardKey ? path23.join(this.dir, shardKey) : this.dir;
16755
+ const dir = shardKey ? path25.join(this.dir, shardKey) : this.dir;
16306
16756
  const entries = await this.collectSessionFiles(dir, shardKey);
16307
16757
  return shardKey ? entries.filter((entry) => entry.id.startsWith(`${shardKey}/`)) : entries.filter((entry) => !entry.id.includes("/"));
16308
16758
  }
@@ -16398,10 +16848,35 @@ var DefaultSessionStore = class _DefaultSessionStore {
16398
16848
  await this.writeTombstone(id);
16399
16849
  }
16400
16850
  async delete(id) {
16851
+ if (this.catalogClient) {
16852
+ const canonical = await this.resolveId(id);
16853
+ const lease = await this.catalogClient.call("acquire_maintenance", {
16854
+ sessionId: canonical,
16855
+ operation: "delete",
16856
+ holderId: this.maintenanceHolderId
16857
+ });
16858
+ try {
16859
+ await this.catalogClient.call("delete", { sessionId: canonical, lease });
16860
+ } catch (error) {
16861
+ await this.catalogClient.call("release_maintenance", { lease }).catch(() => void 0);
16862
+ throw error;
16863
+ }
16864
+ this.clearLoadCache(canonical);
16865
+ return;
16866
+ }
16401
16867
  await assertSessionCanBeDeleted(id, this.isSessionInUse);
16402
16868
  await this.deleteSession(id);
16403
16869
  }
16404
16870
  async rename(id, name) {
16871
+ if (this.catalogClient) {
16872
+ const canonical = await this.resolveId(id);
16873
+ const summary = await this.catalogClient.call("rename", {
16874
+ sessionId: canonical,
16875
+ name: sessionContentText(this.secretScrubber.scrub(name))
16876
+ });
16877
+ this.clearLoadCache(canonical);
16878
+ return summary;
16879
+ }
16405
16880
  const trimmed = sessionContentText(this.secretScrubber.scrub(name));
16406
16881
  const manifest = this.sessionPath(id, ".summary.json");
16407
16882
  const jsonlPath = this.sessionPath(id, ".jsonl");
@@ -16453,6 +16928,12 @@ var DefaultSessionStore = class _DefaultSessionStore {
16453
16928
  return updated;
16454
16929
  }
16455
16930
  async prune(maxAgeDays = 30) {
16931
+ if (this.catalogClient) {
16932
+ return this.catalogClient.call("prune", {
16933
+ maxAgeDays,
16934
+ holderId: this.maintenanceHolderId
16935
+ });
16936
+ }
16456
16937
  const deleted = await pruneSessionFiles(this.dir, maxAgeDays, (id) => this.deleteSession(id));
16457
16938
  if (deleted > 0) {
16458
16939
  await this.compactIndex().catch(() => void 0);
@@ -16460,20 +16941,81 @@ var DefaultSessionStore = class _DefaultSessionStore {
16460
16941
  return deleted;
16461
16942
  }
16462
16943
  async clearHistory(id) {
16463
- await this.ensureShardDir(id);
16464
- const file = this.sessionPath(id, ".jsonl");
16465
- const meta = this.sessionPath(id, ".summary.json");
16944
+ const canonical = this.catalogClient ? await this.resolveId(id) : id;
16945
+ const maintenance = this.catalogClient ? await this.catalogClient.call("acquire_maintenance", {
16946
+ sessionId: canonical,
16947
+ operation: "clear",
16948
+ holderId: this.maintenanceHolderId
16949
+ }) : void 0;
16950
+ await this.ensureShardDir(canonical);
16951
+ const file = this.sessionPath(canonical, ".jsonl");
16952
+ const meta = this.sessionPath(canonical, ".summary.json");
16953
+ const backupSuffix = maintenance ? `.${maintenance.leaseId}.clear-backup` : void 0;
16954
+ const fileBackup = backupSuffix ? `${file}${backupSuffix}` : void 0;
16955
+ const metaBackup = backupSuffix ? `${meta}${backupSuffix}` : void 0;
16956
+ let fileStaged = false;
16957
+ let metaStaged = false;
16466
16958
  const record = `${JSON.stringify({
16467
16959
  type: "session_start",
16468
16960
  ts: (/* @__PURE__ */ new Date()).toISOString(),
16469
- id,
16961
+ id: canonical,
16470
16962
  model: "unknown",
16471
16963
  provider: "unknown"
16472
16964
  })}
16473
16965
  `;
16474
- await atomicWrite(file, record);
16475
- await fsp17.unlink(meta).catch(() => void 0);
16476
- this.clearLoadCache(id);
16966
+ try {
16967
+ if (fileBackup) {
16968
+ try {
16969
+ await fsp17.rename(file, fileBackup);
16970
+ fileStaged = true;
16971
+ } catch (error) {
16972
+ if (error.code !== "ENOENT") throw error;
16973
+ }
16974
+ }
16975
+ if (metaBackup) {
16976
+ try {
16977
+ await fsp17.rename(meta, metaBackup);
16978
+ metaStaged = true;
16979
+ } catch (error) {
16980
+ if (error.code !== "ENOENT") throw error;
16981
+ }
16982
+ }
16983
+ await atomicWrite(file, record);
16984
+ if (!metaBackup) await fsp17.unlink(meta).catch(() => void 0);
16985
+ if (this.catalogClient) {
16986
+ const now = (/* @__PURE__ */ new Date()).toISOString();
16987
+ await this.catalogClient.call("upsert_summary", {
16988
+ summary: {
16989
+ id: canonical,
16990
+ title: "",
16991
+ startedAt: now,
16992
+ model: "unknown",
16993
+ provider: "unknown",
16994
+ tokenTotal: 0,
16995
+ lastActivityAt: now
16996
+ },
16997
+ transcriptRelativePath: `${canonical}.jsonl`,
16998
+ summaryRelativePath: `${canonical}.summary.json`
16999
+ });
17000
+ }
17001
+ if (fileStaged && fileBackup) await fsp17.unlink(fileBackup).catch(() => void 0);
17002
+ if (metaStaged && metaBackup) await fsp17.unlink(metaBackup).catch(() => void 0);
17003
+ } catch (error) {
17004
+ if (fileStaged && fileBackup) {
17005
+ await fsp17.unlink(file).catch(() => void 0);
17006
+ await fsp17.rename(fileBackup, file).catch(() => void 0);
17007
+ }
17008
+ if (metaStaged && metaBackup) {
17009
+ await fsp17.unlink(meta).catch(() => void 0);
17010
+ await fsp17.rename(metaBackup, meta).catch(() => void 0);
17011
+ }
17012
+ throw error;
17013
+ } finally {
17014
+ if (maintenance && this.catalogClient) {
17015
+ await this.catalogClient.call("release_maintenance", { lease: maintenance }).catch(() => void 0);
17016
+ }
17017
+ }
17018
+ this.clearLoadCache(canonical);
16477
17019
  }
16478
17020
  async summarize(id, mtime) {
16479
17021
  return summarizeSessionFile({
@@ -16493,9 +17035,9 @@ function makeDirectorSessionFactory(opts) {
16493
17035
  let dir;
16494
17036
  if (opts.store) {
16495
17037
  store = opts.store;
16496
- dir = opts.sessionsRoot ? path24.join(opts.sessionsRoot, runId) : "(caller-managed)";
17038
+ dir = opts.sessionsRoot ? path26.join(opts.sessionsRoot, runId) : "(caller-managed)";
16497
17039
  } else if (opts.sessionsRoot) {
16498
- dir = path24.join(opts.sessionsRoot, runId);
17040
+ dir = path26.join(opts.sessionsRoot, runId);
16499
17041
  store = new DefaultSessionStore({ dir });
16500
17042
  } else {
16501
17043
  throw new Error("makeDirectorSessionFactory requires either `store` or `sessionsRoot`");
@@ -16519,7 +17061,7 @@ function makeDirectorSessionFactory(opts) {
16519
17061
  }
16520
17062
  async function readDirectorSubagentSession(args) {
16521
17063
  if (!args.sessionsRoot) return null;
16522
- const filePath = path24.join(args.sessionsRoot, args.directorRunId, `${args.subagentId}.jsonl`);
17064
+ const filePath = path26.join(args.sessionsRoot, args.directorRunId, `${args.subagentId}.jsonl`);
16523
17065
  let raw;
16524
17066
  try {
16525
17067
  raw = await fsp18.readFile(filePath, "utf8");
@@ -17663,7 +18205,7 @@ function formatRole(role) {
17663
18205
  }
17664
18206
 
17665
18207
  // src/coordination/fleet-spawn.ts
17666
- async function spawn3(host, config, priceLookup) {
18208
+ async function spawn4(host, config, priceLookup) {
17667
18209
  if (host.workCompleteFlag) {
17668
18210
  throw new FleetSpawnBudgetError(
17669
18211
  "max_spawns",
@@ -17947,7 +18489,7 @@ function hashStr(s) {
17947
18489
  }
17948
18490
 
17949
18491
  // src/coordination/multi-agent-coordinator.ts
17950
- import { randomUUID as randomUUID12 } from "node:crypto";
18492
+ import { randomUUID as randomUUID13 } from "node:crypto";
17951
18493
  import { EventEmitter as EventEmitter2 } from "node:events";
17952
18494
 
17953
18495
  // src/coordination/coordinator/error-classifier.ts
@@ -18086,12 +18628,12 @@ async function executeSubagentWithTimeout({
18086
18628
  }
18087
18629
  return new Promise((resolveDecision) => {
18088
18630
  let settled = false;
18089
- const resolve14 = (d) => {
18631
+ const resolve16 = (d) => {
18090
18632
  if (settled) return;
18091
18633
  settled = true;
18092
18634
  resolveDecision(d);
18093
18635
  };
18094
- const fallback = setTimeout(() => resolve14("stop"), DECISION_TIMEOUT_MS);
18636
+ const fallback = setTimeout(() => resolve16("stop"), DECISION_TIMEOUT_MS);
18095
18637
  const sessionId = currentSessionId();
18096
18638
  budget._events?.emit("budget.threshold_reached", {
18097
18639
  ...sessionId ? { sessionId } : {},
@@ -18101,11 +18643,11 @@ async function executeSubagentWithTimeout({
18101
18643
  timeoutMs: DECISION_TIMEOUT_MS,
18102
18644
  extend: (extra) => {
18103
18645
  clearTimeout(fallback);
18104
- queueMicrotask(() => resolve14({ extend: extra }));
18646
+ queueMicrotask(() => resolve16({ extend: extra }));
18105
18647
  },
18106
18648
  deny: () => {
18107
18649
  clearTimeout(fallback);
18108
- resolve14("stop");
18650
+ resolve16("stop");
18109
18651
  }
18110
18652
  });
18111
18653
  });
@@ -18243,7 +18785,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
18243
18785
  pendingTasks = [];
18244
18786
  completedResults = [];
18245
18787
  /** Prevents completedResults from growing unbounded in long-running coordinators. */
18246
- static MAX_COMPLETED_RESULTS = 1e4;
18788
+ static MAX_COMPLETED_RESULTS = 2e5;
18247
18789
  /** Caps each subagent's retained task history (see assign()); bounds RAM + the recordCompletion lookup. */
18248
18790
  static MAX_SUBAGENT_TASK_HISTORY = 64;
18249
18791
  totalIterations = 0;
@@ -18317,7 +18859,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
18317
18859
  return { ...subagent, name: display };
18318
18860
  }
18319
18861
  async spawn(subagent) {
18320
- const id = subagent.id || randomUUID12();
18862
+ const id = subagent.id || randomUUID13();
18321
18863
  const cfg = this.withNickname(subagent, id);
18322
18864
  if (this.subagents.has(id)) {
18323
18865
  throw new Error(`Subagent id "${id}" already exists \u2014 refusing to overwrite`);
@@ -18492,7 +19034,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
18492
19034
  taskIds.map((id) => {
18493
19035
  const cached = this.completedResults.find((r) => r.taskId === id);
18494
19036
  if (cached) return cached;
18495
- return new Promise((resolve14, reject) => {
19037
+ return new Promise((resolve16, reject) => {
18496
19038
  const timeout = setTimeout(() => {
18497
19039
  this.off("task.completed", handler);
18498
19040
  reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
@@ -18501,7 +19043,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
18501
19043
  if (result.taskId === id) {
18502
19044
  clearTimeout(timeout);
18503
19045
  this.off("task.completed", handler);
18504
- resolve14(result);
19046
+ resolve16(result);
18505
19047
  }
18506
19048
  };
18507
19049
  this.on("task.completed", handler);
@@ -18526,13 +19068,13 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
18526
19068
  const done = new Set(completed.map((r) => r.taskId));
18527
19069
  return { completed, pending: taskIds.filter((id) => !done.has(id)) };
18528
19070
  }
18529
- return new Promise((resolve14) => {
19071
+ return new Promise((resolve16) => {
18530
19072
  let timer;
18531
19073
  const handler = ({ result }) => {
18532
19074
  if (!ids.has(result.taskId)) return;
18533
19075
  if (timer) clearTimeout(timer);
18534
19076
  this.off("task.completed", handler);
18535
- resolve14({
19077
+ resolve16({
18536
19078
  completed: [result],
18537
19079
  pending: taskIds.filter((id) => id !== result.taskId)
18538
19080
  });
@@ -18540,7 +19082,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
18540
19082
  if (opts?.timeoutMs !== void 0) {
18541
19083
  timer = setTimeout(() => {
18542
19084
  this.off("task.completed", handler);
18543
- resolve14({ completed: [], pending: [...taskIds], timedOut: true });
19085
+ resolve16({ completed: [], pending: [...taskIds], timedOut: true });
18544
19086
  }, opts.timeoutMs);
18545
19087
  }
18546
19088
  this.on("task.completed", handler);
@@ -19202,7 +19744,7 @@ var Director = class _Director {
19202
19744
  sessionProvider;
19203
19745
  sessionModel;
19204
19746
  constructor(opts) {
19205
- this.id = opts.config.coordinatorId || randomUUID13();
19747
+ this.id = opts.config.coordinatorId || randomUUID14();
19206
19748
  this.manifestPath = opts.manifestPath;
19207
19749
  this.roster = opts.roster;
19208
19750
  this.directorPreamble = opts.directorPreamble ?? DEFAULT_DIRECTOR_PREAMBLE;
@@ -19464,7 +20006,7 @@ var Director = class _Director {
19464
20006
  }
19465
20007
  const config = { ...callerConfig };
19466
20008
  this.resolveSpawnModel(config);
19467
- const subagentId = await spawn3(this, config, priceLookup);
20009
+ const subagentId = await spawn4(this, config, priceLookup);
19468
20010
  const perSubagentIdleMs = typeof config.idleTimeoutMs === "number" && Number.isFinite(config.idleTimeoutMs) && config.idleTimeoutMs >= 0 ? config.idleTimeoutMs : this.subagentIdleTimeoutMs;
19469
20011
  this.armSubagentIdleRetirement(subagentId, perSubagentIdleMs);
19470
20012
  return subagentId;
@@ -19485,7 +20027,7 @@ var Director = class _Director {
19485
20027
  );
19486
20028
  }
19487
20029
  const msg = {
19488
- id: randomUUID13(),
20030
+ id: randomUUID14(),
19489
20031
  type: "task",
19490
20032
  from: this.id,
19491
20033
  to: subagentId,
@@ -19739,9 +20281,9 @@ var Director = class _Director {
19739
20281
  };
19740
20282
 
19741
20283
  // src/coordination/fleet-manager.ts
19742
- import { randomUUID as randomUUID14 } from "node:crypto";
20284
+ import { randomUUID as randomUUID15 } from "node:crypto";
19743
20285
  import * as fsp20 from "node:fs/promises";
19744
- import * as path25 from "node:path";
20286
+ import * as path27 from "node:path";
19745
20287
  var FleetManager = class {
19746
20288
  /** The fleet-wide event bus. */
19747
20289
  fleet;
@@ -19805,7 +20347,7 @@ var FleetManager = class {
19805
20347
  maxContext;
19806
20348
  constructor(opts = {}) {
19807
20349
  this.manifestPath = opts.manifestPath;
19808
- this.directorRunId = opts.directorRunId ?? randomUUID14();
20350
+ this.directorRunId = opts.directorRunId ?? randomUUID15();
19809
20351
  this.maxSpawns = opts.maxSpawns ?? Number.POSITIVE_INFINITY;
19810
20352
  this.maxSpawnDepth = resolveMaxSpawnDepth(opts.maxSpawnDepth);
19811
20353
  this.spawnDepth = opts.spawnDepth ?? 0;
@@ -20074,7 +20616,7 @@ var FleetManager = class {
20074
20616
  })),
20075
20617
  usage: this.usage.snapshot()
20076
20618
  };
20077
- await fsp20.mkdir(path25.dirname(this.manifestPath), { recursive: true });
20619
+ await fsp20.mkdir(path27.dirname(this.manifestPath), { recursive: true });
20078
20620
  await atomicWrite(this.manifestPath, JSON.stringify(manifest, null, 2), { mode: 384 });
20079
20621
  return this.manifestPath;
20080
20622
  }
@@ -20237,23 +20779,23 @@ var FleetManager = class {
20237
20779
  };
20238
20780
 
20239
20781
  // src/coordination/remote-mailbox.ts
20240
- import * as path29 from "node:path";
20782
+ import * as path31 from "node:path";
20241
20783
 
20242
20784
  // src/coordination/mailbox-constants.ts
20243
20785
  var HQ_MAILBOX_SNAPSHOT_MIN_INTERVAL_MS = 1e4;
20244
20786
  var UNREAD_CHECK_MIN_INTERVAL_MS = 1e3;
20245
20787
 
20246
20788
  // src/coordination/mailbox-project-server-client.ts
20247
- import { spawn as spawn4 } from "node:child_process";
20248
- import * as fs3 from "node:fs";
20249
- import * as net from "node:net";
20250
- import * as path27 from "node:path";
20251
- import { fileURLToPath as fileURLToPath3 } from "node:url";
20789
+ import { spawn as spawn5 } from "node:child_process";
20790
+ import * as fs4 from "node:fs";
20791
+ import * as net2 from "node:net";
20792
+ import * as path29 from "node:path";
20793
+ import { fileURLToPath as fileURLToPath4 } from "node:url";
20252
20794
 
20253
20795
  // src/coordination/mailbox-project-server-endpoint.ts
20254
- import { createHash as createHash5 } from "node:crypto";
20255
- import * as os2 from "node:os";
20256
- import * as path26 from "node:path";
20796
+ import { createHash as createHash6 } from "node:crypto";
20797
+ import * as os3 from "node:os";
20798
+ import * as path28 from "node:path";
20257
20799
 
20258
20800
  // src/coordination/mailbox-project-server-protocol.ts
20259
20801
  var MAILBOX_PROJECT_SERVER_PROTOCOL_VERSION = 4;
@@ -20286,25 +20828,25 @@ function encodeMailboxProjectServerMessage(message) {
20286
20828
  // src/coordination/mailbox-project-server-endpoint.ts
20287
20829
  var MAILBOX_PROJECT_SERVER_METADATA_FILE = ".mailbox-server.json";
20288
20830
  function normalizeLocalPath(value) {
20289
- const resolved = path26.resolve(value);
20831
+ const resolved = path28.resolve(value);
20290
20832
  return process.platform === "win32" ? resolved.toLowerCase() : resolved;
20291
20833
  }
20292
20834
  function mailboxProjectServerKey(projectDir) {
20293
- return createHash5("sha256").update(normalizeLocalPath(projectDir)).digest("hex").slice(0, 24);
20835
+ return createHash6("sha256").update(normalizeLocalPath(projectDir)).digest("hex").slice(0, 24);
20294
20836
  }
20295
20837
  function mailboxProjectServerEndpoint(projectDir) {
20296
20838
  const key = mailboxProjectServerKey(projectDir);
20297
20839
  if (process.platform === "win32") {
20298
20840
  return `\\\\.\\pipe\\wrongstack-mailbox-v${MAILBOX_PROJECT_SERVER_PROTOCOL_VERSION}-${key}`;
20299
20841
  }
20300
- return path26.join(
20301
- os2.tmpdir(),
20842
+ return path28.join(
20843
+ os3.tmpdir(),
20302
20844
  `wsmb-v${MAILBOX_PROJECT_SERVER_PROTOCOL_VERSION}`,
20303
20845
  `${key}.sock`
20304
20846
  );
20305
20847
  }
20306
20848
  function mailboxProjectServerMetadataPath(projectDir) {
20307
- return path26.join(path26.resolve(projectDir), MAILBOX_PROJECT_SERVER_METADATA_FILE);
20849
+ return path28.join(path28.resolve(projectDir), MAILBOX_PROJECT_SERVER_METADATA_FILE);
20308
20850
  }
20309
20851
 
20310
20852
  // src/coordination/mailbox-project-server-client.ts
@@ -20315,7 +20857,7 @@ var DEFAULT_HEARTBEAT_INTERVAL_MS = 1e4;
20315
20857
  var AUTH_RETRY_DELAY_MS = 150;
20316
20858
  var AUTH_RETRY_MAX_ATTEMPTS = 13;
20317
20859
  function normalizePath(value) {
20318
- const resolved = path27.resolve(value);
20860
+ const resolved = path29.resolve(value);
20319
20861
  return process.platform === "win32" ? resolved.toLowerCase() : resolved;
20320
20862
  }
20321
20863
  function resolveProjectServerUrl() {
@@ -20325,7 +20867,7 @@ function resolveProjectServerUrl() {
20325
20867
  ]) {
20326
20868
  try {
20327
20869
  const url = new URL(relative4, import.meta.url);
20328
- if (url.protocol === "file:" && fs3.existsSync(fileURLToPath3(url))) return url;
20870
+ if (url.protocol === "file:" && fs4.existsSync(fileURLToPath4(url))) return url;
20329
20871
  } catch {
20330
20872
  }
20331
20873
  }
@@ -20334,8 +20876,8 @@ function resolveProjectServerUrl() {
20334
20876
  function isMailboxProjectServerAvailable() {
20335
20877
  return resolveProjectServerUrl() !== null;
20336
20878
  }
20337
- function delay(ms) {
20338
- return new Promise((resolve14) => setTimeout(resolve14, ms));
20879
+ function delay2(ms) {
20880
+ return new Promise((resolve16) => setTimeout(resolve16, ms));
20339
20881
  }
20340
20882
  function isUnauthorizedMailboxError(error) {
20341
20883
  return error instanceof Error && error.name === "UnauthorizedMailboxRequest";
@@ -20343,7 +20885,7 @@ function isUnauthorizedMailboxError(error) {
20343
20885
  var MailboxProjectServerConnection = class {
20344
20886
  constructor(projectDir) {
20345
20887
  this.projectDir = projectDir;
20346
- this.projectDir = path27.resolve(projectDir);
20888
+ this.projectDir = path29.resolve(projectDir);
20347
20889
  this.endpoint = mailboxProjectServerEndpoint(this.projectDir);
20348
20890
  this.state = {
20349
20891
  status: isMailboxProjectServerAvailable() ? "offline" : "unavailable",
@@ -20426,7 +20968,7 @@ var MailboxProjectServerConnection = class {
20426
20968
  lastError = error;
20427
20969
  const retriable = isUnauthorizedMailboxError(error) && attempt < AUTH_RETRY_MAX_ATTEMPTS;
20428
20970
  if (!retriable) throw error;
20429
- await delay(AUTH_RETRY_DELAY_MS);
20971
+ await delay2(AUTH_RETRY_DELAY_MS);
20430
20972
  }
20431
20973
  }
20432
20974
  throw lastError;
@@ -20498,7 +21040,7 @@ var MailboxProjectServerConnection = class {
20498
21040
  this.spawnDetachedServer();
20499
21041
  spawned = true;
20500
21042
  }
20501
- await delay(75);
21043
+ await delay2(75);
20502
21044
  }
20503
21045
  throw lastError;
20504
21046
  }
@@ -20508,8 +21050,8 @@ var MailboxProjectServerConnection = class {
20508
21050
  this.info = null;
20509
21051
  this.buffer = "";
20510
21052
  this.authToken = void 0;
20511
- return new Promise((resolve14, reject) => {
20512
- const socket = net.createConnection(this.endpoint);
21053
+ return new Promise((resolve16, reject) => {
21054
+ const socket = net2.createConnection(this.endpoint);
20513
21055
  this.socket = socket;
20514
21056
  socket.setEncoding("utf8");
20515
21057
  const timer = setTimeout(() => {
@@ -20523,7 +21065,7 @@ var MailboxProjectServerConnection = class {
20523
21065
  this.connectReject = null;
20524
21066
  this.startHeartbeat();
20525
21067
  this.transition("connected");
20526
- resolve14();
21068
+ resolve16();
20527
21069
  void this.request({ type: "request", op: "ping", args: {} }, 3e3).catch(
20528
21070
  () => void 0
20529
21071
  );
@@ -20552,7 +21094,7 @@ var MailboxProjectServerConnection = class {
20552
21094
  currentAuthToken() {
20553
21095
  if (this.authToken === void 0) {
20554
21096
  try {
20555
- const raw = fs3.readFileSync(mailboxProjectServerMetadataPath(this.projectDir), "utf8");
21097
+ const raw = fs4.readFileSync(mailboxProjectServerMetadataPath(this.projectDir), "utf8");
20556
21098
  const parsed = JSON.parse(raw);
20557
21099
  if (typeof parsed.authToken === "string" && parsed.authToken.length > 0) {
20558
21100
  this.authToken = parsed.authToken;
@@ -20576,7 +21118,7 @@ var MailboxProjectServerConnection = class {
20576
21118
  if (encoded.length > MAILBOX_PROJECT_SERVER_MAX_FRAME_CHARS) {
20577
21119
  return Promise.reject(new Error("Mailbox project server request exceeded frame limit"));
20578
21120
  }
20579
- return new Promise((resolve14, reject) => {
21121
+ return new Promise((resolve16, reject) => {
20580
21122
  const timer = setTimeout(() => {
20581
21123
  const pending = this.pending.get(id);
20582
21124
  if (!pending) return;
@@ -20584,7 +21126,7 @@ var MailboxProjectServerConnection = class {
20584
21126
  pending.reject(new Error(`Mailbox ${message.type} exceeded its ${timeoutMs}ms timeout`));
20585
21127
  }, timeoutMs);
20586
21128
  timer.unref?.();
20587
- this.pending.set(id, { resolve: resolve14, reject, timer });
21129
+ this.pending.set(id, { resolve: resolve16, reject, timer });
20588
21130
  socket.write(encoded);
20589
21131
  });
20590
21132
  }
@@ -20699,8 +21241,8 @@ var MailboxProjectServerConnection = class {
20699
21241
  spawnDetachedServer() {
20700
21242
  const url = resolveProjectServerUrl();
20701
21243
  if (!url) throw new Error("Mailbox project server entrypoint is unavailable");
20702
- fs3.mkdirSync(this.projectDir, { recursive: true });
20703
- const child = spawn4(process.execPath, [fileURLToPath3(url), "--project-dir", this.projectDir], {
21244
+ fs4.mkdirSync(this.projectDir, { recursive: true });
21245
+ const child = spawn5(process.execPath, [fileURLToPath4(url), "--project-dir", this.projectDir], {
20704
21246
  cwd: this.projectDir,
20705
21247
  detached: process.platform !== "win32",
20706
21248
  stdio: "ignore",
@@ -21021,9 +21563,9 @@ var CredentialVerifyThrottle = class {
21021
21563
  var credentialVerifyThrottle = new CredentialVerifyThrottle();
21022
21564
 
21023
21565
  // src/coordination/global-mailbox-paths.ts
21024
- import * as path28 from "node:path";
21566
+ import * as path30 from "node:path";
21025
21567
  function resolveProjectDir(projectRoot, globalRoot) {
21026
- return path28.join(globalRoot, "projects", projectSlug(projectRoot));
21568
+ return path30.join(globalRoot, "projects", projectSlug(projectRoot));
21027
21569
  }
21028
21570
 
21029
21571
  // src/coordination/sqlite-mailbox.ts
@@ -21073,8 +21615,8 @@ var RemoteMailbox = class {
21073
21615
  hqPublisher,
21074
21616
  eventEmitter
21075
21617
  } : optionsOrProjectDir;
21076
- this.projectDir = path29.resolve(options.projectDir);
21077
- this.messagePath = path29.join(this.projectDir, SQLITE_MAILBOX_FILE);
21618
+ this.projectDir = path31.resolve(options.projectDir);
21619
+ this.messagePath = path31.join(this.projectDir, SQLITE_MAILBOX_FILE);
21078
21620
  this.registryPath = this.messagePath;
21079
21621
  this.clientRegistryPath = this.messagePath;
21080
21622
  this.events = options.events;
@@ -21273,7 +21815,7 @@ var RemoteMailbox = class {
21273
21815
  this.hqSnapshotPendingMailboxId = mailboxId;
21274
21816
  if (this.hqSnapshotTimer !== void 0 || this.hqSnapshotInFlight !== void 0) return;
21275
21817
  const elapsed = Date.now() - this.hqSnapshotLastAt;
21276
- const delay2 = Math.max(0, HQ_MAILBOX_SNAPSHOT_MIN_INTERVAL_MS - elapsed);
21818
+ const delay3 = Math.max(0, HQ_MAILBOX_SNAPSHOT_MIN_INTERVAL_MS - elapsed);
21277
21819
  this.hqSnapshotTimer = setTimeout(() => {
21278
21820
  this.hqSnapshotTimer = void 0;
21279
21821
  const pendingMailboxId = this.hqSnapshotPendingMailboxId;
@@ -21294,7 +21836,7 @@ var RemoteMailbox = class {
21294
21836
  }
21295
21837
  })();
21296
21838
  this.hqSnapshotInFlight = inFlight;
21297
- }, delay2);
21839
+ }, delay3);
21298
21840
  this.hqSnapshotTimer.unref?.();
21299
21841
  }
21300
21842
  publishHqEvent(event) {
@@ -21320,7 +21862,7 @@ var RemoteMailbox = class {
21320
21862
  this.hqEventPending.clear();
21321
21863
  return;
21322
21864
  }
21323
- const mailboxId = `${path29.basename(this.projectDir)}:mailbox`;
21865
+ const mailboxId = `${path31.basename(this.projectDir)}:mailbox`;
21324
21866
  const inFlight = this.query({ includeDeleted: true, limit: 100 }).then((messages) => {
21325
21867
  const message = messages.find((candidate) => candidate.id === event.messageId);
21326
21868
  const action = event.type === "message.sent" ? "message.sent" : "message.updated";
@@ -21343,7 +21885,7 @@ var RemoteMailbox = class {
21343
21885
  if (!publisher || !event.startsWith("mailbox.agent_") && !event.startsWith("mailbox.client_")) {
21344
21886
  return;
21345
21887
  }
21346
- const mailboxId = `${path29.basename(this.projectDir)}:mailbox`;
21888
+ const mailboxId = `${path31.basename(this.projectDir)}:mailbox`;
21347
21889
  const record = typeof payload === "object" && payload !== null ? payload : {};
21348
21890
  const agentId = typeof record["agentId"] === "string" ? record["agentId"] : void 0;
21349
21891
  const action = event === "mailbox.agent_registered" ? "agent.registered" : event === "mailbox.agent_heartbeat" ? "agent.heartbeat" : event === "mailbox.agent_deregistered" ? "agent.deregistered" : void 0;
@@ -21366,7 +21908,7 @@ function createProjectMailbox(options) {
21366
21908
  return new RemoteMailbox(options);
21367
21909
  }
21368
21910
  function getSharedProjectMailbox(projectDir, events, hqPublisher) {
21369
- const key = path29.resolve(projectDir);
21911
+ const key = path31.resolve(projectDir);
21370
21912
  let projectCache = sharedRemoteMailboxes.get(key);
21371
21913
  if (!projectCache) {
21372
21914
  projectCache = {
@@ -21406,12 +21948,12 @@ function getSharedProjectMailbox(projectDir, events, hqPublisher) {
21406
21948
  }
21407
21949
 
21408
21950
  // src/coordination/mailbox-tool.ts
21409
- import { createHash as createHash6 } from "node:crypto";
21951
+ import { createHash as createHash7 } from "node:crypto";
21410
21952
  function defaultResolveProjectDir(ctx) {
21411
21953
  return resolveProjectDir(ctx.projectRoot, wstackGlobalRoot());
21412
21954
  }
21413
21955
  function mailboxSessionTag(sessionId) {
21414
- return createHash6("sha256").update(sessionId).digest("hex").slice(0, 8);
21956
+ return createHash7("sha256").update(sessionId).digest("hex").slice(0, 8);
21415
21957
  }
21416
21958
  function resolveMailboxIdentity(ctx, fallbackBase = "leader") {
21417
21959
  const fieldId = ctx.agentId && ctx.agentId !== "unknown" ? ctx.agentId : void 0;
@@ -21816,7 +22358,7 @@ function makeFleetStatusTool(opts = {}) {
21816
22358
  }
21817
22359
 
21818
22360
  // src/coordination/fleet-supervisor.ts
21819
- import { randomUUID as randomUUID15 } from "node:crypto";
22361
+ import { randomUUID as randomUUID16 } from "node:crypto";
21820
22362
  var COLLAB_ID_PREFIXES2 = ["bug-hunter-", "refactor-planner-", "critic-"];
21821
22363
  var DEFAULTS = {
21822
22364
  intervalMs: 2e4,
@@ -22094,7 +22636,7 @@ var FleetSupervisor = class {
22094
22636
  */
22095
22637
  async decide(question, context, options, risk) {
22096
22638
  const request = {
22097
- id: `fleetsup-${randomUUID15()}`,
22639
+ id: `fleetsup-${randomUUID16()}`,
22098
22640
  sessionId: this.opts.sessionId?.(),
22099
22641
  source: "system",
22100
22642
  question,
@@ -23734,16 +24276,16 @@ async function dispatchMailboxRoute(mailbox, eventEmitter, request, response, me
23734
24276
  throw validationError(`routePath must not start with '?' (got ${JSON.stringify(routePath)})`);
23735
24277
  }
23736
24278
  const queryIndex = url.indexOf("?");
23737
- const path34 = queryIndex === -1 ? url : url.slice(0, queryIndex);
24279
+ const path36 = queryIndex === -1 ? url : url.slice(0, queryIndex);
23738
24280
  if (actor !== void 0) {
23739
- const requiredCapability = requiredCredentialCapability(method, path34);
24281
+ const requiredCapability = requiredCredentialCapability(method, path36);
23740
24282
  if (requiredCapability === void 0) {
23741
24283
  writeJson(response, 403, {
23742
- error: { code: "FORBIDDEN", message: `credential access is not permitted for ${method} ${path34}` }
24284
+ error: { code: "FORBIDDEN", message: `credential access is not permitted for ${method} ${path36}` }
23743
24285
  });
23744
24286
  return;
23745
24287
  }
23746
- if (path34 !== "/mailbox/send" && !hasMailboxCapability(actor, requiredCapability)) {
24288
+ if (path36 !== "/mailbox/send" && !hasMailboxCapability(actor, requiredCapability)) {
23747
24289
  writeJson(response, 403, {
23748
24290
  error: {
23749
24291
  code: "FORBIDDEN",
@@ -23753,7 +24295,7 @@ async function dispatchMailboxRoute(mailbox, eventEmitter, request, response, me
23753
24295
  return;
23754
24296
  }
23755
24297
  }
23756
- if (method === "POST" && path34 === "/mailbox/send") {
24298
+ if (method === "POST" && path36 === "/mailbox/send") {
23757
24299
  const input = validateSend(await readJsonBody(request, maxBodyBytes), actor?.actorId);
23758
24300
  if (actor !== void 0) {
23759
24301
  const requiredCapability = requiredSendCapability(input.type);
@@ -23771,7 +24313,7 @@ async function dispatchMailboxRoute(mailbox, eventEmitter, request, response, me
23771
24313
  writeJson(response, 201, await mailbox.send(input));
23772
24314
  return;
23773
24315
  }
23774
- if (method === "POST" && path34 === "/mailbox/query") {
24316
+ if (method === "POST" && path36 === "/mailbox/query") {
23775
24317
  const queryContext = parseSinceMs(url, defaultMaxAgeMs);
23776
24318
  if ("error" in queryContext) {
23777
24319
  writeJson(response, 400, { error: queryContext.error });
@@ -23791,7 +24333,7 @@ async function dispatchMailboxRoute(mailbox, eventEmitter, request, response, me
23791
24333
  writeJson(response, 200, { data: projected, count: projected.length });
23792
24334
  return;
23793
24335
  }
23794
- if (method === "POST" && path34 === "/mailbox/check") {
24336
+ if (method === "POST" && path36 === "/mailbox/check") {
23795
24337
  const queryContext = parseSinceMs(url, defaultMaxAgeMs);
23796
24338
  if ("error" in queryContext) {
23797
24339
  writeJson(response, 400, { error: queryContext.error });
@@ -23825,7 +24367,7 @@ async function dispatchMailboxRoute(mailbox, eventEmitter, request, response, me
23825
24367
  writeJson(response, 200, { data: projected, count: projected.length });
23826
24368
  return;
23827
24369
  }
23828
- if (method === "POST" && path34 === "/mailbox/ack") {
24370
+ if (method === "POST" && path36 === "/mailbox/ack") {
23829
24371
  const input = validateAck(await readJsonBody(request, maxBodyBytes), actor?.actorId);
23830
24372
  if (actor !== void 0) {
23831
24373
  input.readerId = actor.actorId;
@@ -23839,7 +24381,7 @@ async function dispatchMailboxRoute(mailbox, eventEmitter, request, response, me
23839
24381
  writeJson(response, 200, { updated: projectedAck });
23840
24382
  return;
23841
24383
  }
23842
- if (method === "POST" && path34 === "/mailbox/ack-many") {
24384
+ if (method === "POST" && path36 === "/mailbox/ack-many") {
23843
24385
  const input = validateAckMany(await readJsonBody(request, maxBodyBytes), actor?.actorId);
23844
24386
  if (actor !== void 0) {
23845
24387
  const requestedIds = new Set(input.acks.map((ack) => ack.messageId));
@@ -23857,54 +24399,54 @@ async function dispatchMailboxRoute(mailbox, eventEmitter, request, response, me
23857
24399
  writeJson(response, 200, { updated: projectedMany, count: projectedMany.length });
23858
24400
  return;
23859
24401
  }
23860
- if (method === "POST" && path34 === "/mailbox/unread-count") {
24402
+ if (method === "POST" && path36 === "/mailbox/unread-count") {
23861
24403
  const body = await readJsonBody(request, maxBodyBytes);
23862
24404
  const count = actor === void 0 ? await mailbox.unreadCount(requireString2(body, "forAgentId")) : await unreadCountForActor(mailbox, actor);
23863
24405
  writeJson(response, 200, { count });
23864
24406
  return;
23865
24407
  }
23866
- if (method === "POST" && path34 === "/mailbox/agents/register") {
24408
+ if (method === "POST" && path36 === "/mailbox/agents/register") {
23867
24409
  const input = validateAgentRegistration(await readJsonBody(request, maxBodyBytes), actor);
23868
24410
  await mailbox.registerAgent(input);
23869
24411
  writeJson(response, 200, { ok: true });
23870
24412
  return;
23871
24413
  }
23872
- if (method === "POST" && path34 === "/mailbox/agents/heartbeat") {
24414
+ if (method === "POST" && path36 === "/mailbox/agents/heartbeat") {
23873
24415
  const input = validateAgentHeartbeat(await readJsonBody(request, maxBodyBytes), actor?.actorId);
23874
24416
  if (actor !== void 0) input.agentId = actor.actorId;
23875
24417
  await mailbox.heartbeat(input);
23876
24418
  writeJson(response, 200, { ok: true });
23877
24419
  return;
23878
24420
  }
23879
- if (method === "POST" && path34 === "/mailbox/register-client") {
24421
+ if (method === "POST" && path36 === "/mailbox/register-client") {
23880
24422
  await mailbox.registerClient(
23881
24423
  validateClientRegistration(await readJsonBody(request, maxBodyBytes))
23882
24424
  );
23883
24425
  writeJson(response, 200, { ok: true });
23884
24426
  return;
23885
24427
  }
23886
- if (method === "POST" && path34 === "/mailbox/heartbeat") {
24428
+ if (method === "POST" && path36 === "/mailbox/heartbeat") {
23887
24429
  await mailbox.clientHeartbeat(
23888
24430
  validateClientHeartbeat(await readJsonBody(request, maxBodyBytes))
23889
24431
  );
23890
24432
  writeJson(response, 200, { ok: true });
23891
24433
  return;
23892
24434
  }
23893
- if (method === "POST" && path34 === "/mailbox/purge-clients") {
24435
+ if (method === "POST" && path36 === "/mailbox/purge-clients") {
23894
24436
  writeJson(response, 200, { ok: true, purged: await mailbox.purgeClients() });
23895
24437
  return;
23896
24438
  }
23897
- if (method === "GET" && path34 === "/mailbox/agents") {
24439
+ if (method === "GET" && path36 === "/mailbox/agents") {
23898
24440
  const agents = await mailbox.getAgentStatuses();
23899
24441
  writeJson(response, 200, { data: agents, count: agents.length });
23900
24442
  return;
23901
24443
  }
23902
- if (method === "GET" && path34 === "/mailbox/agents/online") {
24444
+ if (method === "GET" && path36 === "/mailbox/agents/online") {
23903
24445
  const agents = await mailbox.getOnlineAgents();
23904
24446
  writeJson(response, 200, { data: agents, count: agents.length });
23905
24447
  return;
23906
24448
  }
23907
- if (method === "GET" && path34 === "/mailbox/events" && eventEmitter) {
24449
+ if (method === "GET" && path36 === "/mailbox/events" && eventEmitter) {
23908
24450
  const queryContext = parseSinceMs(url, defaultMaxAgeMs);
23909
24451
  if ("error" in queryContext) {
23910
24452
  writeJson(response, 400, { error: queryContext.error });
@@ -24013,25 +24555,25 @@ function requiredSendCapability(type) {
24013
24555
  }
24014
24556
  return "mail.send.informational";
24015
24557
  }
24016
- function requiredCredentialCapability(method, path34) {
24017
- if (method === "POST" && path34 === "/mailbox/send") return "mail.send.informational";
24018
- if (method === "POST" && (path34 === "/mailbox/query" || path34 === "/mailbox/check")) {
24558
+ function requiredCredentialCapability(method, path36) {
24559
+ if (method === "POST" && path36 === "/mailbox/send") return "mail.send.informational";
24560
+ if (method === "POST" && (path36 === "/mailbox/query" || path36 === "/mailbox/check")) {
24019
24561
  return "mail.read.self";
24020
24562
  }
24021
- if (method === "POST" && (path34 === "/mailbox/ack" || path34 === "/mailbox/ack-many")) {
24563
+ if (method === "POST" && (path36 === "/mailbox/ack" || path36 === "/mailbox/ack-many")) {
24022
24564
  return "mail.ack.self";
24023
24565
  }
24024
- if (method === "POST" && path34 === "/mailbox/unread-count") return "mail.read.self";
24025
- if (method === "POST" && path34 === "/mailbox/agents/register") {
24566
+ if (method === "POST" && path36 === "/mailbox/unread-count") return "mail.read.self";
24567
+ if (method === "POST" && path36 === "/mailbox/agents/register") {
24026
24568
  return "mail.presence.register.self";
24027
24569
  }
24028
- if (method === "POST" && path34 === "/mailbox/agents/heartbeat") {
24570
+ if (method === "POST" && path36 === "/mailbox/agents/heartbeat") {
24029
24571
  return "mail.presence.heartbeat.self";
24030
24572
  }
24031
- if (method === "GET" && (path34 === "/mailbox/agents" || path34 === "/mailbox/agents/online")) {
24573
+ if (method === "GET" && (path36 === "/mailbox/agents" || path36 === "/mailbox/agents/online")) {
24032
24574
  return "mail.presence.read";
24033
24575
  }
24034
- if (method === "GET" && path34 === "/mailbox/events") return "mail.events.self";
24576
+ if (method === "GET" && path36 === "/mailbox/events") return "mail.events.self";
24035
24577
  return void 0;
24036
24578
  }
24037
24579
  function extractEventTimestamp(event) {
@@ -24233,16 +24775,16 @@ async function checkMailbox(mailbox, input, minTimestampIso, includeReceiptState
24233
24775
  var NULL_FLEET_BUS = new FleetBus();
24234
24776
 
24235
24777
  // src/coordination/package-author-tracker.ts
24236
- import * as fs4 from "node:fs/promises";
24237
- import * as path30 from "node:path";
24778
+ import * as fs5 from "node:fs/promises";
24779
+ import * as path32 from "node:path";
24238
24780
  var DEFAULT_MAX_ENTRIES2 = 1e4;
24239
24781
  var LOG_FILENAME2 = "package-authors.json";
24240
24782
  function logPath2(storageDir) {
24241
- return path30.join(storageDir, LOG_FILENAME2);
24783
+ return path32.join(storageDir, LOG_FILENAME2);
24242
24784
  }
24243
24785
  async function loadLog2(storageDir, projectRoot) {
24244
24786
  try {
24245
- const raw = await fs4.readFile(logPath2(storageDir), "utf-8");
24787
+ const raw = await fs5.readFile(logPath2(storageDir), "utf-8");
24246
24788
  const parsed = JSON.parse(raw);
24247
24789
  if (!parsed.entries || !Array.isArray(parsed.entries)) {
24248
24790
  return { projectRoot, entries: [] };
@@ -24260,7 +24802,7 @@ async function saveLog2(storageDir, log) {
24260
24802
  `);
24261
24803
  }
24262
24804
  function detectEcosystem(manifestPath) {
24263
- const name = path30.win32.basename(manifestPath).toLowerCase();
24805
+ const name = path32.win32.basename(manifestPath).toLowerCase();
24264
24806
  if (name === "package.json") return "npm";
24265
24807
  if (name === "go.mod") return "go";
24266
24808
  if (name === "cargo.toml") return "cargo";
@@ -25142,13 +25684,13 @@ var RemoteMailboxCredentialStore = class {
25142
25684
  import { randomBytes as randomBytes2 } from "node:crypto";
25143
25685
  import * as fsp21 from "node:fs/promises";
25144
25686
  import { execFile } from "node:child_process";
25145
- import * as os3 from "node:os";
25146
- import * as path31 from "node:path";
25687
+ import * as os4 from "node:os";
25688
+ import * as path33 from "node:path";
25147
25689
  var MAILBOX_BRIDGE_LOCK_FILENAME = ".mailbox-bridge.lock";
25148
25690
  var MAILBOX_BRIDGE_TOKEN_FILENAME = ".mailbox.token";
25149
25691
  async function acquireOrJoin(opts) {
25150
- const lockPath = path31.join(opts.projectDir, MAILBOX_BRIDGE_LOCK_FILENAME);
25151
- const tokenPath = path31.join(opts.projectDir, MAILBOX_BRIDGE_TOKEN_FILENAME);
25692
+ const lockPath = path33.join(opts.projectDir, MAILBOX_BRIDGE_LOCK_FILENAME);
25693
+ const tokenPath = path33.join(opts.projectDir, MAILBOX_BRIDGE_TOKEN_FILENAME);
25152
25694
  const inspected = await readLockForInspection(lockPath);
25153
25695
  if (inspected.kind === "live") {
25154
25696
  const existing = inspected.lock;
@@ -25176,8 +25718,8 @@ async function acquireOrJoin(opts) {
25176
25718
  return { kind: "acquired", lock: tentative, tokenPath };
25177
25719
  }
25178
25720
  async function finalize(projectDir, tentative, boundPort) {
25179
- const lockPath = path31.join(projectDir, MAILBOX_BRIDGE_LOCK_FILENAME);
25180
- const tokenPath = path31.join(projectDir, MAILBOX_BRIDGE_TOKEN_FILENAME);
25721
+ const lockPath = path33.join(projectDir, MAILBOX_BRIDGE_LOCK_FILENAME);
25722
+ const tokenPath = path33.join(projectDir, MAILBOX_BRIDGE_TOKEN_FILENAME);
25181
25723
  const finalized = {
25182
25724
  ...tentative,
25183
25725
  port: boundPort,
@@ -25188,8 +25730,8 @@ async function finalize(projectDir, tentative, boundPort) {
25188
25730
  return finalized;
25189
25731
  }
25190
25732
  async function release(projectDir, generation) {
25191
- const lockPath = path31.join(projectDir, MAILBOX_BRIDGE_LOCK_FILENAME);
25192
- const tokenPath = path31.join(projectDir, MAILBOX_BRIDGE_TOKEN_FILENAME);
25733
+ const lockPath = path33.join(projectDir, MAILBOX_BRIDGE_LOCK_FILENAME);
25734
+ const tokenPath = path33.join(projectDir, MAILBOX_BRIDGE_TOKEN_FILENAME);
25193
25735
  try {
25194
25736
  const raw = await fsp21.readFile(lockPath, "utf-8");
25195
25737
  const parsed = JSON.parse(raw);
@@ -25223,7 +25765,7 @@ async function readLockForInspection(lockPath) {
25223
25765
  return { kind: "live", lock: parsed };
25224
25766
  }
25225
25767
  async function readLiveLock(projectDir) {
25226
- const lockPath = path31.join(projectDir, MAILBOX_BRIDGE_LOCK_FILENAME);
25768
+ const lockPath = path33.join(projectDir, MAILBOX_BRIDGE_LOCK_FILENAME);
25227
25769
  const result = await readLockForInspection(lockPath);
25228
25770
  if (result.kind === "live") {
25229
25771
  return { kind: "live", lock: result.lock };
@@ -25234,7 +25776,7 @@ async function readLiveLock(projectDir) {
25234
25776
  return { kind: "absent" };
25235
25777
  }
25236
25778
  async function atomicWriteJson(targetPath, value) {
25237
- const dir = path31.dirname(targetPath);
25779
+ const dir = path33.dirname(targetPath);
25238
25780
  await fsp21.mkdir(dir, { recursive: true });
25239
25781
  const tmp = `${targetPath}.tmp.${process.pid}.${randomBytes2(4).toString("hex")}`;
25240
25782
  const body = JSON.stringify(value, null, 2) + "\n";
@@ -25249,8 +25791,8 @@ async function atomicWriteJson(targetPath, value) {
25249
25791
  async function isProcessAlive(pid) {
25250
25792
  if (!Number.isInteger(pid) || pid <= 0) return false;
25251
25793
  if (pid === process.pid) return true;
25252
- if (os3.platform() === "win32") {
25253
- return new Promise((resolve14) => {
25794
+ if (os4.platform() === "win32") {
25795
+ return new Promise((resolve16) => {
25254
25796
  execFile(
25255
25797
  "tasklist",
25256
25798
  ["/FI", `PID eq ${pid}`, "/NH", "/FO", "CSV"],
@@ -25262,11 +25804,11 @@ async function isProcessAlive(pid) {
25262
25804
  },
25263
25805
  (error, out) => {
25264
25806
  if (error) {
25265
- resolve14(false);
25807
+ resolve16(false);
25266
25808
  return;
25267
25809
  }
25268
25810
  const match = /(?:^|\n)"[^"]*","(\d+)"/.exec(out);
25269
- resolve14(match !== null && match[1] === String(pid));
25811
+ resolve16(match !== null && match[1] === String(pid));
25270
25812
  }
25271
25813
  );
25272
25814
  });
@@ -25397,8 +25939,8 @@ function extractManifestPath(msg) {
25397
25939
  }
25398
25940
  return void 0;
25399
25941
  }
25400
- function isManifestFile(path34) {
25401
- const name = pathBasename(path34).toLowerCase();
25942
+ function isManifestFile(path36) {
25943
+ const name = pathBasename(path36).toLowerCase();
25402
25944
  const manifests = [
25403
25945
  "package.json",
25404
25946
  "package-lock.json",
@@ -25691,8 +26233,8 @@ var AdaptiveConcurrencyController = class {
25691
26233
 
25692
26234
  // src/coordination/agent-monitor.ts
25693
26235
  import { createReadStream as createReadStream5 } from "node:fs";
25694
- import * as fs5 from "node:fs/promises";
25695
- import * as path32 from "node:path";
26236
+ import * as fs6 from "node:fs/promises";
26237
+ import * as path34 from "node:path";
25696
26238
  import { createInterface as createInterface5 } from "node:readline";
25697
26239
  var AgentMonitorService = class _AgentMonitorService {
25698
26240
  _fleetBus;
@@ -25772,7 +26314,7 @@ var AgentMonitorService = class _AgentMonitorService {
25772
26314
  async loadSessionsFromDisk() {
25773
26315
  let subagentIds;
25774
26316
  try {
25775
- const dirents = await fs5.readdir(this._transcriptsDir, { withFileTypes: true });
26317
+ const dirents = await fs6.readdir(this._transcriptsDir, { withFileTypes: true });
25776
26318
  subagentIds = dirents.filter((d) => d.isDirectory()).map((d) => d.name);
25777
26319
  } catch {
25778
26320
  return this.getAllSessions();
@@ -25796,8 +26338,8 @@ var AgentMonitorService = class _AgentMonitorService {
25796
26338
  return this.getAllSessions();
25797
26339
  }
25798
26340
  async _readTranscriptFile(subagentId) {
25799
- const file = path32.join(this._transcriptsDir, subagentId, "transcript.jsonl");
25800
- const accessible = await fs5.access(file).then(() => true).catch(() => false);
26341
+ const file = path34.join(this._transcriptsDir, subagentId, "transcript.jsonl");
26342
+ const accessible = await fs6.access(file).then(() => true).catch(() => false);
25801
26343
  if (!accessible) return [];
25802
26344
  const out = [];
25803
26345
  const input = createReadStream5(file, { encoding: "utf8" });
@@ -26137,14 +26679,14 @@ var AgentMonitorService = class _AgentMonitorService {
26137
26679
  this._writeDrain = drain;
26138
26680
  }
26139
26681
  async _appendToFile(subagentId, line) {
26140
- const dir = path32.join(this._transcriptsDir, subagentId);
26682
+ const dir = path34.join(this._transcriptsDir, subagentId);
26141
26683
  if (!this._ensuredDirs.has(dir)) {
26142
- await fs5.mkdir(dir, { recursive: true });
26684
+ await fs6.mkdir(dir, { recursive: true });
26143
26685
  this._ensuredDirs.add(dir);
26144
26686
  }
26145
- const filePath = path32.join(dir, "transcript.jsonl");
26687
+ const filePath = path34.join(dir, "transcript.jsonl");
26146
26688
  try {
26147
- await fs5.appendFile(filePath, line, { encoding: "utf8", mode: SECRET_FILE_MODE });
26689
+ await fs6.appendFile(filePath, line, { encoding: "utf8", mode: SECRET_FILE_MODE });
26148
26690
  } catch (error) {
26149
26691
  this._ensuredDirs.delete(dir);
26150
26692
  throw error;
@@ -26188,7 +26730,7 @@ function createAgentMonitorService(opts) {
26188
26730
  }
26189
26731
 
26190
26732
  // src/coordination/autonomous-brain.ts
26191
- import { randomUUID as randomUUID16 } from "node:crypto";
26733
+ import { randomUUID as randomUUID17 } from "node:crypto";
26192
26734
  var AutonomousBrain = class {
26193
26735
  graph;
26194
26736
  // Fleet bus for emitting decisions — null-safe, no-op if not provided
@@ -26294,7 +26836,7 @@ var AutonomousBrain = class {
26294
26836
  consequence: i === 0 ? `Spawn the most appropriate agent for: ${taskDescription.slice(0, 80)}` : `Spawn an alternative agent for the same task`
26295
26837
  }));
26296
26838
  return this.decideAuto({
26297
- id: randomUUID16(),
26839
+ id: randomUUID17(),
26298
26840
  source,
26299
26841
  decisionType: "spawn",
26300
26842
  question: `Should we spawn a subagent for this task?`,
@@ -26337,7 +26879,7 @@ var AutonomousBrain = class {
26337
26879
  }
26338
26880
  ];
26339
26881
  return this.decideAuto({
26340
- id: randomUUID16(),
26882
+ id: randomUUID17(),
26341
26883
  source,
26342
26884
  decisionType: "approve_change",
26343
26885
  question: `Should we approve the change "${change.title}"?`,
@@ -26396,7 +26938,7 @@ var AutonomousBrain = class {
26396
26938
  consequence: "Break the task into smaller sub-tasks"
26397
26939
  });
26398
26940
  return this.decideAuto({
26399
- id: randomUUID16(),
26941
+ id: randomUUID17(),
26400
26942
  source,
26401
26943
  decisionType: "escalate_task",
26402
26944
  question: `Task failed: ${error.slice(0, 100)}. How should we proceed?`,
@@ -26530,12 +27072,12 @@ ${ctx.error}`);
26530
27072
  };
26531
27073
 
26532
27074
  // src/coordination/autonomous-coordinator.ts
26533
- import { randomUUID as randomUUID19 } from "node:crypto";
27075
+ import { randomUUID as randomUUID20 } from "node:crypto";
26534
27076
 
26535
27077
  // src/coordination/knowledge-graph.ts
26536
- import { randomUUID as randomUUID17 } from "node:crypto";
27078
+ import { randomUUID as randomUUID18 } from "node:crypto";
26537
27079
  import * as fsp22 from "node:fs/promises";
26538
- import * as path33 from "node:path";
27080
+ import * as path35 from "node:path";
26539
27081
  var DEFAULT_MAX_NODES = 2e3;
26540
27082
  var MAX_SUBSCRIPTIONS = 1e3;
26541
27083
  var MAX_PENDING_DELIVERIES_PER_SUBSCRIPTION = 1e3;
@@ -26570,8 +27112,8 @@ var KnowledgeGraph = class _KnowledgeGraph {
26570
27112
  return this.index;
26571
27113
  }
26572
27114
  constructor(sessionDir, maxNodes = DEFAULT_MAX_NODES, compactEveryWrites = Math.max(1e3, maxNodes * 4)) {
26573
- this.filePath = path33.join(sessionDir, "_knowledge_graph");
26574
- this.graphFilePath = path33.join(this.filePath, "graph.jsonl");
27115
+ this.filePath = path35.join(sessionDir, "_knowledge_graph");
27116
+ this.graphFilePath = path35.join(this.filePath, "graph.jsonl");
26575
27117
  this.maxNodes = maxNodes;
26576
27118
  this.compactEveryWrites = Math.max(1, Math.floor(compactEveryWrites));
26577
27119
  }
@@ -26581,7 +27123,7 @@ var KnowledgeGraph = class _KnowledgeGraph {
26581
27123
  * Returns the node with its assigned id.
26582
27124
  */
26583
27125
  async add(node) {
26584
- const full = { id: randomUUID17(), ...node };
27126
+ const full = { id: randomUUID18(), ...node };
26585
27127
  this.nodes.set(full.id, full);
26586
27128
  this._trackSeq(full.id);
26587
27129
  this._addToIndex(full, this._indexKeys(full));
@@ -26710,8 +27252,8 @@ var KnowledgeGraph = class _KnowledgeGraph {
26710
27252
  if (this.subs.size >= MAX_SUBSCRIPTIONS) {
26711
27253
  throw new Error(`Knowledge graph subscription limit reached (${MAX_SUBSCRIPTIONS})`);
26712
27254
  }
26713
- const channel = randomUUID17();
26714
- const sub = { id: randomUUID17(), agentId, filter, channel };
27255
+ const channel = randomUUID18();
27256
+ const sub = { id: randomUUID18(), agentId, filter, channel };
26715
27257
  this.subs.set(channel, sub);
26716
27258
  this.pendingDeliveries.set(channel, []);
26717
27259
  return channel;
@@ -27192,7 +27734,7 @@ var TaskDAG = class {
27192
27734
  };
27193
27735
 
27194
27736
  // src/coordination/task-auctioneer.ts
27195
- import { randomUUID as randomUUID18 } from "node:crypto";
27737
+ import { randomUUID as randomUUID19 } from "node:crypto";
27196
27738
  function isTerminalGoalStatus(status) {
27197
27739
  return status === "done" || status === "failed";
27198
27740
  }
@@ -27315,7 +27857,7 @@ var TaskAuctioneer = class {
27315
27857
  const score = dispatchResult.confidence * (dispatchResult.role === agent.agentRole ? 1.2 : 1);
27316
27858
  if (score < this.minConfidence) return false;
27317
27859
  const bid = {
27318
- id: randomUUID18(),
27860
+ id: randomUUID19(),
27319
27861
  taskId,
27320
27862
  agentId: agent.agentId,
27321
27863
  agentName: agent.agentName,
@@ -28252,7 +28794,7 @@ var AutonomousCoordinator = class _AutonomousCoordinator {
28252
28794
  break;
28253
28795
  }
28254
28796
  const decision = await this.brain.decideAuto({
28255
- id: randomUUID19(),
28797
+ id: randomUUID20(),
28256
28798
  source: "system",
28257
28799
  decisionType: "prioritize_goals",
28258
28800
  question: `What should we work on next? Open goals: ${dispatchable.map((g) => g.title).join(", ")}`,
@@ -28483,17 +29025,17 @@ ${input.detail}`
28483
29025
  _waitForDagProgress(timeoutMs) {
28484
29026
  const before = this._dagProgressKey();
28485
29027
  if (this.dag.isDone()) return Promise.resolve();
28486
- return new Promise((resolve14) => {
29028
+ return new Promise((resolve16) => {
28487
29029
  let off;
28488
29030
  const timer = setTimeout(() => {
28489
29031
  off?.();
28490
- resolve14();
29032
+ resolve16();
28491
29033
  }, timeoutMs);
28492
29034
  off = this.dag.onEvent(() => {
28493
29035
  if (this._dagProgressKey() === before) return;
28494
29036
  clearTimeout(timer);
28495
29037
  off?.();
28496
- resolve14();
29038
+ resolve16();
28497
29039
  });
28498
29040
  });
28499
29041
  }
@@ -28801,8 +29343,8 @@ var CollaborationBus = class _CollaborationBus {
28801
29343
  if (this.isPaused()) return false;
28802
29344
  this.pausedAtMs = Date.now();
28803
29345
  this.pausedBy = byParticipant;
28804
- this.pausePromise = new Promise((resolve14) => {
28805
- this.pauseResolve = resolve14;
29346
+ this.pausePromise = new Promise((resolve16) => {
29347
+ this.pauseResolve = resolve16;
28806
29348
  });
28807
29349
  return true;
28808
29350
  }
@@ -28838,8 +29380,8 @@ var CollaborationBus = class _CollaborationBus {
28838
29380
  return true;
28839
29381
  }
28840
29382
  let timer;
28841
- const timeoutPromise = new Promise((resolve14) => {
28842
- timer = setTimeout(() => resolve14("timeout"), timeoutMs);
29383
+ const timeoutPromise = new Promise((resolve16) => {
29384
+ timer = setTimeout(() => resolve16("timeout"), timeoutMs);
28843
29385
  });
28844
29386
  const resumedPromise = this.pausePromise.then(() => "resumed").catch(() => "resumed");
28845
29387
  const winner = await Promise.race([resumedPromise, timeoutPromise]);