@wrongstack/core 0.285.0 → 0.286.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 (145) hide show
  1. package/dist/autophase/phase-orchestrator.d.ts.map +1 -1
  2. package/dist/boot.d.ts.map +1 -1
  3. package/dist/coordination/agent-monitor.d.ts +29 -0
  4. package/dist/coordination/agent-monitor.d.ts.map +1 -1
  5. package/dist/coordination/autonomous-brain.d.ts +0 -2
  6. package/dist/coordination/autonomous-brain.d.ts.map +1 -1
  7. package/dist/coordination/autonomous-coordinator.d.ts +4 -0
  8. package/dist/coordination/autonomous-coordinator.d.ts.map +1 -1
  9. package/dist/coordination/brain-ledger.d.ts +142 -0
  10. package/dist/coordination/brain-ledger.d.ts.map +1 -0
  11. package/dist/coordination/brain-monitor.d.ts +31 -2
  12. package/dist/coordination/brain-monitor.d.ts.map +1 -1
  13. package/dist/coordination/brain.d.ts +43 -0
  14. package/dist/coordination/brain.d.ts.map +1 -1
  15. package/dist/coordination/delegate-tool.d.ts.map +1 -1
  16. package/dist/coordination/director-construction.d.ts.map +1 -1
  17. package/dist/coordination/director.d.ts +1 -1
  18. package/dist/coordination/director.d.ts.map +1 -1
  19. package/dist/coordination/fleet.d.ts +4 -4
  20. package/dist/coordination/fleet.d.ts.map +1 -1
  21. package/dist/coordination/global-mailbox.d.ts +63 -2
  22. package/dist/coordination/global-mailbox.d.ts.map +1 -1
  23. package/dist/coordination/index.d.ts +2 -1
  24. package/dist/coordination/index.d.ts.map +1 -1
  25. package/dist/coordination/index.js +1566 -462
  26. package/dist/coordination/index.js.map +4 -4
  27. package/dist/coordination/knowledge-graph.d.ts +13 -1
  28. package/dist/coordination/knowledge-graph.d.ts.map +1 -1
  29. package/dist/coordination/mailbox-actions.d.ts +12 -13
  30. package/dist/coordination/mailbox-actions.d.ts.map +1 -1
  31. package/dist/coordination/mailbox-constants.d.ts +64 -0
  32. package/dist/coordination/mailbox-constants.d.ts.map +1 -0
  33. package/dist/coordination/mailbox-events.d.ts +32 -0
  34. package/dist/coordination/mailbox-events.d.ts.map +1 -0
  35. package/dist/coordination/mailbox-message-codec.d.ts +8 -0
  36. package/dist/coordination/mailbox-message-codec.d.ts.map +1 -0
  37. package/dist/coordination/mailbox-types.d.ts +88 -4
  38. package/dist/coordination/mailbox-types.d.ts.map +1 -1
  39. package/dist/coordination/mailbox.d.ts +21 -2
  40. package/dist/coordination/mailbox.d.ts.map +1 -1
  41. package/dist/coordination/package-author-tracker.d.ts.map +1 -1
  42. package/dist/coordination/subagent-result-tool.d.ts.map +1 -1
  43. package/dist/defaults/index.js +846 -523
  44. package/dist/defaults/index.js.map +4 -4
  45. package/dist/execution/autonomous-runner.d.ts +7 -1
  46. package/dist/execution/autonomous-runner.d.ts.map +1 -1
  47. package/dist/execution/autonomy-brain.d.ts +72 -11
  48. package/dist/execution/autonomy-brain.d.ts.map +1 -1
  49. package/dist/execution/brain-chain.d.ts +53 -0
  50. package/dist/execution/brain-chain.d.ts.map +1 -0
  51. package/dist/execution/brain-evaluation.d.ts +66 -0
  52. package/dist/execution/brain-evaluation.d.ts.map +1 -0
  53. package/dist/execution/brain-runtime.d.ts +171 -0
  54. package/dist/execution/brain-runtime.d.ts.map +1 -0
  55. package/dist/execution/council-brain.d.ts +79 -0
  56. package/dist/execution/council-brain.d.ts.map +1 -0
  57. package/dist/execution/eternal-autonomy.d.ts +12 -0
  58. package/dist/execution/eternal-autonomy.d.ts.map +1 -1
  59. package/dist/execution/index.d.ts +5 -1
  60. package/dist/execution/index.d.ts.map +1 -1
  61. package/dist/execution/index.js +1350 -377
  62. package/dist/execution/index.js.map +4 -4
  63. package/dist/execution/parallel-eternal-engine.d.ts +12 -0
  64. package/dist/execution/parallel-eternal-engine.d.ts.map +1 -1
  65. package/dist/execution/tool-executor.d.ts.map +1 -1
  66. package/dist/hq/auth-store.d.ts +21 -3
  67. package/dist/hq/auth-store.d.ts.map +1 -1
  68. package/dist/hq/factory.d.ts +3 -0
  69. package/dist/hq/factory.d.ts.map +1 -1
  70. package/dist/hq/index.js +628 -72
  71. package/dist/hq/index.js.map +4 -4
  72. package/dist/hq/protocol.d.ts +54 -2
  73. package/dist/hq/protocol.d.ts.map +1 -1
  74. package/dist/hq/publisher.d.ts +4 -0
  75. package/dist/hq/publisher.d.ts.map +1 -1
  76. package/dist/index.d.ts +12 -6
  77. package/dist/index.d.ts.map +1 -1
  78. package/dist/index.js +3482 -1495
  79. package/dist/index.js.map +4 -4
  80. package/dist/kernel/events.d.ts +22 -4
  81. package/dist/kernel/events.d.ts.map +1 -1
  82. package/dist/kernel/index.js.map +2 -2
  83. package/dist/mailbox-attach.d.ts.map +1 -1
  84. package/dist/observability/index.js +16 -15
  85. package/dist/observability/index.js.map +2 -2
  86. package/dist/security/index.d.ts +1 -0
  87. package/dist/security/index.d.ts.map +1 -1
  88. package/dist/security/index.js +253 -21
  89. package/dist/security/index.js.map +4 -4
  90. package/dist/security/permission-policy-schema.d.ts +77 -0
  91. package/dist/security/permission-policy-schema.d.ts.map +1 -0
  92. package/dist/security/permission-policy.d.ts +5 -0
  93. package/dist/security/permission-policy.d.ts.map +1 -1
  94. package/dist/security/secret-vault.d.ts +9 -0
  95. package/dist/security/secret-vault.d.ts.map +1 -1
  96. package/dist/session-registry.d.ts.map +1 -1
  97. package/dist/storage/config-loader.d.ts +10 -0
  98. package/dist/storage/config-loader.d.ts.map +1 -1
  99. package/dist/storage/goal-store.d.ts +1 -1
  100. package/dist/storage/goal-store.d.ts.map +1 -1
  101. package/dist/storage/index.js +147 -162
  102. package/dist/storage/index.js.map +2 -2
  103. package/dist/storage/plan-store.d.ts +1 -1
  104. package/dist/storage/plan-store.d.ts.map +1 -1
  105. package/dist/storage/queue-store.d.ts +4 -0
  106. package/dist/storage/queue-store.d.ts.map +1 -1
  107. package/dist/storage/session-store.d.ts +9 -0
  108. package/dist/storage/session-store.d.ts.map +1 -1
  109. package/dist/storage/task-store.d.ts +1 -1
  110. package/dist/storage/task-store.d.ts.map +1 -1
  111. package/dist/storage/todos-checkpoint.d.ts +2 -2
  112. package/dist/storage/todos-checkpoint.d.ts.map +1 -1
  113. package/dist/types/config.d.ts +209 -1
  114. package/dist/types/config.d.ts.map +1 -1
  115. package/dist/types/index.js +11 -0
  116. package/dist/types/index.js.map +2 -2
  117. package/dist/types/multi-agent.d.ts +8 -0
  118. package/dist/types/multi-agent.d.ts.map +1 -1
  119. package/dist/types/observability.d.ts +5 -0
  120. package/dist/types/observability.d.ts.map +1 -1
  121. package/dist/types/tool.d.ts +7 -0
  122. package/dist/types/tool.d.ts.map +1 -1
  123. package/dist/utils/glob-expand.d.ts.map +1 -1
  124. package/dist/utils/incoming-images.d.ts +39 -0
  125. package/dist/utils/incoming-images.d.ts.map +1 -0
  126. package/dist/utils/index.d.ts +1 -0
  127. package/dist/utils/index.d.ts.map +1 -1
  128. package/dist/utils/index.js +81 -3
  129. package/dist/utils/index.js.map +3 -3
  130. package/dist/worktree/worktree-manager.d.ts +13 -4
  131. package/dist/worktree/worktree-manager.d.ts.map +1 -1
  132. package/instructions/agents/browser.md +25 -16
  133. package/instructions/coordination/subagent-baseline.md +16 -2
  134. package/instructions/leader-after-task.md +3 -1
  135. package/instructions/sections/tool/common-patterns.md +7 -1
  136. package/instructions/system.md +47 -0
  137. package/package.json +2 -2
  138. package/skills/docker-deploy/SKILL.md +1 -1
  139. package/skills/wrongstack-mailbox/SKILL.md +51 -12
  140. package/dist/plugins/git-plugin.d.ts +0 -15
  141. package/dist/plugins/git-plugin.d.ts.map +0 -1
  142. package/dist/plugins/observability-plugin.d.ts +0 -19
  143. package/dist/plugins/observability-plugin.d.ts.map +0 -1
  144. package/dist/plugins/plan-plugin.d.ts +0 -16
  145. package/dist/plugins/plan-plugin.d.ts.map +0 -1
