opencode-swarm 7.113.2 → 7.113.4

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 (69) hide show
  1. package/binaries/win32-arm64/.gitkeep +0 -0
  2. package/binaries/win32-x64/.gitkeep +0 -0
  3. package/dist/background/event-bus.d.ts +1 -1
  4. package/dist/background/queue.d.ts +11 -0
  5. package/dist/background/trigger.d.ts +1 -0
  6. package/dist/cli/{capability-probe-sh9bwh39.js → capability-probe-f1paszww.js} +1 -1
  7. package/dist/cli/{config-doctor-az11cwf5.js → config-doctor-xbdfrbwt.js} +2 -2
  8. package/dist/cli/{core-f4cbabe7.js → core-zg8s1jwx.js} +2 -2
  9. package/dist/cli/{curator-drift-jvs1v6em.js → curator-drift-c0by7063.js} +2 -2
  10. package/dist/cli/curator-llm-factory-b3g0g0cd.js +41 -0
  11. package/dist/cli/{curator-9s04amtf.js → curator-nh9raf1a.js} +26 -22
  12. package/dist/cli/{dispatch-wst7bypk.js → dispatch-mczsxy5s.js} +2 -2
  13. package/dist/cli/{evidence-summary-service-w1er1ea2.js → evidence-summary-service-8g594znj.js} +7 -7
  14. package/dist/cli/{gate-evidence-9hdwj6tt.js → gate-evidence-vkpqt300.js} +5 -5
  15. package/dist/cli/guardrail-explain-wpv5eskq.js +42 -0
  16. package/dist/cli/{guardrail-log-hysxdwg9.js → guardrail-log-qfc2j0tb.js} +4 -4
  17. package/dist/cli/hive-promoter-c0fd3j02.js +51 -0
  18. package/dist/cli/{index-0dab9w37.js → index-0p660a87.js} +2 -2
  19. package/dist/cli/{index-32bx4kch.js → index-0q7rrh59.js} +4 -4
  20. package/dist/cli/{index-n7rd2rkj.js → index-10v7hrkj.js} +2 -2
  21. package/dist/cli/{index-1ey3dxq7.js → index-147ja18h.js} +0 -4
  22. package/dist/cli/{index-0gf6de8b.js → index-2148358e.js} +45 -1
  23. package/dist/cli/{index-30ejh1tx.js → index-43khae15.js} +3 -3
  24. package/dist/cli/{index-x5g7et24.js → index-4h2ea8h5.js} +2 -2
  25. package/dist/cli/{index-5mkc2f9z.js → index-4sckv7y6.js} +1 -1
  26. package/dist/cli/{index-w51xz4dr.js → index-5yzr9fk6.js} +25 -25
  27. package/dist/cli/{index-q1jaeynn.js → index-80jkseqw.js} +2 -2
  28. package/dist/cli/{index-wvrj16f0.js → index-8fwhhayc.js} +4 -0
  29. package/dist/cli/{index-54dgk0bv.js → index-ct9e0y0q.js} +803 -450
  30. package/dist/cli/{index-afgh75zg.js → index-f6y341yk.js} +14 -11
  31. package/dist/cli/{index-db1fh1fv.js → index-g40r5d08.js} +1 -1
  32. package/dist/cli/{index-8f256d7t.js → index-g6va6n3t.js} +1 -1
  33. package/dist/cli/{index-9fxs0rm1.js → index-ga4ta3cr.js} +1 -1
  34. package/dist/cli/{index-t6wfwdm1.js → index-h7q1bvzm.js} +3 -3
  35. package/dist/cli/{index-h389ed8y.js → index-mr4whary.js} +3 -3
  36. package/dist/cli/{index-g55nzpwn.js → index-n6fa2hhk.js} +1 -1
  37. package/dist/cli/{index-vn263hqt.js → index-pa6t33pt.js} +17 -10
  38. package/dist/cli/{index-h91bv3hy.js → index-qe3v54nb.js} +6 -1
  39. package/dist/cli/{index-hpp2r0sd.js → index-qzqx2qky.js} +3 -3
  40. package/dist/cli/{index-fhmw7evd.js → index-rdwfqhp7.js} +2 -2
  41. package/dist/cli/{index-1rga1vvb.js → index-wh8949ef.js} +1 -1
  42. package/dist/cli/{index-r9fjzr3k.js → index-xbe1wtme.js} +1 -1
  43. package/dist/cli/index.js +22 -22
  44. package/dist/cli/{knowledge-escalator-4gbz527n.js → knowledge-escalator-0q1p6br7.js} +8 -8
  45. package/dist/cli/{knowledge-events-b6x28fgc.js → knowledge-events-9518gzsp.js} +6 -6
  46. package/dist/cli/{knowledge-store-h3cjx4dg.js → knowledge-store-k5rab79h.js} +6 -6
  47. package/dist/cli/{knowledge-validator-q6jw2p0t.js → knowledge-validator-csay9wqj.js} +7 -7
  48. package/dist/cli/{pending-delegations-t047f4a7.js → pending-delegations-ddbkbgxy.js} +4 -4
  49. package/dist/cli/{pr-subscriptions-p8g2rzxd.js → pr-subscriptions-vwv7zm2p.js} +5 -5
  50. package/dist/cli/{schema-qb313fyy.js → schema-e5kd993s.js} +1 -1
  51. package/dist/cli/{scope-persistence-5ccgtebg.js → scope-persistence-fm0gzhnk.js} +2 -2
  52. package/dist/cli/{skill-generator-nnwn4sq0.js → skill-generator-z01sjppf.js} +9 -9
  53. package/dist/cli/{telemetry-jm7t8031.js → telemetry-jny76r83.js} +1 -1
  54. package/dist/commands/registry.d.ts +7 -0
  55. package/dist/config/constants.d.ts +1 -1
  56. package/dist/hooks/curator.d.ts +33 -9
  57. package/dist/hooks/hive-promoter.d.ts +7 -0
  58. package/dist/hooks/knowledge-curator.d.ts +13 -0
  59. package/dist/hooks/messages-transform.d.ts +22 -1
  60. package/dist/hooks/spawn-helper.d.ts +10 -0
  61. package/dist/index.js +208 -206
  62. package/dist/sandbox/capability-probe.d.ts +14 -0
  63. package/dist/sandbox/macos/sandbox-exec-executor.d.ts +5 -0
  64. package/dist/tools/tool-metadata.d.ts +1 -1
  65. package/dist/utils/path-security.d.ts +28 -0
  66. package/package.json +2 -1
  67. package/dist/cli/curator-llm-factory-dwvk7rh0.js +0 -41
  68. package/dist/cli/guardrail-explain-2k271yh4.js +0 -42
  69. package/dist/cli/hive-promoter-0y4pnft4.js +0 -49
@@ -7,7 +7,7 @@ import {
7
7
  readDoctorArtifact,
8
8
  removeStraySwarmDir,
9
9
  runConfigDoctor
10
- } from "./index-0gf6de8b.js";
10
+ } from "./index-2148358e.js";
11
11
  import {
12
12
  AGENT_TOOL_MAP,
13
13
  ALL_SUBAGENT_NAMES,
@@ -23,7 +23,7 @@ import {
23
23
  getCanonicalAgentRole,
24
24
  resolveExternalSkillsConfig,
25
25
  stripKnownSwarmPrefix
26
- } from "./index-1ey3dxq7.js";
26
+ } from "./index-147ja18h.js";
27
27
  import {
28
28
  MAX_TRANSIENT_RETRIES,
29
29
  PlanSchema,
@@ -68,7 +68,7 @@ import {
68
68
  savePlan,
69
69
  transientBackoff,
70
70
  validateProjectRoot
71
- } from "./index-afgh75zg.js";
71
+ } from "./index-f6y341yk.js";
72
72
  import {
73
73
  buildOpenSpecProjectionSync,
74
74
  detectSpeckit,
@@ -83,13 +83,13 @@ import {
83
83
  _internals1 as _internals2,
84
84
  isCommandAvailable,
85
85
  tool
86
- } from "./index-9fxs0rm1.js";
86
+ } from "./index-ga4ta3cr.js";
87
87
  import {
88
88
  buildCorrelationId,
89
89
  listActive,
90
90
  subscribe,
91
91
  unsubscribe
92
- } from "./index-q1jaeynn.js";
92
+ } from "./index-80jkseqw.js";
93
93
  import {
94
94
  BUNDLED_PROJECT_SKILL_ROOT,
95
95
  DEFAULT_SKILL_MIN_CONFIDENCE,
@@ -111,7 +111,7 @@ import {
111
111
  retireSkill,
112
112
  selectCandidateEntries,
113
113
  syncBundledProjectSkillsIfMissingAsync
114
- } from "./index-h389ed8y.js";
114
+ } from "./index-mr4whary.js";
115
115
  import {
116
116
  appendUnactionable,
117
117
  quarantineEntry,
@@ -121,10 +121,10 @@ import {
121
121
  validateActionability,
122
122
  validateActionableFields,
123
123
  validateLesson
124
- } from "./index-30ejh1tx.js";
124
+ } from "./index-43khae15.js";
125
125
  import {
126
126
  readRecentEscalations
127
- } from "./index-t6wfwdm1.js";
127
+ } from "./index-h7q1bvzm.js";
128
128
  import {
129
129
  effectiveRetrievalOutcomes,
130
130
  readKnowledgeCounterRollups,
@@ -132,7 +132,7 @@ import {
132
132
  recordHiveKnowledgeEvent,
133
133
  recordKnowledgeEvent,
134
134
  resolveKnowledgeEventsPath
135
- } from "./index-hpp2r0sd.js";
135
+ } from "./index-qzqx2qky.js";
136
136
  import {
137
137
  appendKnowledge,
138
138
  appendRejectedLesson,
@@ -156,7 +156,7 @@ import {
156
156
  rewriteKnowledge,
157
157
  transactFile,
158
158
  transactKnowledge
159
- } from "./index-32bx4kch.js";
159
+ } from "./index-0q7rrh59.js";
160
160
  import {
161
161
  KNOWLEDGE_SCHEMA_VERSION,
162
162
  OUTCOME_BLOCK_THRESHOLD,
@@ -170,7 +170,7 @@ import {
170
170
  resolveLinkDir,
171
171
  sanitizeLinkId,
172
172
  writeLinkPointer
173
- } from "./index-db1fh1fv.js";
173
+ } from "./index-g40r5d08.js";
174
174
  import {
175
175
  CURATOR_INIT_PROMPT,
176
176
  CURATOR_PHASE_PROMPT,
@@ -179,15 +179,15 @@ import {
179
179
  import {
180
180
  SandboxCapabilityProbe,
181
181
  init_capability_probe
182
- } from "./index-wvrj16f0.js";
182
+ } from "./index-8fwhhayc.js";
183
183
  import {
184
184
  clearAllScopes
185
- } from "./index-g55nzpwn.js";
185
+ } from "./index-n6fa2hhk.js";
186
186
  import {
187
187
  readSwarmFileAsync,
188
188
  safeHook,
189
189
  validateSwarmPath
190
- } from "./index-1rga1vvb.js";
190
+ } from "./index-wh8949ef.js";
191
191
  import {
192
192
  deepMerge
193
193
  } from "./index-p0arc26j.js";
@@ -199,16 +199,16 @@ import {
199
199
  } from "./index-zgwm4ryv.js";
200
200
  import {
201
201
  atomicWriteFile
202
- } from "./index-0dab9w37.js";
202
+ } from "./index-0p660a87.js";
203
203
  import {
204
204
  exports_external
205
205
  } from "./index-293f68mj.js";
206
206
  import {
207
207
  tryAcquireLock
208
- } from "./index-5mkc2f9z.js";
208
+ } from "./index-4sckv7y6.js";
209
209
  import {
210
210
  telemetry
211
- } from "./index-vn263hqt.js";
211
+ } from "./index-pa6t33pt.js";
212
212
  import {
213
213
  require_proper_lockfile
214
214
  } from "./index-vvk2g744.js";
