@wrongstack/core 0.299.0 → 0.300.0

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 (50) hide show
  1. package/dist/coordination/director.d.ts +8 -0
  2. package/dist/coordination/fleet-manager.d.ts +48 -3
  3. package/dist/coordination/ifleet-manager.d.ts +2 -0
  4. package/dist/coordination/index.js +120 -20
  5. package/dist/coordination/multi-agent-coordinator.d.ts +1 -0
  6. package/dist/core/fallback-model.d.ts +48 -0
  7. package/dist/core/index.d.ts +3 -2
  8. package/dist/core/index.js +226 -26
  9. package/dist/core/instruction-template.d.ts +80 -0
  10. package/dist/core/system-prompt-blocks.d.ts +10 -1
  11. package/dist/core/system-prompt-builder.d.ts +35 -1
  12. package/dist/defaults/index.js +238 -99
  13. package/dist/execution/autonomy-brain.d.ts +7 -0
  14. package/dist/execution/council-brain.d.ts +11 -0
  15. package/dist/execution/council-orchestrator.d.ts +23 -4
  16. package/dist/execution/council-prompts.d.ts +12 -1
  17. package/dist/execution/index.js +355 -138
  18. package/dist/fleet-notifier.d.ts +9 -2
  19. package/dist/hooks/index.js +8 -4
  20. package/dist/hq/index.js +18 -4
  21. package/dist/hq/protocol/fleet.d.ts +20 -0
  22. package/dist/hq/protocol.js +10 -0
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.js +1512 -707
  25. package/dist/kernel/events/brain-events.d.ts +9 -0
  26. package/dist/kernel/events/provider-events.d.ts +42 -1
  27. package/dist/models/index.js +1 -1
  28. package/dist/plugin/api.d.ts +6 -0
  29. package/dist/plugin/config.d.ts +55 -0
  30. package/dist/plugin/index.d.ts +1 -1
  31. package/dist/plugin/index.js +134 -21
  32. package/dist/security/index.d.ts +1 -1
  33. package/dist/security/index.js +157 -42
  34. package/dist/security/permission-helpers.d.ts +23 -6
  35. package/dist/security/permission-policy.d.ts +16 -0
  36. package/dist/security/totp.d.ts +14 -0
  37. package/dist/storage/director-state.d.ts +7 -0
  38. package/dist/storage/index.js +33 -8
  39. package/dist/tools/fallback-system-config-view-tool.d.ts +1 -1
  40. package/dist/tools/index.js +388 -102
  41. package/dist/types/council.d.ts +11 -0
  42. package/dist/types/index.d.ts +1 -1
  43. package/dist/types/multi-agent.d.ts +10 -0
  44. package/dist/types/one-shot-llm.d.ts +9 -0
  45. package/dist/types/plugin.d.ts +28 -0
  46. package/dist/worktree/index.js +4 -4
  47. package/instructions/system-lite.md +81 -3
  48. package/instructions/system-pro.md +275 -90
  49. package/instructions/system.md +228 -81
  50. package/package.json +3 -3
@@ -295,7 +295,7 @@ var InMemoryAgentBridge = class {
295
295
  });
296
296
  }
297
297
  this.inflightGuards.add(correlationId);
