opencode-swarm 7.139.2 → 7.139.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 (110) hide show
  1. package/.opencode/skills/phase-wrap/SKILL.md +2 -2
  2. package/README.md +2 -2
  3. package/dist/background/stage-b-gates.d.ts +5 -1
  4. package/dist/background/task-envelope.d.ts +4 -4
  5. package/dist/cli/{config-doctor-hrb61yqe.js → config-doctor-whxr386t.js} +6 -6
  6. package/dist/cli/{core-g2dfh9fq.js → core-aj5g7an6.js} +5 -5
  7. package/dist/cli/{curation-policy-4tp0mbcb.js → curation-policy-anym2y3v.js} +8 -8
  8. package/dist/cli/{curator-drift-vfh07mqy.js → curator-drift-49p3jnte.js} +7 -7
  9. package/dist/cli/{curator-vpcs1p1v.js → curator-e8cvb55d.js} +41 -41
  10. package/dist/cli/curator-llm-factory-h9xbpgmw.js +61 -0
  11. package/dist/cli/{dispatch-b1fge4xk.js → dispatch-2s23fbcs.js} +4 -4
  12. package/dist/cli/{evidence-summary-service-kzxr71yd.js → evidence-summary-service-g82bsjqa.js} +16 -16
  13. package/dist/cli/{gate-evidence-z2b1ymnw.js → gate-evidence-72cgrvs2.js} +6 -5
  14. package/dist/cli/guardrail-explain-0be7msvq.js +62 -0
  15. package/dist/cli/{guardrail-log-2ftew0p3.js → guardrail-log-9mm5443g.js} +9 -9
  16. package/dist/cli/{hive-promoter-mpf0cfkk.js → hive-promoter-nnzs5x1r.js} +41 -41
  17. package/dist/cli/{index-w71cq27a.js → index-0e95eck5.js} +5 -5
  18. package/dist/cli/{index-5zyk8qgv.js → index-0xkjhgrf.js} +5 -5
  19. package/dist/cli/{index-q7ezzgwq.js → index-1kyex7z2.js} +1 -1
  20. package/dist/cli/{index-668dpw5e.js → index-33skgk1a.js} +1 -1
  21. package/dist/cli/{index-vm4xw9z3.js → index-41hkt36g.js} +2 -2
  22. package/dist/cli/{index-y111zefa.js → index-4nt52yr9.js} +80 -31
  23. package/dist/cli/{index-3jcyn8g6.js → index-4wjk296r.js} +1 -1
  24. package/dist/cli/{index-3radty3f.js → index-5azdnaty.js} +2 -2
  25. package/dist/cli/{index-8p9pasnp.js → index-5s23pfsy.js} +8 -8
  26. package/dist/cli/{index-5w7ekpy3.js → index-5z2xps64.js} +2 -2
  27. package/dist/cli/{index-0wp67gqj.js → index-6nzmp937.js} +61 -111
  28. package/dist/cli/{index-gvhvz176.js → index-6r522srn.js} +2 -2
  29. package/dist/cli/{index-4xbyy6aw.js → index-6rxgb5r9.js} +10 -6
  30. package/dist/cli/{index-cyw81ngh.js → index-6vh6vrnk.js} +10 -10
  31. package/dist/cli/{index-a12906mj.js → index-6z0a940s.js} +8 -8
  32. package/dist/cli/{index-wsdnttf4.js → index-74hpm6sh.js} +1 -1
  33. package/dist/cli/{index-6w1re1qn.js → index-9cdj4020.js} +6 -6
  34. package/dist/cli/{index-y47dwge1.js → index-e1k9vpqn.js} +5 -5
  35. package/dist/cli/{index-y64jv2pe.js → index-ejbcpbzp.js} +7 -7
  36. package/dist/cli/{index-6c5f309q.js → index-gfmrw2f5.js} +2 -2
  37. package/dist/cli/{index-prmb5qfp.js → index-j77frjq8.js} +7 -7
  38. package/dist/cli/{index-ffpmqx30.js → index-jnfyxeap.js} +4 -4
  39. package/dist/cli/{index-e9tx99ds.js → index-k41dn8me.js} +3 -3
  40. package/dist/cli/{index-x9q4bbhd.js → index-k46me75h.js} +4 -4
  41. package/dist/cli/{index-s608d3hw.js → index-nrx08gcr.js} +6 -2
  42. package/dist/cli/{index-ktagrqxw.js → index-pg84msyc.js} +7 -7
  43. package/dist/cli/{index-a5eba0t8.js → index-rsrx77fg.js} +6 -6
  44. package/dist/cli/index-s0qc4gj6.js +298 -0
  45. package/dist/cli/{index-q11t5erh.js → index-s58vghgj.js} +7 -7
  46. package/dist/cli/{index-se8xc78k.js → index-sa15nfgg.js} +45 -45
  47. package/dist/cli/{index-wrt6m5ze.js → index-sd657fkp.js} +291 -75
  48. package/dist/cli/{index-yr6x707c.js → index-vfsqpcz6.js} +16 -16
  49. package/dist/cli/{index-a7nh382r.js → index-vyqd1hzm.js} +20593 -19882
  50. package/dist/cli/{index-8gftfvpp.js → index-xb1zq933.js} +1 -1
  51. package/dist/cli/{index-3eddtgxt.js → index-xmhhhjjw.js} +39 -4
  52. package/dist/cli/index.js +43 -43
  53. package/dist/cli/{knowledge-escalator-n9pmx4qr.js → knowledge-escalator-a6z30y9p.js} +10 -10
  54. package/dist/cli/{knowledge-events-raevm18w.js → knowledge-events-deq0ds8e.js} +7 -7
  55. package/dist/cli/{knowledge-link-3tq8w6gs.js → knowledge-link-bmbatt8s.js} +6 -6
  56. package/dist/cli/{knowledge-store-bcfqz8fr.js → knowledge-store-vdr19mnq.js} +8 -8
  57. package/dist/cli/{knowledge-validator-jxqj96cx.js → knowledge-validator-5hgacnrf.js} +11 -11
  58. package/dist/cli/{pending-delegations-tmyf18p4.js → pending-delegations-7ayryxbg.js} +8 -8
  59. package/dist/cli/{pr-subscriptions-hhx6yk24.js → pr-subscriptions-w5y08ebc.js} +8 -8
  60. package/dist/cli/{runner-w30gazew.js → runner-h7vmgkth.js} +7 -6
  61. package/dist/cli/{scan-cursor-ah5swtyh.js → scan-cursor-d6qcg9hr.js} +9 -9
  62. package/dist/cli/{schema-f7jgrtxj.js → schema-y1zekrag.js} +3 -3
  63. package/dist/cli/{scope-persistence-3f0d4fwv.js → scope-persistence-tj6qway9.js} +7 -7
  64. package/dist/cli/{skill-generator-hp7as46c.js → skill-generator-bw8xhzzn.js} +13 -13
  65. package/dist/cli/{task-envelope-qn0qtnh0.js → task-envelope-jp2fdsvn.js} +11 -8
  66. package/dist/cli/{telemetry-4tgrfhaz.js → telemetry-62cn5t24.js} +1 -1
  67. package/dist/cli/{workspace-snapshot-h5rzw37b.js → workspace-snapshot-w3tg4ne5.js} +2 -2
  68. package/dist/cli/{worktree-collision-ownership-vexb0b6r.js → worktree-collision-ownership-hs5c2qzp.js} +9 -9
  69. package/dist/commands/approve-plan-critic.d.ts +2 -2
  70. package/dist/commands/registry.d.ts +1 -1
  71. package/dist/config/agent-model.d.ts +35 -0
  72. package/dist/db/qa-gate-profile.d.ts +11 -3
  73. package/dist/evidence/manager.d.ts +5 -2
  74. package/dist/evidence/phase-participation.d.ts +44 -0
  75. package/dist/hooks/compaction-customizer.d.ts +30 -2
  76. package/dist/hooks/context-budget.d.ts +1 -1
  77. package/dist/hooks/delegation-gate.d.ts +3 -3
  78. package/dist/hooks/guardrails/index.d.ts +5 -1
  79. package/dist/hooks/guardrails/messages-transform.d.ts +2 -0
  80. package/dist/hooks/guardrails/pre-check-result.d.ts +20 -0
  81. package/dist/index.js +616 -609
  82. package/dist/prm/escalation.d.ts +34 -0
  83. package/dist/prm/index.d.ts +6 -2
  84. package/dist/prm/pattern-detector.d.ts +22 -1
  85. package/dist/prm/types.d.ts +12 -2
  86. package/dist/sast/semgrep.d.ts +15 -32
  87. package/dist/services/compaction-service.d.ts +3 -1
  88. package/dist/session/snapshot-writer.d.ts +1 -0
  89. package/dist/state.d.ts +119 -19
  90. package/dist/summaries/schema.d.ts +2 -2
  91. package/dist/tools/context-status.d.ts +4 -1
  92. package/dist/tools/convene-council.d.ts +1 -1
  93. package/dist/tools/lint.d.ts +48 -22
  94. package/dist/tools/pre-check-batch.d.ts +41 -13
  95. package/dist/tools/quality-budget.d.ts +3 -2
  96. package/dist/tools/resolve-working-directory.d.ts +4 -4
  97. package/dist/tools/sast-baseline.d.ts +1 -0
  98. package/dist/tools/sast-scan.d.ts +4 -1
  99. package/dist/tools/secretscan.d.ts +2 -2
  100. package/dist/tools/set-qa-gates.d.ts +5 -4
  101. package/dist/tools/submit-phase-council-verdicts.d.ts +1 -1
  102. package/dist/tools/write-final-council-evidence.d.ts +1 -1
  103. package/dist/utils/bun-compat.d.ts +20 -0
  104. package/dist/utils/external-tool-runner.d.ts +10 -0
  105. package/dist/utils/project-boundary.d.ts +34 -0
  106. package/package.json +1 -1
  107. package/dist/cli/curator-llm-factory-hvw13hmr.js +0 -61
  108. package/dist/cli/guardrail-explain-k62h3c92.js +0 -62
  109. package/dist/cli/index-5j6chvj8.js +0 -159
  110. package/dist/cli/{index-z6xqpmqg.js → index-ee3x66a5.js} +3 -3