@@ -2137,6 +2137,7 @@ var DefaultSessionStore = class _DefaultSessionStore {
2137
2137
  projectRoot;
2138
2138
  checkpointCas;
2139
2139
  isSessionInUse;
2140
+ logger;
2140
2141
  /**
2141
2142
  * In-memory cache for load() results, keyed by session ID. The cache is
2142
2143
  * invalidated when the file's mtimeMs or size changes (indicating the
@@ -2162,6 +2163,18 @@ var DefaultSessionStore = class _DefaultSessionStore {
2162
2163
  this.events = opts.events;
2163
2164
  this.secretScrubber = opts.secretScrubber;
2164
2165
  this.isSessionInUse = opts.isSessionInUse;
2166
+ this.logger = opts.logger;
2167
+ }
2168
+ /**
2169
+ * Emit a structured warning. Uses the configured Logger when available;
2170
+ * falls back to console.warn(JSON) so warnings are never silently dropped.
2171
+ */
2172
+ logWarn(msg, ctx) {
2173
+ if (this.logger) {
2174
+ this.logger.warn(msg, ctx);
2175
+ } else {
2176
+ console.warn(JSON.stringify({ ...ctx, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }));
2177
+ }
2165
2178
  }
2166
2179
  /**
2167
2180
  * Clear the load() cache. Useful for testing or when the caller knows
@@ -2263,12 +2276,10 @@ var DefaultSessionStore = class _DefaultSessionStore {
2263
2276
  this.emitWrite(id, file, "create", "success", Date.now() - t0);
2264
2277
  return writer;
2265
2278
  } catch (err) {
2266
- await handle.close().catch((e) => console.warn(JSON.stringify({
2267
- level: "warn",
2268
- event: "session_store.handle_close_failed",
2269
- message: e instanceof Error ? e.message : String(e),
2270
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
2271
- })));
2279
+ await handle.close().catch((e) => this.logWarn(
2280
+ "Session handle close failed",
2281
+ { event: "session_store.handle_close_failed", message: e instanceof Error ? e.message : String(e) }
2282
+ ));
2272
2283
  this.emitError(id, file, "create", toErrorMessage(err), true);
2273
2284
  throw err;
2274
2285
  }
@@ -2399,12 +2410,10 @@ var DefaultSessionStore = class _DefaultSessionStore {
2399
2410
  this.emitWrite(id, file, "resume", "success", Date.now() - t0);
2400
2411
  return { writer, data: resumedData };
2401
2412
  } catch (err) {
2402
- await handle.close().catch((e) => console.warn(JSON.stringify({
2403
- level: "warn",
2404
- event: "session_store.handle_close_failed",
2405
- message: e instanceof Error ? e.message : String(e),
2406
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
2407
- })));
2413
+ await handle.close().catch((e) => this.logWarn(
2414
+ "Session handle close failed",
2415
+ { event: "session_store.handle_close_failed", message: e instanceof Error ? e.message : String(e) }
2416
+ ));
2408
2417
  this.emitError(id, file, "resume", toErrorMessage(err), true);
2409
2418
  throw err;
2410
2419
  }
@@ -3025,13 +3034,10 @@ var DefaultSessionStore = class _DefaultSessionStore {
3025
3034
  await atomicWrite(manifest, JSON.stringify(summary), { mode: 384 }).catch((err) => {
3026
3035
  const msg = toErrorMessage(err);
3027
3036
  this.emitError(id, manifest, "summary_fallback", msg, true);
3028
- console.warn(JSON.stringify({
3029
- level: "warn",
3030
- event: "session_store.manifest_write_failed",
3031
- sessionId: id,
3032
- message: msg,
3033
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
3034
- }));
3037
+ this.logWarn(
3038
+ "Session manifest write failed",
3039
+ { event: "session_store.manifest_write_failed", sessionId: id, message: msg }
3040
+ );
3035
3041
  });
3036
3042
  outcome = "failure";
3037
3043
  errorMsg = "summary fallback \xE2\u20AC\u201D manifest rebuilt";
@@ -3393,10 +3399,19 @@ var QueueStore = class {
3393
3399
  // reject assigning an optional constructor parameter to these fields.
3394
3400
  events;
3395
3401
  traceId;
3402
+ logger;
3396
3403
  constructor(opts) {
3397
3404
  this.file = path8.join(opts.dir, "queue.json");
3398
3405
  this.events = opts.events;
3399
3406
  this.traceId = opts.traceId;
3407
+ this.logger = opts.logger;
3408
+ }
3409
+ logWarn(msg, ctx) {
3410
+ if (this.logger) {
3411
+ this.logger.warn(msg, ctx);
3412
+ } else {
3413
+ console.warn(JSON.stringify({ ...ctx, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }));
3414
+ }
3400
3415
  }
3401
3416
  async write(items) {
3402
3417
  const t0 = Date.now();
@@ -3426,13 +3441,7 @@ var QueueStore = class {
3426
3441
  recoverable: false,
3427
3442
  ...this.traceId !== void 0 && { traceId: this.traceId }
3428
3443
  });
3429
- console.warn(JSON.stringify({
3430
- level: "warn",
3431
- event: "queue_store.write_failed",
3432
- path: this.file,
3433
- message: toErrorMessage(err),
3434
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
3435
- }));
3444
+ this.logWarn("Queue store write failed", { event: "queue_store.write_failed", path: this.file, message: toErrorMessage(err) });
3436
3445
  }
3437
3446
  }
3438
3447
  async read() {
@@ -3464,13 +3473,7 @@ var QueueStore = class {
3464
3473
  recoverable: true,
3465
3474
  ...this.traceId !== void 0 && { traceId: this.traceId }
3466
3475
  });
3467
- console.warn(JSON.stringify({
3468
- level: "warn",
3469
- event: "queue_store.read_failed",
3470
- path: this.file,
3471
- message: toErrorMessage(err),
3472
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
3473
- }));
3476
+ this.logWarn("Queue store read failed", { event: "queue_store.read_failed", path: this.file, message: toErrorMessage(err) });
3474
3477
  return [];
3475
3478
  }
3476
3479
  let parsed;
@@ -3543,13 +3546,7 @@ var QueueStore = class {
3543
3546
  recoverable: true,
3544
3547
  ...this.traceId !== void 0 && { traceId: this.traceId }
3545
3548
  });
3546
- console.warn(JSON.stringify({
3547
- level: "warn",
3548
- event: "queue_store.clear_failed",
3549
- path: this.file,
3550
- message: err.message,
3551
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
3552
- }));
3549
+ this.logWarn("Queue store clear failed", { event: "queue_store.clear_failed", path: this.file, message: err.message });
3553
3550
  }
3554
3551
  }
3555
3552
  };
@@ -5696,6 +5693,10 @@ var KNOWN_DENIED_IN_PROJECT = [
5696
5693
  key: "fleet",
5697
5694
  reason: "Fleet supervision knobs: a repo-committed config could enable autonomous subagent spawning/steering/termination and mailbox traffic on the victim machine."
5698
5695
  },
5696
+ {
5697
+ key: "brain",
5698
+ reason: "Brain decision-layer knobs: a repo-committed config could raise the autonomy risk ceiling, switch the Brain to headless (removing the human tier), or reroute Brain decisions to an attacker-chosen provider/model."
5699
+ },
5699
5700
  {
5700
5701
  key: "git",
5701
5702
  reason: "Carries git.identity (GIT_AUTHOR_*/GIT_COMMITTER_* injection): a repo-committed config could spoof the author identity written into the victim's commit history (impersonation)."
