opencode-swarm 7.77.2 → 7.77.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.
package/dist/cli/index.js CHANGED
@@ -52,7 +52,7 @@ var package_default;
52
52
  var init_package = __esm(() => {
53
53
  package_default = {
54
54
  name: "opencode-swarm",
55
- version: "7.77.2",
55
+ version: "7.77.4",
56
56
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
57
57
  main: "dist/index.js",
58
58
  types: "dist/index.d.ts",
@@ -504,6 +504,14 @@ async function bunWrite(filePath, data) {
504
504
  } catch {}
505
505
  throw lastError;
506
506
  }
507
+ try {
508
+ const dirFd = await fsPromises.open(dir, "r");
509
+ try {
510
+ await dirFd.sync();
511
+ } finally {
512
+ await dirFd.close();
513
+ }
514
+ } catch {}
507
515
  const stats = await fsPromises.stat(filePath);
508
516
  return stats.size;
509
517
  }
@@ -828,14 +836,23 @@ function validateSwarmPath(directory, filename) {
828
836
  return resolved;
829
837
  }
830
838
  async function readSwarmFileAsync(directory, filename) {
831
- try {
832
- const resolvedPath = _internals.validateSwarmPath(directory, filename);
833
- const file = bunFile(resolvedPath);
834
- const content = await file.text();
835
- return content;
836
- } catch {
837
- return null;
839
+ const maxAttempts = 5;
840
+ const retryDelayMs = 10;
841
+ for (let attempt = 0;attempt < maxAttempts; attempt++) {
842
+ try {
843
+ const resolvedPath = _internals.validateSwarmPath(directory, filename);
844
+ const file = bunFile(resolvedPath);
845
+ const content = await file.text();
846
+ return content;
847
+ } catch (err) {
848
+ const isNotFound = err?.code === "ENOENT";
849
+ if (!isNotFound || attempt === maxAttempts - 1) {
850
+ return null;
851
+ }
852
+ await new Promise((resolve3) => setTimeout(resolve3, retryDelayMs));
853
+ }
838
854
  }
855
+ return null;
839
856
  }
840
857
  var _internals;
841
858
  var init_utils2 = __esm(() => {
@@ -17544,7 +17561,7 @@ var init_tool_metadata = __esm(() => {
17544
17561
  agents: ["architect"]
17545
17562
  },
17546
17563
  write_final_council_evidence: {
17547
- description: "write final council evidence for project completion",
17564
+ description: "Persist project-scoped final council evidence to .swarm/evidence/final-council.json. PREREQUISITE: dispatch critic, reviewer, sme, test_engineer, and explorer as project-scoped Agent tasks and collect their CouncilMemberVerdict JSON \u2014 this tool synthesizes only. Rejects on insufficient quorum or CONCERNS with unresolved requiredFixes; normalizes verdicts to approved/concerns/rejected. Architect-only.",
17548
17565
  agents: ["architect"]
17549
17566
  },
17550
17567
  skill_generate: {
@@ -20381,7 +20398,7 @@ GFS4: `);
20381
20398
  }
20382
20399
  function ReadStream$open() {
20383
20400
  var that = this;
20384
- open(that.path, that.flags, that.mode, function(err, fd) {
20401
+ open2(that.path, that.flags, that.mode, function(err, fd) {
20385
20402
  if (err) {
20386
20403
  if (that.autoClose)
20387
20404
  that.destroy();
@@ -20401,7 +20418,7 @@ GFS4: `);
20401
20418
  }
20402
20419
  function WriteStream$open() {
20403
20420
  var that = this;
20404
- open(that.path, that.flags, that.mode, function(err, fd) {
20421
+ open2(that.path, that.flags, that.mode, function(err, fd) {
20405
20422
  if (err) {
20406
20423
  that.destroy();
20407
20424
  that.emit("error", err);
@@ -20418,8 +20435,8 @@ GFS4: `);
20418
20435
  return new fs6.WriteStream(path8, options);
20419
20436
  }
20420
20437
  var fs$open = fs6.open;
20421
- fs6.open = open;
20422
- function open(path8, flags, mode, cb) {
20438
+ fs6.open = open2;
20439
+ function open2(path8, flags, mode, cb) {
20423
20440
  if (typeof mode === "function")
20424
20441
  cb = mode, mode = null;
20425
20442
  return go$open(path8, flags, mode, cb);
@@ -21571,6 +21588,9 @@ function wrapFlatRetrospective(flatEntry, taskId) {
21571
21588
  async function loadEvidence(directory, taskId) {
21572
21589
  const sanitizedTaskId = sanitizeTaskId2(taskId);
21573
21590
  const relativePath = path9.join("evidence", sanitizedTaskId, "evidence.json");
21591
+ if (relativePath.length > 4096) {
21592
+ return { status: "not_found" };
21593
+ }
21574
21594
  const evidencePath = validateSwarmPath(directory, relativePath);
21575
21595
  const content = await readSwarmFileAsync(directory, relativePath);
21576
21596
  if (content === null) {
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.77.2",
72
+ version: "7.77.4",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -611,7 +611,7 @@ var init_tool_metadata = __esm(() => {
611
611
  agents: ["architect"]
612
612
  },
613
613
  write_final_council_evidence: {
614
- description: "write final council evidence for project completion",
614
+ description: "Persist project-scoped final council evidence to .swarm/evidence/final-council.json. PREREQUISITE: dispatch critic, reviewer, sme, test_engineer, and explorer as project-scoped Agent tasks and collect their CouncilMemberVerdict JSON — this tool synthesizes only. Rejects on insufficient quorum or CONCERNS with unresolved requiredFixes; normalizes verdicts to approved/concerns/rejected. Architect-only.",
615
615
  agents: ["architect"]
616
616
  },
617
617
  skill_generate: {
@@ -17346,6 +17346,14 @@ async function bunWrite(filePath, data) {
17346
17346
  } catch {}
17347
17347
  throw lastError;
17348
17348
  }
17349
+ try {
17350
+ const dirFd = await fsPromises2.open(dir, "r");
17351
+ try {
17352
+ await dirFd.sync();
17353
+ } finally {
17354
+ await dirFd.close();
17355
+ }
17356
+ } catch {}
17349
17357
  const stats = await fsPromises2.stat(filePath);
17350
17358
  return stats.size;
17351
17359
  }
@@ -17670,14 +17678,23 @@ function validateSwarmPath(directory, filename) {
17670
17678
  return resolved;
17671
17679
  }
17672
17680
  async function readSwarmFileAsync(directory, filename) {
17673
- try {
17674
- const resolvedPath = _internals3.validateSwarmPath(directory, filename);
17675
- const file2 = bunFile(resolvedPath);
17676
- const content = await file2.text();
17677
- return content;
17678
- } catch {
17679
- return null;
17681
+ const maxAttempts = 5;
17682
+ const retryDelayMs = 10;
17683
+ for (let attempt = 0;attempt < maxAttempts; attempt++) {
17684
+ try {
17685
+ const resolvedPath = _internals3.validateSwarmPath(directory, filename);
17686
+ const file2 = bunFile(resolvedPath);
17687
+ const content = await file2.text();
17688
+ return content;
17689
+ } catch (err2) {
17690
+ const isNotFound = err2?.code === "ENOENT";
17691
+ if (!isNotFound || attempt === maxAttempts - 1) {
17692
+ return null;
17693
+ }
17694
+ await new Promise((resolve3) => setTimeout(resolve3, retryDelayMs));
17695
+ }
17680
17696
  }
17697
+ return null;
17681
17698
  }
17682
17699
  function estimateTokens(text) {
17683
17700
  if (!text) {
@@ -20808,7 +20825,7 @@ GFS4: `);
20808
20825
  }
20809
20826
  function ReadStream$open() {
20810
20827
  var that = this;
20811
- open(that.path, that.flags, that.mode, function(err2, fd) {
20828
+ open2(that.path, that.flags, that.mode, function(err2, fd) {
20812
20829
  if (err2) {
20813
20830
  if (that.autoClose)
20814
20831
  that.destroy();
@@ -20828,7 +20845,7 @@ GFS4: `);
20828
20845
  }
20829
20846
  function WriteStream$open() {
20830
20847
  var that = this;
20831
- open(that.path, that.flags, that.mode, function(err2, fd) {
20848
+ open2(that.path, that.flags, that.mode, function(err2, fd) {
20832
20849
  if (err2) {
20833
20850
  that.destroy();
20834
20851
  that.emit("error", err2);
@@ -20845,8 +20862,8 @@ GFS4: `);
20845
20862
  return new fs8.WriteStream(path9, options);
20846
20863
  }
20847
20864
  var fs$open = fs8.open;
20848
- fs8.open = open;
20849
- function open(path9, flags2, mode, cb) {
20865
+ fs8.open = open2;
20866
+ function open2(path9, flags2, mode, cb) {
20850
20867
  if (typeof mode === "function")
20851
20868
  cb = mode, mode = null;
20852
20869
  return go$open(path9, flags2, mode, cb);
@@ -22180,6 +22197,9 @@ function wrapFlatRetrospective(flatEntry, taskId) {
22180
22197
  async function loadEvidence(directory, taskId) {
22181
22198
  const sanitizedTaskId = sanitizeTaskId2(taskId);
22182
22199
  const relativePath = path10.join("evidence", sanitizedTaskId, "evidence.json");
22200
+ if (relativePath.length > 4096) {
22201
+ return { status: "not_found" };
22202
+ }
22183
22203
  const evidencePath = validateSwarmPath(directory, relativePath);
22184
22204
  const content = await readSwarmFileAsync(directory, relativePath);
22185
22205
  if (content === null) {
@@ -24393,16 +24413,16 @@ var require_parse = __commonJS((exports, module2) => {
24393
24413
  const analysis = analyzeRepeatedExtglob(body2, opts);
24394
24414
  if ((token.type === "plus" || token.type === "star") && analysis.risky) {
24395
24415
  const safeOutput = analysis.safeOutput ? (token.output ? "" : ONE_CHAR) + (opts.capture ? `(${analysis.safeOutput})` : analysis.safeOutput) : undefined;
24396
- const open = tokens[token.tokensIndex];
24397
- open.type = "text";
24398
- open.value = literal2;
24399
- open.output = safeOutput || utils.escapeRegex(literal2);
24416
+ const open2 = tokens[token.tokensIndex];
24417
+ open2.type = "text";
24418
+ open2.value = literal2;
24419
+ open2.output = safeOutput || utils.escapeRegex(literal2);
24400
24420
  for (let i2 = token.tokensIndex + 1;i2 < tokens.length; i2++) {
24401
24421
  tokens[i2].value = "";
24402
24422
  tokens[i2].output = "";
24403
24423
  delete tokens[i2].suffix;
24404
24424
  }
24405
- state.output = token.output + open.output;
24425
+ state.output = token.output + open2.output;
24406
24426
  state.backtrack = true;
24407
24427
  push({ type: "paren", extglob: true, value, output: "" });
24408
24428
  decrement("parens");
@@ -24622,15 +24642,15 @@ var require_parse = __commonJS((exports, module2) => {
24622
24642
  }
24623
24643
  if (value === "{" && opts.nobrace !== true) {
24624
24644
  increment("braces");
24625
- const open = {
24645
+ const open2 = {
24626
24646
  type: "brace",
24627
24647
  value,
24628
24648
  output: "(",
24629
24649
  outputIndex: state.output.length,
24630
24650
  tokensIndex: state.tokens.length
24631
24651
  };
24632
- braces.push(open);
24633
- push(open);
24652
+ braces.push(open2);
24653
+ push(open2);
24634
24654
  continue;
24635
24655
  }
24636
24656
  if (value === "}") {
@@ -63791,7 +63811,7 @@ async function autoRetireSkills(directory, curatorKnowledgePath, excludeSlugs) {
63791
63811
  return true;
63792
63812
  return false;
63793
63813
  });
63794
- const violations = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").length;
63814
+ const violations = skillUsage.filter((e) => e.complianceVerdict === "violation").length;
63795
63815
  const violationRate = skillUsage.length > 0 ? violations / skillUsage.length : 0;
63796
63816
  let allArchived = false;
63797
63817
  try {
@@ -63991,9 +64011,7 @@ async function readCuratorSummary(directory) {
63991
64011
  async function writeCuratorSummary(directory, summary) {
63992
64012
  const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
63993
64013
  fs20.mkdirSync(path39.dirname(resolvedPath), { recursive: true });
63994
- const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
63995
- await bunWrite(tempPath, JSON.stringify(summary, null, 2));
63996
- fs20.renameSync(tempPath, resolvedPath);
64014
+ await bunWrite(resolvedPath, JSON.stringify(summary, null, 2));
63997
64015
  }
63998
64016
  function normalizeAgentName(name2) {
63999
64017
  const registry3 = swarmState.generatedAgentNames.length > 0 ? swarmState.generatedAgentNames : undefined;
@@ -64396,9 +64414,7 @@ ${phaseDigest.summary}`,
64396
64414
  const evidenceDir = path39.join(directory, ".swarm", "evidence", String(phase));
64397
64415
  fs20.mkdirSync(evidenceDir, { recursive: true });
64398
64416
  const findingsPath = path39.join(evidenceDir, "curator-findings.json");
64399
- const tmpPath = `${findingsPath}.tmp.${Date.now()}`;
64400
- fs20.writeFileSync(tmpPath, JSON.stringify({ findings: knowledgeApplicationFindings }, null, 2));
64401
- fs20.renameSync(tmpPath, findingsPath);
64417
+ await bunWrite(findingsPath, JSON.stringify({ findings: knowledgeApplicationFindings }, null, 2));
64402
64418
  } catch (err2) {
64403
64419
  warn(`[curator] failed to persist application findings: ${err2 instanceof Error ? err2.message : String(err2)}`);
64404
64420
  }
@@ -64456,7 +64472,7 @@ ${phaseDigest.summary}`,
64456
64472
  });
64457
64473
  if (skillUsage.length === 0)
64458
64474
  continue;
64459
- const violations = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").length;
64475
+ const violations = skillUsage.filter((e) => e.complianceVerdict === "violation").length;
64460
64476
  const violationRate = violations / skillUsage.length;
64461
64477
  if (violationRate > REVISION_VIOLATION_THRESHOLD && violationRate <= 0.3) {
64462
64478
  const content = await _internals27.readFileAsync(active.path, "utf-8");
@@ -64464,7 +64480,7 @@ ${phaseDigest.summary}`,
64464
64480
  if (fm && fm.skillOrigin === "promoted_external")
64465
64481
  continue;
64466
64482
  const currentVersion = fm?.version ?? 1;
64467
- const violationContexts = skillUsage.filter((e) => normalizeComplianceVerdict(e.complianceVerdict) === "violated").slice(-10).map((e) => ({
64483
+ const violationContexts = skillUsage.filter((e) => e.complianceVerdict === "violation").slice(-10).map((e) => ({
64468
64484
  taskId: e.taskID,
64469
64485
  agent: e.agentName,
64470
64486
  verdict: e.complianceVerdict,
@@ -68922,9 +68938,9 @@ ${llmOutput}`;
68922
68938
  reportContent = buildDataOnlyReport(planId, planSummary, knowledgeSummary, curatorDigest, proposals, unactionable, retrospectives, driftReports);
68923
68939
  }
68924
68940
  try {
68925
- const { mkdirSync: mkdirSync16, writeFileSync: writeFileSync10 } = await import("node:fs");
68941
+ const { mkdirSync: mkdirSync16, writeFileSync: writeFileSync9 } = await import("node:fs");
68926
68942
  mkdirSync16(path48.dirname(reportPath), { recursive: true });
68927
- writeFileSync10(reportPath, reportContent, "utf-8");
68943
+ writeFileSync9(reportPath, reportContent, "utf-8");
68928
68944
  } catch (err2) {
68929
68945
  const msg = err2 instanceof Error ? err2.message : String(err2);
68930
68946
  return {
@@ -71182,7 +71198,7 @@ var init_gate_bridge = __esm(() => {
71182
71198
  });
71183
71199
 
71184
71200
  // src/services/version-check.ts
71185
- import { existsSync as existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync10 } from "node:fs";
71201
+ import { existsSync as existsSync28, mkdirSync as mkdirSync16, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
71186
71202
  import { homedir as homedir6 } from "node:os";
71187
71203
  import { join as join43 } from "node:path";
71188
71204
  function cacheDir() {
@@ -71212,7 +71228,7 @@ function writeVersionCache(entry) {
71212
71228
  try {
71213
71229
  const dir = cacheDir();
71214
71230
  mkdirSync16(dir, { recursive: true });
71215
- writeFileSync10(cacheFile(), JSON.stringify(entry, null, 2), "utf-8");
71231
+ writeFileSync9(cacheFile(), JSON.stringify(entry, null, 2), "utf-8");
71216
71232
  } catch {}
71217
71233
  }
71218
71234
  function compareVersions(a, b) {
@@ -76813,7 +76829,7 @@ var init_handoff_service = __esm(() => {
76813
76829
  });
76814
76830
 
76815
76831
  // src/session/snapshot-writer.ts
76816
- import { closeSync as closeSync5, fsyncSync as fsyncSync2, mkdirSync as mkdirSync19, openSync as openSync5, renameSync as renameSync12 } from "node:fs";
76832
+ import { closeSync as closeSync5, fsyncSync as fsyncSync2, mkdirSync as mkdirSync19, openSync as openSync5, renameSync as renameSync11 } from "node:fs";
76817
76833
  import * as path59 from "node:path";
76818
76834
  function serializeAgentSession(s) {
76819
76835
  const gateLog = {};
@@ -76932,7 +76948,7 @@ async function writeSnapshot(directory, state) {
76932
76948
  closeSync5(fd);
76933
76949
  }
76934
76950
  } catch {}
76935
- renameSync12(tempPath, resolvedPath);
76951
+ renameSync11(tempPath, resolvedPath);
76936
76952
  } catch (error93) {
76937
76953
  log("[snapshot-writer] write failed", {
76938
76954
  error: error93 instanceof Error ? error93.message : String(error93)
@@ -76965,7 +76981,7 @@ var init_snapshot_writer = __esm(() => {
76965
76981
 
76966
76982
  // src/commands/handoff.ts
76967
76983
  import crypto6 from "node:crypto";
76968
- import { renameSync as renameSync13, unlinkSync as unlinkSync7 } from "node:fs";
76984
+ import { renameSync as renameSync12, unlinkSync as unlinkSync7 } from "node:fs";
76969
76985
  async function handleHandoffCommand(directory, _args) {
76970
76986
  const handoffData = await getHandoffData(directory);
76971
76987
  const markdown = formatHandoffMarkdown(handoffData);
@@ -76974,7 +76990,7 @@ async function handleHandoffCommand(directory, _args) {
76974
76990
  const tempPath = `${resolvedPath}.tmp.${crypto6.randomUUID()}`;
76975
76991
  await bunWrite(tempPath, markdown);
76976
76992
  try {
76977
- renameSync13(tempPath, resolvedPath);
76993
+ renameSync12(tempPath, resolvedPath);
76978
76994
  } catch (renameErr) {
76979
76995
  try {
76980
76996
  unlinkSync7(tempPath);
@@ -76986,7 +77002,7 @@ async function handleHandoffCommand(directory, _args) {
76986
77002
  const promptTempPath = `${promptPath}.tmp.${crypto6.randomUUID()}`;
76987
77003
  await bunWrite(promptTempPath, continuationPrompt);
76988
77004
  try {
76989
- renameSync13(promptTempPath, promptPath);
77005
+ renameSync12(promptTempPath, promptPath);
76990
77006
  } catch (renameErr) {
76991
77007
  try {
76992
77008
  unlinkSync7(promptTempPath);
@@ -89909,7 +89925,7 @@ var init_reset_session = __esm(() => {
89909
89925
  });
89910
89926
 
89911
89927
  // src/summaries/manager.ts
89912
- import { mkdirSync as mkdirSync22, readdirSync as readdirSync17, renameSync as renameSync14, rmSync as rmSync5, statSync as statSync18 } from "node:fs";
89928
+ import { mkdirSync as mkdirSync22, readdirSync as readdirSync17, renameSync as renameSync13, rmSync as rmSync5, statSync as statSync18 } from "node:fs";
89913
89929
  import * as path84 from "node:path";
89914
89930
  function sanitizeSummaryId(id) {
89915
89931
  if (!id || id.length === 0) {
@@ -89959,7 +89975,7 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
89959
89975
  const tempPath = path84.join(summaryDir, `${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);
89960
89976
  try {
89961
89977
  await bunWrite(tempPath, entryJson);
89962
- renameSync14(tempPath, summaryPath);
89978
+ renameSync13(tempPath, summaryPath);
89963
89979
  } catch (error93) {
89964
89980
  try {
89965
89981
  rmSync5(tempPath, { force: true });
@@ -97448,7 +97464,7 @@ __export(exports_evidence_summary_integration, {
97448
97464
  createEvidenceSummaryIntegration: () => createEvidenceSummaryIntegration,
97449
97465
  EvidenceSummaryIntegration: () => EvidenceSummaryIntegration
97450
97466
  });
97451
- import { existsSync as existsSync50, mkdirSync as mkdirSync24, writeFileSync as writeFileSync14 } from "node:fs";
97467
+ import { existsSync as existsSync50, mkdirSync as mkdirSync24, writeFileSync as writeFileSync13 } from "node:fs";
97452
97468
  import * as path90 from "node:path";
97453
97469
  function persistSummary(projectDir, artifact, filename) {
97454
97470
  const swarmPath = path90.join(projectDir, ".swarm");
@@ -97457,7 +97473,7 @@ function persistSummary(projectDir, artifact, filename) {
97457
97473
  }
97458
97474
  const artifactPath = path90.join(swarmPath, filename);
97459
97475
  const content = JSON.stringify(artifact, null, 2);
97460
- writeFileSync14(artifactPath, content, "utf-8");
97476
+ writeFileSync13(artifactPath, content, "utf-8");
97461
97477
  log("[EvidenceSummaryIntegration] Summary persisted", {
97462
97478
  path: artifactPath,
97463
97479
  size: content.length
@@ -98467,17 +98483,17 @@ import {
98467
98483
  existsSync as existsSync62,
98468
98484
  mkdirSync as mkdirSync31,
98469
98485
  readFileSync as readFileSync41,
98470
- renameSync as renameSync20,
98486
+ renameSync as renameSync19,
98471
98487
  unlinkSync as unlinkSync15,
98472
- writeFileSync as writeFileSync21
98488
+ writeFileSync as writeFileSync20
98473
98489
  } from "node:fs";
98474
98490
  import * as path103 from "node:path";
98475
98491
  function writeRawSidecar(absPath, bundle) {
98476
98492
  mkdirSync31(path103.dirname(absPath), { recursive: true });
98477
98493
  const tempFile = `${absPath}.tmp-${Date.now()}-${process.pid}`;
98478
98494
  try {
98479
- writeFileSync21(tempFile, JSON.stringify(bundle, null, 2), "utf-8");
98480
- renameSync20(tempFile, absPath);
98495
+ writeFileSync20(tempFile, JSON.stringify(bundle, null, 2), "utf-8");
98496
+ renameSync19(tempFile, absPath);
98481
98497
  } finally {
98482
98498
  if (existsSync62(tempFile)) {
98483
98499
  try {
@@ -105831,7 +105847,7 @@ init_state();
105831
105847
  init_utils();
105832
105848
  init_bun_compat();
105833
105849
  init_utils2();
105834
- import { renameSync as renameSync17, unlinkSync as unlinkSync13 } from "node:fs";
105850
+ import { renameSync as renameSync16, unlinkSync as unlinkSync13 } from "node:fs";
105835
105851
  import * as nodePath2 from "node:path";
105836
105852
  function createAgentActivityHooks(config3, directory) {
105837
105853
  if (config3.hooks?.agent_activity === false) {
@@ -105906,7 +105922,7 @@ async function doFlush(directory) {
105906
105922
  const tempPath = `${path98}.tmp`;
105907
105923
  try {
105908
105924
  await bunWrite(tempPath, updated);
105909
- renameSync17(tempPath, path98);
105925
+ renameSync16(tempPath, path98);
105910
105926
  } catch (writeError) {
105911
105927
  try {
105912
105928
  unlinkSync13(tempPath);
@@ -114359,13 +114375,14 @@ function evictCooldownMap() {
114359
114375
  }
114360
114376
  function execGit2(directory, args2, opts) {
114361
114377
  return new Promise((resolve46, reject) => {
114362
- child_process7.execFile("git", args2, {
114378
+ const proc = child_process7.execFile("git", args2, {
114363
114379
  encoding: "utf-8",
114364
114380
  cwd: directory,
114365
114381
  timeout: opts.timeoutMs,
114366
114382
  maxBuffer: opts.maxBuffer,
114367
114383
  stdio: ["ignore", "pipe", "pipe"]
114368
114384
  }, (error93, stdout) => {
114385
+ proc.kill();
114369
114386
  if (error93) {
114370
114387
  reject(error93);
114371
114388
  return;
@@ -114467,15 +114484,26 @@ async function dispatchReviewer(directory, prompt, agentName, timeoutMs) {
114467
114484
  client.session.delete({ path: { id: sessionId } }).catch(() => {});
114468
114485
  }
114469
114486
  }
114487
+ var _eventWriteLockChain = Promise.resolve();
114488
+ function withEventWriteLock(fn2) {
114489
+ let release;
114490
+ _eventWriteLockChain = new Promise((r) => {
114491
+ release = r;
114492
+ });
114493
+ try {
114494
+ return fn2();
114495
+ } finally {
114496
+ release();
114497
+ }
114498
+ }
114470
114499
  function writeAutoReviewEvent(directory, event) {
114471
114500
  try {
114472
114501
  const eventsPath = validateSwarmPath(directory, "events.jsonl");
114473
- const existing = fs71.existsSync(eventsPath) ? fs71.readFileSync(eventsPath, "utf-8") : "";
114474
114502
  const line = `${JSON.stringify(event)}
114475
114503
  `;
114476
- const tmpPath = `${eventsPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
114477
- fs71.writeFileSync(tmpPath, existing + line, "utf-8");
114478
- fs71.renameSync(tmpPath, eventsPath);
114504
+ withEventWriteLock(() => {
114505
+ fs71.appendFileSync(eventsPath, line, "utf-8");
114506
+ });
114479
114507
  } catch (err2) {
114480
114508
  warn(`[auto-review] event write failed: ${err2 instanceof Error ? err2.message : String(err2)}`);
114481
114509
  }
@@ -114793,7 +114821,7 @@ init_task_file();
114793
114821
  init_logger();
114794
114822
  init_knowledge_store();
114795
114823
  var import_proper_lockfile9 = __toESM(require_proper_lockfile(), 1);
114796
- import { existsSync as existsSync71 } from "node:fs";
114824
+ import { existsSync as existsSync70 } from "node:fs";
114797
114825
  import { appendFile as appendFile11, mkdir as mkdir26, readFile as readFile27 } from "node:fs/promises";
114798
114826
  import * as path123 from "node:path";
114799
114827
  function resolveApplicationLogPath(directory) {
@@ -114873,13 +114901,13 @@ async function bumpCountersBatch(directory, bumps) {
114873
114901
  updated = true;
114874
114902
  }
114875
114903
  }
114876
- return updated;
114904
+ return updated ? entries : null;
114877
114905
  };
114878
114906
  const swarmPath = resolveSwarmKnowledgePath(directory);
114879
- await transactKnowledge(swarmPath, (swarm) => applyOne(swarm) ? swarm : null);
114907
+ await transactKnowledge(swarmPath, applyOne);
114880
114908
  const hivePath = resolveHiveKnowledgePath();
114881
- if (existsSync71(hivePath)) {
114882
- await transactKnowledge(hivePath, (hive) => applyOne(hive) ? hive : null);
114909
+ if (existsSync70(hivePath)) {
114910
+ await transactKnowledge(hivePath, applyOne);
114883
114911
  }
114884
114912
  }
114885
114913
  async function bumpCounters(directory, ids, field) {
@@ -115852,7 +115880,7 @@ init_extractors();
115852
115880
  // src/hooks/phase-directives.ts
115853
115881
  init_knowledge_events();
115854
115882
  init_knowledge_store();
115855
- import { existsSync as existsSync72 } from "node:fs";
115883
+ import { existsSync as existsSync71 } from "node:fs";
115856
115884
  async function collectPhaseDirectiveIds(directory, phaseLabel) {
115857
115885
  const events = await readKnowledgeEvents(directory);
115858
115886
  const ids = new Set;
@@ -115872,7 +115900,7 @@ async function readEntriesById(directory) {
115872
115900
  for (const e of swarm)
115873
115901
  map3.set(e.id, e);
115874
115902
  const hivePath = resolveHiveKnowledgePath();
115875
- if (existsSync72(hivePath)) {
115903
+ if (existsSync71(hivePath)) {
115876
115904
  const hive = await readKnowledge(hivePath);
115877
115905
  for (const e of hive)
115878
115906
  if (!map3.has(e.id))
@@ -117763,7 +117791,7 @@ init_schema();
117763
117791
  // src/services/directive-predicate-runner.ts
117764
117792
  init_bun_compat();
117765
117793
  init_logger();
117766
- import { existsSync as existsSync75 } from "node:fs";
117794
+ import { existsSync as existsSync74 } from "node:fs";
117767
117795
  import * as path129 from "node:path";
117768
117796
  var PREDICATE_TIMEOUT_MS = 15000;
117769
117797
  var TOOL_BINARY_ALLOWLIST = new Set([
@@ -117805,7 +117833,7 @@ function findBinaryInPath(binary2) {
117805
117833
  if (!dir)
117806
117834
  continue;
117807
117835
  const candidate = path129.join(dir, exeName);
117808
- if (existsSync75(candidate))
117836
+ if (existsSync74(candidate))
117809
117837
  return candidate;
117810
117838
  }
117811
117839
  return null;
@@ -119639,7 +119667,7 @@ init_state2();
119639
119667
  init_utils2();
119640
119668
  init_state();
119641
119669
  init_bun_compat();
119642
- import { renameSync as renameSync23 } from "node:fs";
119670
+ import { renameSync as renameSync21 } from "node:fs";
119643
119671
  var TRANSIENT_SESSION_FIELDS = [
119644
119672
  { name: "revisionLimitHit", resetValue: false },
119645
119673
  { name: "coderRevisions", resetValue: 0 },
@@ -119782,7 +119810,7 @@ async function readSnapshot(directory) {
119782
119810
  if (parsed.version !== 1 && parsed.version !== 2) {
119783
119811
  try {
119784
119812
  const quarantinePath = validateSwarmPath(directory, "session/state.json.quarantine");
119785
- renameSync23(resolvedPath, quarantinePath);
119813
+ renameSync21(resolvedPath, quarantinePath);
119786
119814
  } catch {}
119787
119815
  return null;
119788
119816
  }
@@ -119881,15 +119909,15 @@ init_zod();
119881
119909
  init_path_security();
119882
119910
  init_create_tool();
119883
119911
  import {
119884
- existsSync as existsSync77,
119912
+ existsSync as existsSync76,
119885
119913
  mkdirSync as mkdirSync32,
119886
119914
  mkdtempSync as mkdtempSync2,
119887
- readFileSync as readFileSync50,
119915
+ readFileSync as readFileSync49,
119888
119916
  realpathSync as realpathSync16,
119889
- renameSync as renameSync24,
119917
+ renameSync as renameSync22,
119890
119918
  rmdirSync,
119891
119919
  unlinkSync as unlinkSync18,
119892
- writeFileSync as writeFileSync23
119920
+ writeFileSync as writeFileSync21
119893
119921
  } from "node:fs";
119894
119922
  import * as path135 from "node:path";
119895
119923
  var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
@@ -120241,16 +120269,16 @@ function atomicWriteFileSync2(targetPath, content) {
120241
120269
  tempPath = path135.join(dir, `${tempPrefix}.tmp`);
120242
120270
  }
120243
120271
  try {
120244
- writeFileSync23(tempPath, content, "utf-8");
120245
- renameSync24(tempPath, targetPath);
120272
+ writeFileSync21(tempPath, content, "utf-8");
120273
+ renameSync22(tempPath, targetPath);
120246
120274
  } finally {
120247
- if (existsSync77(tempPath)) {
120275
+ if (existsSync76(tempPath)) {
120248
120276
  try {
120249
120277
  unlinkSync18(tempPath);
120250
120278
  } catch {}
120251
120279
  }
120252
120280
  const tempDir = path135.dirname(tempPath);
120253
- if (tempDir !== dir && existsSync77(tempDir)) {
120281
+ if (tempDir !== dir && existsSync76(tempDir)) {
120254
120282
  try {
120255
120283
  rmdirSync(tempDir);
120256
120284
  } catch {}
@@ -120327,7 +120355,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
120327
120355
  };
120328
120356
  }
120329
120357
  const parentDir = path135.dirname(fullPath);
120330
- if (!existsSync77(parentDir)) {
120358
+ if (!existsSync76(parentDir)) {
120331
120359
  return {
120332
120360
  file: targetPath,
120333
120361
  status: "error",
@@ -120343,7 +120371,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
120343
120371
  ]
120344
120372
  };
120345
120373
  }
120346
- if (existsSync77(fullPath)) {
120374
+ if (existsSync76(fullPath)) {
120347
120375
  return {
120348
120376
  file: targetPath,
120349
120377
  status: "error",
@@ -120418,7 +120446,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
120418
120446
  ]
120419
120447
  };
120420
120448
  }
120421
- if (!existsSync77(fullPath)) {
120449
+ if (!existsSync76(fullPath)) {
120422
120450
  return {
120423
120451
  file: targetPath,
120424
120452
  status: "error",
@@ -120462,7 +120490,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
120462
120490
  hunksFailed: 0
120463
120491
  };
120464
120492
  }
120465
- if (!existsSync77(fullPath)) {
120493
+ if (!existsSync76(fullPath)) {
120466
120494
  return {
120467
120495
  file: targetPath,
120468
120496
  status: "error",
@@ -120480,7 +120508,7 @@ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allo
120480
120508
  }
120481
120509
  let content;
120482
120510
  try {
120483
- content = readFileSync50(fullPath, "utf-8");
120511
+ content = readFileSync49(fullPath, "utf-8");
120484
120512
  } catch (err2) {
120485
120513
  return {
120486
120514
  file: targetPath,
@@ -120613,7 +120641,7 @@ var applyPatch = createSwarmTool({
120613
120641
  const dryRun = obj.dryRun ?? false;
120614
120642
  const allowCreates = obj.allowCreates ?? false;
120615
120643
  const allowDeletes = obj.allowDeletes ?? false;
120616
- if (!existsSync77(directory)) {
120644
+ if (!existsSync76(directory)) {
120617
120645
  return JSON.stringify(buildErrorResult("Workspace directory does not exist"), null, 2);
120618
120646
  }
120619
120647
  if (files.length === 0) {
@@ -122432,7 +122460,7 @@ ${body2}`);
122432
122460
  // src/council/council-evidence-writer.ts
122433
122461
  init_zod();
122434
122462
  init_task_file();
122435
- import { appendFileSync as appendFileSync15, existsSync as existsSync82, mkdirSync as mkdirSync34, readFileSync as readFileSync56 } from "node:fs";
122463
+ import { appendFileSync as appendFileSync16, existsSync as existsSync81, mkdirSync as mkdirSync34, readFileSync as readFileSync55 } from "node:fs";
122436
122464
  import { join as join113 } from "node:path";
122437
122465
  var EVIDENCE_DIR2 = ".swarm/evidence";
122438
122466
  var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
@@ -122476,9 +122504,9 @@ async function writeCouncilEvidence(workingDir, synthesis) {
122476
122504
  const filePath = taskEvidencePath(workingDir, synthesis.taskId);
122477
122505
  await _internals78.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
122478
122506
  const existingRoot = Object.create(null);
122479
- if (existsSync82(filePath)) {
122507
+ if (existsSync81(filePath)) {
122480
122508
  try {
122481
- const parsed = EvidenceFileSchema.parse(JSON.parse(readFileSync56(filePath, "utf-8")));
122509
+ const parsed = EvidenceFileSchema.parse(JSON.parse(readFileSync55(filePath, "utf-8")));
122482
122510
  safeAssignOwnProps(existingRoot, parsed);
122483
122511
  } catch {}
122484
122512
  }
@@ -122515,7 +122543,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
122515
122543
  timestamp: synthesis.timestamp,
122516
122544
  vetoedBy: synthesis.vetoedBy
122517
122545
  });
122518
- appendFileSync15(join113(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
122546
+ appendFileSync16(join113(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
122519
122547
  `);
122520
122548
  } catch (auditError) {
122521
122549
  console.warn(`writeCouncilEvidence: failed to append round-history audit log: ${auditError instanceof Error ? auditError.message : String(auditError)}`);
@@ -122870,7 +122898,7 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
122870
122898
 
122871
122899
  // src/council/criteria-store.ts
122872
122900
  init_zod();
122873
- import { existsSync as existsSync83, mkdirSync as mkdirSync35, readFileSync as readFileSync57, writeFileSync as writeFileSync25 } from "node:fs";
122901
+ import { existsSync as existsSync82, mkdirSync as mkdirSync35, readFileSync as readFileSync56, writeFileSync as writeFileSync23 } from "node:fs";
122874
122902
  import { join as join114 } from "node:path";
122875
122903
  var COUNCIL_DIR = ".swarm/council";
122876
122904
  var CouncilCriteriaSchema = exports_external.object({
@@ -122890,14 +122918,14 @@ function writeCriteria(workingDir, taskId, criteria) {
122890
122918
  criteria,
122891
122919
  declaredAt: new Date().toISOString()
122892
122920
  };
122893
- writeFileSync25(join114(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
122921
+ writeFileSync23(join114(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
122894
122922
  }
122895
122923
  function readCriteria(workingDir, taskId) {
122896
122924
  const filePath = join114(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
122897
- if (!existsSync83(filePath))
122925
+ if (!existsSync82(filePath))
122898
122926
  return null;
122899
122927
  try {
122900
- return CouncilCriteriaSchema.parse(JSON.parse(readFileSync57(filePath, "utf-8")));
122928
+ return CouncilCriteriaSchema.parse(JSON.parse(readFileSync56(filePath, "utf-8")));
122901
122929
  } catch {
122902
122930
  return null;
122903
122931
  }
@@ -128887,7 +128915,7 @@ init_zod();
128887
128915
  init_config();
128888
128916
  init_knowledge_store();
128889
128917
  init_create_tool();
128890
- import { existsSync as existsSync89 } from "node:fs";
128918
+ import { existsSync as existsSync88 } from "node:fs";
128891
128919
  var DEFAULT_LIMIT = 10;
128892
128920
  var MAX_LESSON_LENGTH = 200;
128893
128921
  var VALID_CATEGORIES3 = [
@@ -128963,14 +128991,14 @@ function validateLimit(limit) {
128963
128991
  }
128964
128992
  async function readSwarmKnowledge(directory) {
128965
128993
  const swarmPath = resolveSwarmKnowledgePath(directory);
128966
- if (!existsSync89(swarmPath)) {
128994
+ if (!existsSync88(swarmPath)) {
128967
128995
  return [];
128968
128996
  }
128969
128997
  return readKnowledge(swarmPath);
128970
128998
  }
128971
128999
  async function readHiveKnowledge() {
128972
129000
  const hivePath = resolveHiveKnowledgePath();
128973
- if (!existsSync89(hivePath)) {
129001
+ if (!existsSync88(hivePath)) {
128974
129002
  return [];
128975
129003
  }
128976
129004
  return readKnowledge(hivePath);
@@ -131015,7 +131043,7 @@ import * as path155 from "node:path";
131015
131043
 
131016
131044
  // src/mutation/engine.ts
131017
131045
  import { spawnSync as spawnSync11 } from "node:child_process";
131018
- import { unlinkSync as unlinkSync19, writeFileSync as writeFileSync27 } from "node:fs";
131046
+ import { unlinkSync as unlinkSync19, writeFileSync as writeFileSync25 } from "node:fs";
131019
131047
  import * as path154 from "node:path";
131020
131048
 
131021
131049
  // src/mutation/equivalence.ts
@@ -131205,7 +131233,7 @@ async function executeMutation(patch, testCommand, testFiles, workingDir) {
131205
131233
  const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
131206
131234
  patchFile = path154.join(workingDir, `.mutation_patch_${safeId2}.diff`);
131207
131235
  try {
131208
- writeFileSync27(patchFile, patch.patch);
131236
+ writeFileSync25(patchFile, patch.patch);
131209
131237
  } catch (writeErr) {
131210
131238
  error93 = `Failed to write patch file: ${writeErr}`;
131211
131239
  outcome = "error";
@@ -132623,6 +132651,17 @@ async function runFinalCouncilGate(ctx) {
132623
132651
  const gateWarnings = [];
132624
132652
  try {
132625
132653
  const preamble = await resolveGatePreamble(dir, sessionID);
132654
+ if (!preamble.resolved || !preamble.plan) {
132655
+ const warning = "Final council gate: plan.json is missing. If final_council is required, the gate cannot be verified.";
132656
+ gateWarnings.push(warning);
132657
+ safeWarn(`[phase_complete] ${warning}`, undefined);
132658
+ return {
132659
+ blocked: false,
132660
+ agentsDispatched,
132661
+ agentsMissing: [],
132662
+ warnings: [warning]
132663
+ };
132664
+ }
132626
132665
  if (preamble.resolved && preamble.plan) {
132627
132666
  const lastPhaseId = preamble.plan.phases[preamble.plan.phases.length - 1]?.id;
132628
132667
  if (lastPhaseId !== undefined && phase === lastPhaseId) {
@@ -132638,6 +132677,23 @@ async function runFinalCouncilGate(ctx) {
132638
132677
  if (typeof entry.type === "string" && entry.type === "final-council" && typeof entry.verdict === "string") {
132639
132678
  fcVerdictFound = true;
132640
132679
  _fcVerdict = entry.verdict;
132680
+ const now = new Date;
132681
+ const fcTime = entry.timestamp ? new Date(entry.timestamp) : null;
132682
+ if (fcTime && !Number.isNaN(fcTime.getTime()) && fcTime.getTime() > now.getTime()) {
132683
+ return {
132684
+ blocked: true,
132685
+ reason: "FINAL_COUNCIL_FUTURE_TIMESTAMP",
132686
+ message: `Phase ${phase} cannot be completed: final council evidence timestamp is in the future.`,
132687
+ agentsDispatched,
132688
+ agentsMissing: [],
132689
+ warnings: []
132690
+ };
132691
+ }
132692
+ if (fcTime && !Number.isNaN(fcTime.getTime()) && now.getTime() - fcTime.getTime() > 24 * 60 * 60 * 1000) {
132693
+ const warning = "Final council evidence is older than 24 hours. Consider re-running the final council for fresh review.";
132694
+ gateWarnings.push(warning);
132695
+ safeWarn(`[phase_complete] ${warning}`, undefined);
132696
+ }
132641
132697
  if (preamble.plan) {
132642
132698
  const currentPlanId = derivePlanId(preamble.plan);
132643
132699
  if (entry.plan_id && entry.plan_id !== currentPlanId) {
@@ -133372,58 +133428,56 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
133372
133428
  safeWarn
133373
133429
  };
133374
133430
  if (hasActiveTurboMode(sessionID)) {
133375
- warnings.push(`Turbo mode active — skipped completion-verify, drift-verifier, hallucination-guard, mutation-gate, phase-council, and final-council gates for phase ${phase}.`);
133431
+ warnings.push(`Turbo mode active — skipped completion-verify, drift-verifier, hallucination-guard, mutation-gate, and phase-council gates for phase ${phase}.`);
133376
133432
  } else {
133377
133433
  {
133378
- const gateResult = await runCompletionVerifyGate(gateCtx);
133379
- if (gateResult.blocked) {
133380
- return blockedResult(phase, gateResult);
133434
+ const gateResult2 = await runCompletionVerifyGate(gateCtx);
133435
+ if (gateResult2.blocked) {
133436
+ return blockedResult(phase, gateResult2);
133381
133437
  }
133382
- warnings.push(...gateResult.warnings);
133438
+ warnings.push(...gateResult2.warnings);
133383
133439
  }
133384
133440
  {
133385
- const gateResult = await runDriftGate(gateCtx);
133386
- if (gateResult.blocked) {
133387
- return blockedResult(phase, gateResult);
133441
+ const gateResult2 = await runDriftGate(gateCtx);
133442
+ if (gateResult2.blocked) {
133443
+ return blockedResult(phase, gateResult2);
133388
133444
  }
133389
- warnings.push(...gateResult.warnings);
133445
+ warnings.push(...gateResult2.warnings);
133390
133446
  }
133391
133447
  {
133392
- const gateResult = await runHallucinationGate(gateCtx);
133393
- if (gateResult.blocked) {
133394
- return blockedResult(phase, gateResult);
133448
+ const gateResult2 = await runHallucinationGate(gateCtx);
133449
+ if (gateResult2.blocked) {
133450
+ return blockedResult(phase, gateResult2);
133395
133451
  }
133396
- warnings.push(...gateResult.warnings);
133452
+ warnings.push(...gateResult2.warnings);
133397
133453
  }
133398
133454
  {
133399
- const gateResult = await runMutationGate(gateCtx);
133400
- if (gateResult.blocked) {
133401
- return blockedResult(phase, gateResult);
133455
+ const gateResult2 = await runMutationGate(gateCtx);
133456
+ if (gateResult2.blocked) {
133457
+ return blockedResult(phase, gateResult2);
133402
133458
  }
133403
- warnings.push(...gateResult.warnings);
133459
+ warnings.push(...gateResult2.warnings);
133404
133460
  }
133405
133461
  {
133406
- const gateResult = await runPhaseCouncilGate(gateCtx);
133407
- if (gateResult.blocked) {
133408
- return blockedResult(phase, gateResult);
133462
+ const gateResult2 = await runPhaseCouncilGate(gateCtx);
133463
+ if (gateResult2.blocked) {
133464
+ return blockedResult(phase, gateResult2);
133409
133465
  }
133410
- warnings.push(...gateResult.warnings);
133466
+ warnings.push(...gateResult2.warnings);
133411
133467
  }
133412
133468
  }
133413
133469
  if (config3.architectural_supervision?.enabled && config3.architectural_supervision.mode === "gate") {
133414
- const gateResult = await runArchitectureSupervisorGate(gateCtx);
133415
- if (gateResult.blocked) {
133416
- return blockedResult(phase, gateResult);
133470
+ const gateResult2 = await runArchitectureSupervisorGate(gateCtx);
133471
+ if (gateResult2.blocked) {
133472
+ return blockedResult(phase, gateResult2);
133417
133473
  }
133418
- warnings.push(...gateResult.warnings);
133474
+ warnings.push(...gateResult2.warnings);
133419
133475
  }
133420
- if (!hasActiveTurboMode(sessionID)) {
133421
- const gateResult = await runFinalCouncilGate(gateCtx);
133422
- if (gateResult.blocked) {
133423
- return blockedResult(phase, gateResult);
133424
- }
133425
- warnings.push(...gateResult.warnings);
133476
+ const gateResult = await runFinalCouncilGate(gateCtx);
133477
+ if (gateResult.blocked) {
133478
+ return blockedResult(phase, gateResult);
133426
133479
  }
133480
+ warnings.push(...gateResult.warnings);
133427
133481
  {
133428
133482
  const approval = verifyFullAutoPhaseApproval(dir, sessionID, phase, config3);
133429
133483
  if (!approval.ok) {
@@ -141582,12 +141636,12 @@ ${content}
141582
141636
  init_zod();
141583
141637
  init_loader();
141584
141638
  import {
141585
- existsSync as existsSync104,
141639
+ existsSync as existsSync103,
141586
141640
  mkdirSync as mkdirSync41,
141587
- readFileSync as readFileSync82,
141588
- renameSync as renameSync26,
141641
+ readFileSync as readFileSync81,
141642
+ renameSync as renameSync24,
141589
141643
  unlinkSync as unlinkSync21,
141590
- writeFileSync as writeFileSync33
141644
+ writeFileSync as writeFileSync31
141591
141645
  } from "node:fs";
141592
141646
  import path179 from "node:path";
141593
141647
  init_create_tool();
@@ -141758,7 +141812,7 @@ var submit_phase_council_verdicts = createSwarmTool({
141758
141812
  function getPhaseMutationGapFinding(phaseNumber, workingDir) {
141759
141813
  const mutationGatePath = path179.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
141760
141814
  try {
141761
- const raw = readFileSync82(mutationGatePath, "utf-8");
141815
+ const raw = readFileSync81(mutationGatePath, "utf-8");
141762
141816
  const parsed = JSON.parse(raw);
141763
141817
  const gateEntry = (parsed.entries ?? []).find((entry) => entry?.type === "mutation-gate");
141764
141818
  if (!gateEntry) {
@@ -141854,10 +141908,10 @@ function writePhaseCouncilEvidence(workingDir, synthesis, provenance) {
141854
141908
  };
141855
141909
  const tempFile = `${evidenceFile}.tmp-${Date.now()}`;
141856
141910
  try {
141857
- writeFileSync33(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
141858
- renameSync26(tempFile, evidenceFile);
141911
+ writeFileSync31(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
141912
+ renameSync24(tempFile, evidenceFile);
141859
141913
  } finally {
141860
- if (existsSync104(tempFile)) {
141914
+ if (existsSync103(tempFile)) {
141861
141915
  unlinkSync21(tempFile);
141862
141916
  }
141863
141917
  }
@@ -144573,18 +144627,18 @@ function safeFromCodePoint(code) {
144573
144627
  return "";
144574
144628
  }
144575
144629
  }
144576
- function stripSpans(input, open3, close) {
144630
+ function stripSpans(input, open4, close) {
144577
144631
  const lower = input.toLowerCase();
144578
144632
  let out2 = "";
144579
144633
  let i2 = 0;
144580
144634
  while (i2 < input.length) {
144581
- const start2 = lower.indexOf(open3, i2);
144635
+ const start2 = lower.indexOf(open4, i2);
144582
144636
  if (start2 === -1) {
144583
144637
  out2 += input.slice(i2);
144584
144638
  break;
144585
144639
  }
144586
144640
  out2 += input.slice(i2, start2);
144587
- const end = lower.indexOf(close, start2 + open3.length);
144641
+ const end = lower.indexOf(close, start2 + open4.length);
144588
144642
  if (end === -1)
144589
144643
  break;
144590
144644
  i2 = end + close.length;
@@ -145596,7 +145650,7 @@ var VerdictSchema3 = exports_external.object({
145596
145650
  durationMs: exports_external.number().nonnegative()
145597
145651
  });
145598
145652
  var ArgsSchema9 = exports_external.object({
145599
- phase: exports_external.number().int().min(1),
145653
+ phase: exports_external.number().int().min(1).max(1000),
145600
145654
  projectSummary: exports_external.string().min(1),
145601
145655
  roundNumber: exports_external.number().int().min(1).max(10).optional(),
145602
145656
  verdicts: exports_external.array(VerdictSchema3).min(1).max(5)
@@ -145651,7 +145705,16 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
145651
145705
  }, null, 2);
145652
145706
  }
145653
145707
  const plan = await loadPlan(directory);
145654
- const planId = plan ? derivePlanId(plan) : "unknown";
145708
+ if (!plan) {
145709
+ return JSON.stringify({
145710
+ success: false,
145711
+ reason: "plan_not_found",
145712
+ message: "Cannot write final council evidence: plan.json not found. The plan must be loaded and available before writing final council evidence.",
145713
+ phase: input.phase,
145714
+ plan_id: "unknown"
145715
+ }, null, 2);
145716
+ }
145717
+ const planId = derivePlanId(plan);
145655
145718
  const normalizedVerdict = normalizeFinalVerdict(synthesis.overallVerdict, synthesis.requiredFixes.length);
145656
145719
  const evidenceEntry = {
145657
145720
  type: "final-council",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.77.2",
3
+ "version": "7.77.4",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",