@@ -1,17 +1,17 @@
1
1
  // @bun
2
2
  import {
3
3
  validateSwarmPath
4
- } from "./index-x9q4bbhd.js";
4
+ } from "./index-k46me75h.js";
5
5
  import {
6
6
  withEvidenceLock
7
- } from "./index-5j6chvj8.js";
7
+ } from "./index-s0qc4gj6.js";
8
+ import {
9
+ log
10
+ } from "./index-zgwm4ryv.js";
8
11
  import {
9
12
  exports_external,
10
13
  init_zod
11
14
  } from "./index-bpmtbmy9.js";
12
- import {
13
- log
14
- } from "./index-zgwm4ryv.js";
15
15
 
16
16
  // src/background/pr-subscriptions.ts
17
17
  init_zod();
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  validateSwarmPath
4
- } from "./index-x9q4bbhd.js";
4
+ } from "./index-k46me75h.js";
5
5
 
6
6
  // src/hooks/delegation-gate/worktree-provisioning-owner.ts
7
7
  import { createHash, randomBytes } from "crypto";
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  atomicWriteFile
4
- } from "./index-gvhvz176.js";
4
+ } from "./index-6r522srn.js";
5
5
  import {
6
6
  init_logger,
7
7
  warn
@@ -1,10 +1,10 @@
1
1
  // @bun
2
2
  import {
3
3
  simpleGlobToRegex
4
- } from "./index-z6xqpmqg.js";
4
+ } from "./index-ee3x66a5.js";
5
5
  import {
6
6
  bunSpawnSync
7
- } from "./index-y111zefa.js";
7
+ } from "./index-4nt52yr9.js";
8
8
  import {
9
9
  warn
10
10
  } from "./index-zgwm4ryv.js";