@@ -5744,6 +5745,7 @@ var KNOWN_CONFIG_TOP_LEVEL_KEYS = /* @__PURE__ */ new Set([
5744
5745
  "extensions",
5745
5746
  "acp",
5746
5747
  "fleet",
5748
+ "brain",
5747
5749
  "git"
5748
5750
  ]);
5749
5751
  function assertInProjectAllowListComplete() {
@@ -5895,6 +5897,7 @@ var DefaultConfigLoader = class {
5895
5897
  extraSources;
5896
5898
  events;
5897
5899
  traceId;
5900
+ logger;
5898
5901
  jsonCache = /* @__PURE__ */ new Map();
5899
5902
  constructor(opts) {
5900
5903
  this.paths = opts.paths;
@@ -5903,6 +5906,19 @@ var DefaultConfigLoader = class {
5903
5906
  this.extraSources = opts.sources ?? [];
5904
5907
  this.events = opts.events;
5905
5908
  this.traceId = opts.traceId;
5909
+ this.logger = opts.logger;
5910
+ }
5911
+ /**
5912
+ * Emit a structured warning. Uses the configured Logger when available;
5913
+ * falls back to console.warn(JSON) so warnings are never silently dropped
5914
+ * during early boot (before a Logger is constructed).
5915
+ */
5916
+ logWarn(msg, ctx) {
5917
+ if (this.logger) {
5918
+ this.logger.warn(msg, ctx);
5919
+ } else {
5920
+ console.warn(JSON.stringify({ ...ctx, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }));
5921
+ }
5906
5922
  }
5907
5923
  async load(opts = {}) {
5908
5924
  let cfg = { ...BEHAVIOR_DEFAULTS };
@@ -5915,7 +5931,14 @@ var DefaultConfigLoader = class {
5915
5931
  ]);
5916
5932
  cfg = deepMerge2(cfg, global);
5917
5933
  cfg = deepMerge2(cfg, local);
5918
- cfg = deepMerge2(cfg, stripUnsafeInProjectFields(inProject, this.paths.inProjectConfig));
5934
+ cfg = deepMerge2(
5935
+ cfg,
5936
+ stripUnsafeInProjectFields(
5937
+ inProject,
5938
+ this.paths.inProjectConfig,
5939
+ this.logger ? (msg) => this.logger.warn(msg) : void 0
5940
+ )
5941
+ );
5919
5942
  for (const [key, fn] of Object.entries(ENV_MAP)) {
5920
5943
  const v = process.env[key];
5921
5944
  if (v) fn(cfg, v);
@@ -5932,14 +5955,9 @@ var DefaultConfigLoader = class {
5932
5955
  cfg = deepMerge2(cfg, patch);
5933
5956
  }
5934
5957
  } catch (err) {
5935
- console.warn(
5936
- JSON.stringify({
5937
- level: "warn",
5938
- event: "config.source_load_failed",
5939
- source: src.name,
5940
- message: toErrorMessage(err),
5941
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
5942
- })
5958
+ this.logWarn(
5959
+ "Config source load failed",
5960
+ { event: "config.source_load_failed", source: src.name, message: toErrorMessage(err) }
5943
5961
  );
5944
5962
  }
5945
5963
  }
@@ -5999,14 +6017,9 @@ var DefaultConfigLoader = class {
5999
6017
  durationMs: Date.now() - t0,
6000
6018
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
6001
6019
  });
6002
- console.warn(
6003
- JSON.stringify({
6004
- level: "warn",
6005
- event: "config.defaults_read_failed",
6006
- path: fp,
6007
- message: toErrorMessage(err),
6008
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
6009
- })
6020
+ this.logWarn(
6021
+ "Config defaults read failed",
6022
+ { event: "config.defaults_read_failed", path: fp, message: toErrorMessage(err) }
6010
6023
  );
6011
6024
  return;
6012
6025
  }
@@ -6040,14 +6053,9 @@ var DefaultConfigLoader = class {
6040
6053
  durationMs: Date.now() - t0,
6041
6054
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
6042
6055
  });
6043
- console.warn(
6044
- JSON.stringify({
6045
- level: "warn",
6046
- event: "config.defaults_write_failed",
6047
- path: fp,
6048
- message: toErrorMessage(err),
6049
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
6050
- })
6056
+ this.logWarn(
6057
+ "Config defaults write failed",
6058
+ { event: "config.defaults_write_failed", path: fp, message: toErrorMessage(err) }
6051
6059
  );
6052
6060
  }
6053
6061
  }