@@ -216,7 +216,7 @@ import {
216
216
  bunSpawn,
217
217
  bunWrite,
218
218
  mergeEnvForChild
219
- } from "./index-h91bv3hy.js";
219
+ } from "./index-qe3v54nb.js";
220
220
  import {
221
221
  __require,
222
222
  __toESM
@@ -4397,6 +4397,7 @@ var head = null;
4397
4397
  var tail = null;
4398
4398
  var entriesByKey = new Map;
4399
4399
  var deferredEntries = new Set;
4400
+ var resolvedKeyCache = new Map;
4400
4401
  function markAsPooled(provider) {
4401
4402
  const originalClose = provider.close;
4402
4403
  provider.close = () => {
@@ -4524,10 +4525,19 @@ function unlinkEntry(entry) {
4524
4525
  tail = entry.prev;
4525
4526
  }
4526
4527
  function resolvePoolKey(directory) {
4528
+ const rawKey = path6.resolve(directory);
4527
4529
  try {
4528
- return realpathSync(directory);
4530
+ const canonical = realpathSync(directory);
4531
+ resolvedKeyCache.delete(rawKey);
4532
+ resolvedKeyCache.set(rawKey, canonical);
4533
+ if (resolvedKeyCache.size > MAX_POOL_SIZE) {
4534
+ const oldest = resolvedKeyCache.keys().next().value;
4535
+ if (oldest !== undefined)
4536
+ resolvedKeyCache.delete(oldest);
4537
+ }
4538
+ return canonical;
4529
4539
  } catch {
4530
- return path6.resolve(directory);
4540
+ return resolvedKeyCache.get(rawKey) ?? rawKey;
4531
4541
  }
4532
4542
  }
4533
4543
  function evictAndClose(directory) {
@@ -4923,6 +4933,73 @@ function sanitizeGatesConfig(raw) {
4923
4933
  function sanitizeSectionConfigs(raw) {
4924
4934
  return sanitizeGatesConfig(sanitizeExternalSkillsConfig(raw));
4925
4935
  }
4936
+ function stripUnrecognizedKeys(raw, error2) {
4937
+ const removed = [];
4938
+ const cleaned = structuredClone(raw);
4939
+ for (const issue of error2.issues) {
4940
+ if (issue.code !== "unrecognized_keys")
4941
+ continue;
4942
+ const keys = issue.keys ?? [];
4943
+ let node = cleaned;
4944
+ for (const seg of issue.path) {
4945
+ if (node && typeof node === "object") {
4946
+ node = node[seg];
4947
+ } else {
4948
+ node = undefined;
4949
+ break;
4950
+ }
4951
+ }
4952
+ if (!node || typeof node !== "object")
4953
+ continue;
4954
+ for (const key of keys) {
4955
+ if (key in node) {
4956
+ delete node[key];
4957
+ const dotted = [...issue.path.map(String), key].join(".");
4958
+ removed.push(dotted);
4959
+ }
4960
+ }
4961
+ }
4962
+ return { cleaned, removed };
4963
+ }
4964
+ function parseConfigWithFallback(mergedRaw, rawUserConfig, failedResult, loadedFromFile, configHadErrors) {
4965
+ const result = failedResult;
4966
+ const secure = (config) => loadedFromFile && configHadErrors ? PluginConfigSchema.parse({
4967
+ ...config,
4968
+ guardrails: { enabled: true }
4969
+ }) : config;
4970
+ const { cleaned, removed } = stripUnrecognizedKeys(mergedRaw, result.error);
4971
+ if (removed.length > 0) {
4972
+ const recovered = PluginConfigSchema.safeParse(cleaned);
4973
+ if (recovered.success) {
4974
+ advisoryWarn(`[opencode-swarm] Ignored ${removed.length} unrecognized config key(s): ${removed.join(", ")}. The rest of your configuration was preserved. Fix or remove these keys.`);
4975
+ return secure(recovered.data);
4976
+ }
4977
+ }
4978
+ if (rawUserConfig) {
4979
+ const userSanitized = sanitizeSectionConfigs(rawUserConfig ?? {});
4980
+ const userParseResult = PluginConfigSchema.safeParse(userSanitized);
4981
+ if (userParseResult.success) {
4982
+ advisoryWarn("[opencode-swarm] Project config ignored due to validation errors. Using user config.");
4983
+ return secure(userParseResult.data);
4984
+ }
4985
+ const userStripped = stripUnrecognizedKeys(userSanitized, userParseResult.error);
4986
+ if (userStripped.removed.length > 0) {
4987
+ const userRecovered = PluginConfigSchema.safeParse(userStripped.cleaned);
4988
+ if (userRecovered.success) {
4989
+ advisoryWarn(`[opencode-swarm] Project config ignored; also ignored ${userStripped.removed.length} unrecognized user-config key(s): ${userStripped.removed.join(", ")}.`);
4990
+ return secure(userRecovered.data);
4991
+ }
4992
+ }
4993
+ }
4994
+ const offending = stripUnrecognizedKeys(mergedRaw, result.error).removed;
4995
+ if (offending.length > 0) {
4996
+ advisoryWarn(`[opencode-swarm] Merged config validation failed. Unrecognized key(s): ${offending.join(", ")}.`);
4997
+ } else {
4998
+ advisoryWarn("[opencode-swarm] Merged config validation failed:", result.error.format());
4999
+ }
5000
+ advisoryWarn("[opencode-swarm] \u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration.");
5001
+ return PluginConfigSchema.parse({ guardrails: { enabled: true } });
5002
+ }
4926
5003
  function rawFullAutoLocked(raw) {
4927
5004
  if (!raw || typeof raw !== "object")
4928
5005
  return false;
@@ -4955,27 +5032,16 @@ function loadPluginConfig(directory) {
4955
5032
  mergedRaw = migratePresetsConfig(mergedRaw);
4956
5033
  mergedRaw = sanitizeSectionConfigs(mergedRaw);
4957
5034
  const result = PluginConfigSchema.safeParse(mergedRaw);
4958
- if (!result.success) {
4959
- if (rawUserConfig) {
4960
- const userParseResult = PluginConfigSchema.safeParse(sanitizeSectionConfigs(rawUserConfig ?? {}));
4961
- if (userParseResult.success) {
4962
- advisoryWarn("[opencode-swarm] Project config ignored due to validation errors. Using user config.");
4963
- return userParseResult.data;
4964
- }
5035
+ if (result.success) {
5036
+ if (loadedFromFile && configHadErrors) {
5037
+ return PluginConfigSchema.parse({
5038
+ ...mergedRaw,
5039
+ guardrails: { enabled: true }
5040
+ });
4965
5041
  }
4966
- advisoryWarn("[opencode-swarm] Merged config validation failed:", result.error.format());
4967
- advisoryWarn("[opencode-swarm] \u26A0\uFE0F SECURITY: Falling back to conservative defaults with guardrails ENABLED. Fix the config file to restore custom configuration.");
4968
- return PluginConfigSchema.parse({
4969
- guardrails: { enabled: true }
4970
- });
4971
- }
4972
- if (loadedFromFile && configHadErrors) {
4973
- return PluginConfigSchema.parse({
4974
- ...mergedRaw,
4975
- guardrails: { enabled: true }
4976
- });
5042
+ return result.data;
4977
5043
  }
4978
- return result.data;
5044
+ return parseConfigWithFallback(mergedRaw, rawUserConfig, result, loadedFromFile, configHadErrors);
4979
5045
  }
4980
5046
  function loadPluginConfigWithMeta(directory) {
4981
5047
  const userConfigPath = path7.join(getUserConfigDir(), "opencode", CONFIG_FILENAME);
@@ -8169,6 +8235,11 @@ var _internals11 = {
8169
8235
  parseKnowledgeRecommendationsWithDiagnostics,
8170
8236
  readCuratorSummary,
8171
8237
  writeCuratorSummary,
8238
+ appendCuratorRecommendation,
8239
+ mergeCuratorPhaseSummary,
8240
+ readCuratorSummaryState,
8241
+ writeCuratorSummaryState,
8242
+ transactFile,
8172
8243
  filterPhaseEvents,
8173
8244
  checkPhaseCompliance,
8174
8245
  normalizeAgentName,
@@ -8222,8 +8293,39 @@ function capPhaseDigests(digests) {
8222
8293
  function capComplianceObservations(observations) {
8223
8294
  return observations.slice(-MAX_CURATOR_COMPLIANCE_OBSERVATIONS);
8224
8295
  }
8225
- function capKnowledgeRecommendations(recommendations) {
8226
- return recommendations.slice(-MAX_CURATOR_RECOMMENDATIONS);
8296
+ function canonicalizeJson(value) {
8297
+ if (Array.isArray(value))
8298
+ return value.map(canonicalizeJson);
8299
+ if (value === null || typeof value !== "object")
8300
+ return value;
8301
+ return Object.fromEntries(Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, nested]) => [key, canonicalizeJson(nested)]));
8302
+ }
8303
+ function recommendationIdentity(recommendation) {
8304
+ const stable = { ...recommendation };
8305
+ if (recommendation.action === "promote" && recommendation.lesson.startsWith("Hive promotion:")) {
8306
+ try {
8307
+ const parsedReason = JSON.parse(recommendation.reason);
8308
+ if (parsedReason !== null && typeof parsedReason === "object" && !Array.isArray(parsedReason)) {
8309
+ const { timestamp: _volatileTimestamp, ...stableReason } = parsedReason;
8310
+ stable.reason = stableReason;
8311
+ }
8312
+ } catch {}
8313
+ }
8314
+ return JSON.stringify(canonicalizeJson(stable));
8315
+ }
8316
+ function normalizeKnowledgeRecommendations(recommendations) {
8317
+ const input = Array.isArray(recommendations) ? recommendations.filter((entry) => entry !== null && typeof entry === "object" && typeof entry.action === "string" && typeof entry.lesson === "string" && typeof entry.reason === "string") : [];
8318
+ const seen = new Set;
8319
+ const newestUnique = [];
8320
+ for (let index = input.length - 1;index >= 0; index--) {
8321
+ const recommendation = input[index];
8322
+ const identity = recommendationIdentity(recommendation);
8323
+ if (seen.has(identity))
8324
+ continue;
8325
+ seen.add(identity);
8326
+ newestUnique.push(recommendation);
8327
+ }
8328
+ return newestUnique.reverse().slice(-MAX_CURATOR_RECOMMENDATIONS);
8227
8329
  }
8228
8330
  function buildDigestFromPhaseDigests(digests) {
8229
8331
  return digests.map((digest) => `### Phase ${digest.phase}
@@ -8498,27 +8600,166 @@ function clampConf(v) {
8498
8600
  return 1;
8499
8601
  return v;
8500
8602
  }
8501
- async function readCuratorSummary(directory) {
8502
- const content = await readSwarmFileAsync(directory, "curator-summary.json");
8503
- if (content === null) {
8504
- return null;
8603
+ function normalizeCuratorSummary(summary) {
8604
+ const recommendations = normalizeKnowledgeRecommendations(summary.knowledge_recommendations);
8605
+ const original = Array.isArray(summary.knowledge_recommendations) ? summary.knowledge_recommendations : [];
8606
+ const changed = !Array.isArray(summary.knowledge_recommendations) || original.length !== recommendations.length || original.some((entry, index) => entry !== recommendations[index]);
8607
+ return {
8608
+ summary: changed ? { ...summary, knowledge_recommendations: recommendations } : summary,
8609
+ changed
8610
+ };
8611
+ }
8612
+ async function readCuratorSummaryState(filePath) {
8613
+ let content;
8614
+ try {
8615
+ content = await fs6.promises.readFile(filePath, "utf-8");
8616
+ } catch (error2) {
8617
+ if (error2.code === "ENOENT") {
8618
+ return { summary: null, dirty: false };
8619
+ }
8620
+ throw error2;
8505
8621
  }
8622
+ return parseCuratorSummaryContent(content);
8623
+ }
8624
+ function parseCuratorSummaryContent(content) {
8506
8625
  try {
8507
8626
  const parsed = JSON.parse(content);
8508
8627
  if (parsed.schema_version !== 1) {
8509
8628
  warn(`Curator summary has unsupported schema version: ${parsed.schema_version}. Expected 1.`);
8510
- return null;
8629
+ return { summary: null, dirty: false };
8511
8630
  }
8512
- return parsed;
8631
+ const normalized = normalizeCuratorSummary(parsed);
8632
+ return { summary: normalized.summary, dirty: normalized.changed };
8513
8633
  } catch {
8514
8634
  warn("Failed to parse curator-summary.json: invalid JSON");
8635
+ return { summary: null, dirty: false };
8636
+ }
8637
+ }
8638
+ async function writeCuratorSummaryState(filePath, state) {
8639
+ if (!state.summary)
8640
+ return;
8641
+ await bunWrite(filePath, JSON.stringify(state.summary, null, 2));
8642
+ }
8643
+ async function transactCuratorSummary(directory, mutate) {
8644
+ const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
8645
+ let invoked = false;
8646
+ let mutationResult;
8647
+ await _internals11.transactFile(resolvedPath, _internals11.readCuratorSummaryState, _internals11.writeCuratorSummaryState, (state) => {
8648
+ invoked = true;
8649
+ const mutation = mutate(state.summary);
8650
+ mutationResult = mutation.result;
8651
+ if (mutation.next === null)
8652
+ return null;
8653
+ const candidate = mutation.next ?? state.summary;
8654
+ if (!candidate)
8655
+ return null;
8656
+ const normalized = normalizeCuratorSummary(candidate).summary;
8657
+ const explicitlyChanged = mutation.next !== undefined && JSON.stringify(normalized) !== JSON.stringify(state.summary);
8658
+ if (!state.dirty && !explicitlyChanged)
8659
+ return null;
8660
+ return { summary: normalized, dirty: false };
8661
+ });
8662
+ return { invoked, result: mutationResult };
8663
+ }
8664
+ async function readCuratorSummary(directory) {
8665
+ const content = await readSwarmFileAsync(directory, "curator-summary.json");
8666
+ if (content === null)
8515
8667
  return null;
8668
+ const initial = parseCuratorSummaryContent(content);
8669
+ if (!initial.summary || !initial.dirty)
8670
+ return initial.summary;
8671
+ let normalized = initial.summary;
8672
+ try {
8673
+ await transactCuratorSummary(directory, (summary) => {
8674
+ if (summary)
8675
+ normalized = summary;
8676
+ return { result: normalized };
8677
+ });
8678
+ } catch (error2) {
8679
+ warn(`Failed to persist curator-summary cleanup: ${error2 instanceof Error ? error2.message : String(error2)}`);
8516
8680
  }
8681
+ return normalized;
8517
8682
  }
8518
8683
  async function writeCuratorSummary(directory, summary) {
8519
- const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
8520
- fs6.mkdirSync(path16.dirname(resolvedPath), { recursive: true });
8521
- await bunWrite(resolvedPath, JSON.stringify(summary, null, 2));
8684
+ const transaction = await transactCuratorSummary(directory, () => ({
8685
+ next: summary,
8686
+ result: undefined
8687
+ }));
8688
+ if (!transaction.invoked) {
8689
+ throw new Error("Failed to persist curator summary");
8690
+ }
8691
+ }
8692
+ async function appendCuratorRecommendation(directory, recommendation) {
8693
+ const transaction = await transactCuratorSummary(directory, (summary) => {
8694
+ if (!summary)
8695
+ return { next: null, result: false };
8696
+ const recommendations = normalizeKnowledgeRecommendations([
8697
+ ...normalizeKnowledgeRecommendations(summary.knowledge_recommendations),
8698
+ recommendation
8699
+ ]);
8700
+ const current = normalizeKnowledgeRecommendations(summary.knowledge_recommendations);
8701
+ const changed = current.length !== recommendations.length || current.some((entry, index) => entry !== recommendations[index]);
8702
+ if (!changed)
8703
+ return { result: false };
8704
+ return {
8705
+ next: {
8706
+ ...summary,
8707
+ last_updated: new Date().toISOString(),
8708
+ knowledge_recommendations: recommendations
8709
+ },
8710
+ result: true
8711
+ };
8712
+ });
8713
+ return transaction.invoked ? transaction.result ?? false : false;
8714
+ }
8715
+ async function mergeCuratorPhaseSummary(directory, merge) {
8716
+ const transaction = await transactCuratorSummary(directory, (current) => {
8717
+ if (current?.phase_digests?.some((digest) => digest.phase === merge.phase)) {
8718
+ return { result: false };
8719
+ }
8720
+ if (current) {
8721
+ const phaseDigests2 = capPhaseDigests([
8722
+ ...Array.isArray(current.phase_digests) ? current.phase_digests : [],
8723
+ merge.phaseDigest
8724
+ ]);
8725
+ return {
8726
+ next: {
8727
+ ...current,
8728
+ last_updated: merge.timestamp,
8729
+ last_phase_covered: Math.max(typeof current.last_phase_covered === "number" ? current.last_phase_covered : 0, merge.phase),
8730
+ digest: buildDigestFromPhaseDigests(phaseDigests2),
8731
+ phase_digests: phaseDigests2,
8732
+ compliance_observations: capComplianceObservations([
8733
+ ...Array.isArray(current.compliance_observations) ? current.compliance_observations : [],
8734
+ ...merge.complianceObservations
8735
+ ]),
8736
+ knowledge_recommendations: normalizeKnowledgeRecommendations([
8737
+ ...normalizeKnowledgeRecommendations(current.knowledge_recommendations),
8738
+ ...merge.knowledgeRecommendations
8739
+ ])
8740
+ },
8741
+ result: true
8742
+ };
8743
+ }
8744
+ const phaseDigests = capPhaseDigests([merge.phaseDigest]);
8745
+ return {
8746
+ next: {
8747
+ schema_version: 1,
8748
+ session_id: merge.sessionId,
8749
+ last_updated: merge.timestamp,
8750
+ last_phase_covered: merge.phase,
8751
+ digest: buildDigestFromPhaseDigests(phaseDigests),
8752
+ phase_digests: phaseDigests,
8753
+ compliance_observations: capComplianceObservations(merge.complianceObservations),
8754
+ knowledge_recommendations: normalizeKnowledgeRecommendations(merge.knowledgeRecommendations)
8755
+ },
8756
+ result: true
8757
+ };
8758
+ });
8759
+ if (!transaction.invoked) {
8760
+ throw new Error("Failed to persist curator phase summary");
8761
+ }
8762
+ return transaction.result ?? false;
8522
8763
  }
8523
8764
  function normalizeAgentName(name) {
8524
8765
  const registry = swarmState.generatedAgentNames.length > 0 ? swarmState.generatedAgentNames : undefined;
@@ -8918,41 +9159,14 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
8918
9159
  }
8919
9160
  const sessionId = `session-${Date.now()}`;
8920
9161
  const now = new Date().toISOString();
8921
- let updatedSummary;
8922
- if (priorSummary) {
8923
- const phaseDigests = capPhaseDigests([
8924
- ...priorSummary.phase_digests,
8925
- phaseDigest
8926
- ]);
8927
- updatedSummary = {
8928
- ...priorSummary,
8929
- last_updated: now,
8930
- last_phase_covered: Math.max(priorSummary.last_phase_covered, phase),
8931
- digest: buildDigestFromPhaseDigests(phaseDigests),
8932
- phase_digests: phaseDigests,
8933
- compliance_observations: capComplianceObservations([
8934
- ...priorSummary.compliance_observations,
8935
- ...complianceObservations
8936
- ]),
8937
- knowledge_recommendations: capKnowledgeRecommendations([
8938
- ...priorSummary.knowledge_recommendations,
8939
- ...knowledgeRecommendations
8940
- ])
8941
- };
8942
- } else {
8943
- const phaseDigests = capPhaseDigests([phaseDigest]);
8944
- updatedSummary = {
8945
- schema_version: 1,
8946
- session_id: sessionId,
8947
- last_updated: now,
8948
- last_phase_covered: phase,
8949
- digest: buildDigestFromPhaseDigests(phaseDigests),
8950
- phase_digests: phaseDigests,
8951
- compliance_observations: capComplianceObservations(complianceObservations),
8952
- knowledge_recommendations: capKnowledgeRecommendations(knowledgeRecommendations)
8953
- };
8954
- }
8955
- await _internals11.writeCuratorSummary(directory, updatedSummary);
9162
+ const summaryUpdated = await _internals11.mergeCuratorPhaseSummary(directory, {
9163
+ phase,
9164
+ phaseDigest,
9165
+ complianceObservations,
9166
+ knowledgeRecommendations,
9167
+ sessionId,
9168
+ timestamp: now
9169
+ });
8956
9170
  if (knowledgeApplicationFindings.length > 0) {
8957
9171
  try {
8958
9172
  const evidenceDir = path16.join(directory, ".swarm", "evidence", String(phase));
@@ -8976,7 +9190,7 @@ async function runCuratorPhase(directory, phase, agentsDispatched, config, knowl
8976
9190
  }
8977
9191
  if (config.skill_generation_enabled === true && skillCandidates.length > 0) {
8978
9192
  try {
8979
- const skillModule = await import("./skill-generator-nnwn4sq0.js");
9193
+ const skillModule = await import("./skill-generator-z01sjppf.js");
8980
9194
  for (const cand of skillCandidates) {
8981
9195
  if (cand.confidence < (config.min_skill_confidence ?? DEFAULT_SKILL_MIN_CONFIDENCE)) {
8982
9196
  continue;
@@ -9097,14 +9311,14 @@ ${summary}`;
9097
9311
  digest: phaseDigest,
9098
9312
  compliance: complianceObservations,
9099
9313
  knowledge_recommendations: knowledgeRecommendations,
9100
- summary_updated: true,
9314
+ summary_updated: summaryUpdated,
9101
9315
  knowledge_application_findings: knowledgeApplicationFindings,
9102
9316
  skill_candidates: skillCandidates
9103
9317
  };
9104
9318
  getGlobalEventBus().publish("curator.phase.completed", {
9105
9319
  phase,
9106
9320
  compliance_count: complianceObservations.length,
9107
- summary_updated: true
9321
+ summary_updated: summaryUpdated
9108
9322
  });
9109
9323
  return result;
9110
9324
  } catch (err) {
@@ -9257,7 +9471,7 @@ async function applyCuratorKnowledgeUpdates(directory, recommendations, knowledg
9257
9471
  } catch {}
9258
9472
  }
9259
9473
  if (contradictedEntries.length > 0 && knowledgeConfig.contradiction_threshold_action === "quarantine") {
9260
- const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-4gbz527n.js");
9474
+ const { maybeQuarantineOnContradiction } = await import("./knowledge-escalator-0q1p6br7.js");
9261
9475
  for (const { id } of contradictedEntries) {
9262
9476
  try {
9263
9477
  await maybeQuarantineOnContradiction(directory, id, knowledgeConfig.contradiction_quarantine_threshold, knowledgeConfig.contradiction_quarantine_window_days);
@@ -10214,15 +10428,15 @@ var _internals12 = {
10214
10428
  verifyPostMortemKnowledgeActions,
10215
10429
  repairPostMortemActions,
10216
10430
  loadDefaultKnowledgeConfig: async () => {
10217
- const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-qb313fyy.js");
10431
+ const { KnowledgeConfigSchema: KnowledgeConfigSchema2 } = await import("./schema-e5kd993s.js");
10218
10432
  return KnowledgeConfigSchema2.parse({});
10219
10433
  },
10220
10434
  applyCuratorKnowledgeUpdates: async (directory, recommendations, knowledgeConfig) => {
10221
- const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-9s04amtf.js");
10435
+ const { applyCuratorKnowledgeUpdates: applyCuratorKnowledgeUpdates2 } = await import("./curator-nh9raf1a.js");
10222
10436
  return applyCuratorKnowledgeUpdates2(directory, recommendations, knowledgeConfig);
10223
10437
  },
10224
10438
  checkHivePromotions: async (entries, knowledgeConfig) => {
10225
- const { checkHivePromotions } = await import("./hive-promoter-0y4pnft4.js");
10439
+ const { checkHivePromotions } = await import("./hive-promoter-c0fd3j02.js");
10226
10440
  return checkHivePromotions(entries, knowledgeConfig);
10227
10441
  },
10228
10442
  applyProposalTriage: async (directory, triage) => {
@@ -10231,7 +10445,7 @@ var _internals12 = {
10231
10445
  activateProposal,
10232
10446
  listSkills: listSkills2,
10233
10447
  sanitizeSlug
10234
- } = await import("./skill-generator-nnwn4sq0.js");
10448
+ } = await import("./skill-generator-z01sjppf.js");
10235
10449
  const result = {
10236
10450
  approved: [],
10237
10451
  rejected: [],
@@ -10273,7 +10487,7 @@ var _internals12 = {
10273
10487
  return result;
10274
10488
  },
10275
10489
  readPriorDriftReports: async (directory) => {
10276
- const { readPriorDriftReports } = await import("./curator-drift-jvs1v6em.js");
10490
+ const { readPriorDriftReports } = await import("./curator-drift-c0by7063.js");
10277
10491
  return readPriorDriftReports(directory);
10278
10492
  },
10279
10493
  readSwarmKnowledge: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory))
@@ -10450,31 +10664,33 @@ async function checkHivePromotions(swarmEntries, config) {
10450
10664
  total_hive_entries: hiveEntries.length
10451
10665
  };
10452
10666
  }
10667
+ var _internals13 = {
10668
+ readSwarmEntries: (directory) => readKnowledge(resolveSwarmKnowledgePath(directory)),
10669
+ checkHivePromotions,
10670
+ readCuratorSummary,
10671
+ appendCuratorRecommendation
10672
+ };
10453
10673
  function createHivePromoterHook(directory, config) {
10454
10674
  const hook = async (_input, _output) => {
10455
- const swarmEntries = await readKnowledge(resolveSwarmKnowledgePath(directory));
10456
- const promotionSummary = await checkHivePromotions(swarmEntries, config);
10457
- const curatorSummary = await readCuratorSummary(directory);
10458
- if (curatorSummary) {
10459
- const existingRecommendations = Array.isArray(curatorSummary.knowledge_recommendations) ? curatorSummary.knowledge_recommendations : [];
10460
- const recommendation = {
10461
- action: "promote",
10462
- lesson: `Hive promotion: ${promotionSummary.new_promotions} new, ${promotionSummary.encounters_incremented} encounters, ${promotionSummary.advancements} advancements, ${promotionSummary.total_hive_entries} total entries`,
10463
- reason: JSON.stringify({
10464
- timestamp: promotionSummary.timestamp,
10465
- new_promotions: promotionSummary.new_promotions,
10466
- encounters_incremented: promotionSummary.encounters_incremented,
10467
- advancements: promotionSummary.advancements,
10468
- total_hive_entries: promotionSummary.total_hive_entries
10469
- })
10470
- };
10471
- const updatedSummary = {
10472
- ...curatorSummary,
10473
- knowledge_recommendations: [...existingRecommendations, recommendation],
10474
- last_updated: new Date().toISOString()
10475
- };
10476
- await writeCuratorSummary(directory, updatedSummary);
10477
- }
10675
+ const swarmEntries = await _internals13.readSwarmEntries(directory);
10676
+ const promotionSummary = await _internals13.checkHivePromotions(swarmEntries, config);
10677
+ const curatorSummary = await _internals13.readCuratorSummary(directory);
10678
+ if (!curatorSummary)
10679
+ return;
10680
+ const hasActivity = promotionSummary.new_promotions > 0 || promotionSummary.encounters_incremented > 0 || promotionSummary.advancements > 0;
10681
+ if (!hasActivity)
10682
+ return;
10683
+ await _internals13.appendCuratorRecommendation(directory, {
10684
+ action: "promote",
10685
+ lesson: `Hive promotion: ${promotionSummary.new_promotions} new, ${promotionSummary.encounters_incremented} encounters, ${promotionSummary.advancements} advancements, ${promotionSummary.total_hive_entries} total entries`,
10686
+ reason: JSON.stringify({
10687
+ timestamp: promotionSummary.timestamp,
10688
+ new_promotions: promotionSummary.new_promotions,
10689
+ encounters_incremented: promotionSummary.encounters_incremented,
10690
+ advancements: promotionSummary.advancements,
10691
+ total_hive_entries: promotionSummary.total_hive_entries
10692
+ })
10693
+ });
10478
10694
  };
10479
10695
  return safeHook(hook);
10480
10696
  }
@@ -10563,7 +10779,13 @@ async function promoteFromSwarm(directory, lessonId) {
10563
10779
  // src/hooks/knowledge-curator.ts
10564
10780
  import { createHash as createHash4 } from "crypto";
10565
10781
  import { existsSync as existsSync14 } from "fs";
10566
- import { appendFile as appendFile2, mkdir as mkdir6, readFile as readFile7, writeFile as writeFile7 } from "fs/promises";
10782
+ import {
10783
+ appendFile as appendFile2,
10784
+ mkdir as mkdir6,
10785
+ readFile as readFile7,
10786
+ realpath,
10787
+ writeFile as writeFile7
10788
+ } from "fs/promises";
10567
10789
  import * as path23 from "path";
10568
10790
 
10569
10791
  // src/services/synonym-map.ts
@@ -10799,7 +11021,7 @@ var SKILL_AUDIENCE_RUNNER_PATTERN = /^runner:(opencode|claude|codex)$/;
10799
11021
  var WORKFLOW_BOOST_MIN_CONTEXT = 0.05;
10800
11022
  var RECENCY_DECAY_MS = 30 * 24 * 60 * 60 * 1000;
10801
11023
  var SKILL_FRONTMATTER_READ_BYTES = 16 * 1024;
10802
- var _internals13 = {
11024
+ var _internals14 = {
10803
11025
  computeSkillRelevanceScore: null,
10804
11026
  rankSkillsForContext: null,
10805
11027
  getSkillStats: null,
@@ -11166,7 +11388,7 @@ function rankSkillsForContext(skills, taskContext, directory) {
11166
11388
  const results = [];
11167
11389
  for (const skillPath of skills) {
11168
11390
  const skillEntries = allEntries.filter((e) => e.skillPath === skillPath);
11169
- const metadata = _internals13.readSkillMetadata(skillPath, directory);
11391
+ const metadata = _internals14.readSkillMetadata(skillPath, directory);
11170
11392
  const score = computeSkillRelevanceScore(skillPath, taskContext, skillEntries, metadata);
11171
11393
  const entriesWithVerdict = skillEntries.filter((e) => e.complianceVerdict !== undefined && e.complianceVerdict !== "not_checked");
11172
11394
  const compliantCount = entriesWithVerdict.filter((e) => e.complianceVerdict === "compliant").length;
@@ -11225,7 +11447,7 @@ function formatSkillIndexWithContext(skills, directory, metadataBySkillPath) {
11225
11447
  } catch {}
11226
11448
  if (!hasHistory) {
11227
11449
  return skills.map((sp) => {
11228
- const meta = metadataBySkillPath?.get(sp) ?? _internals13.readSkillMetadata(sp, directory);
11450
+ const meta = metadataBySkillPath?.get(sp) ?? _internals14.readSkillMetadata(sp, directory);
11229
11451
  return ` - file:${meta.path} - ${meta.name}: ${meta.description}`;
11230
11452
  }).join(`
11231
11453
  `);
@@ -11233,7 +11455,7 @@ function formatSkillIndexWithContext(skills, directory, metadataBySkillPath) {
11233
11455
  const lines = [];
11234
11456
  for (const skillPath of skills) {
11235
11457
  const stats = getSkillStats(skillPath, directory);
11236
- const meta = metadataBySkillPath?.get(skillPath) ?? _internals13.readSkillMetadata(skillPath, directory);
11458
+ const meta = metadataBySkillPath?.get(skillPath) ?? _internals14.readSkillMetadata(skillPath, directory);
11237
11459
  const compliancePct = Math.round(stats.complianceRate * 100);
11238
11460
  const topAgentNames = stats.topAgents.slice(0, 3).map((a) => a.agent).join(", ");
11239
11461
  lines.push(` - file:${meta.path} - ${meta.name}: ${meta.description} (used: ${stats.totalUsage}, compliance: ${compliancePct}%)` + (stats.topAgents.length > 0 ? ` \u2192 ${topAgentNames}` : ""));
@@ -11241,16 +11463,16 @@ function formatSkillIndexWithContext(skills, directory, metadataBySkillPath) {
11241
11463
  return lines.join(`
11242
11464
  `);
11243
11465
  }
11244
- _internals13.computeSkillRelevanceScore = computeSkillRelevanceScore;
11245
- _internals13.rankSkillsForContext = rankSkillsForContext;
11246
- _internals13.getSkillStats = getSkillStats;
11247
- _internals13.formatSkillIndexWithContext = formatSkillIndexWithContext;
11248
- _internals13.parseSkillFrontmatter = parseSkillFrontmatter;
11249
- _internals13.readSkillMetadata = readSkillMetadata;
11250
- _internals13.extractSkillName = extractSkillName;
11251
- _internals13.computeRecencyScore = computeRecencyScore;
11252
- _internals13.computeContextMatchScore = computeContextMatchScore;
11253
- _internals13.computeTriggerMatchBoost = computeTriggerMatchBoost;
11466
+ _internals14.computeSkillRelevanceScore = computeSkillRelevanceScore;
11467
+ _internals14.rankSkillsForContext = rankSkillsForContext;
11468
+ _internals14.getSkillStats = getSkillStats;
11469
+ _internals14.formatSkillIndexWithContext = formatSkillIndexWithContext;
11470
+ _internals14.parseSkillFrontmatter = parseSkillFrontmatter;
11471
+ _internals14.readSkillMetadata = readSkillMetadata;
11472
+ _internals14.extractSkillName = extractSkillName;
11473
+ _internals14.computeRecencyScore = computeRecencyScore;
11474
+ _internals14.computeContextMatchScore = computeContextMatchScore;
11475
+ _internals14.computeTriggerMatchBoost = computeTriggerMatchBoost;
11254
11476
 
11255
11477
  // src/hooks/skill-propagation-gate.ts
11256
11478
  function parseSimpleYaml(content) {
@@ -11352,10 +11574,10 @@ function parseYamlValue(value) {
11352
11574
  }
11353
11575
  function loadRoutingSkills(directory, targetAgent) {
11354
11576
  const routingPath = path21.join(directory, ".opencode", "skill-routing.yaml");
11355
- if (!_internals14.existsSync(routingPath))
11577
+ if (!_internals15.existsSync(routingPath))
11356
11578
  return [];
11357
11579
  try {
11358
- const content = _internals14.readFileSync(routingPath, "utf-8");
11580
+ const content = _internals15.readFileSync(routingPath, "utf-8");
11359
11581
  const config = parseSimpleYaml(content);
11360
11582
  if (!config?.routing)
11361
11583
  return [];
@@ -11382,7 +11604,7 @@ var SKILL_SEARCH_ROOTS = [
11382
11604
  ".claude/skills"
11383
11605
  ];
11384
11606
  var MAX_SCORING_SESSION_ENTRIES = 500;
11385
- var _internals14 = {
11607
+ var _internals15 = {
11386
11608
  readdirSync: fs8.readdirSync.bind(fs8),
11387
11609
  existsSync: fs8.existsSync.bind(fs8),
11388
11610
  statSync: fs8.statSync.bind(fs8),
@@ -11415,11 +11637,11 @@ function discoverAvailableSkills(directory) {
11415
11637
  const results = [];
11416
11638
  for (const root of SKILL_SEARCH_ROOTS) {
11417
11639
  const rootPath = path21.join(directory, root);
11418
- if (!_internals14.existsSync(rootPath))
11640
+ if (!_internals15.existsSync(rootPath))
11419
11641
  continue;
11420
11642
  let entries;
11421
11643
  try {
11422
- entries = _internals14.readdirSync(rootPath);
11644
+ entries = _internals15.readdirSync(rootPath);
11423
11645
  } catch {
11424
11646
  continue;
11425
11647
  }
@@ -11427,11 +11649,11 @@ function discoverAvailableSkills(directory) {
11427
11649
  if (entry.startsWith("."))
11428
11650
  continue;
11429
11651
  const skillDir = path21.join(rootPath, entry);
11430
- if (_internals14.existsSync(path21.join(skillDir, "retired.marker")) || _internals14.existsSync(path21.join(skillDir, "stale.marker")))
11652
+ if (_internals15.existsSync(path21.join(skillDir, "retired.marker")) || _internals15.existsSync(path21.join(skillDir, "stale.marker")))
11431
11653
  continue;
11432
11654
  const skillFile = path21.join(skillDir, "SKILL.md");
11433
11655
  try {
11434
- if (_internals14.statSync(skillDir).isDirectory() && _internals14.existsSync(skillFile)) {
11656
+ if (_internals15.statSync(skillDir).isDirectory() && _internals15.existsSync(skillFile)) {
11435
11657
  results.push(path21.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
11436
11658
  }
11437
11659
  } catch (err) {
@@ -11463,7 +11685,7 @@ function parseDelegationArgs(args) {
11463
11685
  }
11464
11686
  if (!targetAgent)
11465
11687
  return null;
11466
- const skillsField = prompt ? _internals14.extractSkillsFieldFromPrompt(prompt) : "";
11688
+ const skillsField = prompt ? _internals15.extractSkillsFieldFromPrompt(prompt) : "";
11467
11689
  return { targetAgent, skillsField };
11468
11690
  }
11469
11691
  function extractSkillsFieldFromPrompt(prompt) {
@@ -11504,10 +11726,10 @@ function writeWarnEvent(directory, record) {
11504
11726
  const filePath = path21.join(directory, ".swarm", "events.jsonl");
11505
11727
  try {
11506
11728
  const dir = path21.dirname(filePath);
11507
- if (!_internals14.existsSync(dir)) {
11508
- _internals14.mkdirSync(dir, { recursive: true });
11729
+ if (!_internals15.existsSync(dir)) {
11730
+ _internals15.mkdirSync(dir, { recursive: true });
11509
11731
  }
11510
- _internals14.appendFileSync(filePath, `${JSON.stringify(record)}
11732
+ _internals15.appendFileSync(filePath, `${JSON.stringify(record)}
11511
11733
  `, "utf-8");
11512
11734
  } catch (err) {
11513
11735
  warn(`[skill-propagation-gate] failed to write warning event: ${err instanceof Error ? err.message : String(err)}`);
@@ -11562,7 +11784,7 @@ function validateSkillReference(directory, reference, context, options) {
11562
11784
  };
11563
11785
  }
11564
11786
  try {
11565
- const root = _internals14.realpathSync(directory);
11787
+ const root = _internals15.realpathSync(directory);
11566
11788
  const lexicalPath = path21.resolve(root, withoutPrefix);
11567
11789
  if (!isWithinRoot(root, lexicalPath)) {
11568
11790
  return {
@@ -11570,10 +11792,10 @@ function validateSkillReference(directory, reference, context, options) {
11570
11792
  reason: "skill path resolves outside the project"
11571
11793
  };
11572
11794
  }
11573
- if (!_internals14.existsSync(lexicalPath) || !_internals14.statSync(lexicalPath).isFile()) {
11795
+ if (!_internals15.existsSync(lexicalPath) || !_internals15.statSync(lexicalPath).isFile()) {
11574
11796
  return { valid: false, reason: "skill file does not exist" };
11575
11797
  }
11576
- const realPath = _internals14.realpathSync(lexicalPath);
11798
+ const realPath = _internals15.realpathSync(lexicalPath);
11577
11799
  if (!isWithinRoot(root, realPath)) {
11578
11800
  return {
11579
11801
  valid: false,
@@ -11582,7 +11804,7 @@ function validateSkillReference(directory, reference, context, options) {
11582
11804
  }
11583
11805
  const normalizedPath = withoutPrefix.replace(/^\.\//, "");
11584
11806
  const validatedMetadataPath = path21.relative(root, realPath).replace(/\\/g, "/");
11585
- const metadata = _internals14.readSkillMetadata(validatedMetadataPath, root);
11807
+ const metadata = _internals15.readSkillMetadata(validatedMetadataPath, root);
11586
11808
  if (metadata.frontmatterStatus !== "valid" && metadata.frontmatterStatus !== "absent") {
11587
11809
  return {
11588
11810
  valid: false,
@@ -11614,18 +11836,18 @@ async function validateExplicitSkillReferencesBefore(directory, input, config) {
11614
11836
  if (!agentRaw || stripKnownSwarmPrefix(agentRaw) !== "architect") {
11615
11837
  return { blocked: false, reason: null };
11616
11838
  }
11617
- const parsed = _internals14.parseDelegationArgs(input.args);
11839
+ const parsed = _internals15.parseDelegationArgs(input.args);
11618
11840
  if (!parsed)
11619
11841
  return { blocked: false, reason: null };
11620
11842
  const targetBase = stripKnownSwarmPrefix(parsed.targetAgent);
11621
- if (!_internals14.SKILL_CAPABLE_AGENTS.has(targetBase)) {
11843
+ if (!_internals15.SKILL_CAPABLE_AGENTS.has(targetBase)) {
11622
11844
  return { blocked: false, reason: null };
11623
11845
  }
11624
11846
  const skillsValue = parsed.skillsField.trim();
11625
11847
  if (!skillsValue || skillsValue.toLowerCase() === "none") {
11626
11848
  return { blocked: false, reason: null };
11627
11849
  }
11628
- const fileReferences = _internals14.extractFileSkillReferences(skillsValue);
11850
+ const fileReferences = _internals15.extractFileSkillReferences(skillsValue);
11629
11851
  if (fileReferences.length === 0) {
11630
11852
  return { blocked: false, reason: null, validatedSkillPaths: [] };
11631
11853
  }
@@ -11638,7 +11860,7 @@ async function validateExplicitSkillReferencesBefore(directory, input, config) {
11638
11860
  const context = resolveSkillAudienceContext(config);
11639
11861
  const validatedSkillPaths = [];
11640
11862
  for (const reference of fileReferences) {
11641
- const result = _internals14.validateSkillReference(directory, reference, context, {
11863
+ const result = _internals15.validateSkillReference(directory, reference, context, {
11642
11864
  enforceAudience: true
11643
11865
  });
11644
11866
  if (!result.valid) {
@@ -11683,18 +11905,18 @@ async function skillPropagationGateBefore(directory, input, config) {
11683
11905
  const baseAgent = stripKnownSwarmPrefix(agentRaw);
11684
11906
  if (baseAgent !== "architect")
11685
11907
  return { blocked: false, reason: null, recommendedSkills: undefined };
11686
- const parsed = _internals14.parseDelegationArgs(input.args);
11908
+ const parsed = _internals15.parseDelegationArgs(input.args);
11687
11909
  if (!parsed)
11688
11910
  return { blocked: false, reason: null, recommendedSkills: undefined };
11689
11911
  const targetBase = stripKnownSwarmPrefix(parsed.targetAgent);
11690
- if (!_internals14.SKILL_CAPABLE_AGENTS.has(targetBase))
11912
+ if (!_internals15.SKILL_CAPABLE_AGENTS.has(targetBase))
11691
11913
  return { blocked: false, reason: null, recommendedSkills: undefined };
11692
11914
  const sessionID = typeof input.sessionID === "string" ? input.sessionID : "unknown";
11693
11915
  const audienceContext = resolveSkillAudienceContext(config);
11694
11916
  const availableSkills = [];
11695
11917
  const metadataBySkillPath = new Map;
11696
- for (const skillPath of _internals14.discoverAvailableSkills(directory)) {
11697
- const validation = _internals14.validateSkillReference(directory, skillPath, audienceContext, { enforceAudience: true, requireFilePrefix: false });
11918
+ for (const skillPath of _internals15.discoverAvailableSkills(directory)) {
11919
+ const validation = _internals15.validateSkillReference(directory, skillPath, audienceContext, { enforceAudience: true, requireFilePrefix: false });
11698
11920
  if (!validation.valid || !validation.skillPath)
11699
11921
  continue;
11700
11922
  availableSkills.push(validation.skillPath);
@@ -11705,7 +11927,7 @@ async function skillPropagationGateBefore(directory, input, config) {
11705
11927
  const skillsValue = parsed.skillsField.trim();
11706
11928
  if (skillsValue && skillsValue.toLowerCase() !== "none") {
11707
11929
  const prompt = typeof input.args?.prompt === "string" ? String(input.args.prompt) : "";
11708
- const taskId = _internals14.extractTaskIdFromPrompt(prompt);
11930
+ const taskId = _internals15.extractTaskIdFromPrompt(prompt);
11709
11931
  const skillPaths = explicitIntegrity.validatedSkillPaths ?? [];
11710
11932
  let coderSkillPaths = [];
11711
11933
  if (prompt) {
@@ -11714,19 +11936,19 @@ async function skillPropagationGateBefore(directory, input, config) {
11714
11936
  const trimmed = line.trim();
11715
11937
  if (trimmed.startsWith("SKILLS_USED_BY_CODER:")) {
11716
11938
  const fieldVal = trimmed.slice("SKILLS_USED_BY_CODER:".length).trim();
11717
- coderSkillPaths = _internals14.parseSkillPaths(fieldVal);
11939
+ coderSkillPaths = _internals15.parseSkillPaths(fieldVal);
11718
11940
  break;
11719
11941
  }
11720
11942
  }
11721
11943
  }
11722
11944
  const safeCoderSkillPaths = coderSkillPaths.flatMap((skillPath) => {
11723
- const validation = _internals14.validateSkillReference(directory, skillPath, audienceContext, { enforceAudience: false });
11945
+ const validation = _internals15.validateSkillReference(directory, skillPath, audienceContext, { enforceAudience: false });
11724
11946
  return validation.valid && validation.skillPath ? [validation.skillPath] : [];
11725
11947
  });
11726
11948
  const allPaths = [...new Set([...skillPaths, ...safeCoderSkillPaths])];
11727
11949
  for (const skillPath of allPaths) {
11728
11950
  try {
11729
- _internals14.appendSkillUsageEntry(directory, {
11951
+ _internals15.appendSkillUsageEntry(directory, {
11730
11952
  skillPath,
11731
11953
  agentName: targetBase,
11732
11954
  taskID: taskId,
@@ -11743,18 +11965,18 @@ async function skillPropagationGateBefore(directory, input, config) {
11743
11965
  let scored = [];
11744
11966
  if (skillsValue.toLowerCase() !== "none" && availableSkills.length > 0) {
11745
11967
  try {
11746
- const sessionEntries = _internals14.readSkillUsageEntriesTail(directory, {
11968
+ const sessionEntries = _internals15.readSkillUsageEntriesTail(directory, {
11747
11969
  sessionID
11748
11970
  });
11749
- if (sessionEntries.length > _internals14.MAX_SCORING_SESSION_ENTRIES) {
11971
+ if (sessionEntries.length > _internals15.MAX_SCORING_SESSION_ENTRIES) {
11750
11972
  scoringSkipped = true;
11751
- warn(`[skill-propagation-gate] skipping scoring \u2014 tail window has ${sessionEntries.length} session entries (limit: ${_internals14.MAX_SCORING_SESSION_ENTRIES})`);
11973
+ warn(`[skill-propagation-gate] skipping scoring \u2014 tail window has ${sessionEntries.length} session entries (limit: ${_internals15.MAX_SCORING_SESSION_ENTRIES})`);
11752
11974
  } else {
11753
11975
  const prompt = typeof input.args?.prompt === "string" ? String(input.args.prompt) : "";
11754
11976
  scored = availableSkills.map((skillPath) => {
11755
11977
  const skillEntries = sessionEntries.filter((e) => e.skillPath === skillPath);
11756
- const metadata = metadataBySkillPath.get(skillPath) ?? _internals14.readSkillMetadata(skillPath, directory);
11757
- const score = _internals14.computeSkillRelevanceScore(skillPath, prompt, skillEntries, metadata);
11978
+ const metadata = metadataBySkillPath.get(skillPath) ?? _internals15.readSkillMetadata(skillPath, directory);
11979
+ const score = _internals15.computeSkillRelevanceScore(skillPath, prompt, skillEntries, metadata);
11758
11980
  return { skillPath, score, usageCount: skillEntries.length };
11759
11981
  }).sort((a, b) => b.score - a.score || b.usageCount - a.usageCount);
11760
11982
  if (scored.length > 0) {
@@ -11768,11 +11990,11 @@ async function skillPropagationGateBefore(directory, input, config) {
11768
11990
  }
11769
11991
  }
11770
11992
  try {
11771
- const routingPaths = _internals14.loadRoutingSkills(directory, targetBase);
11993
+ const routingPaths = _internals15.loadRoutingSkills(directory, targetBase);
11772
11994
  if (routingPaths.length > 0) {
11773
11995
  const existingPaths = new Set(scored.map((s) => s.skillPath));
11774
11996
  for (const routingPath of routingPaths) {
11775
- const validation = _internals14.validateSkillReference(directory, routingPath, audienceContext, { enforceAudience: true, requireFilePrefix: false });
11997
+ const validation = _internals15.validateSkillReference(directory, routingPath, audienceContext, { enforceAudience: true, requireFilePrefix: false });
11776
11998
  if (!validation.valid || !validation.skillPath)
11777
11999
  continue;
11778
12000
  const eligibleRoutingPath = validation.skillPath;
@@ -11780,7 +12002,7 @@ async function skillPropagationGateBefore(directory, input, config) {
11780
12002
  metadataBySkillPath.set(eligibleRoutingPath, validation.metadata);
11781
12003
  }
11782
12004
  const routedSkillDir = path21.dirname(path21.join(directory, eligibleRoutingPath));
11783
- if (_internals14.existsSync(path21.join(routedSkillDir, "retired.marker")) || _internals14.existsSync(path21.join(routedSkillDir, "stale.marker")))
12005
+ if (_internals15.existsSync(path21.join(routedSkillDir, "retired.marker")) || _internals15.existsSync(path21.join(routedSkillDir, "stale.marker")))
11784
12006
  continue;
11785
12007
  if (!existingPaths.has(eligibleRoutingPath)) {
11786
12008
  scored.push({
@@ -11806,12 +12028,12 @@ async function skillPropagationGateBefore(directory, input, config) {
11806
12028
  } else if (typeof scored !== "undefined" && scored.length > 0) {
11807
12029
  skillsForIndex = scored.map((r) => r.skillPath);
11808
12030
  }
11809
- const formattedIndex = _internals14.formatSkillIndexWithContext(skillsForIndex, directory, metadataBySkillPath);
12031
+ const formattedIndex = _internals15.formatSkillIndexWithContext(skillsForIndex, directory, metadataBySkillPath);
11810
12032
  if (formattedIndex.length > 0) {
11811
12033
  const contextPath = path21.join(directory, ".swarm", "context.md");
11812
12034
  let existingContent = "";
11813
- if (_internals14.existsSync(contextPath)) {
11814
- existingContent = _internals14.readFileSync(contextPath, "utf-8");
12035
+ if (_internals15.existsSync(contextPath)) {
12036
+ existingContent = _internals15.readFileSync(contextPath, "utf-8");
11815
12037
  }
11816
12038
  const sectionHeader = "## Available Skills";
11817
12039
  const newSection = `${sectionHeader}
@@ -11831,10 +12053,10 @@ ${newSection}`;
11831
12053
  }
11832
12054
  }
11833
12055
  const swarmDir = path21.dirname(contextPath);
11834
- if (!_internals14.existsSync(swarmDir)) {
11835
- _internals14.mkdirSync(swarmDir, { recursive: true });
12056
+ if (!_internals15.existsSync(swarmDir)) {
12057
+ _internals15.mkdirSync(swarmDir, { recursive: true });
11836
12058
  }
11837
- _internals14.writeFileSync(contextPath, updatedContent, "utf-8");
12059
+ _internals15.writeFileSync(contextPath, updatedContent, "utf-8");
11838
12060
  }
11839
12061
  } catch (err) {
11840
12062
  warn(`[skill-propagation-gate] failed to write skill index to context.md: ${err instanceof Error ? err.message : String(err)}`);
@@ -11860,7 +12082,7 @@ ${newSection}`;
11860
12082
  });
11861
12083
  const warningMsg = `Skill propagation warning: Delegating to ${targetBase} without SKILLS field. ` + `Available skills: ${skillNames.join(", ")}`;
11862
12084
  try {
11863
- _internals14.writeWarnEvent(directory, {
12085
+ _internals15.writeWarnEvent(directory, {
11864
12086
  type: "skill_propagation_warn",
11865
12087
  timestamp: new Date().toISOString(),
11866
12088
  tool: toolName,
@@ -11892,17 +12114,17 @@ async function skillPropagationTransformScan(directory, output, sessionID, confi
11892
12114
  const validatedProvenancePaths = (fieldValue) => {
11893
12115
  if (remainingProvenanceValidationBudget <= 0)
11894
12116
  return [];
11895
- const references = _internals14.parseSkillPaths(fieldValue).slice(0, remainingProvenanceValidationBudget);
12117
+ const references = _internals15.parseSkillPaths(fieldValue).slice(0, remainingProvenanceValidationBudget);
11896
12118
  remainingProvenanceValidationBudget -= references.length;
11897
12119
  return references.flatMap((reference) => {
11898
- const validation = _internals14.validateSkillReference(directory, reference, audienceContext, { enforceAudience: true });
12120
+ const validation = _internals15.validateSkillReference(directory, reference, audienceContext, { enforceAudience: true });
11899
12121
  return validation.valid && validation.skillPath ? [validation.skillPath] : [];
11900
12122
  });
11901
12123
  };
11902
12124
  let dedupKeys = new Set;
11903
12125
  let existingEntries = [];
11904
12126
  try {
11905
- existingEntries = _internals14.readSkillUsageEntriesTail(directory, {
12127
+ existingEntries = _internals15.readSkillUsageEntriesTail(directory, {
11906
12128
  sessionID
11907
12129
  });
11908
12130
  dedupKeys = new Set(existingEntries.map((e, i) => {
@@ -11973,7 +12195,7 @@ async function skillPropagationTransformScan(directory, output, sessionID, confi
11973
12195
  if (isDuplicate(skillPath, "reviewer", resolvedTaskID))
11974
12196
  continue;
11975
12197
  try {
11976
- _internals14.appendSkillUsageEntry(directory, {
12198
+ _internals15.appendSkillUsageEntry(directory, {
11977
12199
  skillPath,
11978
12200
  agentName: "reviewer",
11979
12201
  taskID: resolvedTaskID,
@@ -12018,14 +12240,14 @@ async function skillPropagationTransformScan(directory, output, sessionID, confi
12018
12240
  }
12019
12241
  if (currentTargetAgent && skillsField && skillsField.toLowerCase() !== "none") {
12020
12242
  const skillPaths = validatedProvenancePaths(skillsField);
12021
- const taskId = _internals14.extractTaskIdFromPrompt(text);
12243
+ const taskId = _internals15.extractTaskIdFromPrompt(text);
12022
12244
  for (const skillPath of skillPaths) {
12023
12245
  if (hadRecordingError)
12024
12246
  break;
12025
12247
  if (isDuplicate(skillPath, currentTargetAgent, taskId))
12026
12248
  continue;
12027
12249
  try {
12028
- _internals14.appendSkillUsageEntry(directory, {
12250
+ _internals15.appendSkillUsageEntry(directory, {
12029
12251
  skillPath,
12030
12252
  agentName: currentTargetAgent,
12031
12253
  taskID: taskId,
@@ -12045,18 +12267,18 @@ async function skillPropagationTransformScan(directory, output, sessionID, confi
12045
12267
  break;
12046
12268
  }
12047
12269
  }
12048
- _internals14.skillPropagationGateBefore = skillPropagationGateBefore;
12049
- _internals14.skillPropagationTransformScan = skillPropagationTransformScan;
12050
- _internals14.writeWarnEvent = writeWarnEvent;
12051
- _internals14.discoverAvailableSkills = discoverAvailableSkills;
12052
- _internals14.parseDelegationArgs = parseDelegationArgs;
12053
- _internals14.parseSkillPaths = parseSkillPaths;
12054
- _internals14.extractFileSkillReferences = extractFileSkillReferences;
12055
- _internals14.validateSkillReference = validateSkillReference;
12056
- _internals14.extractTaskIdFromPrompt = extractTaskIdFromPrompt;
12057
- _internals14.extractSkillsFieldFromPrompt = extractSkillsFieldFromPrompt;
12058
- _internals14.formatSkillIndexWithContext = formatSkillIndexWithContext;
12059
- _internals14.loadRoutingSkills = loadRoutingSkills;
12270
+ _internals15.skillPropagationGateBefore = skillPropagationGateBefore;
12271
+ _internals15.skillPropagationTransformScan = skillPropagationTransformScan;
12272
+ _internals15.writeWarnEvent = writeWarnEvent;
12273
+ _internals15.discoverAvailableSkills = discoverAvailableSkills;
12274
+ _internals15.parseDelegationArgs = parseDelegationArgs;
12275
+ _internals15.parseSkillPaths = parseSkillPaths;
12276
+ _internals15.extractFileSkillReferences = extractFileSkillReferences;
12277
+ _internals15.validateSkillReference = validateSkillReference;
12278
+ _internals15.extractTaskIdFromPrompt = extractTaskIdFromPrompt;
12279
+ _internals15.extractSkillsFieldFromPrompt = extractSkillsFieldFromPrompt;
12280
+ _internals15.formatSkillIndexWithContext = formatSkillIndexWithContext;
12281
+ _internals15.loadRoutingSkills = loadRoutingSkills;
12060
12282
 
12061
12283
  // src/hooks/micro-reflector.ts
12062
12284
  var REFLECT_OUTCOMES = new Set([
@@ -12094,6 +12316,8 @@ async function readTaskTrajectory(directory, taskId) {
12094
12316
  // src/hooks/knowledge-curator.ts
12095
12317
  var seenRetroSections = new Map;
12096
12318
  var MAX_TRACKED_RETRO_SECTIONS = 500;
12319
+ var MAX_IN_FLIGHT_EVIDENCE_ENTRIES = 500;
12320
+ var inFlightEvidenceEntries = new Set;
12097
12321
  function pruneSeenRetroSections() {
12098
12322
  const cutoff = Date.now() - 86400000;
12099
12323
  for (const [key, entry] of seenRetroSections) {
@@ -12118,6 +12342,81 @@ function recordSeenRetroSection(key, value, timestamp) {
12118
12342
  function hashContent(content) {
12119
12343
  return createHash4("sha1").update(content).digest("hex");
12120
12344
  }
12345
+ async function canonicalExistingPath(candidate) {
12346
+ let resolved = path23.resolve(candidate);
12347
+ try {
12348
+ resolved = await _internals16.realpath(resolved);
12349
+ } catch {}
12350
+ return resolved;
12351
+ }
12352
+ function isPathContained(root, candidate) {
12353
+ const relative3 = path23.relative(root, candidate);
12354
+ return relative3 === "" || !relative3.startsWith(`..${path23.sep}`) && relative3 !== ".." && !path23.isAbsolute(relative3);
12355
+ }
12356
+ function physicalPathIdentity(candidate) {
12357
+ const normalized = candidate.replaceAll("\\", "/").normalize("NFC");
12358
+ return process.platform === "win32" ? normalized.toLowerCase() : normalized;
12359
+ }
12360
+ async function resolveEvidencePathScope(directory, relativeEvidencePath) {
12361
+ const projectRoot = await canonicalExistingPath(directory);
12362
+ const swarmRoot = await canonicalExistingPath(path23.join(projectRoot, ".swarm"));
12363
+ if (!isPathContained(projectRoot, swarmRoot))
12364
+ return null;
12365
+ const evidenceRoot = await canonicalExistingPath(path23.join(swarmRoot, "evidence"));
12366
+ if (!isPathContained(swarmRoot, evidenceRoot))
12367
+ return null;
12368
+ const evidenceTarget = await canonicalExistingPath(path23.join(swarmRoot, ...relativeEvidencePath.split("/")));
12369
+ if (!isPathContained(evidenceRoot, evidenceTarget))
12370
+ return null;
12371
+ return {
12372
+ projectIdentity: hashContent(physicalPathIdentity(projectRoot)),
12373
+ evidenceIdentity: hashContent(physicalPathIdentity(evidenceTarget))
12374
+ };
12375
+ }
12376
+ function sanitizeEvidenceLessons(value) {
12377
+ if (!Array.isArray(value))
12378
+ return [];
12379
+ return value.filter((lesson) => typeof lesson === "string").map((lesson) => lesson.trim()).filter((lesson) => lesson.length > 0 && lesson.length <= 280);
12380
+ }
12381
+ function evidenceProjectName(entry, root) {
12382
+ const metadata = isRecord2(entry.metadata) ? entry.metadata : null;
12383
+ return typeof entry.project_name === "string" ? entry.project_name : typeof metadata?.project_name === "string" ? metadata.project_name : typeof root.project_name === "string" ? root.project_name : "unknown";
12384
+ }
12385
+ function evidencePhaseNumber(entry, root) {
12386
+ return typeof entry.phase_number === "number" ? entry.phase_number : typeof root.phase_number === "number" ? root.phase_number : 1;
12387
+ }
12388
+ function extractEvidenceLessonBatches(evidenceData) {
12389
+ const rawEntries = Array.isArray(evidenceData.entries) ? evidenceData.entries : [evidenceData];
12390
+ const batches = [];
12391
+ for (const rawEntry of rawEntries) {
12392
+ if (!isRecord2(rawEntry))
12393
+ continue;
12394
+ if (Object.hasOwn(rawEntry, "type") && rawEntry.type !== "retrospective") {
12395
+ continue;
12396
+ }
12397
+ const lessons = sanitizeEvidenceLessons(rawEntry.lessons_learned);
12398
+ if (lessons.length === 0)
12399
+ continue;
12400
+ const phaseNumber = evidencePhaseNumber(rawEntry, evidenceData);
12401
+ const projectName = evidenceProjectName(rawEntry, evidenceData);
12402
+ const identity = hashContent(JSON.stringify([
12403
+ rawEntry.type ?? "legacy-retrospective",
12404
+ rawEntry.task_id ?? evidenceData.task_id ?? "",
12405
+ rawEntry.timestamp ?? "",
12406
+ rawEntry.agent ?? "",
12407
+ phaseNumber,
12408
+ projectName,
12409
+ lessons
12410
+ ]));
12411
+ batches.push({
12412
+ identity,
12413
+ lessons,
12414
+ projectName,
12415
+ phaseNumber
12416
+ });
12417
+ }
12418
+ return batches;
12419
+ }
12121
12420
  function isWriteToEvidenceFile(input) {
12122
12421
  const trigger = normalizeWriteTrigger(input);
12123
12422
  return isEvidencePath(trigger?.filePath);
@@ -12827,9 +13126,9 @@ async function curateAndStoreSwarm(lessons, projectName, phaseInfo, directory, c
12827
13126
  } catch {}
12828
13127
  }
12829
13128
  if (!options?.skipAutoPromotion) {
12830
- await _internals15.runAutoPromotion(directory, config);
13129
+ await _internals16.runAutoPromotion(directory, config);
12831
13130
  if (phaseInfo.phase_number > 0) {
12832
- await _internals15.runAutoDemotion(directory, config, phaseInfo.phase_number);
13131
+ await _internals16.runAutoDemotion(directory, config, phaseInfo.phase_number);
12833
13132
  }
12834
13133
  }
12835
13134
  return { stored, reinforced, skipped, rejected, quarantined };
@@ -12918,9 +13217,11 @@ function createKnowledgeCuratorHook(directory, config, options = {}) {
12918
13217
  if (!isPlanTrigger && !isEvidenceTrigger)
12919
13218
  return;
12920
13219
  if (isEvidenceTrigger) {
12921
- const relativeEvidencePath = trigger.filePath.replace(/^.*\.swarm\//, "");
12922
- const evidenceKey = `evidence:${trigger.sessionID}:${relativeEvidencePath}`;
12923
- const lastSeenEvidence = seenRetroSections.get(evidenceKey);
13220
+ const relativeEvidencePath = trigger.filePath.replaceAll("\\", "/").replace(/^.*\.swarm\//i, "");
13221
+ const canonicalRelativeEvidencePath = path23.posix.normalize(relativeEvidencePath);
13222
+ const evidenceScope = await resolveEvidencePathScope(directory, canonicalRelativeEvidencePath);
13223
+ if (!evidenceScope)
13224
+ return;
12924
13225
  const evidenceContent = await readSwarmFileAsync(directory, relativeEvidencePath);
12925
13226
  if (!evidenceContent)
12926
13227
  return;
@@ -12930,28 +13231,29 @@ function createKnowledgeCuratorHook(directory, config, options = {}) {
12930
13231
  } catch {
12931
13232
  return;
12932
13233
  }
12933
- let lessons = [];
12934
- if (Array.isArray(evidenceData.entries) && evidenceData.entries.length > 0) {
12935
- const firstEntry = evidenceData.entries[0];
12936
- if (Array.isArray(firstEntry.lessons_learned)) {
12937
- lessons = firstEntry.lessons_learned;
13234
+ const batches = extractEvidenceLessonBatches(evidenceData);
13235
+ for (const batch of batches) {
13236
+ const evidenceKey = `evidence:${evidenceScope.projectIdentity}:${evidenceScope.evidenceIdentity}:entry:${batch.identity}`;
13237
+ if (seenRetroSections.has(evidenceKey) || inFlightEvidenceEntries.has(evidenceKey)) {
13238
+ continue;
13239
+ }
13240
+ if (inFlightEvidenceEntries.size >= MAX_IN_FLIGHT_EVIDENCE_ENTRIES) {
13241
+ warn(`Evidence curation overload: ${MAX_IN_FLIGHT_EVIDENCE_ENTRIES} entries already in flight; retrying ${relativeEvidencePath} on a later trigger`);
13242
+ continue;
13243
+ }
13244
+ inFlightEvidenceEntries.add(evidenceKey);
13245
+ try {
13246
+ await _internals16.curateAndStoreSwarm(batch.lessons, batch.projectName, { phase_number: batch.phaseNumber }, directory, config, {
13247
+ llmDelegate: options.llmDelegateFactory?.(trigger.sessionID),
13248
+ enrichmentQuota: options.enrichmentQuota
13249
+ });
13250
+ recordSeenRetroSection(evidenceKey, batch.identity, Date.now());
13251
+ } catch (err) {
13252
+ warn(`Evidence curation failed for entry ${batch.identity}, will retry on next trigger: ${err instanceof Error ? err.message : String(err)}`);
13253
+ } finally {
13254
+ inFlightEvidenceEntries.delete(evidenceKey);
12938
13255
  }
12939
- } else if (Array.isArray(evidenceData.lessons_learned)) {
12940
- lessons = evidenceData.lessons_learned;
12941
- }
12942
- if (lessons.length === 0)
12943
- return;
12944
- const evidenceHash = hashContent(JSON.stringify(lessons));
12945
- if (lastSeenEvidence?.value === evidenceHash) {
12946
- return;
12947
13256
  }
12948
- recordSeenRetroSection(evidenceKey, evidenceHash, Date.now());
12949
- const projectName2 = evidenceData.project_name ?? "unknown";
12950
- const phaseNumber2 = typeof evidenceData.phase_number === "number" ? evidenceData.phase_number : 1;
12951
- await _internals15.curateAndStoreSwarm(lessons, projectName2, { phase_number: phaseNumber2 }, directory, config, {
12952
- llmDelegate: options.llmDelegateFactory?.(trigger.sessionID),
12953
- enrichmentQuota: options.enrichmentQuota
12954
- });
12955
13257
  return;
12956
13258
  }
12957
13259
  const planContent = await readSwarmFileAsync(directory, "plan.md");
@@ -12973,14 +13275,14 @@ function createKnowledgeCuratorHook(directory, config, options = {}) {
12973
13275
  const projectName = projectNameMatch ? projectNameMatch[1].trim() : "unknown";
12974
13276
  const phaseMatch = /^Phase:\s*(\d+)/m.exec(planContent);
12975
13277
  const phaseNumber = phaseMatch ? parseInt(phaseMatch[1], 10) : 1;
12976
- await _internals15.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config, {
13278
+ await _internals16.curateAndStoreSwarm(normalLessons, projectName, { phase_number: phaseNumber }, directory, config, {
12977
13279
  llmDelegate: options.llmDelegateFactory?.(trigger.sessionID),
12978
13280
  enrichmentQuota: options.enrichmentQuota
12979
13281
  });
12980
13282
  };
12981
13283
  return safeHook(handler);
12982
13284
  }
12983
- var _internals15 = {
13285
+ var _internals16 = {
12984
13286
  isWriteToEvidenceFile,
12985
13287
  curateAndStoreSwarm,
12986
13288
  runAutoPromotion,
@@ -12990,7 +13292,11 @@ var _internals15 = {
12990
13292
  recordSeenRetroSection,
12991
13293
  hashContent,
12992
13294
  capSeenRetroSections,
12993
- MAX_TRACKED_RETRO_SECTIONS
13295
+ MAX_TRACKED_RETRO_SECTIONS,
13296
+ inFlightEvidenceEntries,
13297
+ MAX_IN_FLIGHT_EVIDENCE_ENTRIES,
13298
+ extractEvidenceLessonBatches,
13299
+ realpath
12994
13300
  };
12995
13301
 
12996
13302
  // src/memory/finalize-reward-sweep.ts
@@ -13015,7 +13321,7 @@ async function runFinalizeRewardSweep(args) {
13015
13321
  return result;
13016
13322
  }
13017
13323
  const timestamp = args.timestamp ?? new Date().toISOString();
13018
- const provider = _internals16.createConfiguredMemoryProvider(directory, memoryConfig);
13324
+ const provider = _internals17.createConfiguredMemoryProvider(directory, memoryConfig);
13019
13325
  try {
13020
13326
  result.swept = true;
13021
13327
  for (const taskId of taskIds) {
@@ -13035,7 +13341,7 @@ async function runFinalizeRewardSweep(args) {
13035
13341
  }
13036
13342
  let taskRewarded = 0;
13037
13343
  for (const runId of runIds) {
13038
- const { memoriesRewarded } = await _internals16.applyCouncilReward(provider, {
13344
+ const { memoriesRewarded } = await _internals17.applyCouncilReward(provider, {
13039
13345
  runId,
13040
13346
  unitId: taskId,
13041
13347
  reward: FINALIZE_NEGATIVE_TERMINAL_REWARD,
@@ -13061,7 +13367,7 @@ async function runFinalizeRewardSweep(args) {
13061
13367
  }
13062
13368
  return result;
13063
13369
  }
13064
- var _internals16 = {
13370
+ var _internals17 = {
13065
13371
  createConfiguredMemoryProvider,
13066
13372
  applyCouncilReward
13067
13373
  };
@@ -14088,7 +14394,7 @@ async function reconcileStaleActiveSkills(directory, options = {}) {
14088
14394
  continue;
14089
14395
  }
14090
14396
  try {
14091
- const regen = await _internals17.regenerateSkill(directory, skill.slug, {
14397
+ const regen = await _internals18.regenerateSkill(directory, skill.slug, {
14092
14398
  evaluate: false
14093
14399
  });
14094
14400
  if (regen.regenerated) {
@@ -14338,7 +14644,7 @@ async function runSkillImprover(req) {
14338
14644
  autoApply
14339
14645
  };
14340
14646
  }
14341
- var _internals17 = {
14647
+ var _internals18 = {
14342
14648
  runSkillImprover,
14343
14649
  buildDeterministicProposal,
14344
14650
  buildLLMProposalFrame,
@@ -14741,13 +15047,13 @@ var write_retro = createSwarmTool({
14741
15047
  task_id: args.task_id !== undefined ? String(args.task_id) : undefined,
14742
15048
  metadata: args.metadata
14743
15049
  };
14744
- return await _internals18.executeWriteRetro(writeRetroArgs, directory);
15050
+ return await _internals19.executeWriteRetro(writeRetroArgs, directory);
14745
15051
  } catch {
14746
15052
  return JSON.stringify({ success: false, phase: rawPhase, message: "Invalid arguments" }, null, 2);
14747
15053
  }
14748
15054
  }
14749
15055
  });
14750
- var _internals18 = {
15056
+ var _internals19 = {
14751
15057
  executeWriteRetro,
14752
15058
  write_retro
14753
15059
  };
@@ -15046,8 +15352,8 @@ async function runFinalizeStage(ctx) {
15046
15352
  ];
15047
15353
  ctx.curationSucceeded = false;
15048
15354
  try {
15049
- ctx.curationResult = await _internals19.curateAndStoreSwarm(ctx.allLessons, ctx.projectName, { phase_number: 0 }, ctx.directory, ctx.config, {
15050
- llmDelegate: _internals19.createCuratorLLMDelegate(ctx.directory, "phase", ctx.options.sessionID),
15355
+ ctx.curationResult = await _internals20.curateAndStoreSwarm(ctx.allLessons, ctx.projectName, { phase_number: 0 }, ctx.directory, ctx.config, {
15356
+ llmDelegate: _internals20.createCuratorLLMDelegate(ctx.directory, "phase", ctx.options.sessionID),
15051
15357
  enrichmentQuota: {
15052
15358
  maxCalls: ctx.config.enrichment.max_calls_per_day,
15053
15359
  window: ctx.config.enrichment.quota_window
@@ -15066,7 +15372,7 @@ async function runFinalizeStage(ctx) {
15066
15372
  if (ctx.config.hive_enabled === false) {} else {
15067
15373
  try {
15068
15374
  const entries = await readKnowledge(resolveSwarmKnowledgePath(ctx.directory));
15069
- const result = await _internals19.checkHivePromotions(entries, ctx.config);
15375
+ const result = await _internals20.checkHivePromotions(entries, ctx.config);
15070
15376
  ctx.hivePromoted = result.new_promotions;
15071
15377
  } catch (hiveErr) {
15072
15378
  const msg = hiveErr instanceof Error ? hiveErr.message : String(hiveErr);
@@ -15087,7 +15393,7 @@ async function runFinalizeStage(ctx) {
15087
15393
  ctx.knowledgeSkillHint = ctx.sessionKnowledgeCreated > 0 ? `${ctx.sessionKnowledgeCreated} knowledge entries created this session. Consider running skill_improve or skill_generate to compile mature entries into skills.` : "";
15088
15394
  if (ctx.runSkillReview) {
15089
15395
  try {
15090
- const { config: loadedConfig } = _internals19.loadPluginConfigWithMeta(ctx.directory);
15396
+ const { config: loadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
15091
15397
  const skillImproverConfig = SkillImproverConfigSchema.parse(loadedConfig.skill_improver ?? {});
15092
15398
  const skillReviewResult = await runAbortableSkillReview({
15093
15399
  directory: ctx.directory,
@@ -15150,7 +15456,7 @@ async function runFinalizeStage(ctx) {
15150
15456
  }
15151
15457
  if (!ctx.planAlreadyDone || ctx.guaranteeResult.closedPhaseIds.length > 0 || ctx.guaranteeResult.closedTaskIds.length > 0) {
15152
15458
  try {
15153
- await _internals19.closePlanTerminalState(ctx.directory, ctx.planData, {
15459
+ await _internals20.closePlanTerminalState(ctx.directory, ctx.planData, {
15154
15460
  closedPhaseIds: ctx.guaranteeResult.closedPhaseIds,
15155
15461
  closedTaskIds: ctx.guaranteeResult.closedTaskIds,
15156
15462
  originalStatuses: ctx.originalStatuses
@@ -15166,12 +15472,12 @@ async function runFinalizeStage(ctx) {
15166
15472
  }
15167
15473
  }
15168
15474
  try {
15169
- const { CuratorConfigSchema: CCS } = await import("./schema-qb313fyy.js");
15170
- const { config: pmLoadedConfig } = _internals19.loadPluginConfigWithMeta(ctx.directory);
15475
+ const { CuratorConfigSchema: CCS } = await import("./schema-e5kd993s.js");
15476
+ const { config: pmLoadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
15171
15477
  const curatorCfg = CCS.parse(pmLoadedConfig.curator ?? {});
15172
15478
  if (curatorCfg.enabled && curatorCfg.postmortem_enabled) {
15173
- const pmResult = await _internals19.runCuratorPostMortem(ctx.directory, {
15174
- llmDelegate: _internals19.createCuratorLLMDelegate(ctx.directory, "postmortem", ctx.options.sessionID),
15479
+ const pmResult = await _internals20.runCuratorPostMortem(ctx.directory, {
15480
+ llmDelegate: _internals20.createCuratorLLMDelegate(ctx.directory, "postmortem", ctx.options.sessionID),
15175
15481
  scope: "project",
15176
15482
  sessionID: ctx.options.sessionID
15177
15483
  });
@@ -15197,7 +15503,7 @@ async function copySqliteSafe(srcPath, destPath, laneEnv) {
15197
15503
  }
15198
15504
  let checkpointVerified = false;
15199
15505
  try {
15200
- const result = _internals19.spawnSync("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
15506
+ const result = _internals20.spawnSync("sqlite3", [srcPath, "PRAGMA wal_checkpoint(TRUNCATE);"], {
15201
15507
  cwd: path29.dirname(srcPath),
15202
15508
  encoding: "utf-8",
15203
15509
  stdio: ["ignore", "pipe", "pipe"],
@@ -15368,7 +15674,7 @@ async function runArchiveEvidenceRetention(ctx) {
15368
15674
  let maxAgeDays = 30;
15369
15675
  let maxBundles = 10;
15370
15676
  try {
15371
- const { config: evidenceLoadedConfig } = _internals19.loadPluginConfigWithMeta(ctx.directory);
15677
+ const { config: evidenceLoadedConfig } = _internals20.loadPluginConfigWithMeta(ctx.directory);
15372
15678
  const evidenceCfg = evidenceLoadedConfig.evidence ?? {};
15373
15679
  if (typeof evidenceCfg.max_age_days === "number") {
15374
15680
  maxAgeDays = evidenceCfg.max_age_days;
@@ -15378,7 +15684,7 @@ async function runArchiveEvidenceRetention(ctx) {
15378
15684
  }
15379
15685
  } catch {}
15380
15686
  try {
15381
- await _internals19.archiveEvidence(ctx.directory, maxAgeDays, maxBundles);
15687
+ await _internals20.archiveEvidence(ctx.directory, maxAgeDays, maxBundles);
15382
15688
  } catch (error2) {
15383
15689
  const msg = error2 instanceof Error ? error2.message : String(error2);
15384
15690
  ctx.warnings.push(`Evidence retention archive failed: ${msg}`);
@@ -15579,9 +15885,9 @@ async function runAlignStage(ctx) {
15579
15885
  const pruneBranches = ctx.args.includes("--prune-branches");
15580
15886
  let gitAlignResult = "";
15581
15887
  const prunedBranches = [];
15582
- const gitStatus = _internals19.getGitRepositoryStatus(ctx.directory);
15888
+ const gitStatus = _internals20.getGitRepositoryStatus(ctx.directory);
15583
15889
  if (gitStatus.isRepo) {
15584
- const aggressiveResult = await _internals19.resetToMainAfterMerge(ctx.directory, {
15890
+ const aggressiveResult = await _internals20.resetToMainAfterMerge(ctx.directory, {
15585
15891
  pruneBranches
15586
15892
  });
15587
15893
  if (aggressiveResult.success) {
@@ -15593,7 +15899,7 @@ async function runAlignStage(ctx) {
15593
15899
  ctx.warnings.push("Uncommitted changes were discarded during git alignment");
15594
15900
  }
15595
15901
  } else {
15596
- const alignResult = await _internals19.resetToRemoteBranch(ctx.directory, {
15902
+ const alignResult = await _internals20.resetToRemoteBranch(ctx.directory, {
15597
15903
  pruneBranches
15598
15904
  });
15599
15905
  gitAlignResult = alignResult.message;
@@ -15653,7 +15959,7 @@ async function handleCloseCommand(directory, args, options = {}) {
15653
15959
  let finalizeLock = {
15654
15960
  acquired: false
15655
15961
  };
15656
- finalizeLock = await _internals19.acquireFinalizeLock(directory);
15962
+ finalizeLock = await _internals20.acquireFinalizeLock(directory);
15657
15963
  if (!finalizeLock.acquired) {
15658
15964
  return `\u274C Another /swarm finalize is already running for this project. If you are certain no other run is active, wait for the lock to expire or remove the stale lock and retry.`;
15659
15965
  }
@@ -15684,7 +15990,7 @@ This project was already finalized in a previous /swarm close run. The plan has
15684
15990
  if (planExists) {
15685
15991
  planAlreadyDone = phases.length > 0 && phases.every((p) => p.status === "complete" || p.status === "completed" || p.status === "blocked" || p.status === "closed");
15686
15992
  }
15687
- const { config: loadedConfig } = _internals19.loadPluginConfigWithMeta(directory);
15993
+ const { config: loadedConfig } = _internals20.loadPluginConfigWithMeta(directory);
15688
15994
  const config = KnowledgeConfigSchema.parse(loadedConfig.knowledge ?? {});
15689
15995
  const ctx = {
15690
15996
  directory,
@@ -15728,7 +16034,7 @@ This project was already finalized in a previous /swarm close run. The plan has
15728
16034
  args
15729
16035
  };
15730
16036
  await runFinalizeStage(ctx);
15731
- await _internals19.runFinalizeRewardSweep({
16037
+ await _internals20.runFinalizeRewardSweep({
15732
16038
  directory,
15733
16039
  closedTaskIds: ctx.guaranteeResult.closedTaskIds,
15734
16040
  memoryConfig: loadedConfig.memory
@@ -15809,9 +16115,9 @@ This project was already finalized in a previous /swarm close run. The plan has
15809
16115
  }
15810
16116
  const sessionIdsToEnd = [...swarmState.agentSessions.keys()];
15811
16117
  for (const sessionId of sessionIdsToEnd) {
15812
- _internals19.endAgentSession(sessionId);
16118
+ _internals20.endAgentSession(sessionId);
15813
16119
  }
15814
- _internals19.resetSwarmStatePreservingSingletons();
16120
+ _internals20.resetSwarmStatePreservingSingletons();
15815
16121
  const retroWarnings = ctx.warnings.filter((w) => w.includes("Retrospective write") || w.includes("retrospective write") || w.includes("Session retrospective"));
15816
16122
  const otherWarnings = ctx.warnings.filter((w) => !w.includes("Retrospective write") && !w.includes("retrospective write") && !w.includes("Session retrospective"));
15817
16123
  let warningMsg = "";
@@ -15880,7 +16186,7 @@ async function acquireFinalizeLock(directory) {
15880
16186
  }
15881
16187
  return { acquired: false };
15882
16188
  }
15883
- var _internals19 = {
16189
+ var _internals20 = {
15884
16190
  ACTIVE_STATE_DIRS_TO_CLEAN,
15885
16191
  countSessionKnowledgeEntries,
15886
16192
  CLOSE_SKILL_REVIEW_TIMEOUT_MS,
@@ -16727,9 +17033,9 @@ async function detectDarkMatter(directory, options) {
16727
17033
  } catch {
16728
17034
  return [];
16729
17035
  }
16730
- const commitMap = await _internals20.parseGitLog(directory, maxCommitsToAnalyze);
16731
- const matrix = _internals20.buildCoChangeMatrix(commitMap, maxFilesPerCommit);
16732
- const staticEdges = await _internals20.getStaticEdges(directory);
17036
+ const commitMap = await _internals21.parseGitLog(directory, maxCommitsToAnalyze);
17037
+ const matrix = _internals21.buildCoChangeMatrix(commitMap, maxFilesPerCommit);
17038
+ const staticEdges = await _internals21.getStaticEdges(directory);
16733
17039
  const results = [];
16734
17040
  for (const entry of matrix.values()) {
16735
17041
  const key = `${entry.fileA}::${entry.fileB}`;
@@ -16845,11 +17151,11 @@ var co_change_analyzer = createSwarmTool({
16845
17151
  npmiThreshold,
16846
17152
  maxCommitsToAnalyze
16847
17153
  };
16848
- const pairs = await _internals20.detectDarkMatter(directory, options);
16849
- return _internals20.formatDarkMatterOutput(pairs);
17154
+ const pairs = await _internals21.detectDarkMatter(directory, options);
17155
+ return _internals21.formatDarkMatterOutput(pairs);
16850
17156
  }
16851
17157
  });
16852
- var _internals20 = {
17158
+ var _internals21 = {
16853
17159
  parseGitLog,
16854
17160
  buildCoChangeMatrix,
16855
17161
  getStaticEdges,
@@ -16866,7 +17172,7 @@ var DEFAULT_MAX_COMMITS = 500;
16866
17172
  var cache = new Map;
16867
17173
  async function readGitHead(directory) {
16868
17174
  try {
16869
- const { stdout } = await _internals21.execFile("git", ["rev-parse", "HEAD"], {
17175
+ const { stdout } = await _internals22.execFile("git", ["rev-parse", "HEAD"], {
16870
17176
  cwd: directory,
16871
17177
  timeout: GIT_HEAD_TIMEOUT_MS
16872
17178
  });
@@ -16892,9 +17198,9 @@ async function getCoChangeData(directory, options) {
16892
17198
  let entries;
16893
17199
  let commitsObserved;
16894
17200
  try {
16895
- const commitMap = await _internals21.parseGitLog(directory, maxCommits);
17201
+ const commitMap = await _internals22.parseGitLog(directory, maxCommits);
16896
17202
  commitsObserved = commitMap.size;
16897
- const matrix = _internals21.buildCoChangeMatrix(commitMap);
17203
+ const matrix = _internals22.buildCoChangeMatrix(commitMap);
16898
17204
  entries = Array.from(matrix.values());
16899
17205
  } catch {
16900
17206
  return { pairs: [], commitsObserved: 0 };
@@ -16918,10 +17224,10 @@ async function getCoChangePairs(directory, options) {
16918
17224
  const data = await getCoChangeData(directory, options);
16919
17225
  return data.pairs;
16920
17226
  }
16921
- var _internals21 = {
17227
+ var _internals22 = {
16922
17228
  execFile: execFileAsync,
16923
- parseGitLog: _internals20.parseGitLog,
16924
- buildCoChangeMatrix: _internals20.buildCoChangeMatrix
17229
+ parseGitLog: _internals21.parseGitLog,
17230
+ buildCoChangeMatrix: _internals21.buildCoChangeMatrix
16925
17231
  };
16926
17232
 
16927
17233
  // src/turbo/epic/cochange-conflict.ts
@@ -17203,7 +17509,7 @@ async function handleCouplingCommand(directory, args) {
17203
17509
 
17204
17510
  Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>] [--format markdown|json] [--persist]`;
17205
17511
  }
17206
- const plan = await _internals22.loadPlanJsonOnly(directory);
17512
+ const plan = await _internals23.loadPlanJsonOnly(directory);
17207
17513
  if (plan === null) {
17208
17514
  return "No plan found at `.swarm/plan.json`. Run `/swarm plan` to create one before measuring coupling.";
17209
17515
  }
@@ -17227,7 +17533,7 @@ Usage: /swarm coupling [--phase <n>] [--threshold <-1..1>] [--min-co-changes <n>
17227
17533
  const scope = scopeFiles ?? task.files_touched ?? [];
17228
17534
  return { id: task.id, scope };
17229
17535
  });
17230
- const cochangePairs = await _internals22.getCoChangePairs(directory);
17536
+ const cochangePairs = await _internals23.getCoChangePairs(directory);
17231
17537
  const report = computeCouplingReport(tasks, cochangePairs, {
17232
17538
  npmi: parsed.threshold,
17233
17539
  minCoChanges: parsed.minCoChanges
@@ -17266,22 +17572,22 @@ _Warning: failed to persist report (${persistStatus.error})._`;
17266
17572
  }
17267
17573
  return `${formatCouplingReportMarkdown(report)}${persistTrailer}`;
17268
17574
  }
17269
- var _internals22 = {
17575
+ var _internals23 = {
17270
17576
  loadPlanJsonOnly,
17271
17577
  getCoChangePairs
17272
17578
  };
17273
17579
 
17274
17580
  // src/commands/curate.ts
17275
- var _internals23 = {
17581
+ var _internals24 = {
17276
17582
  checkHivePromotions,
17277
17583
  readKnowledge,
17278
17584
  resolveSwarmKnowledgePath,
17279
17585
  readSwarmFileAsync,
17280
17586
  loadCuratorDeps: async () => {
17281
17587
  const [{ CuratorConfigSchema }, curator, { createCuratorLLMDelegate: createCuratorLLMDelegate2 }] = await Promise.all([
17282
- import("./schema-qb313fyy.js"),
17283
- import("./curator-9s04amtf.js"),
17284
- import("./curator-llm-factory-dwvk7rh0.js")
17588
+ import("./schema-e5kd993s.js"),
17589
+ import("./curator-nh9raf1a.js"),
17590
+ import("./curator-llm-factory-b3g0g0cd.js")
17285
17591
  ]);
17286
17592
  return { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 };
17287
17593
  }
@@ -17289,15 +17595,15 @@ var _internals23 = {
17289
17595
  async function handleCurateCommand(directory, _args, options) {
17290
17596
  try {
17291
17597
  const config = KnowledgeConfigSchema.parse({});
17292
- const swarmPath = _internals23.resolveSwarmKnowledgePath(directory);
17293
- const swarmEntries = await _internals23.readKnowledge(swarmPath) ?? [];
17294
- const summary = await _internals23.checkHivePromotions(swarmEntries, config);
17598
+ const swarmPath = _internals24.resolveSwarmKnowledgePath(directory);
17599
+ const swarmEntries = await _internals24.readKnowledge(swarmPath) ?? [];
17600
+ const summary = await _internals24.checkHivePromotions(swarmEntries, config);
17295
17601
  if (options?.sessionID) {
17296
17602
  let onDemandPhase = 1;
17297
17603
  try {
17298
- const { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 } = await _internals23.loadCuratorDeps();
17604
+ const { CuratorConfigSchema, curator, createCuratorLLMDelegate: createCuratorLLMDelegate2 } = await _internals24.loadCuratorDeps();
17299
17605
  const curatorConfig = CuratorConfigSchema.parse({});
17300
- const priorSummary = await _internals23.readSwarmFileAsync(directory, "curator-summary.json");
17606
+ const priorSummary = await _internals24.readSwarmFileAsync(directory, "curator-summary.json");
17301
17607
  if (priorSummary) {
17302
17608
  try {
17303
17609
  const parsed = JSON.parse(priorSummary);
@@ -17308,7 +17614,7 @@ async function handleCurateCommand(directory, _args, options) {
17308
17614
  }
17309
17615
  let planPhaseCount = Infinity;
17310
17616
  try {
17311
- const planRaw = await _internals23.readSwarmFileAsync(directory, "plan.json");
17617
+ const planRaw = await _internals24.readSwarmFileAsync(directory, "plan.json");
17312
17618
  if (planRaw) {
17313
17619
  const plan = JSON.parse(planRaw);
17314
17620
  if (Array.isArray(plan.phases))
@@ -17327,8 +17633,8 @@ async function handleCurateCommand(directory, _args, options) {
17327
17633
  summary.knowledge_skipped = applied.skipped;
17328
17634
  summary.curator_phase = onDemandPhase;
17329
17635
  try {
17330
- const updatedEntries = await _internals23.readKnowledge(swarmPath) ?? [];
17331
- const postUpdateHive = await _internals23.checkHivePromotions(updatedEntries, config);
17636
+ const updatedEntries = await _internals24.readKnowledge(swarmPath) ?? [];
17637
+ const postUpdateHive = await _internals24.checkHivePromotions(updatedEntries, config);
17332
17638
  summary.new_promotions += postUpdateHive.new_promotions;
17333
17639
  summary.encounters_incremented += postUpdateHive.encounters_incremented;
17334
17640
  summary.advancements += postUpdateHive.advancements;
@@ -17393,7 +17699,7 @@ async function handleDarkMatterCommand(directory, args) {
17393
17699
  }
17394
17700
  let pairs;
17395
17701
  try {
17396
- pairs = await _internals20.detectDarkMatter(directory, options);
17702
+ pairs = await _internals21.detectDarkMatter(directory, options);
17397
17703
  } catch (err) {
17398
17704
  const errMsg = err instanceof Error ? err.message : String(err);
17399
17705
  return `## Dark Matter Analysis Failed
@@ -17777,7 +18083,7 @@ import { fileURLToPath } from "url";
17777
18083
  // package.json
17778
18084
  var package_default = {
17779
18085
  name: "opencode-swarm",
17780
- version: "7.113.2",
18086
+ version: "7.113.4",
17781
18087
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
17782
18088
  main: "dist/index.js",
17783
18089
  types: "dist/index.d.ts",
@@ -17817,6 +18123,7 @@ var package_default = {
17817
18123
  files: [
17818
18124
  "dist",
17819
18125
  "dist/lang/grammars",
18126
+ "binaries",
17820
18127
  ".opencode/skills/brainstorm",
17821
18128
  ".opencode/skills/specify",
17822
18129
  ".opencode/skills/clarify-spec",
@@ -18229,7 +18536,7 @@ function resolveCachePackageRoot(cachePath) {
18229
18536
  const nestedPackageRoot = path36.join(cachePath, "node_modules", "opencode-swarm");
18230
18537
  return existsSync23(nestedPackageRoot) ? nestedPackageRoot : cachePath;
18231
18538
  }
18232
- var _internals24 = {
18539
+ var _internals25 = {
18233
18540
  detectSandboxCapability: () => sandboxCapabilityProbe.detect(),
18234
18541
  getSandboxExecutor: getExecutor
18235
18542
  };
@@ -18813,15 +19120,24 @@ async function checkCurator(directory) {
18813
19120
  }
18814
19121
  async function getSandboxStatus() {
18815
19122
  try {
18816
- const capability = await _internals24.detectSandboxCapability();
19123
+ const capability = await _internals25.detectSandboxCapability();
18817
19124
  const mechanism = capability.mechanism ?? "none";
18818
- const executor = await _internals24.getSandboxExecutor();
19125
+ const executor = await _internals25.getSandboxExecutor();
18819
19126
  const hasExecutor = executor !== null;
18820
19127
  if (hasExecutor) {
19128
+ const executorStrength = executor?.strength;
19129
+ const strength = executorStrength === "weak" || executorStrength === "advisory" ? "advisory" : capability.strength ?? executorStrength ?? "strong";
19130
+ if (strength === "advisory") {
19131
+ return {
19132
+ name: "Sandbox",
19133
+ status: "\u26A0\uFE0F",
19134
+ detail: `Mechanism: ${mechanism.toLowerCase()} | Available: advisory only | Strength: ADVISORY (env-scrub, NOT kernel-enforced) | Commands are NOT strongly sandboxed`
19135
+ };
19136
+ }
18821
19137
  return {
18822
19138
  name: "Sandbox",
18823
19139
  status: "\u2705",
18824
- detail: `Mechanism: ${mechanism.toLowerCase()} | Available: yes | Sandboxing commands: yes`
19140
+ detail: `Mechanism: ${mechanism.toLowerCase()} | Available: yes | Strength: strong (kernel-enforced) | Sandboxing commands: yes`
18825
19141
  };
18826
19142
  }
18827
19143
  if (mechanism !== "none") {
@@ -19237,7 +19553,7 @@ async function handleDoctorCommand(directory, args) {
19237
19553
  const result = runConfigDoctor(config, directory);
19238
19554
  let output;
19239
19555
  if (enableAutoFix && result.hasAutoFixableIssues) {
19240
- const { runConfigDoctorWithFixes } = await import("./config-doctor-az11cwf5.js");
19556
+ const { runConfigDoctorWithFixes } = await import("./config-doctor-xbdfrbwt.js");
19241
19557
  const fixResult = await runConfigDoctorWithFixes(directory, config, true);
19242
19558
  output = formatDoctorMarkdown(fixResult.result);
19243
19559
  } else {
@@ -19558,7 +19874,7 @@ function readPromotionEvidence(directory) {
19558
19874
  }
19559
19875
 
19560
19876
  // src/commands/epic.ts
19561
- var _internals25 = {
19877
+ var _internals26 = {
19562
19878
  loadPluginConfigWithMeta,
19563
19879
  loadPlanJsonOnly,
19564
19880
  getCoChangeData,
@@ -19580,7 +19896,7 @@ async function handleEpicCommand(directory, args, sessionID) {
19580
19896
  if (!sessionID || sessionID.trim() === "") {
19581
19897
  return "Error: No active session context. Epic Mode requires an active session. Use /swarm epic from within an OpenCode session.";
19582
19898
  }
19583
- const session = _internals25.ensureAgentSession(sessionID, undefined, directory);
19899
+ const session = _internals26.ensureAgentSession(sessionID, undefined, directory);
19584
19900
  const arg0 = args[0]?.toLowerCase();
19585
19901
  switch (arg0) {
19586
19902
  case "status":
@@ -19607,7 +19923,7 @@ Usage:
19607
19923
  }
19608
19924
  function enableAndAck(directory, sessionID, session) {
19609
19925
  try {
19610
- _internals25.enableEpicMode(directory, sessionID);
19926
+ _internals26.enableEpicMode(directory, sessionID);
19611
19927
  } catch (err) {
19612
19928
  return `Error enabling Epic Mode: ${err instanceof Error ? err.message : String(err)}`;
19613
19929
  }
@@ -19623,7 +19939,7 @@ function enableAndAck(directory, sessionID, session) {
19623
19939
  }
19624
19940
  function disableAndAck(directory, sessionID, session) {
19625
19941
  try {
19626
- _internals25.disableEpicMode(directory, sessionID);
19942
+ _internals26.disableEpicMode(directory, sessionID);
19627
19943
  } catch (err) {
19628
19944
  return `Error disabling Epic Mode: ${err instanceof Error ? err.message : String(err)}`;
19629
19945
  }
@@ -19632,12 +19948,12 @@ function disableAndAck(directory, sessionID, session) {
19632
19948
  }
19633
19949
  function renderStatus(directory, sessionID) {
19634
19950
  const lines = ["## Epic Mode \u2014 Status", ""];
19635
- if (_internals25.isStateUnreadable(directory)) {
19951
+ if (_internals26.isStateUnreadable(directory)) {
19636
19952
  lines.push("**Epic Mode state is unreadable** (`.swarm/epic-state.json` is corrupt or has an unexpected shape). Status cannot be reported until the file is repaired or removed. The fail-closed marker means `epic_decide_phase` will refuse to compute a verdict in this state.");
19637
19953
  return lines.join(`
19638
19954
  `);
19639
19955
  }
19640
- const state = _internals25.loadEpicSessionState(directory, sessionID);
19956
+ const state = _internals26.loadEpicSessionState(directory, sessionID);
19641
19957
  if (!state) {
19642
19958
  lines.push("Epic Mode has not been toggled for this session.");
19643
19959
  return lines.join(`
@@ -19689,7 +20005,7 @@ function formatGreenfieldDetail(input) {
19689
20005
  function renderLast(directory) {
19690
20006
  let records;
19691
20007
  try {
19692
- records = _internals25.readPromotionEvidence(directory);
20008
+ records = _internals26.readPromotionEvidence(directory);
19693
20009
  } catch (err) {
19694
20010
  return `Error reading epic-promotions.jsonl: ${err instanceof Error ? err.message : String(err)}`;
19695
20011
  }
@@ -19744,7 +20060,7 @@ function renderLast(directory) {
19744
20060
  `);
19745
20061
  }
19746
20062
  function renderCalibration(directory) {
19747
- if (_internals25.isCalibrationStateUnreadable(directory)) {
20063
+ if (_internals26.isCalibrationStateUnreadable(directory)) {
19748
20064
  return [
19749
20065
  "## Epic Mode \u2014 Calibration",
19750
20066
  "",
@@ -19756,11 +20072,11 @@ function renderCalibration(directory) {
19756
20072
  }
19757
20073
  let state;
19758
20074
  try {
19759
- state = _internals25.loadCalibrationState(directory);
20075
+ state = _internals26.loadCalibrationState(directory);
19760
20076
  } catch (err) {
19761
20077
  return `Error reading calibration state: ${err instanceof Error ? err.message : String(err)}`;
19762
20078
  }
19763
- const { config } = _internals25.loadPluginConfigWithMeta(directory);
20079
+ const { config } = _internals26.loadPluginConfigWithMeta(directory);
19764
20080
  const staticThreshold = config.turbo?.epic?.mode?.activation_threshold ?? 0.3;
19765
20081
  const calibrationCfg = config.turbo?.epic?.calibration;
19766
20082
  const loosenWindow = calibrationCfg?.loosen_window ?? 10;
@@ -19808,7 +20124,7 @@ function renderCalibration(directory) {
19808
20124
  lines.push("");
19809
20125
  let recentDivergent = [];
19810
20126
  try {
19811
- const all = _internals25.readDivergenceHistory(directory, { limit: 50 });
20127
+ const all = _internals26.readDivergenceHistory(directory, { limit: 50 });
19812
20128
  recentDivergent = all.filter((r) => !r.isClean).slice(-5);
19813
20129
  } catch {}
19814
20130
  lines.push("### Recent divergent tasks (tightened the threshold)");
@@ -19825,11 +20141,11 @@ function renderCalibration(directory) {
19825
20141
  `);
19826
20142
  }
19827
20143
  async function renderDecide(directory) {
19828
- const plan = await _internals25.loadPlanJsonOnly(directory);
20144
+ const plan = await _internals26.loadPlanJsonOnly(directory);
19829
20145
  if (!plan) {
19830
20146
  return "No plan found at `.swarm/plan.json`. Run `/swarm plan` first.";
19831
20147
  }
19832
- const { config } = _internals25.loadPluginConfigWithMeta(directory);
20148
+ const { config } = _internals26.loadPluginConfigWithMeta(directory);
19833
20149
  const modeCfg = config.turbo?.epic?.mode;
19834
20150
  const cochangeCfg = config.turbo?.epic?.cochange;
19835
20151
  const activationThreshold = modeCfg?.activation_threshold ?? 0.3;
@@ -19839,20 +20155,20 @@ async function renderDecide(directory) {
19839
20155
  const tasks = [];
19840
20156
  for (const phase of plan.phases) {
19841
20157
  for (const task of phase.tasks) {
19842
- const scopeFiles = _internals25.readTaskScopes(directory, task.id);
20158
+ const scopeFiles = _internals26.readTaskScopes(directory, task.id);
19843
20159
  const scope = scopeFiles ?? task.files_touched ?? [];
19844
20160
  tasks.push({ id: task.id, scope });
19845
20161
  }
19846
20162
  }
19847
- const { pairs, commitsObserved } = await _internals25.getCoChangeData(directory);
20163
+ const { pairs, commitsObserved } = await _internals26.getCoChangeData(directory);
19848
20164
  const isGitProject = (() => {
19849
20165
  try {
19850
- return _internals25.isGitRepo(directory);
20166
+ return _internals26.isGitRepo(directory);
19851
20167
  } catch {
19852
20168
  return false;
19853
20169
  }
19854
20170
  })();
19855
- const verdict = _internals25.decideEpicActivation(tasks, pairs, commitsObserved, {
20171
+ const verdict = _internals26.decideEpicActivation(tasks, pairs, commitsObserved, {
19856
20172
  activationThreshold,
19857
20173
  minCommitsForSignal,
19858
20174
  cochangeNpmiThreshold,
@@ -19896,7 +20212,7 @@ function formatVerdict(verdict) {
19896
20212
  }
19897
20213
 
19898
20214
  // src/services/evidence-service.ts
19899
- var _internals26 = {
20215
+ var _internals27 = {
19900
20216
  loadEvidence,
19901
20217
  listEvidenceTaskIds
19902
20218
  };
@@ -19941,7 +20257,7 @@ function getVerdictEmoji(verdict) {
19941
20257
  return getVerdictIcon(verdict);
19942
20258
  }
19943
20259
  async function getTaskEvidenceData(directory, taskId) {
19944
- const result = await _internals26.loadEvidence(directory, taskId);
20260
+ const result = await _internals27.loadEvidence(directory, taskId);
19945
20261
  if (result.status !== "found") {
19946
20262
  return {
19947
20263
  hasEvidence: false,
@@ -19964,13 +20280,13 @@ async function getTaskEvidenceData(directory, taskId) {
19964
20280
  };
19965
20281
  }
19966
20282
  async function getEvidenceListData(directory) {
19967
- const taskIds = await _internals26.listEvidenceTaskIds(directory);
20283
+ const taskIds = await _internals27.listEvidenceTaskIds(directory);
19968
20284
  if (taskIds.length === 0) {
19969
20285
  return { hasEvidence: false, tasks: [] };
19970
20286
  }
19971
20287
  const tasks = [];
19972
20288
  for (const taskId of taskIds) {
19973
- const result = await _internals26.loadEvidence(directory, taskId);
20289
+ const result = await _internals27.loadEvidence(directory, taskId);
19974
20290
  if (result.status === "found") {
19975
20291
  tasks.push({
19976
20292
  taskId,
@@ -20050,7 +20366,7 @@ async function handleEvidenceCommand(directory, args) {
20050
20366
  return formatTaskEvidenceMarkdown(evidenceData);
20051
20367
  }
20052
20368
  async function handleEvidenceSummaryCommand(directory) {
20053
- const { buildEvidenceSummary } = await import("./evidence-summary-service-w1er1ea2.js");
20369
+ const { buildEvidenceSummary } = await import("./evidence-summary-service-8g594znj.js");
20054
20370
  const artifact = await buildEvidenceSummary(directory);
20055
20371
  if (!artifact) {
20056
20372
  return "No plan found. Run `/swarm plan` to check plan status.";
@@ -20598,7 +20914,7 @@ function extractCurrentPhaseFromPlan(plan) {
20598
20914
  if (!plan) {
20599
20915
  return { currentPhase: null, currentTask: null, incompleteTasks: [] };
20600
20916
  }
20601
- if (!_internals27.validatePlanPhases(plan)) {
20917
+ if (!_internals28.validatePlanPhases(plan)) {
20602
20918
  return { currentPhase: null, currentTask: null, incompleteTasks: [] };
20603
20919
  }
20604
20920
  let currentPhase = null;
@@ -20740,9 +21056,9 @@ function extractPhaseMetrics(content) {
20740
21056
  async function getHandoffData(directory) {
20741
21057
  const now = new Date().toISOString();
20742
21058
  const sessionContent = await readSwarmFileAsync(directory, "session/state.json");
20743
- const sessionState = _internals27.parseSessionState(sessionContent);
21059
+ const sessionState = _internals28.parseSessionState(sessionContent);
20744
21060
  const plan = await loadPlanJsonOnly(directory);
20745
- const planInfo = _internals27.extractCurrentPhaseFromPlan(plan);
21061
+ const planInfo = _internals28.extractCurrentPhaseFromPlan(plan);
20746
21062
  if (!plan) {
20747
21063
  const planMdContent = await readSwarmFileAsync(directory, "plan.md");
20748
21064
  if (planMdContent) {
@@ -20761,8 +21077,8 @@ async function getHandoffData(directory) {
20761
21077
  }
20762
21078
  }
20763
21079
  const contextContent = await readSwarmFileAsync(directory, "context.md");
20764
- const recentDecisions = _internals27.extractDecisions(contextContent);
20765
- const rawPhaseMetrics = _internals27.extractPhaseMetrics(contextContent);
21080
+ const recentDecisions = _internals28.extractDecisions(contextContent);
21081
+ const rawPhaseMetrics = _internals28.extractPhaseMetrics(contextContent);
20766
21082
  const phaseMetrics = sanitizeString(rawPhaseMetrics, 1000);
20767
21083
  let delegationState = null;
20768
21084
  if (sessionState?.delegationState) {
@@ -20926,7 +21242,7 @@ ${lines.join(`
20926
21242
  `)}
20927
21243
  \`\`\``;
20928
21244
  }
20929
- var _internals27 = {
21245
+ var _internals28 = {
20930
21246
  getHandoffData,
20931
21247
  formatHandoffMarkdown,
20932
21248
  formatContinuationPrompt,
@@ -21075,15 +21391,15 @@ async function writeSnapshot(directory, state) {
21075
21391
  }
21076
21392
  function createSnapshotWriterHook(directory) {
21077
21393
  return (_input, _output) => {
21078
- _writeInFlight = _writeInFlight.then(() => _internals28.writeSnapshot(directory, swarmState), () => _internals28.writeSnapshot(directory, swarmState));
21394
+ _writeInFlight = _writeInFlight.then(() => _internals29.writeSnapshot(directory, swarmState), () => _internals29.writeSnapshot(directory, swarmState));
21079
21395
  return _writeInFlight;
21080
21396
  };
21081
21397
  }
21082
21398
  async function flushPendingSnapshot(directory) {
21083
- _writeInFlight = _writeInFlight.then(() => _internals28.writeSnapshot(directory, swarmState), () => _internals28.writeSnapshot(directory, swarmState));
21399
+ _writeInFlight = _writeInFlight.then(() => _internals29.writeSnapshot(directory, swarmState), () => _internals29.writeSnapshot(directory, swarmState));
21084
21400
  await _writeInFlight;
21085
21401
  }
21086
- var _internals28 = {
21402
+ var _internals29 = {
21087
21403
  writeSnapshot,
21088
21404
  createSnapshotWriterHook,
21089
21405
  flushPendingSnapshot
@@ -21291,7 +21607,7 @@ var IPV4_PRIVATE_192 = /^192\.168\./;
21291
21607
  var IPV4_ZERO_NETWORK = /^0\./;
21292
21608
  var IPV6_LINK_LOCAL = /^fe80:/i;
21293
21609
  var IPV6_UNIQUE_LOCAL = /^f[cd][0-9a-f]{2}:/i;
21294
- var _internals29 = {
21610
+ var _internals30 = {
21295
21611
  spawnSync: (cmd, args, options) => {
21296
21612
  const mergedEnv = mergeEnvForChild(options?.env, options?.envOverrides);
21297
21613
  return child_process6.spawnSync(cmd, args, {
@@ -21409,7 +21725,7 @@ function validateAndSanitizeGithubUrl(rawUrl, resource) {
21409
21725
  }
21410
21726
  function detectGitRemote(cwd, laneEnv) {
21411
21727
  try {
21412
- const result = _internals29.spawnSync("git", ["remote", "get-url", "origin"], {
21728
+ const result = _internals30.spawnSync("git", ["remote", "get-url", "origin"], {
21413
21729
  encoding: "utf-8",
21414
21730
  stdio: ["ignore", "pipe", "pipe"],
21415
21731
  timeout: 5000,
@@ -21586,7 +21902,7 @@ import * as path42 from "path";
21586
21902
  async function migrateKnowledgeToExternal(_directory, _config) {
21587
21903
  const externalSentinelPath = path42.join(_directory, ".swarm", ".knowledge-external-migrated");
21588
21904
  const contextPath = path42.join(_directory, ".swarm", "context.md");
21589
- if (_internals30.existsSync(externalSentinelPath)) {
21905
+ if (_internals31.existsSync(externalSentinelPath)) {
21590
21906
  return {
21591
21907
  migrated: false,
21592
21908
  entriesMigrated: 0,
@@ -21595,7 +21911,7 @@ async function migrateKnowledgeToExternal(_directory, _config) {
21595
21911
  skippedReason: "external-sentinel-exists"
21596
21912
  };
21597
21913
  }
21598
- if (!_internals30.existsSync(contextPath)) {
21914
+ if (!_internals31.existsSync(contextPath)) {
21599
21915
  return {
21600
21916
  migrated: false,
21601
21917
  entriesMigrated: 0,
@@ -21604,7 +21920,7 @@ async function migrateKnowledgeToExternal(_directory, _config) {
21604
21920
  skippedReason: "no-context-file"
21605
21921
  };
21606
21922
  }
21607
- const contextContent = await _internals30.readFile(contextPath, "utf-8");
21923
+ const contextContent = await _internals31.readFile(contextPath, "utf-8");
21608
21924
  if (contextContent.trim().length === 0) {
21609
21925
  return {
21610
21926
  migrated: false,
@@ -21622,7 +21938,7 @@ async function migrateKnowledgeToExternal(_directory, _config) {
21622
21938
  entriesCount++;
21623
21939
  }
21624
21940
  }
21625
- await _internals30.writeSentinel(externalSentinelPath, entriesCount, entriesCount);
21941
+ await _internals31.writeSentinel(externalSentinelPath, entriesCount, entriesCount);
21626
21942
  return {
21627
21943
  migrated: true,
21628
21944
  entriesMigrated: entriesCount,
@@ -21630,7 +21946,7 @@ async function migrateKnowledgeToExternal(_directory, _config) {
21630
21946
  entriesTotal: entriesCount
21631
21947
  };
21632
21948
  }
21633
- var _internals30 = {
21949
+ var _internals31 = {
21634
21950
  appendKnowledge,
21635
21951
  migrateContextToKnowledge,
21636
21952
  migrateKnowledgeToExternal,
@@ -21681,9 +21997,9 @@ async function migrateContextToKnowledge(directory, config) {
21681
21997
  skippedReason: "empty-context"
21682
21998
  };
21683
21999
  }
21684
- const rawEntries = _internals30.parseContextMd(contextContent);
22000
+ const rawEntries = _internals31.parseContextMd(contextContent);
21685
22001
  if (rawEntries.length === 0) {
21686
- await _internals30.writeSentinel(sentinelPath, 0, 0);
22002
+ await _internals31.writeSentinel(sentinelPath, 0, 0);
21687
22003
  return {
21688
22004
  migrated: true,
21689
22005
  entriesMigrated: 0,
@@ -21694,10 +22010,10 @@ async function migrateContextToKnowledge(directory, config) {
21694
22010
  const existing = await readKnowledge(knowledgePath);
21695
22011
  let migrated = 0;
21696
22012
  let dropped = 0;
21697
- const projectName = _internals30.inferProjectName(directory);
22013
+ const projectName = _internals31.inferProjectName(directory);
21698
22014
  for (const raw of rawEntries) {
21699
22015
  if (config.validation_enabled !== false) {
21700
- const category = raw.categoryHint ?? _internals30.inferCategoryFromText(raw.text);
22016
+ const category = raw.categoryHint ?? _internals31.inferCategoryFromText(raw.text);
21701
22017
  const result = validateLesson(raw.text, existing.map((e) => e.lesson), {
21702
22018
  category,
21703
22019
  scope: "global",
@@ -21717,8 +22033,8 @@ async function migrateContextToKnowledge(directory, config) {
21717
22033
  const entry = {
21718
22034
  id: randomUUID6(),
21719
22035
  tier: "swarm",
21720
- lesson: _internals30.truncateLesson(raw.text),
21721
- category: raw.categoryHint ?? _internals30.inferCategoryFromText(raw.text),
22036
+ lesson: _internals31.truncateLesson(raw.text),
22037
+ category: raw.categoryHint ?? _internals31.inferCategoryFromText(raw.text),
21722
22038
  tags: [...inferredTags, `migration:${raw.sourceSection}`],
21723
22039
  scope: "global",
21724
22040
  confidence: 0.3,
@@ -21741,7 +22057,7 @@ async function migrateContextToKnowledge(directory, config) {
21741
22057
  if (migrated > 0) {
21742
22058
  await rewriteKnowledge(knowledgePath, existing);
21743
22059
  }
21744
- await _internals30.writeSentinel(sentinelPath, migrated, dropped);
22060
+ await _internals31.writeSentinel(sentinelPath, migrated, dropped);
21745
22061
  log(`[knowledge-migrator] Migrated ${migrated} entries, dropped ${dropped}`);
21746
22062
  return {
21747
22063
  migrated: true,
@@ -21751,7 +22067,7 @@ async function migrateContextToKnowledge(directory, config) {
21751
22067
  };
21752
22068
  }
21753
22069
  async function migrateHiveKnowledgeLegacy(config) {
21754
- const legacyHivePath = _internals30.resolveLegacyHiveKnowledgePath();
22070
+ const legacyHivePath = _internals31.resolveLegacyHiveKnowledgePath();
21755
22071
  const canonicalHivePath = resolveHiveKnowledgePath();
21756
22072
  const sentinelPath = path42.join(path42.dirname(canonicalHivePath), ".hive-knowledge-migrated");
21757
22073
  if (existsSync28(sentinelPath)) {
@@ -21774,7 +22090,7 @@ async function migrateHiveKnowledgeLegacy(config) {
21774
22090
  }
21775
22091
  const legacyEntries = await readKnowledge(legacyHivePath);
21776
22092
  if (legacyEntries.length === 0) {
21777
- await _internals30.writeSentinel(sentinelPath, 0, 0);
22093
+ await _internals31.writeSentinel(sentinelPath, 0, 0);
21778
22094
  return {
21779
22095
  migrated: true,
21780
22096
  entriesMigrated: 0,
@@ -21822,7 +22138,7 @@ async function migrateHiveKnowledgeLegacy(config) {
21822
22138
  const newHiveEntry = {
21823
22139
  id: resolvedId,
21824
22140
  tier: "hive",
21825
- lesson: _internals30.truncateLesson(lesson),
22141
+ lesson: _internals31.truncateLesson(lesson),
21826
22142
  category,
21827
22143
  tags: ["migration:legacy-hive"],
21828
22144
  scope: scopeTag,
@@ -21841,7 +22157,7 @@ async function migrateHiveKnowledgeLegacy(config) {
21841
22157
  encounter_score: 1
21842
22158
  };
21843
22159
  try {
21844
- await _internals30.appendKnowledge(canonicalHivePath, newHiveEntry);
22160
+ await _internals31.appendKnowledge(canonicalHivePath, newHiveEntry);
21845
22161
  existingHiveEntries.push(newHiveEntry);
21846
22162
  migrated++;
21847
22163
  } catch (appendError) {
@@ -21857,7 +22173,7 @@ async function migrateHiveKnowledgeLegacy(config) {
21857
22173
  dropped++;
21858
22174
  }
21859
22175
  }
21860
- await _internals30.writeSentinel(sentinelPath, migrated, dropped);
22176
+ await _internals31.writeSentinel(sentinelPath, migrated, dropped);
21861
22177
  log(`[knowledge-migrator] Migrated ${migrated} legacy hive entries, dropped ${dropped}`);
21862
22178
  return {
21863
22179
  migrated: true,
@@ -21868,7 +22184,7 @@ async function migrateHiveKnowledgeLegacy(config) {
21868
22184
  };
21869
22185
  }
21870
22186
  function parseContextMd(content) {
21871
- const sections = _internals30.splitIntoSections(content);
22187
+ const sections = _internals31.splitIntoSections(content);
21872
22188
  const entries = [];
21873
22189
  const seen = new Set;
21874
22190
  const sectionPatterns = [
@@ -21884,7 +22200,7 @@ function parseContextMd(content) {
21884
22200
  const match = sectionPatterns.find((sp) => sp.pattern.test(section.heading));
21885
22201
  if (!match)
21886
22202
  continue;
21887
- const bullets = _internals30.extractBullets(section.body);
22203
+ const bullets = _internals31.extractBullets(section.body);
21888
22204
  for (const bullet of bullets) {
21889
22205
  if (bullet.length < 15)
21890
22206
  continue;
@@ -21893,9 +22209,9 @@ function parseContextMd(content) {
21893
22209
  continue;
21894
22210
  seen.add(normalized);
21895
22211
  entries.push({
21896
- text: _internals30.truncateLesson(bullet),
22212
+ text: _internals31.truncateLesson(bullet),
21897
22213
  sourceSection: match.sourceSection,
21898
- categoryHint: _internals30.inferCategoryFromText(bullet)
22214
+ categoryHint: _internals31.inferCategoryFromText(bullet)
21899
22215
  });
21900
22216
  }
21901
22217
  }
@@ -21985,8 +22301,8 @@ async function writeSentinel(sentinelPath, migrated, dropped) {
21985
22301
  schema_version: 1,
21986
22302
  migration_tool: "knowledge-migrator.ts"
21987
22303
  };
21988
- await _internals30.mkdir(path42.dirname(sentinelPath), { recursive: true });
21989
- await _internals30.writeFile(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
22304
+ await _internals31.mkdir(path42.dirname(sentinelPath), { recursive: true });
22305
+ await _internals31.writeFile(sentinelPath, JSON.stringify(sentinel, null, 2), "utf-8");
21990
22306
  }
21991
22307
  function resolveLegacyHiveKnowledgePath() {
21992
22308
  const platform = process.platform;
@@ -22367,7 +22683,7 @@ function timeoutMessage(timeoutMs) {
22367
22683
  async function computeWithTimeout(directory, currentPhase, timeoutMs) {
22368
22684
  const controller = new AbortController;
22369
22685
  let timeout;
22370
- const metricsPromise = _internals31.computeLearningMetrics(directory, {
22686
+ const metricsPromise = _internals32.computeLearningMetrics(directory, {
22371
22687
  currentPhase,
22372
22688
  signal: controller.signal
22373
22689
  });
@@ -22424,7 +22740,7 @@ ${JSON.stringify({
22424
22740
  return `Error computing learning metrics: ${message}. Run /swarm diagnose to check .swarm/ health.`;
22425
22741
  }
22426
22742
  }
22427
- var _internals31 = {
22743
+ var _internals32 = {
22428
22744
  computeLearningMetrics
22429
22745
  };
22430
22746
 
@@ -22626,7 +22942,7 @@ async function readLatestLoopState(directory) {
22626
22942
  return null;
22627
22943
  }
22628
22944
  }
22629
- var _internals32 = {
22945
+ var _internals33 = {
22630
22946
  readLatestLoopState
22631
22947
  };
22632
22948
  var USAGE7 = `Usage: /swarm loop <objective> [--max-cycles 1..5] [--autonomy checkpoint|auto] [--depth standard|exhaustive] [--resume]
@@ -22739,7 +23055,7 @@ ${USAGE7}`;
22739
23055
  }
22740
23056
  let autonomy = parsed.autonomy;
22741
23057
  if (parsed.resume && !parsed.autonomyExplicit) {
22742
- const state = await _internals32.readLatestLoopState(_directory);
23058
+ const state = await _internals33.readLatestLoopState(_directory);
22743
23059
  if (state?.autonomy && AUTONOMY_LEVELS.has(state.autonomy)) {
22744
23060
  autonomy = state.autonomy;
22745
23061
  }
@@ -22827,7 +23143,7 @@ async function rmTempRoot(tempRoot) {
22827
23143
  } catch (err) {
22828
23144
  if (attempt === 9)
22829
23145
  throw err;
22830
- await new Promise((resolve12) => setTimeout(resolve12, 50));
23146
+ await new Promise((resolve13) => setTimeout(resolve13, 50));
22831
23147
  }
22832
23148
  }
22833
23149
  }
@@ -23675,15 +23991,15 @@ function truncate(value, maxLength) {
23675
23991
  }
23676
23992
 
23677
23993
  // src/services/plan-service.ts
23678
- var _internals33 = {
23994
+ var _internals34 = {
23679
23995
  loadPlanJsonOnly,
23680
23996
  derivePlanMarkdown,
23681
23997
  readSwarmFileAsync
23682
23998
  };
23683
23999
  async function getPlanData(directory, phaseArg) {
23684
- const plan = await _internals33.loadPlanJsonOnly(directory);
24000
+ const plan = await _internals34.loadPlanJsonOnly(directory);
23685
24001
  if (plan) {
23686
- const fullMarkdown = _internals33.derivePlanMarkdown(plan);
24002
+ const fullMarkdown = _internals34.derivePlanMarkdown(plan);
23687
24003
  if (phaseArg === undefined || phaseArg === null || phaseArg === "") {
23688
24004
  return {
23689
24005
  hasPlan: true,
@@ -23726,7 +24042,7 @@ async function getPlanData(directory, phaseArg) {
23726
24042
  isLegacy: false
23727
24043
  };
23728
24044
  }
23729
- const planContent = await _internals33.readSwarmFileAsync(directory, "plan.md");
24045
+ const planContent = await _internals34.readSwarmFileAsync(directory, "plan.md");
23730
24046
  if (!planContent) {
23731
24047
  return {
23732
24048
  hasPlan: false,
@@ -23823,7 +24139,7 @@ async function handlePlanCommand(directory, args) {
23823
24139
  return formatPlanMarkdown(planData);
23824
24140
  }
23825
24141
  // src/commands/post-mortem.ts
23826
- var _internals34 = {
24142
+ var _internals35 = {
23827
24143
  createCuratorLLMDelegate,
23828
24144
  runCuratorPostMortem
23829
24145
  };
@@ -23871,10 +24187,10 @@ async function handlePostMortemCommand(directory, args, options) {
23871
24187
  };
23872
24188
  if (options?.sessionID) {
23873
24189
  try {
23874
- pmOptions.llmDelegate = _internals34.createCuratorLLMDelegate(directory, "postmortem", options.sessionID);
24190
+ pmOptions.llmDelegate = _internals35.createCuratorLLMDelegate(directory, "postmortem", options.sessionID);
23875
24191
  } catch {}
23876
24192
  }
23877
- const result = await _internals34.runCuratorPostMortem(directory, pmOptions);
24193
+ const result = await _internals35.runCuratorPostMortem(directory, pmOptions);
23878
24194
  const lines = [];
23879
24195
  if (result.success) {
23880
24196
  lines.push("## Post-Mortem Report Generated");
@@ -24110,7 +24426,7 @@ function formatMergeGroupStatus(status, conclusion, htmlUrl) {
24110
24426
  }
24111
24427
  return parts.join(" ");
24112
24428
  }
24113
- var _internals35 = {
24429
+ var _internals36 = {
24114
24430
  formatRelativeTime,
24115
24431
  formatMergeGroupStatus,
24116
24432
  listActive,
@@ -24118,7 +24434,7 @@ var _internals35 = {
24118
24434
  parseMergeGroupRuns
24119
24435
  };
24120
24436
  async function handlePrMonitorStatusCommand(directory, _args, sessionID, source) {
24121
- const allActive = await _internals35.listActive(directory);
24437
+ const allActive = await _internals36.listActive(directory);
24122
24438
  const allSessions = source === "cli";
24123
24439
  const subs = allSessions ? allActive : allActive.filter((record) => record.sessionID === sessionID);
24124
24440
  if (subs.length === 0) {
@@ -24134,7 +24450,7 @@ async function handlePrMonitorStatusCommand(directory, _args, sessionID, source)
24134
24450
  const index = i + 1;
24135
24451
  lines.push(` ${index}. ${sub.repoFullName}#${sub.prNumber}`);
24136
24452
  lines.push(` URL: ${sub.prUrl}`);
24137
- const mergeGroupRuns = await _internals35.listMergeGroupRuns(directory, sub.repoFullName, sub.prNumber);
24453
+ const mergeGroupRuns = await _internals36.listMergeGroupRuns(directory, sub.repoFullName, sub.prNumber);
24138
24454
  if (mergeGroupRuns.runs.length > 0) {
24139
24455
  lines.push(" Merge-group runs:");
24140
24456
  for (const run of mergeGroupRuns.runs) {
@@ -24274,7 +24590,7 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
24274
24590
  const repoFullName = `${prInfo.owner}/${prInfo.repo}`;
24275
24591
  const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
24276
24592
  try {
24277
- const config = _internals36.loadPluginConfig(directory);
24593
+ const config = _internals37.loadPluginConfig(directory);
24278
24594
  const prMonitorConfig = config.pr_monitor;
24279
24595
  if (!prMonitorConfig?.enabled) {
24280
24596
  return [
@@ -24284,7 +24600,7 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
24284
24600
  ].join(`
24285
24601
  `);
24286
24602
  }
24287
- await _internals36.subscribe(directory, {
24603
+ await _internals37.subscribe(directory, {
24288
24604
  sessionID,
24289
24605
  prNumber: prInfo.number,
24290
24606
  repoFullName,
@@ -24312,7 +24628,7 @@ async function handlePrSubscribeCommand(directory, args, sessionID) {
24312
24628
  `);
24313
24629
  }
24314
24630
  }
24315
- var _internals36 = {
24631
+ var _internals37 = {
24316
24632
  loadPluginConfig,
24317
24633
  subscribe
24318
24634
  };
@@ -24335,9 +24651,9 @@ async function handlePrUnsubscribeCommand(directory, args, sessionID) {
24335
24651
  `);
24336
24652
  }
24337
24653
  const refToken = rest[0];
24338
- const prInfo = _internals37.parsePrRef(refToken, directory);
24654
+ const prInfo = _internals38.parsePrRef(refToken, directory);
24339
24655
  if (!prInfo) {
24340
- if (_internals37.looksLikePrRef(refToken)) {
24656
+ if (_internals38.looksLikePrRef(refToken)) {
24341
24657
  return [
24342
24658
  `Error: Could not resolve PR reference from "${refToken}".`,
24343
24659
  "",
@@ -24358,8 +24674,8 @@ async function handlePrUnsubscribeCommand(directory, args, sessionID) {
24358
24674
  const repoFullName = `${prInfo.owner}/${prInfo.repo}`;
24359
24675
  const prUrl = `https://github.com/${prInfo.owner}/${prInfo.repo}/pull/${prInfo.number}`;
24360
24676
  try {
24361
- const correlationId = _internals37.buildCorrelationId(sessionID, repoFullName, prInfo.number);
24362
- const result = await _internals37.unsubscribe(directory, correlationId);
24677
+ const correlationId = _internals38.buildCorrelationId(sessionID, repoFullName, prInfo.number);
24678
+ const result = await _internals38.unsubscribe(directory, correlationId);
24363
24679
  if (!result) {
24364
24680
  return [
24365
24681
  `Not subscribed to ${prUrl}`,
@@ -24386,7 +24702,7 @@ async function handlePrUnsubscribeCommand(directory, args, sessionID) {
24386
24702
  `);
24387
24703
  }
24388
24704
  }
24389
- var _internals37 = {
24705
+ var _internals38 = {
24390
24706
  unsubscribe,
24391
24707
  buildCorrelationId,
24392
24708
  parsePrRef,
@@ -24704,7 +25020,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24704
25020
  stderr: "pipe"
24705
25021
  });
24706
25022
  const biomeExit = biomeProc.exited;
24707
- const timeout = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), DETECT_TIMEOUT));
25023
+ const timeout = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), DETECT_TIMEOUT));
24708
25024
  const result = await Promise.race([biomeExit, timeout]);
24709
25025
  if (result === "timeout") {
24710
25026
  biomeProc.kill();
@@ -24718,7 +25034,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
24718
25034
  stderr: "pipe"
24719
25035
  });
24720
25036
  const eslintExit = eslintProc.exited;
24721
- const timeout = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), DETECT_TIMEOUT));
25037
+ const timeout = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), DETECT_TIMEOUT));
24722
25038
  const result = await Promise.race([eslintExit, timeout]);
24723
25039
  if (result === "timeout") {
24724
25040
  eslintProc.kill();
@@ -24868,15 +25184,15 @@ var lint = createSwarmTool({
24868
25184
  }
24869
25185
  const { mode } = args;
24870
25186
  const cwd = directory;
24871
- const linter = await _internals38.detectAvailableLinter(directory);
25187
+ const linter = await _internals39.detectAvailableLinter(directory);
24872
25188
  if (linter) {
24873
- const result = await _internals38.runLint(linter, mode, directory);
25189
+ const result = await _internals39.runLint(linter, mode, directory);
24874
25190
  return JSON.stringify(result, null, 2);
24875
25191
  }
24876
- const additionalLinter = _internals38.detectAdditionalLinter(cwd);
25192
+ const additionalLinter = _internals39.detectAdditionalLinter(cwd);
24877
25193
  if (additionalLinter) {
24878
25194
  warn(`[lint] Using ${additionalLinter} linter for this project`);
24879
- const result = await _internals38.runAdditionalLint(additionalLinter, mode, cwd);
25195
+ const result = await _internals39.runAdditionalLint(additionalLinter, mode, cwd);
24880
25196
  return JSON.stringify(result, null, 2);
24881
25197
  }
24882
25198
  const errorResult = {
@@ -24890,7 +25206,7 @@ For Rust: rustup component add clippy`
24890
25206
  return JSON.stringify(errorResult, null, 2);
24891
25207
  }
24892
25208
  });
24893
- var _internals38 = {
25209
+ var _internals39 = {
24894
25210
  detectAvailableLinter,
24895
25211
  runLint,
24896
25212
  detectAdditionalLinter,
@@ -25578,7 +25894,7 @@ var secretscan = createSwarmTool({
25578
25894
  });
25579
25895
  async function runSecretscan(directory) {
25580
25896
  try {
25581
- const result = await _internals39.secretscan.execute({ directory }, {});
25897
+ const result = await _internals40.secretscan.execute({ directory }, {});
25582
25898
  const jsonStr = typeof result === "string" ? result : result.output;
25583
25899
  return JSON.parse(jsonStr);
25584
25900
  } catch (e) {
@@ -25650,7 +25966,7 @@ async function runSecretscanOnFiles(files, directory) {
25650
25966
  };
25651
25967
  }
25652
25968
  }
25653
- var _internals39 = {
25969
+ var _internals40 = {
25654
25970
  secretscan,
25655
25971
  runSecretscan,
25656
25972
  runSecretscanOnFiles,
@@ -25926,7 +26242,7 @@ async function buildImpactMapInternal(cwd) {
25926
26242
  }
25927
26243
  return impactMap;
25928
26244
  }
25929
- var _internals40 = {
26245
+ var _internals41 = {
25930
26246
  validateProjectRoot,
25931
26247
  normalizePath: normalizePath2,
25932
26248
  isCacheStale,
@@ -25941,8 +26257,8 @@ var _internals40 = {
25941
26257
  _clearGoModuleCache
25942
26258
  };
25943
26259
  async function buildImpactMap(cwd) {
25944
- const impactMap = await _internals40.buildImpactMapInternal(cwd);
25945
- await _internals40.saveImpactMap(cwd, impactMap);
26260
+ const impactMap = await _internals41.buildImpactMapInternal(cwd);
26261
+ await _internals41.saveImpactMap(cwd, impactMap);
25946
26262
  return impactMap;
25947
26263
  }
25948
26264
  async function loadImpactMap(cwd, options) {
@@ -25956,7 +26272,7 @@ async function loadImpactMap(cwd, options) {
25956
26272
  const hasValidValues = Object.values(map).every((v) => Array.isArray(v) && v.every((item) => typeof item === "string"));
25957
26273
  if (hasValidValues) {
25958
26274
  const generatedAt = new Date(data.generatedAt).getTime();
25959
- if (!_internals40.isCacheStale(map, generatedAt)) {
26275
+ if (!_internals41.isCacheStale(map, generatedAt)) {
25960
26276
  return map;
25961
26277
  }
25962
26278
  if (options?.skipRebuild) {
@@ -25976,13 +26292,13 @@ async function loadImpactMap(cwd, options) {
25976
26292
  if (options?.skipRebuild) {
25977
26293
  return {};
25978
26294
  }
25979
- return _internals40.buildImpactMap(cwd);
26295
+ return _internals41.buildImpactMap(cwd);
25980
26296
  }
25981
26297
  async function saveImpactMap(cwd, impactMap) {
25982
26298
  if (!path50.isAbsolute(cwd)) {
25983
26299
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
25984
26300
  }
25985
- _internals40.validateProjectRoot(cwd);
26301
+ _internals41.validateProjectRoot(cwd);
25986
26302
  const cacheDir2 = path50.join(cwd, ".swarm", "cache");
25987
26303
  const cachePath = path50.join(cacheDir2, "impact-map.json");
25988
26304
  if (!fs19.existsSync(cacheDir2)) {
@@ -26006,7 +26322,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
26006
26322
  };
26007
26323
  }
26008
26324
  const validFiles = changedFiles.filter((f) => typeof f === "string" && f.length > 0 && !f.includes("\x00"));
26009
- const impactMap = await _internals40.loadImpactMap(cwd);
26325
+ const impactMap = await _internals41.loadImpactMap(cwd);
26010
26326
  const impactedTestsSet = new Set;
26011
26327
  const untestedFiles = [];
26012
26328
  let visitedCount = 0;
@@ -26476,7 +26792,7 @@ function batchAppendTestRuns(records, workingDir) {
26476
26792
  }
26477
26793
  const historyPath = getHistoryPath(workingDir);
26478
26794
  const historyDir = path51.dirname(historyPath);
26479
- _internals41.validateProjectRoot(workingDir);
26795
+ _internals42.validateProjectRoot(workingDir);
26480
26796
  if (!fs20.existsSync(historyDir)) {
26481
26797
  fs20.mkdirSync(historyDir, { recursive: true });
26482
26798
  }
@@ -26599,7 +26915,7 @@ function getAllHistory(workingDir) {
26599
26915
  records.sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
26600
26916
  return records;
26601
26917
  }
26602
- var _internals41 = {
26918
+ var _internals42 = {
26603
26919
  validateProjectRoot
26604
26920
  };
26605
26921
 
@@ -26848,7 +27164,7 @@ var DISPATCH_FRAMEWORK_MAP = {
26848
27164
  };
26849
27165
  async function detectTestFrameworkViaDispatch(cwd) {
26850
27166
  try {
26851
- const { pickBackend } = await import("./dispatch-wst7bypk.js");
27167
+ const { pickBackend } = await import("./dispatch-mczsxy5s.js");
26852
27168
  const backend = await pickBackend(cwd);
26853
27169
  if (!backend?.selectTestFramework)
26854
27170
  return "none";
@@ -26864,7 +27180,7 @@ async function buildTestCommandViaDispatch(framework, scope, files, coverage, ba
26864
27180
  if (framework === "none")
26865
27181
  return null;
26866
27182
  try {
26867
- const { pickBackend } = await import("./dispatch-wst7bypk.js");
27183
+ const { pickBackend } = await import("./dispatch-mczsxy5s.js");
26868
27184
  const backend = await pickBackend(baseDir);
26869
27185
  if (backend?.buildTestCommand) {
26870
27186
  const cmd = backend.buildTestCommand(framework, files, baseDir, {
@@ -26884,7 +27200,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
26884
27200
  if (framework === "none")
26885
27201
  return null;
26886
27202
  try {
26887
- const { pickBackend } = await import("./dispatch-wst7bypk.js");
27203
+ const { pickBackend } = await import("./dispatch-mczsxy5s.js");
26888
27204
  const backend = await pickBackend(baseDir);
26889
27205
  if (!backend?.parseTestOutput)
26890
27206
  return null;
@@ -27868,9 +28184,9 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
27868
28184
  stderr: "pipe",
27869
28185
  cwd
27870
28186
  });
27871
- const timeoutPromise = new Promise((resolve16) => setTimeout(() => {
28187
+ const timeoutPromise = new Promise((resolve17) => setTimeout(() => {
27872
28188
  proc.kill();
27873
- resolve16(-1);
28189
+ resolve17(-1);
27874
28190
  }, timeout_ms));
27875
28191
  const [exitCode, stdoutResult, stderrResult] = await Promise.all([
27876
28192
  Promise.race([proc.exited, timeoutPromise]),
@@ -28028,11 +28344,11 @@ function normalizeHistoryTestFile(testFile, workingDir) {
28028
28344
  const normalized = testFile.replace(/\\/g, "/");
28029
28345
  if (!path53.isAbsolute(testFile))
28030
28346
  return normalized;
28031
- const relative6 = path53.relative(workingDir, testFile);
28032
- if (relative6.startsWith("..") || path53.isAbsolute(relative6)) {
28347
+ const relative7 = path53.relative(workingDir, testFile);
28348
+ if (relative7.startsWith("..") || path53.isAbsolute(relative7)) {
28033
28349
  return normalized;
28034
28350
  }
28035
- return relative6.replace(/\\/g, "/");
28351
+ return relative7.replace(/\\/g, "/");
28036
28352
  }
28037
28353
  function combineAggregateResult(current, next) {
28038
28354
  if (current === "fail" || next === "fail")
@@ -28577,9 +28893,9 @@ function getVersionFileVersion(dir) {
28577
28893
  async function runVersionCheck(dir, _timeoutMs) {
28578
28894
  const startTime = Date.now();
28579
28895
  try {
28580
- const packageVersion = _internals42.getPackageVersion(dir);
28581
- const changelogVersion = _internals42.getChangelogVersion(dir);
28582
- const versionFileVersion = _internals42.getVersionFileVersion(dir);
28896
+ const packageVersion = _internals43.getPackageVersion(dir);
28897
+ const changelogVersion = _internals43.getChangelogVersion(dir);
28898
+ const versionFileVersion = _internals43.getVersionFileVersion(dir);
28583
28899
  const versions = [];
28584
28900
  if (packageVersion)
28585
28901
  versions.push(`package.json: ${packageVersion}`);
@@ -28943,7 +29259,7 @@ async function runPreflight(dir, phase, config) {
28943
29259
  const reportId = `preflight-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
28944
29260
  let validatedDir;
28945
29261
  try {
28946
- validatedDir = _internals42.validateDirectoryPath(dir);
29262
+ validatedDir = _internals43.validateDirectoryPath(dir);
28947
29263
  } catch (error2) {
28948
29264
  return {
28949
29265
  id: reportId,
@@ -28963,7 +29279,7 @@ async function runPreflight(dir, phase, config) {
28963
29279
  }
28964
29280
  let validatedTimeout;
28965
29281
  try {
28966
- validatedTimeout = _internals42.validateTimeout(config?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
29282
+ validatedTimeout = _internals43.validateTimeout(config?.checkTimeoutMs, DEFAULT_CONFIG.checkTimeoutMs);
28967
29283
  } catch (error2) {
28968
29284
  return {
28969
29285
  id: reportId,
@@ -29004,12 +29320,12 @@ async function runPreflight(dir, phase, config) {
29004
29320
  });
29005
29321
  const checks = [];
29006
29322
  log("[Preflight] Running lint check...");
29007
- const lintResult = await _internals42.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
29323
+ const lintResult = await _internals43.runLintCheck(validatedDir, cfg.linter, cfg.checkTimeoutMs);
29008
29324
  checks.push(lintResult);
29009
29325
  log(`[Preflight] Lint check: ${lintResult.status} ${lintResult.message}`);
29010
29326
  if (!cfg.skipTests) {
29011
29327
  log("[Preflight] Running tests check...");
29012
- const testsResult = await _internals42.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
29328
+ const testsResult = await _internals43.runTestsCheck(validatedDir, cfg.testScope, cfg.checkTimeoutMs);
29013
29329
  checks.push(testsResult);
29014
29330
  log(`[Preflight] Tests check: ${testsResult.status} ${testsResult.message}`);
29015
29331
  } else {
@@ -29021,7 +29337,7 @@ async function runPreflight(dir, phase, config) {
29021
29337
  }
29022
29338
  if (!cfg.skipSecrets) {
29023
29339
  log("[Preflight] Running secrets check...");
29024
- const secretsResult = await _internals42.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
29340
+ const secretsResult = await _internals43.runSecretsCheck(validatedDir, cfg.checkTimeoutMs);
29025
29341
  checks.push(secretsResult);
29026
29342
  log(`[Preflight] Secrets check: ${secretsResult.status} ${secretsResult.message}`);
29027
29343
  } else {
@@ -29033,7 +29349,7 @@ async function runPreflight(dir, phase, config) {
29033
29349
  }
29034
29350
  if (!cfg.skipEvidence) {
29035
29351
  log("[Preflight] Running evidence check...");
29036
- const evidenceResult = await _internals42.runEvidenceCheck(validatedDir);
29352
+ const evidenceResult = await _internals43.runEvidenceCheck(validatedDir);
29037
29353
  checks.push(evidenceResult);
29038
29354
  log(`[Preflight] Evidence check: ${evidenceResult.status} ${evidenceResult.message}`);
29039
29355
  } else {
@@ -29044,12 +29360,12 @@ async function runPreflight(dir, phase, config) {
29044
29360
  });
29045
29361
  }
29046
29362
  log("[Preflight] Running requirement coverage check...");
29047
- const reqCoverageResult = await _internals42.runRequirementCoverageCheck(validatedDir, phase);
29363
+ const reqCoverageResult = await _internals43.runRequirementCoverageCheck(validatedDir, phase);
29048
29364
  checks.push(reqCoverageResult);
29049
29365
  log(`[Preflight] Requirement coverage check: ${reqCoverageResult.status} ${reqCoverageResult.message}`);
29050
29366
  if (!cfg.skipVersion) {
29051
29367
  log("[Preflight] Running version check...");
29052
- const versionResult = await _internals42.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
29368
+ const versionResult = await _internals43.runVersionCheck(validatedDir, cfg.checkTimeoutMs);
29053
29369
  checks.push(versionResult);
29054
29370
  log(`[Preflight] Version check: ${versionResult.status} ${versionResult.message}`);
29055
29371
  } else {
@@ -29112,10 +29428,10 @@ function formatPreflightMarkdown(report) {
29112
29428
  async function handlePreflightCommand(directory, _args) {
29113
29429
  const plan = await loadPlan(directory);
29114
29430
  const phase = plan?.current_phase ?? 1;
29115
- const report = await _internals42.runPreflight(directory, phase);
29116
- return _internals42.formatPreflightMarkdown(report);
29431
+ const report = await _internals43.runPreflight(directory, phase);
29432
+ return _internals43.formatPreflightMarkdown(report);
29117
29433
  }
29118
- var _internals42 = {
29434
+ var _internals43 = {
29119
29435
  runPreflight,
29120
29436
  formatPreflightMarkdown,
29121
29437
  handlePreflightCommand,
@@ -29351,13 +29667,13 @@ class CircuitBreaker {
29351
29667
  if (this.config.callTimeoutMs <= 0) {
29352
29668
  return fn();
29353
29669
  }
29354
- return new Promise((resolve17, reject) => {
29670
+ return new Promise((resolve18, reject) => {
29355
29671
  const timeout = setTimeout(() => {
29356
29672
  reject(new Error(`Call timeout after ${this.config.callTimeoutMs}ms`));
29357
29673
  }, this.config.callTimeoutMs);
29358
29674
  fn().then((result) => {
29359
29675
  clearTimeout(timeout);
29360
- resolve17(result);
29676
+ resolve18(result);
29361
29677
  }).catch((error2) => {
29362
29678
  clearTimeout(timeout);
29363
29679
  reject(error2);
@@ -29517,12 +29833,14 @@ class AutomationQueue {
29517
29833
  defaultBackoffMs;
29518
29834
  maxBackoffMs;
29519
29835
  eventBus;
29836
+ overflowStrategy;
29520
29837
  itemCounter = 0;
29521
29838
  constructor(config) {
29522
29839
  this.maxSize = config?.maxSize ?? 1000;
29523
29840
  this.defaultMaxRetries = config?.defaultMaxRetries ?? 3;
29524
29841
  this.defaultBackoffMs = config?.defaultBackoffMs ?? 1000;
29525
29842
  this.maxBackoffMs = config?.maxBackoffMs ?? 60000;
29843
+ this.overflowStrategy = config?.overflowStrategy ?? "throw";
29526
29844
  this.eventBus = getGlobalEventBus();
29527
29845
  }
29528
29846
  generateId() {
@@ -29530,7 +29848,20 @@ class AutomationQueue {
29530
29848
  }
29531
29849
  enqueue(payload, priority = "normal", metadata) {
29532
29850
  if (this.items.length >= this.maxSize) {
29533
- throw new Error(`Queue is full (max ${this.maxSize} items)`);
29851
+ if (this.overflowStrategy === "evict-oldest") {
29852
+ let oldestIdx = 0;
29853
+ for (let i = 1;i < this.items.length; i++) {
29854
+ if (this.items[i].createdAt < this.items[oldestIdx].createdAt) {
29855
+ oldestIdx = i;
29856
+ }
29857
+ }
29858
+ const [evicted] = this.items.splice(oldestIdx, 1);
29859
+ if (evicted) {
29860
+ this.eventBus.publish("queue.item.evicted", { itemId: evicted.id });
29861
+ }
29862
+ } else {
29863
+ throw new Error(`Queue is full (max ${this.maxSize} items)`);
29864
+ }
29534
29865
  }
29535
29866
  const item = {
29536
29867
  id: this.generateId(),
@@ -29641,7 +29972,7 @@ class AutomationQueue {
29641
29972
 
29642
29973
  // src/background/worker.ts
29643
29974
  function sleep(ms) {
29644
- return new Promise((resolve17) => setTimeout(resolve17, ms));
29975
+ return new Promise((resolve18) => setTimeout(resolve18, ms));
29645
29976
  }
29646
29977
 
29647
29978
  class WorkerManager {
@@ -30606,7 +30937,7 @@ async function recordReplayEntry(artifactPath, sessionID, entry) {
30606
30937
  }
30607
30938
 
30608
30939
  // src/prm/index.ts
30609
- var _internals43 = {
30940
+ var _internals44 = {
30610
30941
  getAgentSession,
30611
30942
  readTrajectory,
30612
30943
  getInMemoryTrajectory,
@@ -30629,12 +30960,12 @@ function resetPrmSessionState(session, sessionId) {
30629
30960
  session.prmTrajectoryStep = 0;
30630
30961
  session.replayArtifactPath = null;
30631
30962
  if (sessionId) {
30632
- _internals43.clearTrajectoryCache(sessionId);
30963
+ _internals44.clearTrajectoryCache(sessionId);
30633
30964
  }
30634
30965
  }
30635
30966
 
30636
30967
  // src/commands/reset-session.ts
30637
- var _internals44 = {
30968
+ var _internals45 = {
30638
30969
  cleanupOrphanedBranches
30639
30970
  };
30640
30971
  function errorMessage(err) {
@@ -30700,7 +31031,7 @@ async function handleResetSessionCommand(directory, _args) {
30700
31031
  results.push(`\u26A0\uFE0F Failed to remove .swarm-worktrees/: ${errorMessage(err)}`);
30701
31032
  }
30702
31033
  try {
30703
- const branchResult = await _internals44.cleanupOrphanedBranches(directory, []);
31034
+ const branchResult = await _internals45.cleanupOrphanedBranches(directory, []);
30704
31035
  if (branchResult.removed.length > 0) {
30705
31036
  results.push(`\u2705 Removed ${branchResult.removed.length} orphan swarm-lane branch(es)`);
30706
31037
  }
@@ -31037,7 +31368,7 @@ async function handleRollbackCommand(directory, args) {
31037
31368
  // src/commands/sdd.ts
31038
31369
  import * as fs29 from "fs";
31039
31370
  import * as path61 from "path";
31040
- var _internals45 = {
31371
+ var _internals46 = {
31041
31372
  writeProjectedSpecSync
31042
31373
  };
31043
31374
  var SWARM_SPEC_REL = path61.join(".swarm", "spec.md");
@@ -31433,7 +31764,7 @@ ${USAGE9}`;
31433
31764
 
31434
31765
  ${USAGE9}`;
31435
31766
  }
31436
- const result2 = _internals45.writeProjectedSpecSync(directory, {
31767
+ const result2 = _internals46.writeProjectedSpecSync(directory, {
31437
31768
  source: "speckit",
31438
31769
  feature: resolution.feature,
31439
31770
  dryRun: parsed.dryRun,
@@ -31491,7 +31822,7 @@ ${formatList(result2.projection.warnings)}` : ""
31491
31822
  ].join(`
31492
31823
  `);
31493
31824
  }
31494
- const result = _internals45.writeProjectedSpecSync(directory, {
31825
+ const result = _internals46.writeProjectedSpecSync(directory, {
31495
31826
  changeId: parsed.changeId,
31496
31827
  dryRun: parsed.dryRun,
31497
31828
  overwrite: parsed.overwrite
@@ -31572,7 +31903,7 @@ async function handleSimulateCommand(directory, args) {
31572
31903
  }
31573
31904
  let darkMatterPairs;
31574
31905
  try {
31575
- darkMatterPairs = await _internals20.detectDarkMatter(directory, options);
31906
+ darkMatterPairs = await _internals21.detectDarkMatter(directory, options);
31576
31907
  } catch (err) {
31577
31908
  const errMsg = err instanceof Error ? err.message : String(err);
31578
31909
  return `## Simulate Report
@@ -31877,7 +32208,7 @@ var DEFAULT_CONTEXT_BUDGET_CONFIG = {
31877
32208
  };
31878
32209
 
31879
32210
  // src/services/status-service.ts
31880
- var _internals46 = {
32211
+ var _internals47 = {
31881
32212
  loadLeanTurboRunState,
31882
32213
  hasActiveLeanTurbo,
31883
32214
  hasActiveFullAuto
@@ -31982,7 +32313,7 @@ async function getStatusData(directory, agents) {
31982
32313
  }
31983
32314
  function enrichWithLeanTurbo(status, directory) {
31984
32315
  const turboMode = hasActiveTurboMode();
31985
- const leanActive = _internals46.hasActiveLeanTurbo();
32316
+ const leanActive = _internals47.hasActiveLeanTurbo();
31986
32317
  let turboStrategy = "off";
31987
32318
  if (leanActive) {
31988
32319
  turboStrategy = "lean";
@@ -32001,7 +32332,7 @@ function enrichWithLeanTurbo(status, directory) {
32001
32332
  }
32002
32333
  }
32003
32334
  if (leanSessionID) {
32004
- const runState = _internals46.loadLeanTurboRunState(directory, leanSessionID);
32335
+ const runState = _internals47.loadLeanTurboRunState(directory, leanSessionID);
32005
32336
  if (runState) {
32006
32337
  status.leanTurboPhase = runState.phase;
32007
32338
  status.leanMaxParallelCoders = runState.maxParallelCoders;
@@ -32033,7 +32364,7 @@ function enrichWithLeanTurbo(status, directory) {
32033
32364
  }
32034
32365
  }
32035
32366
  }
32036
- status.fullAutoActive = _internals46.hasActiveFullAuto();
32367
+ status.fullAutoActive = _internals47.hasActiveFullAuto();
32037
32368
  return status;
32038
32369
  }
32039
32370
  function formatStatusMarkdown(status) {
@@ -32187,7 +32518,7 @@ No active swarm plan found. Nothing to sync.`;
32187
32518
 
32188
32519
  // src/commands/turbo.ts
32189
32520
  init_logger();
32190
- var _internals47 = {
32521
+ var _internals48 = {
32191
32522
  loadPluginConfigWithMeta
32192
32523
  };
32193
32524
  async function handleTurboCommand(directory, args, sessionID) {
@@ -32247,7 +32578,7 @@ async function handleTurboCommand(directory, args, sessionID) {
32247
32578
  if (arg0 === "on") {
32248
32579
  let strategy = "standard";
32249
32580
  try {
32250
- const { config } = _internals47.loadPluginConfigWithMeta(directory);
32581
+ const { config } = _internals48.loadPluginConfigWithMeta(directory);
32251
32582
  if (config.turbo?.strategy === "lean") {
32252
32583
  strategy = "lean";
32253
32584
  }
@@ -32344,7 +32675,7 @@ function enableLeanTurbo(session, directory, sessionID) {
32344
32675
  let maxParallelCoders = 4;
32345
32676
  let conflictPolicy = "serialize";
32346
32677
  try {
32347
- const { config } = _internals47.loadPluginConfigWithMeta(directory);
32678
+ const { config } = _internals48.loadPluginConfigWithMeta(directory);
32348
32679
  const leanConfig = config.turbo?.lean;
32349
32680
  if (leanConfig) {
32350
32681
  maxParallelCoders = leanConfig.max_parallel_coders ?? 4;
@@ -32560,7 +32891,7 @@ function findSimilarCommands(query) {
32560
32891
  }
32561
32892
  const scored = VALID_COMMANDS.map((cmd) => {
32562
32893
  const cmdLower = cmd.toLowerCase();
32563
- const fullScore = _internals48.levenshteinDistance(q, cmdLower);
32894
+ const fullScore = _internals49.levenshteinDistance(q, cmdLower);
32564
32895
  let tokenScore = Infinity;
32565
32896
  if (cmd.includes(" ") || cmd.includes("-")) {
32566
32897
  const qTokens = q.split(/[\s-]+/);
@@ -32573,7 +32904,7 @@ function findSimilarCommands(query) {
32573
32904
  for (const ct of cmdTokens) {
32574
32905
  if (ct.length === 0)
32575
32906
  continue;
32576
- const dist = _internals48.levenshteinDistance(qt, ct);
32907
+ const dist = _internals49.levenshteinDistance(qt, ct);
32577
32908
  if (dist < minDist)
32578
32909
  minDist = dist;
32579
32910
  }
@@ -32583,7 +32914,7 @@ function findSimilarCommands(query) {
32583
32914
  }
32584
32915
  const dashStrippedQ = q.replace(/-/g, "");
32585
32916
  const dashStrippedCmd = cmdLower.replace(/-/g, "");
32586
- const dashScore = _internals48.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
32917
+ const dashScore = _internals49.levenshteinDistance(dashStrippedQ, dashStrippedCmd);
32587
32918
  const score = Math.min(fullScore, tokenScore, dashScore);
32588
32919
  return { cmd, score };
32589
32920
  });
@@ -32618,16 +32949,16 @@ function buildDetailedHelp(commandName, entry) {
32618
32949
  async function handleHelpCommand(ctx) {
32619
32950
  const targetCommand = ctx.args.join(" ");
32620
32951
  if (!targetCommand) {
32621
- const { buildHelpText } = await import("./index-w51xz4dr.js");
32952
+ const { buildHelpText } = await import("./index-5yzr9fk6.js");
32622
32953
  return buildHelpText();
32623
32954
  }
32624
32955
  const tokens = targetCommand.split(/\s+/);
32625
- const resolved = _internals48.resolveCommand(tokens);
32956
+ const resolved = _internals49.resolveCommand(tokens);
32626
32957
  if (resolved) {
32627
- return _internals48.buildDetailedHelp(resolved.key, resolved.entry);
32958
+ return _internals49.buildDetailedHelp(resolved.key, resolved.entry);
32628
32959
  }
32629
- const similar = _internals48.findSimilarCommands(targetCommand);
32630
- const { buildHelpText: fullHelp } = await import("./index-w51xz4dr.js");
32960
+ const similar = _internals49.findSimilarCommands(targetCommand);
32961
+ const { buildHelpText: fullHelp } = await import("./index-5yzr9fk6.js");
32631
32962
  if (similar.length > 0) {
32632
32963
  return `Command '/swarm ${targetCommand}' not found.
32633
32964
 
@@ -32691,7 +33022,7 @@ var COMMAND_REGISTRY = {
32691
33022
  toolNoArgs: true
32692
33023
  },
32693
33024
  help: {
32694
- handler: (ctx) => _internals48.handleHelpCommand(ctx),
33025
+ handler: (ctx) => _internals49.handleHelpCommand(ctx),
32695
33026
  description: "Show help for swarm commands",
32696
33027
  category: "core",
32697
33028
  args: "[command]",
@@ -32760,7 +33091,7 @@ var COMMAND_REGISTRY = {
32760
33091
  },
32761
33092
  "guardrail explain": {
32762
33093
  handler: async (ctx) => {
32763
- const { handleGuardrailExplain } = await import("./guardrail-explain-2k271yh4.js");
33094
+ const { handleGuardrailExplain } = await import("./guardrail-explain-wpv5eskq.js");
32764
33095
  return handleGuardrailExplain(ctx.directory, ctx.args);
32765
33096
  },
32766
33097
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -32768,9 +33099,19 @@ var COMMAND_REGISTRY = {
32768
33099
  toolPolicy: "agent",
32769
33100
  toolNoArgs: false
32770
33101
  },
33102
+ "guardrail-explain": {
33103
+ handler: async (ctx) => {
33104
+ const { handleGuardrailExplain } = await import("./guardrail-explain-wpv5eskq.js");
33105
+ return handleGuardrailExplain(ctx.directory, ctx.args);
33106
+ },
33107
+ description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
33108
+ category: "diagnostics",
33109
+ aliasOf: "guardrail explain",
33110
+ deprecated: true
33111
+ },
32771
33112
  "guardrail-log": {
32772
33113
  handler: async (ctx) => {
32773
- const { handleGuardrailLog } = await import("./guardrail-log-hysxdwg9.js");
33114
+ const { handleGuardrailLog } = await import("./guardrail-log-qfc2j0tb.js");
32774
33115
  return handleGuardrailLog(ctx.directory, ctx.args);
32775
33116
  },
32776
33117
  description: "Read the guardrail decision log (use --blocks-only for blocks)",
@@ -33594,7 +33935,7 @@ function validateToolPolicy() {
33594
33935
  }
33595
33936
  return { valid: warnings.length === 0, warnings };
33596
33937
  }
33597
- var _internals48 = {
33938
+ var _internals49 = {
33598
33939
  handleHelpCommand,
33599
33940
  validateAliases,
33600
33941
  validateToolPolicy,
@@ -33604,16 +33945,16 @@ var _internals48 = {
33604
33945
  findSimilarCommands,
33605
33946
  buildDetailedHelp
33606
33947
  };
33607
- var validation = _internals48.validateAliases();
33948
+ var validation = _internals49.validateAliases();
33608
33949
  if (!validation.valid) {
33609
33950
  throw new Error(`COMMAND_REGISTRY alias validation failed:
33610
33951
  ${validation.errors.join(`
33611
33952
  `)}`);
33612
33953
  }
33613
- _internals48.emitValidationWarnings("COMMAND_REGISTRY alias warnings", validation.warnings);
33954
+ _internals49.emitValidationWarnings("COMMAND_REGISTRY alias warnings", validation.warnings);
33614
33955
  try {
33615
- const toolPolicyValidation = _internals48.validateToolPolicy();
33616
- _internals48.emitValidationWarnings("COMMAND_REGISTRY toolPolicy warnings", toolPolicyValidation.warnings);
33956
+ const toolPolicyValidation = _internals49.validateToolPolicy();
33957
+ _internals49.emitValidationWarnings("COMMAND_REGISTRY toolPolicy warnings", toolPolicyValidation.warnings);
33617
33958
  } catch (e) {
33618
33959
  warn(`COMMAND_REGISTRY toolPolicy validation failed (non-fatal): ${e.message}`);
33619
33960
  }
@@ -36019,6 +36360,9 @@ function dcStripOneWrapper(cmd) {
36019
36360
  const shellMatch = /^(?:bash|sh|zsh|dash|fish)(?:\.exe)?\s+-c\s+"?(.*?)"?\s*$/is.exec(t);
36020
36361
  if (shellMatch)
36021
36362
  return shellMatch[1].trim();
36363
+ const evalMatch = /^eval\s+(.+)$/is.exec(t);
36364
+ if (evalMatch)
36365
+ return evalMatch[1].replace(/^["']|["']$/g, "").trim();
36022
36366
  const prefixMatch = /^(?:sudo|time|nohup)\s+(.+)$/is.exec(t) ?? /^env(?:\s+[A-Za-z_][A-Za-z0-9_]*=[^\s]*)*\s+(.+)$/is.exec(t) ?? /^nice\s+(?:-n\s+\d+\s+)?(.+)$/is.exec(t);
36023
36367
  if (prefixMatch)
36024
36368
  return prefixMatch[1].trim();
@@ -36080,6 +36424,15 @@ function dcSplitSegments(cmd) {
36080
36424
  current = "";
36081
36425
  continue;
36082
36426
  }
36427
+ if (ch === "&" && next !== "&") {
36428
+ const prev = cmd[i - 1];
36429
+ const isFdRedirect = prev === ">" || next === ">";
36430
+ if (!isFdRedirect) {
36431
+ segments.push(current.trim());
36432
+ current = "";
36433
+ continue;
36434
+ }
36435
+ }
36083
36436
  }
36084
36437
  current += ch;
36085
36438
  }
@@ -36284,7 +36637,7 @@ function formatCommandNotFound(tokens) {
36284
36637
  const attemptedCommand = tokens[0] || "";
36285
36638
  const MAX_DISPLAY = 100;
36286
36639
  const displayCommand = attemptedCommand.length > MAX_DISPLAY ? `${attemptedCommand.slice(0, MAX_DISPLAY)}...` : attemptedCommand;
36287
- const similar = _internals48.findSimilarCommands(attemptedCommand);
36640
+ const similar = _internals49.findSimilarCommands(attemptedCommand);
36288
36641
  const header = `Command \`/swarm ${displayCommand}\` not found.`;
36289
36642
  const suggestions = similar.length > 0 ? `Did you mean:
36290
36643
  ${similar.map((cmd) => ` - /swarm ${cmd}`).join(`
@@ -37957,11 +38310,11 @@ function markSuggested(sessionId) {
37957
38310
  _suggestedSessions.add(sessionId);
37958
38311
  }
37959
38312
  function countWorktrees(directory) {
37960
- return new Promise((resolve20) => {
38313
+ return new Promise((resolve21) => {
37961
38314
  try {
37962
38315
  const child = execFile3("git", ["-C", directory, "worktree", "list", "--porcelain"], { timeout: GIT_TIMEOUT_MS3, windowsHide: true, encoding: "utf-8" }, (err, stdout) => {
37963
38316
  if (err || typeof stdout !== "string") {
37964
- resolve20(0);
38317
+ resolve21(0);
37965
38318
  return;
37966
38319
  }
37967
38320
  let count = 0;
@@ -37970,14 +38323,14 @@ function countWorktrees(directory) {
37970
38323
  if (line.startsWith("worktree "))
37971
38324
  count++;
37972
38325
  }
37973
- resolve20(count);
38326
+ resolve21(count);
37974
38327
  });
37975
38328
  try {
37976
38329
  child.stdin?.end();
37977
38330
  } catch {}
37978
- child.on("error", () => resolve20(0));
38331
+ child.on("error", () => resolve21(0));
37979
38332
  } catch {
37980
- resolve20(0);
38333
+ resolve21(0);
37981
38334
  }
37982
38335
  });
37983
38336
  }
@@ -38201,10 +38554,10 @@ function startAgentSession(sessionId, agentName, staleDurationMs = STALE_SESSION
38201
38554
  }
38202
38555
  telemetry.sessionStarted(sessionId, agentName);
38203
38556
  swarmState.activeAgent.set(sessionId, agentName);
38204
- _internals51.applyRehydrationCache(sessionState);
38557
+ _internals52.applyRehydrationCache(sessionState);
38205
38558
  if (directory) {
38206
38559
  let rehydrationPromise;
38207
- rehydrationPromise = _internals51.rehydrateSessionFromDisk(directory, sessionState).then(async () => {
38560
+ rehydrationPromise = _internals52.rehydrateSessionFromDisk(directory, sessionState).then(async () => {
38208
38561
  try {
38209
38562
  sessionState.prSubscriptions = await rehydratePrSubscriptions(sessionId, directory);
38210
38563
  } catch (err) {
@@ -38385,7 +38738,7 @@ function ensureAgentSession(sessionId, agentName, directory) {
38385
38738
  maybeSweepStaleSessions();
38386
38739
  return session;
38387
38740
  }
38388
- _internals51.startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
38741
+ _internals52.startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
38389
38742
  session = swarmState.agentSessions.get(sessionId);
38390
38743
  if (!session) {
38391
38744
  throw new Error(`Failed to create guardrail session for ${sessionId}`);
@@ -38673,8 +39026,8 @@ function applyRehydrationCache(session) {
38673
39026
  }
38674
39027
  }
38675
39028
  async function rehydrateSessionFromDisk(directory, session) {
38676
- await _internals51.buildRehydrationCache(directory);
38677
- _internals51.applyRehydrationCache(session);
39029
+ await _internals52.buildRehydrationCache(directory);
39030
+ _internals52.applyRehydrationCache(session);
38678
39031
  }
38679
39032
  function hasActiveTurboMode(sessionID) {
38680
39033
  if (sessionID) {
@@ -38727,7 +39080,7 @@ function hasActiveEpicMode(sessionID) {
38727
39080
  async function rehydratePrSubscriptions(sessionID, directory) {
38728
39081
  const map = new Map;
38729
39082
  try {
38730
- const { listActive: listActive2 } = await import("./pr-subscriptions-p8g2rzxd.js");
39083
+ const { listActive: listActive2 } = await import("./pr-subscriptions-vwv7zm2p.js");
38731
39084
  const records = await listActive2(directory);
38732
39085
  for (const record of records) {
38733
39086
  if (record.sessionID !== sessionID)
@@ -38748,7 +39101,7 @@ async function rehydratePrSubscriptions(sessionID, directory) {
38748
39101
  }
38749
39102
  return map;
38750
39103
  }
38751
- var _internals51 = {
39104
+ var _internals52 = {
38752
39105
  swarmState,
38753
39106
  resetSwarmState,
38754
39107
  ensureAgentSession,
@@ -38887,4 +39240,4 @@ function createCuratorLLMDelegate(directory, mode = "init", sessionId) {
38887
39240
  };
38888
39241
  }
38889
39242
 
38890
- export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals11 as _internals, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, checkHivePromotions, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals48 as _internals1, resolveCommand };
39243
+ export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleCiSimulateCommand, handleClarifyCommand, createCuratorLLMDelegate, _internals11 as _internals, normalizeRecommendationEntryIdToken, parseKnowledgeRecommendations, parseKnowledgeRecommendationsWithDiagnostics, parseStructuredCuratorBlocks, readCuratorSummary, writeCuratorSummary, appendCuratorRecommendation, mergeCuratorPhaseSummary, filterPhaseEvents, checkPhaseCompliance, runCuratorInit, runCuratorPhase, applyCuratorKnowledgeUpdates, isHiveEligible, checkHivePromotions, _internals13 as _internals1, createHivePromoterHook, promoteToHive, promoteFromSwarm, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCostsCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryValueLogCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals49 as _internals2, resolveCommand };