@@ -124,24 +124,41 @@ function bunHash(input) {
124
124
  }
125
125
  return hash;
126
126
  }
127
- function killProcessTreeImpl(pid, signal, directKill, wasDetached) {
127
+ async function killProcessTreeImpl(pid, signal, directKill, wasDetached) {
128
128
  if (typeof pid !== "number" || pid <= 0) {
129
- directKill();
129
+ directKill(signal);
130
130
  return;
131
131
  }
132
- if (process.platform === "win32") {
132
+ if (_internals.platform() === "win32") {
133
+ let taskkill;
133
134
  try {
134
- const result = nodeSpawnSync("taskkill", ["/PID", String(pid), "/T", "/F"], {
135
- cwd: process.cwd(),
135
+ taskkill = _internals.spawnTaskkill(["/PID", String(pid), "/T", "/F"], {
136
+ cwd: _internals.cwd(),
136
137
  stdio: ["ignore", "ignore", "ignore"],
137
138
  timeout: 5000,
139
+ killSignal: "SIGKILL",
138
140
  windowsHide: true
139
141
  });
140
- if (!result.error && result.status === 0)
142
+ const succeeded = await new Promise((resolve) => {
143
+ let settled = false;
144
+ const finish = (value) => {
145
+ if (settled)
146
+ return;
147
+ settled = true;
148
+ resolve(value);
149
+ };
150
+ taskkill?.once("error", () => finish(false));
151
+ taskkill?.once("exit", (code) => finish(code === 0));
152
+ });
153
+ if (succeeded)
141
154
  return;
142
- } catch {}
143
- directKill();
144
- return;
155
+ } catch {} finally {
156
+ try {
157
+ taskkill?.kill("SIGKILL");
158
+ } catch {}
159
+ }
160
+ directKill(signal);
161
+ throw new Error("Windows process-tree termination could not be confirmed");
145
162
  }
146
163
  if (wasDetached) {
147
164
  try {
@@ -149,8 +166,17 @@ function killProcessTreeImpl(pid, signal, directKill, wasDetached) {
149
166
  return;
150
167
  } catch {}
151
168
  }
152
- directKill();
169
+ directKill(signal);
170
+ }
171
+ function createProcessTreeKiller(pid, directKill, wasDetached) {
172
+ return (signal) => killProcessTreeImpl(pid, signal, directKill, wasDetached);
153
173
  }
174
+ var _internals = {
175
+ platform: () => process.platform,
176
+ cwd: () => process.cwd(),
177
+ spawnTaskkill: (args, options) => nodeSpawn("taskkill", args, options),
178
+ createProcessTreeKiller
179
+ };
154
180
  function streamFromNode(pipe) {
155
181
  let collected;
156
182
  let readerClaimed = false;
@@ -312,18 +338,15 @@ function bunSpawn(cmd, options) {
312
338
  spawnOpts.detached = true;
313
339
  }
314
340
  const proc2 = bun.spawn(cmd, spawnOpts);
315
- const killBunProcess = (sig) => {
316
- if (options?.killProcessTree) {
317
- killProcessTreeImpl(proc2.pid, sig, () => proc2.kill(sig), true);
318
- } else {
319
- proc2.kill(sig);
320
- }
321
- };
341
+ const killBunTree = createProcessTreeKiller(proc2.pid, (sig) => proc2.kill(sig), true);
342
+ const killBunProcess = (sig) => options?.killProcessTree ? killBunTree(sig) : Promise.resolve(proc2.kill(sig));
322
343
  let timeoutHandle2;
323
344
  if (options?.killProcessTree === true && options.timeout && options.timeout > 0) {
324
345
  timeoutHandle2 = setTimeout(() => {
325
346
  try {
326
- killBunProcess("SIGKILL");
347
+ killBunProcess("SIGKILL").catch(() => {
348
+ return;
349
+ });
327
350
  } catch {}
328
351
  }, options.timeout);
329
352
  if (typeof timeoutHandle2.unref === "function")
@@ -340,9 +363,15 @@ function bunSpawn(cmd, options) {
340
363
  get exitCode() {
341
364
  return proc2.exitCode;
342
365
  },
366
+ get signalCode() {
367
+ return proc2.signalCode;
368
+ },
343
369
  kill(sig) {
344
- killBunProcess(sig);
345
- }
370
+ killBunProcess(sig).catch(() => {
371
+ return;
372
+ });
373
+ },
374
+ killTree: killBunProcess
346
375
  };
347
376
  }
348
377
  const [file, ...args] = cmd;
@@ -353,27 +382,38 @@ function bunSpawn(cmd, options) {
353
382
  env: mergedEnv,
354
383
  detached,
355
384
  windowsHide: true,
385
+ windowsVerbatimArguments: options?.windowsVerbatimArguments,
356
386
  stdio: [
357
387
  mapStdio(options?.stdin),
358
388
  mapStdio(options?.stdout),
359
389
  mapStdio(options?.stderr)
360
390
  ]
361
391
  });
392
+ const killChildTree = createProcessTreeKiller(proc.pid, (signal) => proc.kill(signal), true);
362
393
  const killChild = (signal) => {
363
- if (detached) {
364
- killProcessTreeImpl(proc.pid, signal, () => proc.kill(signal), true);
365
- } else {
366
- proc.kill(signal);
367
- }
394
+ if (detached)
395
+ return killChildTree(signal);
396
+ proc.kill(signal);
397
+ return Promise.resolve();
368
398
  };
369
399
  let timeoutHandle;
400
+ let observedSignal = null;
401
+ let observedSpawnError = null;
370
402
  const exited = new Promise((resolve) => {
371
- proc.on("exit", (code) => resolve(code ?? 0));
372
- proc.on("error", () => resolve(1));
403
+ proc.on("exit", (code, signal) => {
404
+ observedSignal = signal;
405
+ resolve(code ?? -1);
406
+ });
407
+ proc.on("error", (error) => {
408
+ observedSpawnError = error;
409
+ resolve(1);
410
+ });
373
411
  if (options?.timeout && options.timeout > 0) {
374
412
  timeoutHandle = setTimeout(() => {
375
413
  try {
376
- killChild("SIGKILL");
414
+ killChild("SIGKILL").catch(() => {
415
+ return;
416
+ });
377
417
  } catch {}
378
418
  }, options.timeout);
379
419
  if (typeof timeoutHandle.unref === "function") {
@@ -389,11 +429,20 @@ function bunSpawn(cmd, options) {
389
429
  stderr: streamFromNode(proc.stderr),
390
430
  exited,
391
431
  get exitCode() {
392
- return proc.exitCode;
432
+ return observedSpawnError ? null : proc.exitCode;
433
+ },
434
+ get signalCode() {
435
+ return observedSignal ?? proc.signalCode;
436
+ },
437
+ get spawnError() {
438
+ return observedSpawnError;
393
439
  },
394
440
  kill(signal) {
395
- killChild(signal);
396
- }
441
+ killChild(signal).catch(() => {
442
+ return;
443
+ });
444
+ },
445
+ killTree: killChild
397
446
  };
398
447
  }
399
448
  function bunSpawnSync(cmd, options) {
@@ -639,7 +639,7 @@ var init_tool_metadata = __esm(() => {
639
639
  agents: ["architect"]
640
640
  },
641
641
  set_qa_gates: {
642
- description: "configure the QA gate profile for the current plan. Architect-only. Ratchet-tighter only \u2014 rejected once the profile is locked after critic approval. Supports: reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council.",
642
+ description: "configure the QA gate profile for the current plan. Architect-only. The initial selection may override defaults; existing profiles are ratchet-tighter and rejected once locked after critic approval. Supports: reviewer, test_engineer, sme_enabled, critic_pre_plan, sast_enabled, council_mode, hallucination_guard, mutation_test, phase_council, drift_check, final_council.",
643
643
  agents: ["architect"]
644
644
  },
645
645
  web_search: {
@@ -4,13 +4,13 @@ import {
4
4
  } from "./index-rtry5xyf.js";
5
5
  import {
6
6
  readKnowledgeEvents
7
- } from "./index-e9tx99ds.js";
7
+ } from "./index-k41dn8me.js";
8
8
  import {
9
9
  isLinked,
10
10
  readLinkPointer,
11
11
  resolveKnowledgeStoreDir,
12
12
  resolveLinkDir
13
- } from "./index-668dpw5e.js";
13
+ } from "./index-33skgk1a.js";
14
14
 
15
15
  // src/knowledge/curation-policy.ts
16
16
  import { appendFile, mkdir as mkdir2, readFile as readFile2 } from "fs/promises";
@@ -1,13 +1,13 @@
1
1
  // @bun
2
- import {
3
- OUTCOME_BLOCK_THRESHOLD,
4
- init_knowledge_types
5
- } from "./index-bk5tah7q.js";
6
2
  import {
7
3
  ALL_AGENT_NAMES,
8
4
  SUMMARIZER_EXEMPT_TOOL_NAMES,
9
5
  init_constants
10
- } from "./index-3jcyn8g6.js";
6
+ } from "./index-4wjk296r.js";
7
+ import {
8
+ OUTCOME_BLOCK_THRESHOLD,
9
+ init_knowledge_types
10
+ } from "./index-bk5tah7q.js";
11
11
  import {
12
12
  exports_external,
13
13
  init_zod
@@ -21,7 +21,7 @@ var package_default;
21
21
  var init_package = __esm(() => {
22
22
  package_default = {
23
23
  name: "opencode-swarm",
24
- version: "7.139.2",
24
+ version: "7.139.4",
25
25
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
26
26
  main: "dist/index.js",
27
27
  types: "dist/index.d.ts",
@@ -1297,13 +1297,13 @@ var init_schema = __esm(() => {
1297
1297
  ping_pong: exports_external.number().min(1).default(2),
1298
1298
  expansion_drift: exports_external.number().min(1).default(3),
1299
1299
  stuck_on_test: exports_external.number().min(1).default(3),
1300
- context_thrash: exports_external.number().min(1).default(3)
1300
+ context_thrash: exports_external.number().min(1).default(10)
1301
1301
  }).default(() => ({
1302
1302
  repetition_loop: 2,
1303
1303
  ping_pong: 2,
1304
1304
  expansion_drift: 3,
1305
1305
  stuck_on_test: 3,
1306
- context_thrash: 3
1306
+ context_thrash: 10
1307
1307
  })),
1308
1308
  max_trajectory_lines: exports_external.number().min(10).default(1000),
1309
1309
  escalation_enabled: exports_external.boolean().default(true),
@@ -3,10 +3,10 @@ import {
3
3
  atomicWriteFile,
4
4
  taskEvidencePath,
5
5
  withTaskEvidenceLock
6
- } from "./index-gvhvz176.js";
6
+ } from "./index-6r522srn.js";
7
7
  import {
8
8
  telemetry
9
- } from "./index-a5eba0t8.js";
9
+ } from "./index-rsrx77fg.js";
10
10
  import {
11
11
  exports_external,
12
12
  init_zod
@@ -3,28 +3,10 @@ import {
3
3
  EvaluationRunV1Schema,
4
4
  GateAuditResultV1Schema,
5
5
  getProtectedEvaluationRunIds
6
- } from "./index-s608d3hw.js";
6
+ } from "./index-nrx08gcr.js";
7
7
  import {
8
8
  readEffectiveSpecSync
9
9
  } from "./index-9ss2m4rs.js";
10
- import {
11
- isValidTaskId,
12
- readTaskEvidence,
13
- readTaskEvidenceRaw,
14
- sanitizeTaskId
15
- } from "./index-5w7ekpy3.js";
16
- import {
17
- EVIDENCE_MAX_JSON_BYTES,
18
- EvidenceBundleSchema,
19
- EvidenceSchema
20
- } from "./index-gprxjmm7.js";
21
- import {
22
- _internals,
23
- buildDefaultPolicy,
24
- execute,
25
- init_runner_client,
26
- probe
27
- } from "./index-q1exe2b3.js";
28
10
  import {
29
11
  LedgerStaleWriterError,
30
12
  appendLedgerEvent,
@@ -40,42 +22,61 @@ import {
40
22
  replayFromLedgerWithStatus,
41
23
  takeSnapshotEvent,
42
24
  takeSnapshotWithRetry
43
- } from "./index-4xbyy6aw.js";
44
- import {
45
- PlanSchema
46
- } from "./index-1kz6da87.js";
25
+ } from "./index-6rxgb5r9.js";
47
26
  import {
48
27
  getWorktreeMergeFailure
49
28
  } from "./index-b8zgtz81.js";
50
29
  import {
51
30
  readSwarmFileAsync,
52
31
  validateSwarmPath
53
- } from "./index-x9q4bbhd.js";
32
+ } from "./index-k46me75h.js";
33
+ import {
34
+ isValidTaskId,
35
+ readTaskEvidence,
36
+ readTaskEvidenceRaw,
37
+ sanitizeTaskId
38
+ } from "./index-5z2xps64.js";
39
+ import {
40
+ _internals,
41
+ buildDefaultPolicy,
42
+ execute,
43
+ init_runner_client,
44
+ probe
45
+ } from "./index-q1exe2b3.js";
54
46
  import {
55
47
  invalidateCachedArtifact,
56
48
  readCachedParsedFile
57
49
  } from "./index-ed5ykebp.js";
58
50
  import {
51
+ assertProjectRoot,
59
52
  withEvidenceLock
60
- } from "./index-5j6chvj8.js";
61
- import {
62
- emit
63
- } from "./index-a5eba0t8.js";
64
- import {
65
- ZodError,
66
- init_zod
67
- } from "./index-bpmtbmy9.js";
53
+ } from "./index-s0qc4gj6.js";
68
54
  import {
69
55
  bunHash,
70
56
  bunWrite,
71
57
  mergeEnvForChild
72
- } from "./index-y111zefa.js";
58
+ } from "./index-4nt52yr9.js";
59
+ import {
60
+ EVIDENCE_MAX_JSON_BYTES,
61
+ EvidenceBundleSchema,
62
+ EvidenceSchema
63
+ } from "./index-gprxjmm7.js";
64
+ import {
65
+ PlanSchema
66
+ } from "./index-1kz6da87.js";
73
67
  import {
74
68
  criticalWarn,
75
69
  error,
76
70
  init_logger,
77
71
  warn
78
72
  } from "./index-zgwm4ryv.js";
73
+ import {
74
+ emit
75
+ } from "./index-rsrx77fg.js";
76
+ import {
77
+ ZodError,
78
+ init_zod
79
+ } from "./index-bpmtbmy9.js";
79
80
  import {
80
81
  __esm,
81
82
  __export,
@@ -2659,6 +2660,7 @@ async function isPlanMdInSync(directory, plan, cache) {
2659
2660
  return false;
2660
2661
  }
2661
2662
  async function regeneratePlanMarkdown(directory, plan) {
2663
+ assertProjectRoot(directory);
2662
2664
  const swarmDir = path8.resolve(directory, ".swarm");
2663
2665
  const contentHash = computePlanContentHash(plan);
2664
2666
  const markdown = derivePlanMarkdown(plan);
@@ -2771,6 +2773,7 @@ async function loadPlan(directory, cache) {
2771
2773
  const preserving = await isObligationPreserving(directory);
2772
2774
  if (!preserving) {
2773
2775
  try {
2776
+ assertProjectRoot(directory);
2774
2777
  const diffInfo = computeSpecDiff(directory);
2775
2778
  const specStalenessPath = path8.join(directory, ".swarm", "spec-staleness.json");
2776
2779
  await fsPromises.writeFile(specStalenessPath, JSON.stringify({
@@ -2787,6 +2790,7 @@ async function loadPlan(directory, cache) {
2787
2790
  invalidateCachedArtifact(specStalenessPath);
2788
2791
  } catch {}
2789
2792
  try {
2793
+ assertProjectRoot(directory);
2790
2794
  const eventsPath = path8.join(directory, ".swarm", "events.jsonl");
2791
2795
  const event = {
2792
2796
  type: "spec_stale_detected",
@@ -2942,6 +2946,7 @@ async function savePlan(directory, plan, options) {
2942
2946
  if (directory === null || directory === undefined || typeof directory !== "string" || directory.trim().length === 0) {
2943
2947
  throw new Error(`Invalid directory: directory must be a non-empty string`);
2944
2948
  }
2949
+ assertProjectRoot(directory);
2945
2950
  const validated = PlanSchema.parse(plan);
2946
2951
  if (options?.preserveCompletedStatuses !== false) {
2947
2952
  try {
@@ -3254,6 +3259,7 @@ ${markdown}`;
3254
3259
  } catch {}
3255
3260
  }
3256
3261
  async function rebuildPlan(directory, plan, options) {
3262
+ assertProjectRoot(directory);
3257
3263
  const targetPlan = plan ?? await replayFromLedger(directory);
3258
3264
  if (!targetPlan)
3259
3265
  return null;
@@ -3324,6 +3330,7 @@ ${markdown}`;
3324
3330
  return targetPlan;
3325
3331
  }
3326
3332
  async function closePlanTerminalState(directory, plan, options) {
3333
+ assertProjectRoot(directory);
3327
3334
  const planId = derivePlanId(plan);
3328
3335
  const validated = PlanSchema.parse(plan);
3329
3336
  const hashAfter = computePlanHash(validated);
@@ -3679,11 +3686,11 @@ import {
3679
3686
  mkdirSync as mkdirSync4,
3680
3687
  readdirSync as readdirSync2,
3681
3688
  realpathSync,
3689
+ renameSync as renameSync3,
3682
3690
  rmSync,
3683
3691
  statSync as statSync2
3684
3692
  } from "fs";
3685
3693
  import * as fs7 from "fs/promises";
3686
- import * as os4 from "os";
3687
3694
  import * as path10 from "path";
3688
3695
 
3689
3696
  // src/evaluation/retention.ts
@@ -3792,6 +3799,7 @@ var _retentionInternals = {
3792
3799
  removeCandidate
3793
3800
  };
3794
3801
  async function archiveEvaluationArtifacts(args) {
3802
+ assertProjectRoot(args.directory);
3795
3803
  return withEvidenceLock(args.directory, path9.join("evolution", "retention-index"), "evaluation-retention", "archive", async () => {
3796
3804
  const inventory = await retentionCandidates(args.directory);
3797
3805
  let protectedKeys = await _retentionInternals.protectedArtifacts(args.directory);
@@ -3992,6 +4000,7 @@ async function rewriteAtomic(filePath, survivors) {
3992
4000
  return Buffer.byteLength(payload, "utf8");
3993
4001
  }
3994
4002
  async function pruneEvidenceDocuments(args) {
4003
+ assertProjectRoot(args.directory);
3995
4004
  const dryRun = args.dryRun === true;
3996
4005
  const capsUnset = (typeof args.maxBytes !== "number" || args.maxBytes <= 0) && (typeof args.maxRecords !== "number" || args.maxRecords <= 0);
3997
4006
  const filePath = validateSwarmPath(args.directory, EVIDENCE_CACHE_FILE);
@@ -4096,94 +4105,26 @@ function isValidEvidenceType(type) {
4096
4105
  return VALID_EVIDENCE_TYPES.includes(type);
4097
4106
  }
4098
4107
  var sanitizeTaskId2 = sanitizeTaskId;
4099
- var MAX_DEPTH = 20;
4100
- var PROJECT_INDICATORS = [
4101
- "package.json",
4102
- ".git",
4103
- ".opencode",
4104
- "Cargo.toml",
4105
- "go.mod",
4106
- "pyproject.toml",
4107
- "Gemfile",
4108
- "composer.json",
4109
- "pom.xml",
4110
- "build.gradle",
4111
- "CMakeLists.txt"
4112
- ];
4113
- function isWeakConfigContainerRoot(directory) {
4114
- try {
4115
- const resolved = realpathSync(directory);
4116
- return resolved === realpathSync(os4.tmpdir()) || resolved === realpathSync(os4.homedir());
4117
- } catch {
4118
- const resolved = path10.resolve(directory);
4119
- return resolved === path10.resolve(os4.tmpdir()) || resolved === path10.resolve(os4.homedir());
4120
- }
4121
- }
4122
- function hasAccessibleProjectIndicator(directory, options = {}) {
4123
- const allowConfigOnly = options.allowConfigOnly ?? true;
4124
- for (const indicator of PROJECT_INDICATORS) {
4125
- if (!allowConfigOnly && indicator === ".opencode") {
4126
- continue;
4127
- }
4128
- try {
4129
- const indicatorStat = statSync2(path10.join(directory, indicator));
4130
- if (indicatorStat.isFile() || indicatorStat.isDirectory()) {
4131
- return true;
4132
- }
4133
- } catch {}
4134
- }
4135
- return false;
4136
- }
4137
4108
  function validateProjectRoot(directory) {
4138
- let resolved;
4139
- try {
4140
- resolved = realpathSync(directory);
4141
- } catch {
4142
- warn(`[evidence] Cannot canonicalize directory "${directory}" \u2014 failing closed`);
4143
- throw new Error(`Cannot verify project root for "${directory}" \u2014 directory may not exist or is inaccessible`);
4144
- }
4145
- let current = resolved;
4146
- let depth = 0;
4147
- while (true) {
4148
- if (depth >= MAX_DEPTH)
4149
- break;
4150
- depth++;
4151
- const parent = path10.dirname(current);
4152
- if (parent === current)
4153
- break;
4154
- if (path10.dirname(parent) === parent) {
4155
- current = parent;
4156
- continue;
4157
- }
4158
- const parentSwarm = path10.join(parent, ".swarm");
4159
- try {
4160
- if (statSync2(parentSwarm).isDirectory()) {
4161
- if (hasAccessibleProjectIndicator(parent, {
4162
- allowConfigOnly: !isWeakConfigContainerRoot(parent)
4163
- })) {
4164
- warn(`[evidence] Rejecting write to subdirectory "${resolved}" \u2014 parent "${parent}" already contains .swarm/`);
4165
- throw new Error(`Cannot write evidence in "${resolved}" \u2014 parent directory "${parent}" already contains a .swarm/ folder. Evidence must be written to the project root.`);
4166
- }
4167
- }
4168
- } catch (error2) {
4169
- if (error2 instanceof Error && error2.message.startsWith("Cannot write evidence")) {
4170
- throw error2;
4171
- }
4172
- }
4173
- current = parent;
4174
- }
4109
+ assertProjectRoot(directory, {
4110
+ realpathSync: _internals11.realpathSync,
4111
+ statSync: _internals11.statSync
4112
+ }, "evidence");
4175
4113
  }
4176
- async function saveEvidence(directory, taskId, evidence) {
4114
+ async function saveEvidence(directory, taskId, evidence, abortSignal) {
4115
+ abortSignal?.throwIfAborted();
4177
4116
  _internals11.validateProjectRoot(directory);
4178
4117
  const sanitizedTaskId = sanitizeTaskId2(taskId);
4179
4118
  const relativePath = path10.join("evidence", sanitizedTaskId, "evidence.json");
4180
4119
  validateSwarmPath(directory, relativePath);
4181
4120
  _internals11.validateEvidence(evidence);
4182
4121
  return withEvidenceLock(directory, relativePath, "evidence-manager", sanitizedTaskId, async () => {
4122
+ abortSignal?.throwIfAborted();
4183
4123
  const evidencePath = validateSwarmPath(directory, relativePath);
4184
4124
  const evidenceDir = path10.dirname(evidencePath);
4185
4125
  let bundle;
4186
4126
  const existingContent = await readSwarmFileAsync(directory, relativePath);
4127
+ abortSignal?.throwIfAborted();
4187
4128
  if (existingContent !== null) {
4188
4129
  try {
4189
4130
  const parsed = JSON.parse(existingContent);
@@ -4227,7 +4168,8 @@ async function saveEvidence(directory, taskId, evidence) {
4227
4168
  const tempPath = path10.join(evidenceDir, `evidence.json.tmp.${Date.now()}.${process.pid}`);
4228
4169
  try {
4229
4170
  await bunWrite(tempPath, bundleJson);
4230
- await fs7.rename(tempPath, evidencePath);
4171
+ abortSignal?.throwIfAborted();
4172
+ renameSync3(tempPath, evidencePath);
4231
4173
  } catch (error2) {
4232
4174
  try {
4233
4175
  rmSync(tempPath, { force: true });
@@ -4292,6 +4234,7 @@ async function loadEvidence(directory, taskId, options) {
4292
4234
  return { status: "found", bundle: validated };
4293
4235
  }
4294
4236
  try {
4237
+ validateProjectRoot(directory);
4295
4238
  await withEvidenceLock(directory, relativePath, "evidence-loader", sanitizedTaskId, async () => {
4296
4239
  const evidenceDir = path10.dirname(evidencePath);
4297
4240
  const bundleJson = JSON.stringify(validated);
@@ -4359,6 +4302,11 @@ async function listEvidenceTaskIds(directory) {
4359
4302
  }
4360
4303
  async function deleteEvidence(directory, taskId) {
4361
4304
  const sanitizedTaskId = sanitizeTaskId2(taskId);
4305
+ try {
4306
+ validateProjectRoot(directory);
4307
+ } catch {
4308
+ return false;
4309
+ }
4362
4310
  const relativePath = path10.join("evidence", sanitizedTaskId);
4363
4311
  const evidenceDir = validateSwarmPath(directory, relativePath);
4364
4312
  try {
@@ -4489,6 +4437,8 @@ var _internals11 = {
4489
4437
  saveEvidence,
4490
4438
  deleteEvidence,
4491
4439
  pruneEvidenceDocuments,
4440
+ realpathSync,
4441
+ statSync: statSync2,
4492
4442
  now: () => new Date
4493
4443
  };
4494
4444
 
@@ -4,10 +4,10 @@ import {
4
4
  } from "./index-ed5ykebp.js";
5
5
  import {
6
6
  withEvidenceLock
7
- } from "./index-5j6chvj8.js";
7
+ } from "./index-s0qc4gj6.js";
8
8
  import {
9
9
  bunWrite
10
- } from "./index-y111zefa.js";
10
+ } from "./index-4nt52yr9.js";
11
11
 
12
12
  // src/evidence/task-file.ts
13
13
  import { renameSync, unlinkSync } from "fs";