@@ -6150,13 +6158,9 @@ var DefaultConfigLoader = class {
6150
6158
  error: storageErrorString(err),
6151
6159
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
6152
6160
  });
6153
- console.warn(
6154
- JSON.stringify({
6155
- level: "warn",
6156
- event: "config.sync_load_failed",
6157
- message: toErrorMessage(err),
6158
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
6159
- })
6161
+ this.logWarn(
6162
+ "Config sync load failed",
6163
+ { event: "config.sync_load_failed", message: toErrorMessage(err) }
6160
6164
  );
6161
6165
  return null;
6162
6166
  }
@@ -6186,14 +6190,9 @@ var DefaultConfigLoader = class {
6186
6190
  error: storageErrorString(err),
6187
6191
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
6188
6192
  });
6189
- console.warn(
6190
- JSON.stringify({
6191
- level: "warn",
6192
- event: "config.read_failed",
6193
- path: file,
6194
- message: toErrorMessage(err),
6195
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
6196
- })
6193
+ this.logWarn(
6194
+ "Config read failed (stat)",
6195
+ { event: "config.read_failed", path: file, message: toErrorMessage(err) }
6197
6196
  );
6198
6197
  return {};
6199
6198
  }
@@ -6212,14 +6211,9 @@ var DefaultConfigLoader = class {
6212
6211
  error: storageErrorString(err),
6213
6212
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
6214
6213
  });