298
- return new Promise((resolve17, reject) => {
298
+ return new Promise((resolve19, reject) => {
299
299
  const timer = setTimeout(() => {
300
300
  this.inflightGuards.delete(correlationId);
301
301
  this.pendingRequests.delete(correlationId);
@@ -314,7 +314,7 @@ var InMemoryAgentBridge = class {
314
314
  return;
315
315
  }
316
316
  this.pendingRequests.set(correlationId, {
317
- resolve: resolve17,
317
+ resolve: resolve19,
318
318
  reject,
319
319
  timer
320
320
  });
@@ -663,13 +663,13 @@ var SubagentBudget = class _SubagentBudget {
663
663
  if (!bus?.hasListenerFor("budget.threshold_reached")) {
664
664
  return Promise.resolve("stop");
665
665
  }
666
- return new Promise((resolve17) => {
666
+ return new Promise((resolve19) => {
667
667
  let resolved = false;
668
668
  const respond = (d) => {
669
669
  if (resolved) return;
670
670
  resolved = true;
671
671
  clearTimeout(fallback);
672
- resolve17(d);
672
+ resolve19(d);
673
673
  };
674
674
  const fallback = setTimeout(() => respond("stop"), _SubagentBudget.DECISION_TIMEOUT_MS);
675
675
  const sessionId = this.currentSessionId();
@@ -5306,7 +5306,7 @@ function createDelegateTool(opts) {
5306
5306
  };
5307
5307
  }
5308
5308
  async function awaitDelegateAttempt(director, subagentId, taskId, timeoutMs, abortSignal) {
5309
- return new Promise((resolve17) => {
5309
+ return new Promise((resolve19) => {
5310
5310
  let settled = false;
5311
5311
  let timer;
5312
5312
  let offAbort = () => {
@@ -5319,7 +5319,7 @@ async function awaitDelegateAttempt(director, subagentId, taskId, timeoutMs, abo
5319
5319
  offIter();
5320
5320
  offProgress();
5321
5321
  offAbort();
5322
- resolve17(value);
5322
+ resolve19(value);
5323
5323
  };
5324
5324
  const arm = () => {
5325
5325
  if (timer) clearTimeout(timer);
@@ -5661,6 +5661,21 @@ var DirectorStateCheckpoint = class {
5661
5661
  resume(snapshot) {
5662
5662
  this.snapshot = snapshot;
5663
5663
  }
5664
+ /**
5665
+ * After resume, pin the live spawn ceiling from the current profile/flag
5666
+ * while preserving `spawnCount` (cumulative used budget). Checkpoint
5667
+ * metadata previously stored a historical `maxSpawns` that can diverge
5668
+ * from the live runtime ceiling — operators need the live value to win.
5669
+ */
5670
+ applyLiveMaxSpawns(maxSpawns) {
5671
+ if (this.snapshot.maxSpawns === maxSpawns) return;
5672
+ this.snapshot = {
5673
+ ...this.snapshot,
5674
+ maxSpawns
5675
+ };
5676
+ this.bumpUpdatedAt();
5677
+ this.schedule();
5678
+ }
5664
5679
  current() {
5665
5680
  return this.snapshot;
5666
5681
  }
@@ -7173,10 +7188,10 @@ var DirectorTaskRegistry = class _DirectorTaskRegistry {
7173
7188
  pending: taskIds.filter((id) => !done.has(id))
7174
7189
  });
7175
7190
  }
7176
- return new Promise((resolve17) => {
7191
+ return new Promise((resolve19) => {
7177
7192
  const entry = {
7178
7193
  ids: new Set(taskIds),
7179
- resolve: (result) => resolve17({
7194
+ resolve: (result) => resolve19({
7180
7195
  completed: [result],
7181
7196
  pending: taskIds.filter((id) => id !== result.taskId)
7182
7197
  })
@@ -7184,7 +7199,7 @@ var DirectorTaskRegistry = class _DirectorTaskRegistry {
7184
7199
  if (opts?.timeoutMs !== void 0) {
7185
7200
  entry.timer = setTimeout(() => {
7186
7201
  this.anyWaiters.delete(entry);
7187
- resolve17({ completed: [], pending: [...taskIds], timedOut: true });
7202
+ resolve19({ completed: [], pending: [...taskIds], timedOut: true });
7188
7203
  }, opts.timeoutMs);
7189
7204
  }
7190
7205
  this.anyWaiters.add(entry);
@@ -7302,11 +7317,11 @@ ${JSON.stringify(result.result, null, 2)}
7302
7317
  this.makeStoppedResult(taskId, "director", `Unknown task id "${taskId}" \u2014 never assigned`)
7303
7318
  );
7304
7319
  }
7305
- let resolve17;
7320
+ let resolve19;
7306
7321
  const promise = new Promise((done) => {
7307
- resolve17 = done;
7322
+ resolve19 = done;
7308
7323
  });
7309
- this.taskWaiters.set(taskId, { promise, resolve: resolve17 });
7324
+ this.taskWaiters.set(taskId, { promise, resolve: resolve19 });
7310
7325
  return promise;
7311
7326
  }
7312
7327
  recordAssignment(task) {
@@ -11060,7 +11075,7 @@ async function spawn(host, config, priceLookup) {
11060
11075
  if (host.spawnDepth >= maxSpawnDepth) {
11061
11076
  throw new FleetSpawnBudgetError("max_spawn_depth", maxSpawnDepth, host.spawnDepth);
11062
11077
  }
11063
- if (host.spawnCount >= host.maxSpawns) {
11078
+ if (host.spawnCount >= host.maxSpawns && !config.spawnBudgetExempt) {
11064
11079
  throw new FleetSpawnBudgetError("max_spawns", host.maxSpawns, host.spawnCount + 1);
11065
11080
  }
11066
11081
  if (host.maxFleetCostUsd < Number.POSITIVE_INFINITY) {
@@ -11111,7 +11126,9 @@ async function spawn(host, config, priceLookup) {
11111
11126
  ...Number.isFinite(budget?.remainingSpawns ?? host.maxSpawns - host.spawnCount) ? {
11112
11127
  remainingSpawns: Math.max(
11113
11128
  0,
11114
- (budget?.remainingSpawns ?? host.maxSpawns - host.spawnCount) - 1
11129
+ // Exempt spawns don't consume leader budget, so the reported
11130
+ // headroom is not decremented for them.
11131
+ (budget?.remainingSpawns ?? host.maxSpawns - host.spawnCount) - (config.spawnBudgetExempt ? 0 : 1)
11115
11132
  )
11116
11133
  } : {},
11117
11134
  ...Number.isFinite(maxFleetTokens) ? { maxTokens: maxFleetTokens } : {},
@@ -11124,7 +11141,9 @@ async function spawn(host, config, priceLookup) {
11124
11141
  if (host.fleetManager) {
11125
11142
  host.fleetManager.recordSpawn(result.subagentId, config, priceLookup);
11126
11143
  } else {
11127
- host.spawnCount += 1;
11144
+ if (!config.spawnBudgetExempt) {
11145
+ host.spawnCount += 1;
11146
+ }
11128
11147
  host.subagentMeta.set(result.subagentId, {
11129
11148
  provider: config.provider,
11130
11149
  model: config.model
@@ -11476,12 +11495,12 @@ async function executeSubagentWithTimeout({
11476
11495
  }
11477
11496
  return new Promise((resolveDecision) => {
11478
11497
  let settled = false;
11479
- const resolve17 = (d) => {
11498
+ const resolve19 = (d) => {
11480
11499
  if (settled) return;
11481
11500
  settled = true;
11482
11501
  resolveDecision(d);
11483
11502
  };
11484
- const fallback = setTimeout(() => resolve17("stop"), DECISION_TIMEOUT_MS);
11503
+ const fallback = setTimeout(() => resolve19("stop"), DECISION_TIMEOUT_MS);
11485
11504
  const sessionId = currentSessionId();
11486
11505
  budget._events?.emit("budget.threshold_reached", {
11487
11506
  ...sessionId ? { sessionId } : {},
@@ -11491,11 +11510,11 @@ async function executeSubagentWithTimeout({
11491
11510
  timeoutMs: DECISION_TIMEOUT_MS,
11492
11511
  extend: (extra) => {
11493
11512
  clearTimeout(fallback);
11494
- queueMicrotask(() => resolve17({ extend: extra }));
11513
+ queueMicrotask(() => resolve19({ extend: extra }));
11495
11514
  },
11496
11515
  deny: () => {
11497
11516
  clearTimeout(fallback);
11498
- resolve17("stop");
11517
+ resolve19("stop");
11499
11518
  }
11500
11519
  });
11501
11520
  });
@@ -11882,7 +11901,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
11882
11901
  taskIds.map((id) => {
11883
11902
  const cached = this.completedResults.find((r) => r.taskId === id);
11884
11903
  if (cached) return cached;
11885
- return new Promise((resolve17, reject) => {
11904
+ return new Promise((resolve19, reject) => {
11886
11905
  const timeout = setTimeout(() => {
11887
11906
  this.off("task.completed", handler);
11888
11907
  reject(new Error(`awaitTasks timed out waiting for task "${id}"`));
@@ -11891,7 +11910,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
11891
11910
  if (result.taskId === id) {
11892
11911
  clearTimeout(timeout);
11893
11912
  this.off("task.completed", handler);
11894
- resolve17(result);
11913
+ resolve19(result);
11895
11914
  }
11896
11915
  };
11897
11916
  this.on("task.completed", handler);
@@ -11916,13 +11935,13 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
11916
11935
  const done = new Set(completed.map((r) => r.taskId));
11917
11936
  return { completed, pending: taskIds.filter((id) => !done.has(id)) };
11918
11937
  }
11919
- return new Promise((resolve17) => {
11938
+ return new Promise((resolve19) => {
11920
11939
  let timer;
11921
11940
  const handler = ({ result }) => {
11922
11941
  if (!ids.has(result.taskId)) return;
11923
11942
  if (timer) clearTimeout(timer);
11924
11943
  this.off("task.completed", handler);
11925
- resolve17({
11944
+ resolve19({
11926
11945
  completed: [result],
11927
11946
  pending: taskIds.filter((id) => id !== result.taskId)
11928
11947
  });
@@ -11930,7 +11949,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
11930
11949
  if (opts?.timeoutMs !== void 0) {
11931
11950
  timer = setTimeout(() => {
11932
11951
  this.off("task.completed", handler);
11933
- resolve17({ completed: [], pending: [...taskIds], timedOut: true });
11952
+ resolve19({ completed: [], pending: [...taskIds], timedOut: true });
11934
11953
  }, opts.timeoutMs);
11935
11954
  }
11936
11955
  this.on("task.completed", handler);
@@ -12049,8 +12068,17 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
12049
12068
  durationMs: 0
12050
12069
  };
12051
12070
  this.completedResults.push(synthetic);
12071
+ this.trimCompletedResults();
12052
12072
  this.emit("task.completed", { task, result: synthetic });
12053
12073
  }
12074
+ trimCompletedResults() {
12075
+ if (this.completedResults.length > _DefaultMultiAgentCoordinator.MAX_COMPLETED_RESULTS) {
12076
+ this.completedResults.splice(
12077
+ 0,
12078
+ this.completedResults.length - _DefaultMultiAgentCoordinator.MAX_COMPLETED_RESULTS
12079
+ );
12080
+ }
12081
+ }
12054
12082
  async runDispatched(subagentId, task) {
12055
12083
  const subagent = this.subagents.get(subagentId);
12056
12084
  if (!subagent) return;
@@ -12184,12 +12212,7 @@ var DefaultMultiAgentCoordinator = class _DefaultMultiAgentCoordinator extends E
12184
12212
  }
12185
12213
  recordCompletion(result) {
12186
12214
  this.completedResults.push(result);
12187
- if (this.completedResults.length > _DefaultMultiAgentCoordinator.MAX_COMPLETED_RESULTS) {
12188
- this.completedResults.splice(
12189
- 0,
12190
- this.completedResults.length - _DefaultMultiAgentCoordinator.MAX_COMPLETED_RESULTS
12191
- );
12192
- }
12215
+ this.trimCompletedResults();
12193
12216
  this.totalIterations += result.iterations;
12194
12217
  if (this.inFlight > 0) {
12195
12218
  this.inFlight--;
@@ -13607,10 +13630,10 @@ function validateAgainstSchema(value, schema) {
13607
13630
  return { ok: errors.length === 0, errors };
13608
13631
  }
13609
13632
  var MAX_SCHEMA_DEPTH = 64;
13610
- function walk(value, schema, path40, errors, depth) {
13633
+ function walk(value, schema, path42, errors, depth) {
13611
13634
  if (depth > MAX_SCHEMA_DEPTH) {
13612
13635
  errors.push({
13613
- path: path40 || "<root>",
13636
+ path: path42 || "<root>",
13614
13637
  message: `schema nesting exceeds maximum depth (${MAX_SCHEMA_DEPTH})`
13615
13638
  });
13616
13639
  return;
@@ -13618,7 +13641,7 @@ function walk(value, schema, path40, errors, depth) {
13618
13641
  if (schema.enum !== void 0) {
13619
13642
  if (!enumIncludes(schema.enum, value)) {
13620
13643
  errors.push({
13621
- path: path40 || "<root>",
13644
+ path: path42 || "<root>",
13622
13645
  message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
13623
13646
  });
13624
13647
  return;
@@ -13627,7 +13650,7 @@ function walk(value, schema, path40, errors, depth) {
13627
13650
  if (typeof schema.type === "string") {
13628
13651
  if (!checkType(value, schema.type)) {
13629
13652
  errors.push({
13630
- path: path40 || "<root>",
13653
+ path: path42 || "<root>",
13631
13654
  message: `expected ${schema.type}, got ${describeType(value)} (${previewValue(value)})`
13632
13655
  });
13633
13656
  return;
@@ -13639,7 +13662,7 @@ function walk(value, schema, path40, errors, depth) {
13639
13662
  if (!(req in obj)) {
13640
13663
  const expected = schema.properties?.[req]?.type;
13641
13664
  errors.push({
13642
- path: joinPath(path40, req),
13665
+ path: joinPath(path42, req),
13643
13666
  message: `required property missing${typeof expected === "string" ? ` (expected ${expected})` : ""}`
13644
13667
  });
13645
13668
  }
@@ -13647,14 +13670,14 @@ function walk(value, schema, path40, errors, depth) {
13647
13670
  if (schema.properties) {
13648
13671
  for (const [key, subSchema] of Object.entries(schema.properties)) {
13649
13672
  if (key in obj) {
13650
- walk(obj[key], subSchema, joinPath(path40, key), errors, depth + 1);
13673
+ walk(obj[key], subSchema, joinPath(path42, key), errors, depth + 1);
13651
13674
  }
13652
13675
  }
13653
13676
  }
13654
13677
  }
13655
13678
  if (schema.type === "array" && Array.isArray(value) && schema.items) {
13656
13679
  for (let i = 0; i < value.length; i++) {
13657
- walk(value[i], schema.items, `${path40}[${i}]`, errors, depth + 1);
13680
+ walk(value[i], schema.items, `${path42}[${i}]`, errors, depth + 1);
13658
13681
  }
13659
13682
  }
13660
13683
  }
@@ -13950,7 +13973,7 @@ function invalid(sessionId) {
13950
13973
 
13951
13974
  // src/utils/sleep.ts
13952
13975
  function sleep(ms) {
13953
- return new Promise((resolve17) => setTimeout(resolve17, ms));
13976
+ return new Promise((resolve19) => setTimeout(resolve19, ms));
13954
13977
  }
13955
13978
 
13956
13979
  // src/utils/slug.ts
@@ -16221,7 +16244,7 @@ var SessionCheckpointCas = class {
16221
16244
  }
16222
16245
  };
16223
16246
  function defaultRunGit(args, cwd) {
16224
- return new Promise((resolve17) => {
16247
+ return new Promise((resolve19) => {
16225
16248
  const stdoutChunks = [];
16226
16249
  const stderrChunks = [];
16227
16250
  let stdoutBytes = 0;
@@ -16264,8 +16287,8 @@ function defaultRunGit(args, cwd) {
16264
16287
  stdoutTruncated,
16265
16288
  stderrTruncated
16266
16289
  });
16267
- child.on("error", (err) => resolve17(result(1, err.message)));
16268
- child.on("close", (code) => resolve17(result(code ?? 1)));
16290
+ child.on("error", (err) => resolve19(result(1, err.message)));
16291
+ child.on("close", (code) => resolve19(result(code ?? 1)));
16269
16292
  });
16270
16293
  }
16271
16294
 
@@ -18905,6 +18928,7 @@ var Director = class _Director {
18905
18928
  }
18906
18929
  setCheckpointState(snapshot) {
18907
18930
  setCheckpointState(this.checkpointHost(), snapshot);
18931
+ this.applyResumeBudget(snapshot);
18908
18932
  }
18909
18933
  async readSession(subagentId, tail) {
18910
18934
  return readDirectorSubagentSession({
@@ -18956,6 +18980,22 @@ var Director = class _Director {
18956
18980
  }
18957
18981
  resumeFromCheckpoint(snapshot) {
18958
18982
  resumeFromCheckpoint(this.checkpointHost(), snapshot);
18983
+ this.applyResumeBudget(snapshot);
18984
+ }
18985
+ /**
18986
+ * After re-attaching checkpoint metadata, pin the live maxSpawns ceiling
18987
+ * (profile/flag/env wins over historical checkpoint metadata). The
18988
+ * historical cumulative spawn counter is deliberately NOT restored — the
18989
+ * lifetime budget is scoped to this director run, so a restarted session
18990
+ * resumes with a fresh budget rather than a possibly-exhausted counter.
18991
+ */
18992
+ applyResumeBudget(snapshot) {
18993
+ if (this.fleetManager) {
18994
+ this.fleetManager.restoreFromCheckpoint(snapshot);
18995
+ }
18996
+ this.stateCheckpoint?.applyLiveMaxSpawns(
18997
+ Number.isFinite(this.maxSpawns) ? this.maxSpawns : void 0
18998
+ );
18959
18999
  }
18960
19000
  };
18961
19001
 
@@ -21623,12 +21663,12 @@ function verifyFiles(tokens, files) {
21623
21663
  const violations = [];
21624
21664
  let onPalette = 0;
21625
21665
  let offPalette = 0;
21626
- for (const { path: path40, text } of files) {
21666
+ for (const { path: path42, text } of files) {
21627
21667
  const lines = text.split("\n");
21628
21668
  lines.forEach((lineText, i) => {
21629
21669
  const lineNo = i + 1;
21630
21670
  const flag = (snippet, reason, axis = "color") => {
21631
- violations.push({ file: path40, line: lineNo, snippet: snippet.slice(0, 80), reason, axis });
21671
+ violations.push({ file: path42, line: lineNo, snippet: snippet.slice(0, 80), reason, axis });
21632
21672
  };
21633
21673
  for (const re of [HEX_RE, FUNC_COLOR_RE]) {
21634
21674
  re.lastIndex = 0;
@@ -22311,9 +22351,9 @@ function buildRecoveryStrategies(opts) {
22311
22351
  const delayMs = err.body?.retryAfterMs ?? 5e3;
22312
22352
  const delay = Math.min(6e4, Math.max(1e3, delayMs));
22313
22353
  if (ctx?.signal) {
22314
- await new Promise((resolve17) => {
22354
+ await new Promise((resolve19) => {
22315
22355
  if (ctx.signal.aborted) {
22316
- resolve17();
22356
+ resolve19();
22317
22357
  return;
22318
22358
  }
22319
22359
  let settled = false;
@@ -22324,7 +22364,7 @@ function buildRecoveryStrategies(opts) {
22324
22364
  settled = true;
22325
22365
  if (timer !== void 0) clearTimeout(timer);
22326
22366
  ctx.signal.removeEventListener("abort", onAbort);
22327
- resolve17();
22367
+ resolve19();
22328
22368
  };
22329
22369
  timer = setTimeout(finish, delay);
22330
22370
  ctx.signal.addEventListener("abort", onAbort, { once: true });
@@ -24517,8 +24557,8 @@ async function streamProviderToResponse(provider, req, signal, ctx, events, logg
24517
24557
  });
24518
24558
  await Promise.race([
24519
24559
  drainPromise,
24520
- new Promise((resolve17) => {
24521
- drainTimer = setTimeout(resolve17, STREAM_DRAIN_TIMEOUT_MS);
24560
+ new Promise((resolve19) => {
24561
+ drainTimer = setTimeout(resolve19, STREAM_DRAIN_TIMEOUT_MS);
24522
24562
  })
24523
24563
  ]);
24524
24564
  } finally {
@@ -24869,7 +24909,7 @@ async function runProviderWithRetry(opts) {
24869
24909
  description,
24870
24910
  ...providerErrorBody ? { errorBody: providerErrorBody } : {}
24871
24911
  });
24872
- await new Promise((resolve17, reject) => {
24912
+ await new Promise((resolve19, reject) => {
24873
24913
  let settled = false;
24874
24914
  const cleanup = () => {
24875
24915
  clearTimeout(t);
@@ -24885,7 +24925,7 @@ async function runProviderWithRetry(opts) {
24885
24925
  if (settled) return;
24886
24926
  settled = true;
24887
24927
  cleanup();
24888
- resolve17();
24928
+ resolve19();
24889
24929
  }, delay);
24890
24930
  if (signal.aborted) {
24891
24931
  onAbort();
@@ -27147,18 +27187,18 @@ ${errorDetails}`,
27147
27187
  if (this.opts.confirmAwaiter) {
27148
27188
  const awaiter = this.opts.confirmAwaiter;
27149
27189
  const choice = await new Promise(
27150
- (resolve17, reject) => {
27190
+ (resolve19, reject) => {
27151
27191
  const signal = ctx.signal;
27152
- const onAbort = () => resolve17("abort");
27192
+ const onAbort = () => resolve19("abort");
27153
27193
  if (signal.aborted) {
27154
- resolve17("abort");
27194
+ resolve19("abort");
27155
27195
  return;
27156
27196
  }
27157
27197
  signal.addEventListener("abort", onAbort, { once: true });
27158
27198
  awaiter(tool, use.input, use.id, suggestedPattern).then(
27159
27199
  (c) => {
27160
27200
  signal.removeEventListener("abort", onAbort);
27161
- resolve17(c);
27201
+ resolve19(c);
27162
27202
  },
27163
27203
  (e) => {
27164
27204
  signal.removeEventListener("abort", onAbort);
@@ -27496,7 +27536,7 @@ ${post.additionalContext}`;
27496
27536
  toolPromise.catch(() => {
27497
27537
  });
27498
27538
  try {
27499
- output = await new Promise((resolve17, reject) => {
27539
+ output = await new Promise((resolve19, reject) => {
27500
27540
  const onAbort = () => {
27501
27541
  setTimeout(() => reject(abortReasonToError(combined.reason)), 0);
27502
27542
  };
@@ -27504,7 +27544,7 @@ ${post.additionalContext}`;
27504
27544
  toolPromise.then(
27505
27545
  (v) => {
27506
27546
  combined.removeEventListener("abort", onAbort);
27507
- resolve17(v);
27547
+ resolve19(v);
27508
27548
  },
27509
27549
  (e) => {
27510
27550
  combined.removeEventListener("abort", onAbort);
@@ -28452,7 +28492,7 @@ var DefaultModelsRegistry = class {
28452
28492
  async load(opts = {}) {
28453
28493
  if (this.payload && !opts.force) return this.payload;
28454
28494
  if (this.seed) {
28455
- this.payload = this.seed;
28495
+ this.payload = this.withExtraOverlay(this.seed);
28456
28496
  this.fetchedAt = /* @__PURE__ */ new Date();
28457
28497
  return this.payload;
28458
28498
  }
@@ -29072,9 +29112,9 @@ var DefaultHealthRegistry = class {
29072
29112
  }
29073
29113
  async runOne(check) {
29074
29114
  let timer = null;
29075
- const timeout = new Promise((resolve17) => {
29115
+ const timeout = new Promise((resolve19) => {
29076
29116
  timer = setTimeout(
29077
- () => resolve17({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
29117
+ () => resolve19({ status: "unhealthy", detail: `timeout after ${this.timeoutMs}ms` }),
29078
29118
  this.timeoutMs
29079
29119
  );
29080
29120
  });
@@ -29272,7 +29312,7 @@ async function startMetricsServer(opts) {
29272
29312
  const tls = opts.tls;
29273
29313
  const useHttps = !!(tls?.cert && tls?.key);
29274
29314
  const host = opts.host ?? "127.0.0.1";
29275
- const path40 = opts.path ?? "/metrics";
29315
+ const path42 = opts.path ?? "/metrics";
29276
29316
  const healthPath = opts.healthPath ?? "/healthz";
29277
29317
  const healthRegistry = opts.healthRegistry;
29278
29318
  const token = opts.token;
@@ -29295,7 +29335,7 @@ async function startMetricsServer(opts) {
29295
29335
  return;
29296
29336
  }
29297
29337
  const url = req.url.split("?")[0];
29298
- if (url === path40) {
29338
+ if (url === path42) {
29299
29339
  let body;
29300
29340
  try {
29301
29341
  body = renderPrometheus(opts.sink.snapshot());
@@ -29341,14 +29381,14 @@ async function startMetricsServer(opts) {
29341
29381
  const { createServer } = await import("node:http");
29342
29382
  server = createServer(listener);
29343
29383
  }
29344
- await new Promise((resolve17, reject) => {
29384
+ await new Promise((resolve19, reject) => {
29345
29385
  const onError = (err) => {
29346
29386
  server.off("listening", onListening);
29347
29387
  reject(err);
29348
29388
  };
29349
29389
  const onListening = () => {
29350
29390
  server.off("error", onError);
29351
- resolve17();
29391
+ resolve19();
29352
29392
  };
29353
29393
  server.once("error", onError);
29354
29394
  server.once("listening", onListening);
@@ -29359,9 +29399,9 @@ async function startMetricsServer(opts) {
29359
29399
  const protocol = useHttps ? "https" : "http";
29360
29400
  return {
29361
29401
  port: boundPort,
29362
- url: `${protocol}://${host}:${boundPort}${path40}`,
29363
- close: () => new Promise((resolve17, reject) => {
29364
- server.close((err) => err ? reject(err) : resolve17());
29402
+ url: `${protocol}://${host}:${boundPort}${path42}`,
29403
+ close: () => new Promise((resolve19, reject) => {
29404
+ server.close((err) => err ? reject(err) : resolve19());
29365
29405
  })
29366
29406
  };
29367
29407
  }
@@ -29632,6 +29672,7 @@ function startOtlpTraceExporter(opts) {
29632
29672
 
29633
29673
  // src/security/permission-policy.ts
29634
29674
  import * as fs12 from "node:fs/promises";
29675
+ import * as path36 from "node:path";
29635
29676
 
29636
29677
  // src/security/permission-policy-schema.ts
29637
29678
  var TRUST_POLICY_LIMITS = Object.freeze({
@@ -29676,19 +29717,19 @@ var UNSAFE_PROPERTY_NAMES = /* @__PURE__ */ new Set(["__proto__", "prototype", "
29676
29717
  function isRecord5(value) {
29677
29718
  return typeof value === "object" && value !== null && !Array.isArray(value);
29678
29719
  }
29679
- function error(diagnostics, code, path40, message) {
29680
- diagnostics.push({ severity: "error", code, path: path40, message });
29720
+ function error(diagnostics, code, path42, message) {
29721
+ diagnostics.push({ severity: "error", code, path: path42, message });
29681
29722
  }
29682
- function validatePatterns(value, path40, diagnostics) {
29723
+ function validatePatterns(value, path42, diagnostics) {
29683
29724
  if (!Array.isArray(value)) {
29684
- error(diagnostics, "invalid_pattern_list", path40, "must be an array of strings");
29725
+ error(diagnostics, "invalid_pattern_list", path42, "must be an array of strings");
29685
29726
  return void 0;
29686
29727
  }
29687
29728
  if (value.length > TRUST_POLICY_LIMITS.maxPatternsPerRule) {
29688
29729
  error(
29689
29730
  diagnostics,
29690
29731
  "too_many_patterns",
29691
- path40,
29732
+ path42,
29692
29733
  `must contain at most ${TRUST_POLICY_LIMITS.maxPatternsPerRule} patterns`
29693
29734
  );
29694
29735
  return void 0;
@@ -29696,7 +29737,7 @@ function validatePatterns(value, path40, diagnostics) {
29696
29737
  const patterns = [];
29697
29738
  const seen = /* @__PURE__ */ new Set();
29698
29739
  for (const [index, pattern] of value.entries()) {
29699
- const itemPath = `${path40}[${index}]`;
29740
+ const itemPath = `${path42}[${index}]`;
29700
29741
  if (typeof pattern !== "string" || pattern.length === 0 || pattern.length > TRUST_POLICY_LIMITS.maxPatternChars) {
29701
29742
  error(
29702
29743
  diagnostics,
@@ -30111,6 +30152,8 @@ var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
30111
30152
  };
30112
30153
 
30113
30154
  // src/security/permission-helpers.ts
30155
+ import { realpathSync } from "node:fs";
30156
+ import * as path35 from "node:path";
30114
30157
  function matchesTrust(patterns, subject) {
30115
30158
  return patterns.includes(subject) || matchAny(patterns, subject);
30116
30159
  }
@@ -30181,9 +30224,51 @@ var SHELL_READ_VERBS = /* @__PURE__ */ new Set([
30181
30224
  function stripShellQuotes(value) {
30182
30225
  return value.replace(/^['"]|['"]$/g, "");
30183
30226
  }
30227
+ var AGENT_STATE_SENSITIVE_BASENAMES = /^(?:config\.json|config\.local\.json|trust\.json|auth\.json|\.key)$/i;
30228
+ function unescapeGlobSubject(value) {
30229
+ return value.replace(/\\([*?[\]])/g, "$1");
30230
+ }
30231
+ function normalizeForCompare(value) {
30232
+ const forward = unescapeGlobSubject(value).replace(/\\/g, "/").replace(/\/+$/, "");
30233
+ return process.platform === "win32" ? forward.toLowerCase() : forward;
30234
+ }
30235
+ function realpathOfNearestExisting(p) {
30236
+ let probe = p;
30237
+ const tail = [];
30238
+ for (; ; ) {
30239
+ try {
30240
+ return tail.length === 0 ? realpathSync(probe) : path35.join(realpathSync(probe), ...tail);
30241
+ } catch {
30242
+ const parent = path35.dirname(probe);
30243
+ if (parent === probe) return p;
30244
+ tail.unshift(path35.basename(probe));
30245
+ probe = parent;
30246
+ }
30247
+ }
30248
+ }
30249
+ var agentStateRootRealCache = /* @__PURE__ */ new Map();
30250
+ function isInsideAgentStateRoot(absPath) {
30251
+ const lexicalRoot = normalizeForCompare(path35.resolve(wstackGlobalRoot()));
30252
+ if (!lexicalRoot) return false;
30253
+ const target = normalizeForCompare(absPath);
30254
+ if (target === lexicalRoot || target.startsWith(`${lexicalRoot}/`)) return true;
30255
+ let realRoot = agentStateRootRealCache.get(lexicalRoot);
30256
+ if (realRoot === void 0) {
30257
+ realRoot = normalizeForCompare(realpathOfNearestExisting(path35.resolve(wstackGlobalRoot())));
30258
+ agentStateRootRealCache.set(lexicalRoot, realRoot);
30259
+ }
30260
+ if (!realRoot || realRoot === lexicalRoot) return false;
30261
+ const realTarget = normalizeForCompare(realpathOfNearestExisting(absPath));
30262
+ return realTarget === realRoot || realTarget.startsWith(`${realRoot}/`);
30263
+ }
30264
+ function isProtectedAgentStatePath(absPath) {
30265
+ if (!isInsideAgentStateRoot(absPath)) return false;
30266
+ return AGENT_STATE_SENSITIVE_BASENAMES.test(path35.basename(normalizeForCompare(absPath)));
30267
+ }
30184
30268
  function pathLooksSensitive(rawPath) {
30185
30269
  const normalized = stripShellQuotes(rawPath).replace(/\\/g, "/");
30186
- return SENSITIVE_READ_PATHS.some((pattern) => pattern.test(normalized));
30270
+ if (SENSITIVE_READ_PATHS.some((pattern) => pattern.test(normalized))) return true;
30271
+ return isProtectedAgentStatePath(normalized);
30187
30272
  }
30188
30273
  function inputPathLooksSensitive(input) {
30189
30274
  if (!input || typeof input !== "object") return false;
@@ -30207,6 +30292,34 @@ function shellCommandReadsSensitivePath(command) {
30207
30292
  }
30208
30293
 
30209
30294
  // src/security/permission-policy.ts
30295
+ function fsWriteTargetPaths(input) {
30296
+ const out = [];
30297
+ if (!input || typeof input !== "object") return out;
30298
+ const obj = input;
30299
+ for (const key of [
30300
+ "path",
30301
+ "file_path",
30302
+ "file",
30303
+ "filePath",
30304
+ "files",
30305
+ "target",
30306
+ "targetPath",
30307
+ "out",
30308
+ "directory",
30309
+ "cwd",
30310
+ "template"
30311
+ ]) {
30312
+ const value = obj[key];
30313
+ if (typeof value === "string") {
30314
+ if (value.length > 0) out.push(value);
30315
+ } else if (Array.isArray(value)) {
30316
+ for (const item of value) {
30317
+ if (typeof item === "string" && item.length > 0) out.push(item);
30318
+ }
30319
+ }
30320
+ }
30321
+ return out;
30322
+ }
30210
30323
  var DefaultPermissionPolicy = class {
30211
30324
  policy = {};
30212
30325
  loaded = false;
@@ -30292,6 +30405,30 @@ var DefaultPermissionPolicy = class {
30292
30405
  getYoloDestructive() {
30293
30406
  return this.yoloDestructive;
30294
30407
  }
30408
+ /**
30409
+ * True when this call is an FS_WRITE whose target lands inside WrongStack's
30410
+ * own state root.
30411
+ *
30412
+ * FS_WRITE tools disagree on where the target path lives: write/edit use
30413
+ * `path`, replace/format/git `files` (string OR array), patch `directory`,
30414
+ * design `out`, scaffold writes under `cwd`/`template`. Checking only
30415
+ * `path`/`file_path` let a state-root write merely switch tools, so every
30416
+ * path-bearing key is inspected.
30417
+ *
30418
+ * Shared by the YOLO carve-out and the eval-cache guard so the two cannot
30419
+ * drift: the carve-out scans all path keys while the cache key fingerprints
30420
+ * only the subject key, so the cache must consult the same predicate or a
30421
+ * secondary state-root key can be replayed a cached `auto`.
30422
+ */
30423
+ hasAgentStateWriteTarget(tool, input, ctx) {
30424
+ if (!hasCapability(tool, ToolCapabilities.FS_WRITE)) return false;
30425
+ for (const targetPath of fsWriteTargetPaths(input)) {
30426
+ const base = ctx.workingDir ?? ctx.cwd;
30427
+ const resolved = base ? path36.resolve(base, targetPath) : path36.resolve(targetPath);
30428
+ if (isInsideAgentStateRoot(resolved)) return true;
30429
+ }
30430
+ return false;
30431
+ }
30295
30432
  /**
30296
30433
  * True when YOLO is on but this specific call is a destructive shell command
30297
30434
  * the user has not opted to auto-approve. Shared by `evaluate()` and the
@@ -30299,6 +30436,7 @@ var DefaultPermissionPolicy = class {
30299
30436
  */
30300
30437
  yoloBlockedAsDestructive(tool, input, ctx) {
30301
30438
  if (!this.yolo || this.yoloDestructive) return false;
30439
+ if (this.hasAgentStateWriteTarget(tool, input, ctx)) return true;
30302
30440
  const isShellSurface = tool.name === "bash" || tool.name === "exec" || (tool.capabilities ?? []).includes("shell.arbitrary");
30303
30441
  if (!isShellSurface) return false;
30304
30442
  const command = getInputString(input, "command") ?? shellCommandLineFromInput(input);
@@ -30405,7 +30543,7 @@ var DefaultPermissionPolicy = class {
30405
30543
  const subject = subjectForToolInput(tool.name, input, tool.subjectKey);
30406
30544
  const cacheKey = `${tool.name}::${subject ?? tool.name}`;
30407
30545
  const evalKey = `${cacheKey}::${permissionFingerprint(tool)}`;
30408
- if (tool.name !== "write") {
30546
+ if (tool.name !== "write" && !this.hasAgentStateWriteTarget(tool, input, ctx)) {
30409
30547
  const cached = this._evalCache.get(evalKey);
30410
30548
  if (cached !== void 0) return cached;
30411
30549
  }
@@ -30513,7 +30651,7 @@ var DefaultPermissionPolicy = class {
30513
30651
  return decision;
30514
30652
  }
30515
30653
  if (tool.name === "write" && subject) {
30516
- if (ctx.hasRead(subject)) {
30654
+ if (ctx.hasRead(subject) && !isInsideAgentStateRoot(subject)) {
30517
30655
  return {
30518
30656
  permission: "auto",
30519
30657
  source: "context",
@@ -30863,13 +31001,14 @@ var DefaultPermissionPolicy = class {
30863
31001
  }
30864
31002
  add("yolo", false, "auto", "yolo", "YOLO mode is not active");
30865
31003
  if (tool.name === "write" && subject) {
30866
- const hasRead = ctx.hasRead(subject);
31004
+ const isAgentState = isInsideAgentStateRoot(subject);
31005
+ const hasRead = ctx.hasRead(subject) && !isAgentState;
30867
31006
  add(
30868
31007
  "write smart bypass",
30869
31008
  hasRead,
30870
31009
  "auto",
30871
31010
  "context",
30872
- hasRead ? `file "${subject}" was already read in this session \u2014 auto-approving write` : `file "${subject}" was not read in this session \u2014 bypass does not apply`
31011
+ isAgentState ? `file "${subject}" is WrongStack's own state \u2014 bypass never applies, write always confirms` : hasRead ? `file "${subject}" was already read in this session \u2014 auto-approving write` : `file "${subject}" was not read in this session \u2014 bypass does not apply`
30873
31012
  );
30874
31013
  if (hasRead) {
30875
31014
  winnerIndex = steps.length - 1;
@@ -30954,7 +31093,7 @@ var DefaultPermissionPolicy = class {
30954
31093
  import { createCipheriv, createDecipheriv, randomBytes as randomBytes3, scryptSync } from "node:crypto";
30955
31094
  import * as fs13 from "node:fs";
30956
31095
  import * as fsp22 from "node:fs/promises";
30957
- import * as path35 from "node:path";
31096
+ import * as path37 from "node:path";
30958
31097
 
30959
31098
  // src/types/secret-vault.ts
30960
31099
  var ENCRYPTED_PREFIX_PATTERN = /^enc:v(\d+):/;
@@ -31247,7 +31386,7 @@ var DefaultSecretVault = class {
31247
31386
  const oldVersion = this._keyVersion;
31248
31387
  const newKey = randomBytes3(KEY_BYTES);
31249
31388
  const newVersion = oldVersion + 1;
31250
- fs13.mkdirSync(path35.dirname(this.keyFile), { recursive: true });
31389
+ fs13.mkdirSync(path37.dirname(this.keyFile), { recursive: true });
31251
31390
  const passphrase = getVaultPassphrase();
31252
31391
  if (passphrase) {
31253
31392
  writeKeyFileAtomicSync(this.keyFile, wrapDataKey(newKey, newVersion, passphrase));
@@ -31334,7 +31473,7 @@ var DefaultSecretVault = class {
31334
31473
  } catch (err) {
31335
31474
  if (err.code !== "ENOENT") throw err;
31336
31475
  }
31337
- fs13.mkdirSync(path35.dirname(this.keyFile), { recursive: true });
31476
+ fs13.mkdirSync(path37.dirname(this.keyFile), { recursive: true });
31338
31477
  const key = randomBytes3(KEY_BYTES);
31339
31478
  const passphrase = getVaultPassphrase();
31340
31479
  const initialBytes = passphrase ? wrapDataKey(key, 1, passphrase) : key;
@@ -31394,7 +31533,7 @@ async function rewriteConfigEncrypted(configPath, vault, patch) {
31394
31533
  }
31395
31534
  const merged = deepMerge(current, patch ?? {});
31396
31535
  const encrypted = encryptConfigSecrets(merged, vault);
31397
- await fsp22.mkdir(path35.dirname(configPath), { recursive: true });
31536
+ await fsp22.mkdir(path37.dirname(configPath), { recursive: true });
31398
31537
  await atomicWrite(configPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
31399
31538
  await restrictFilePermissions2(configPath);
31400
31539
  await vault.flushHardening?.();
@@ -31449,7 +31588,7 @@ function walkCount(node, vault, counter) {
31449
31588
  // src/storage/attachment-store.ts
31450
31589
  import { randomBytes as randomBytes4 } from "node:crypto";
31451
31590
  import * as fsp23 from "node:fs/promises";
31452
- import * as path36 from "node:path";
31591
+ import * as path38 from "node:path";
31453
31592
  var DEFAULT_SPOOL_THRESHOLD = 256 * 1024;
31454
31593
  var PLACEHOLDER_RE = /\[(pasted|image|file) #(\d+)[^\]]*\]|\[file:([^\]]+)\]/g;
31455
31594
  var DefaultAttachmentStore = class {
@@ -31470,7 +31609,7 @@ var DefaultAttachmentStore = class {
31470
31609
  let data = input.data;
31471
31610
  if (this.spoolDir && bytes >= this.spoolThreshold) {
31472
31611
  await fsp23.mkdir(this.spoolDir, { recursive: true });
31473
- spooledPath = path36.join(this.spoolDir, `${id}.bin`);
31612
+ spooledPath = path38.join(this.spoolDir, `${id}.bin`);
31474
31613
  await atomicWrite(spooledPath, input.data, {
31475
31614
  encoding: input.kind === "image" ? "base64" : "utf8"
31476
31615
  });
@@ -32003,8 +32142,8 @@ var IN_PROJECT_DENIED_PATHS = [
32003
32142
  reason: "The other half of the filesystem confinement switch."
32004
32143
  }
32005
32144
  ];
32006
- function deleteNestedPath(target, path40) {
32007
- const segments = path40.split(".");
32145
+ function deleteNestedPath(target, path42) {
32146
+ const segments = path42.split(".");
32008
32147
  const last = segments[segments.length - 1];
32009
32148
  if (last === void 0) return false;
32010
32149
  let cursor = target;
@@ -32061,16 +32200,16 @@ function assertInProjectAllowListComplete() {
32061
32200
  );
32062
32201
  }
32063
32202
  const orphanedPaths = IN_PROJECT_DENIED_PATHS.filter(
32064
- ({ path: path40 }) => !IN_PROJECT_ALLOWED_KEYS.has(path40.split(".")[0] ?? "")
32065
- ).map(({ path: path40 }) => path40);
32203
+ ({ path: path42 }) => !IN_PROJECT_ALLOWED_KEYS.has(path42.split(".")[0] ?? "")
32204
+ ).map(({ path: path42 }) => path42);
32066
32205
  if (orphanedPaths.length > 0) {
32067
32206
  problems.push(
32068
32207
  `IN_PROJECT_DENIED_PATHS entr(ies) whose top-level parent is not allowed: ` + orphanedPaths.join(", ") + ". The parent is already stripped wholesale, so the nested denial is dead \u2014 remove it."
32069
32208
  );
32070
32209
  }
32071
32210
  const malformedPaths = IN_PROJECT_DENIED_PATHS.filter(
32072
- ({ path: path40 }) => path40.split(".").length < 2 || path40.split(".").some((s) => s.length === 0)
32073
- ).map(({ path: path40 }) => path40);
32211
+ ({ path: path42 }) => path42.split(".").length < 2 || path42.split(".").some((s) => s.length === 0)
32212
+ ).map(({ path: path42 }) => path42);
32074
32213
  if (malformedPaths.length > 0) {
32075
32214
  problems.push(
32076
32215
  `IN_PROJECT_DENIED_PATHS entr(ies) are not dotted nested paths: ` + malformedPaths.join(", ") + ". Top-level keys belong in KNOWN_DENIED_IN_PROJECT instead."
@@ -32098,8 +32237,8 @@ function stripUnsafeInProjectFields(inProject, sourcePath, warn = (msg) => conso
32098
32237
  }
32099
32238
  stripped.push(k);
32100
32239
  }
32101
- for (const { path: path40 } of IN_PROJECT_DENIED_PATHS) {
32102
- if (deleteNestedPath(out, path40)) stripped.push(path40);
32240
+ for (const { path: path42 } of IN_PROJECT_DENIED_PATHS) {
32241
+ if (deleteNestedPath(out, path42)) stripped.push(path42);
32103
32242
  }
32104
32243
  if (stripped.length > 0) {
32105
32244
  warn(
@@ -32288,10 +32427,10 @@ function removeLegacySageEngine(config) {
32288
32427
  }
32289
32428
 
32290
32429
  // src/storage/config-loader/path-identity.ts
32291
- import * as path37 from "node:path";
32430
+ import * as path39 from "node:path";
32292
32431
  function samePath(a, b) {
32293
- let ra = path37.resolve(a);
32294
- let rb = path37.resolve(b);
32432
+ let ra = path39.resolve(a);
32433
+ let rb = path39.resolve(b);
32295
32434
  if (process.platform === "win32" || process.platform === "darwin") {
32296
32435
  ra = ra.toLowerCase();
32297
32436
  rb = rb.toLowerCase();
@@ -33272,7 +33411,7 @@ ${cat}:`);
33272
33411
 
33273
33412
  // src/storage/queue-store.ts
33274
33413
  import * as fsp25 from "node:fs/promises";
33275
- import * as path38 from "node:path";
33414
+ import * as path40 from "node:path";
33276
33415
  var QUEUE_MAX_ITEMS = 100;
33277
33416
  var QUEUE_MAX_BYTES = 16 * 1024 * 1024;
33278
33417
  var QUEUE_MAX_ITEM_BYTES = 8 * 1024 * 1024;
@@ -33305,7 +33444,7 @@ var QueueStore = class {
33305
33444
  traceId;
33306
33445
  logger;
33307
33446
  constructor(opts) {
33308
- this.file = path38.join(opts.dir, "queue.json");
33447
+ this.file = path40.join(opts.dir, "queue.json");
33309
33448
  this.events = opts.events;
33310
33449
  this.traceId = opts.traceId;
33311
33450
  this.logger = opts.logger;
@@ -33521,7 +33660,7 @@ function isPersistedQueueItem(v) {
33521
33660
  // src/storage/recovery-lock.ts
33522
33661
  import * as fsp26 from "node:fs/promises";
33523
33662
  import * as os2 from "node:os";
33524
- import * as path39 from "node:path";
33663
+ import * as path41 from "node:path";
33525
33664
  var LOCK_FILE = "active.json";
33526
33665
  var DEFAULT_MAX_AGE_MS = 24 * 60 * 60 * 1e3;
33527
33666
  var RecoveryLock = class {
@@ -33532,7 +33671,7 @@ var RecoveryLock = class {
33532
33671
  sessionStore;
33533
33672
  probe;
33534
33673
  constructor(opts) {
33535
- this.file = path39.join(opts.dir, LOCK_FILE);
33674
+ this.file = path41.join(opts.dir, LOCK_FILE);
33536
33675
  this.pid = opts.pid ?? process.pid;
33537
33676
  this.hostname = opts.hostname ?? os2.hostname();
33538
33677
  this.maxAgeMs = opts.maxAgeMs ?? DEFAULT_MAX_AGE_MS;
@@ -33606,7 +33745,7 @@ var RecoveryLock = class {
33606
33745
  * null return before calling this.
33607
33746
  */
33608
33747
  async write(sessionId) {
33609
- await ensureDir(path39.dirname(this.file));
33748
+ await ensureDir(path41.dirname(this.file));
33610
33749
  const lock = {
33611
33750
  v: 1,
33612
33751
  sessionId,