6215
- console.warn(
6216
- JSON.stringify({
6217
- level: "warn",
6218
- event: "config.read_failed",
6219
- path: file,
6220
- message: toErrorMessage(err),
6221
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
6222
- })
6214
+ this.logWarn(
6215
+ "Config read failed (read)",
6216
+ { event: "config.read_failed", path: file, message: toErrorMessage(err) }
6223
6217
  );
6224
6218
  }
6225
6219
  this.jsonCache.set(file, { mtimeMs: null, value: {} });
@@ -6237,14 +6231,9 @@ var DefaultConfigLoader = class {
6237
6231
  error: "parse error or empty file",
6238
6232
  ...this.traceId !== void 0 ? { traceId: this.traceId } : {}
6239
6233
  });
6240
- console.warn(
6241
- JSON.stringify({
6242
- level: "warn",
6243
- event: "config.parse_failed",
6244
- path: file,
6245
- message: "invalid JSON \u2014 falling back to defaults for this layer",
6246
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
6247
- })
6234
+ this.logWarn(
6235
+ "Config parse failed \u2014 falling back to defaults",
6236
+ { event: "config.parse_failed", path: file }
6248
6237
  );
6249
6238
  return {};
6250
6239
  }
@@ -6291,8 +6280,9 @@ var DefaultConfigLoader = class {
6291
6280
  }
6292
6281
  if (c.mode !== void 0 && !isContextWindowModeId(c.mode)) {
6293
6282
  const known = listContextWindowModes().map((m) => m.id).join(", ");
6294
- console.warn(
6295
- `[config] Ignoring unknown context.mode "${c.mode}" (expected one of: ${known}); falling back to "${DEFAULT_CONTEXT_WINDOW_MODE_ID}".`
6283
+ this.logWarn(
6284
+ `Ignoring unknown context.mode "${c.mode}" \u2014 falling back to "${DEFAULT_CONTEXT_WINDOW_MODE_ID}"`,
6285
+ { event: "config.unknown_context_mode", mode: c.mode, known }
6296
6286
  );
6297
6287
  c.mode = DEFAULT_CONTEXT_WINDOW_MODE_ID;
6298
6288
  }
@@ -8212,7 +8202,8 @@ var REGISTRY_FILE = "session-registry.json";
8212
8202
  var HEARTBEAT_INTERVAL_MS = 5e3;
8213
8203
  var STALE_TIMEOUT_MS = 3e4;
8214
8204
  var CLOSING_GRACE_MS = 15e3;
8215
- var LOST_GRACE_MS = 3e5;
8205
+ var LOST_GRACE_MS = 3e4;
8206
+ var AGENT_STALE_MS = 5 * 6e4;
8216
8207
  var STALE_LOCK_MS = 1e4;
8217
8208
  var STALE_TMP_MS = 6e4;
8218
8209
  var MAX_STALE_TMP_FILES = 20;
@@ -8406,31 +8397,38 @@ var SessionRegistry = class {
8406
8397
  const now = Date.now();
8407
8398
  let pruned = false;
8408
8399
  for (const [id, entry] of Object.entries(registry)) {
8409
- const heartbeatAge = now - new Date(entry.lastHeartbeatAt).getTime();
8400
+ const heartbeatAt = Date.parse(entry.lastHeartbeatAt);
8401
+ if (!Number.isFinite(heartbeatAt)) {
8402
+ delete registry[id];
8403
+ pruned = true;
8404
+ continue;
8405
+ }
8406
+ const heartbeatAge = now - heartbeatAt;
8407
+ const agents = Array.isArray(entry.agents) ? entry.agents : [];
8408
+ const liveAgents = agents.filter((agent) => {
8409
+ if (agent.id === "leader") return true;
8410
+ const lastActivityAt = Date.parse(agent.lastActivityAt);
8411
+ return Number.isFinite(lastActivityAt) && now - lastActivityAt <= AGENT_STALE_MS;
8412
+ });
8413
+ if (liveAgents.length !== agents.length || entry.agentCount !== liveAgents.length) {
8414
+ entry.agents = liveAgents;
8415
+ entry.agentCount = liveAgents.length;
8416
+ pruned = true;
8417
+ }
8410
8418
  if (entry.status === "closing" && heartbeatAge > CLOSING_GRACE_MS) {
8411
8419
  delete registry[id];
8412
8420
  pruned = true;
8413
8421
  continue;
8414
8422
  }
8415
- if (heartbeatAge > STALE_TIMEOUT_MS) {
8416
- const alive = pidAlive(entry.pid);
8417
- if (alive) {
8418
- if (entry.status !== "lost" && entry.status !== "closing" && entry.status !== "stale") {
8419
- entry.status = "lost";
8420
- pruned = true;
8421
- }
8422
- if (entry.status === "lost" && heartbeatAge > STALE_TIMEOUT_MS + LOST_GRACE_MS) {
8423
- delete registry[id];
8424
- pruned = true;
8425
- }
8426
- } else {
8427
- entry.status = "stale";
8428
- const startedAge = now - new Date(entry.startedAt).getTime();
8429
- if (startedAge > 5 * 6e4) {
8430
- delete registry[id];
8431
- pruned = true;
8432
- }
8433
- }
8423
+ if (heartbeatAge <= STALE_TIMEOUT_MS) continue;
8424
+ if (!pidAlive(entry.pid) || heartbeatAge > STALE_TIMEOUT_MS + LOST_GRACE_MS) {
8425
+ delete registry[id];
8426
+ pruned = true;
8427
+ continue;
8428
+ }
8429
+ if (entry.status !== "lost") {
8430
+ entry.status = "lost";
8431
+ pruned = true;
8434
8432
  }
8435
8433
  }
8436
8434
  if (pruned) {
@@ -9275,7 +9273,7 @@ async function loadTodosCheckpoint(filePath, events, traceId) {
9275
9273
  return null;
9276
9274
  }
9277
9275
  }
9278
- async function saveTodosCheckpoint(filePath, sessionId, todos, events, traceId) {
9276
+ async function saveTodosCheckpoint(filePath, sessionId, todos, events, traceId, warn) {
9279
9277
  const t0 = Date.now();
9280
9278
  const payload = {
9281
9279
  version: 1,
@@ -9304,28 +9302,17 @@ async function saveTodosCheckpoint(filePath, sessionId, todos, events, traceId)
9304
9302
  error: toErrorMessage(err),
9305
9303
  recoverable: false
9306
9304
  });
9307
- console.warn(JSON.stringify({
9308
- level: "warn",
9309
- event: "todos_checkpoint.save_failed",
9310
- message: toErrorMessage(err),
9311
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
9312
- }));
9305
+ (warn ?? ((m) => console.warn(JSON.stringify({ level: "warn", event: "todos_checkpoint.save_failed", message: m, timestamp: (/* @__PURE__ */ new Date()).toISOString() }))))(toErrorMessage(err));
9313
9306
  }
9314
9307
  }
9315
- function attachTodosCheckpoint(state, filePath, sessionId, events, traceId) {
9308
+ function attachTodosCheckpoint(state, filePath, sessionId, events, traceId, warn) {
9316
9309
  let timer = null;
9317
9310
  let pending = null;
9318
9311
  let writeChain = Promise.resolve();
9319
9312
  const enqueueWrite = (todos) => {
9320
9313
  writeChain = writeChain.then(() => saveTodosCheckpoint(filePath, sessionId, todos, events, traceId)).catch((err) => {
9321
9314
  const msg = toErrorMessage(err);
9322
- console.error(JSON.stringify({
9323
- level: "error",
9324
- event: "todos_checkpoint.write_chain_failed",
9325
- sessionId,
9326
- message: msg,
9327
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
9328
- }));
9315
+ (warn ?? ((m) => console.error(JSON.stringify({ level: "error", event: "todos_checkpoint.write_chain_failed", sessionId, message: m, timestamp: (/* @__PURE__ */ new Date()).toISOString() }))))(msg);
9329
9316
  });
9330
9317
  return writeChain;
9331
9318
  };
@@ -9513,7 +9500,7 @@ async function loadPlan(filePath, events) {
9513
9500
  return null;
9514
9501
  }
9515
9502
  }
9516
- async function savePlan(filePath, plan, events) {
9503
+ async function savePlan(filePath, plan, events, warn) {
9517
9504
  const t0 = Date.now();
9518
9505
  try {
9519
9506
  await atomicWrite(filePath, JSON.stringify(plan, null, 2), { mode: 384 });
@@ -9535,10 +9522,14 @@ async function savePlan(filePath, plan, events) {
9535
9522
  error: toErrorMessage(err),
9536
9523
  recoverable: false
9537
9524
  });
9538
- console.warn(
9539
- "[plan-store] save failed:",
9540
- toErrorMessage(err)
9541
- );
9525
+ (warn ?? ((m) => console.warn(
9526
+ JSON.stringify({
9527
+ level: "warn",
9528
+ event: "plan_store.save_failed",
9529
+ message: m,
9530
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
9531
+ })
9532
+ )))(toErrorMessage(err));
9542
9533
  return false;
9543
9534
  }
9544
9535
  }
@@ -9579,9 +9570,7 @@ function setPlanItemStatus(plan, idOrIndex, status) {
9579
9570
  const idx = matchIndex(plan, idOrIndex);
9580
9571
  if (idx === -1) return plan;
9581
9572
  const now = (/* @__PURE__ */ new Date()).toISOString();
9582
- const items = plan.items.map(
9583
- (it, i) => i === idx ? { ...it, status, updatedAt: now } : it
9584
- );
9573
+ const items = plan.items.map((it, i) => i === idx ? { ...it, status, updatedAt: now } : it);
9585
9574
  return { ...plan, items, updatedAt: now };
9586
9575
  }
9587
9576
  function clearPlan(plan) {
@@ -9836,7 +9825,7 @@ async function loadTasks(filePath, events, traceId) {
9836
9825
  return null;
9837
9826
  }
9838
9827
  }
9839
- async function saveTasks(filePath, tasks, events, traceId) {
9828
+ async function saveTasks(filePath, tasks, events, traceId, warn) {
9840
9829
  const t0 = Date.now();
9841
9830
  try {
9842
9831
  tasks.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -9862,10 +9851,14 @@ async function saveTasks(filePath, tasks, events, traceId) {
9862
9851
  recoverable: false,
9863
9852
  ...traceId !== void 0 && { traceId }
9864
9853
  });
9865
- console.warn(
9866
- "[task-store] save failed:",
9867
- toErrorMessage(err)
9868
- );
9854
+ (warn ?? ((m) => console.warn(
9855
+ JSON.stringify({
9856
+ level: "warn",
9857
+ event: "task_store.save_failed",
9858
+ message: m,
9859
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
9860
+ })
9861
+ )))(toErrorMessage(err));
9869
9862
  return false;
9870
9863
  }
9871
9864
  }
@@ -10093,7 +10086,7 @@ var MAX_JOURNAL_ENTRIES = 500;
10093
10086
  function goalFilePath(projectRoot) {
10094
10087
  return resolveWstackPaths({ projectRoot }).projectGoal;
10095
10088
  }
10096
- async function loadGoal(filePath, events) {
10089
+ async function loadGoal(filePath, events, warn) {
10097
10090
  const t0 = Date.now();
10098
10091
  let raw;
10099
10092
  try {
@@ -10124,13 +10117,9 @@ async function loadGoal(filePath, events) {
10124
10117
  try {
10125
10118
  const parsed = JSON.parse(raw);
10126
10119
  if (parsed?.version !== 1 || typeof parsed.goal !== "string" || !Array.isArray(parsed.journal)) {
10127
- console.warn(JSON.stringify({
10128
- level: "warn",
10129
- event: "goal_store.invalid_schema",
10130
- path: filePath,
10131
- message: "invalid schema \u2014 consider deleting and re-creating",
10132
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
10133
- }));
10120
+ (warn ?? ((msg) => console.warn(JSON.stringify({ level: "warn", event: "goal_store.invalid_schema", path: filePath, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }))))(
10121
+ "invalid schema \u2014 consider deleting and re-creating"
10122
+ );
10134
10123
  events?.emit("storage.read", {
10135
10124
  sessionId: "~boot~",
10136
10125
  store: "goal",
@@ -10152,13 +10141,9 @@ async function loadGoal(filePath, events) {
10152
10141
  });
10153
10142
  return parsed;
10154
10143
  } catch {
10155
- console.warn(JSON.stringify({
10156
- level: "warn",
10157
- event: "goal_store.parse_failed",
10158
- path: filePath,
10159
- message: "JSON parse failed \u2014 consider deleting and re-creating",
10160
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
10161
- }));
10144
+ (warn ?? ((msg) => console.warn(JSON.stringify({ level: "warn", event: "goal_store.parse_failed", path: filePath, message: msg, timestamp: (/* @__PURE__ */ new Date()).toISOString() }))))(
10145
+ "JSON parse failed \u2014 consider deleting and re-creating"
10146
+ );
10162
10147
  events?.emit("storage.read", {
10163
10148
  sessionId: "~boot~",
10164
10149
  store: "goal",