opencode-swarm 7.11.1 → 7.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ var package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "opencode-swarm",
36
- version: "7.11.1",
36
+ version: "7.13.0",
37
37
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
38
38
  main: "dist/index.js",
39
39
  types: "dist/index.d.ts",
@@ -23769,6 +23769,13 @@ var init_normalize_tool_name = __esm(() => {
23769
23769
  import * as fsSync2 from "node:fs";
23770
23770
  import * as fs8 from "node:fs/promises";
23771
23771
  import * as path10 from "node:path";
23772
+ function extractStatusCode(errorMsg) {
23773
+ const match = errorMsg.match(/\b(408|429|500|502|503|504|529)\b/);
23774
+ if (match) {
23775
+ return parseInt(match[1], 10);
23776
+ }
23777
+ return null;
23778
+ }
23772
23779
  function getStoredInputArgs(callID) {
23773
23780
  return storedInputArgs.get(callID);
23774
23781
  }
@@ -24977,14 +24984,40 @@ function createGuardrailsHooks(directory, directoryOrConfig, config2, authorityC
24977
24984
  if (hasError) {
24978
24985
  const outputStr = typeof output.output === "string" ? output.output : "";
24979
24986
  const errorContent = output.error ?? outputStr;
24987
+ const extractedStatus = typeof errorContent === "string" ? extractStatusCode(errorContent) : null;
24988
+ const isTransientStatusCode = extractedStatus !== null && TRANSIENT_STATUS_CODES.has(extractedStatus);
24980
24989
  const isTransientPatternMatch = typeof errorContent === "string" && TRANSIENT_MODEL_ERROR_PATTERN.test(errorContent);
24981
- const isTransient = !!session && isTransientPatternMatch && window2.transientRetryCount < cfg.max_transient_retries;
24982
- if (!isTransient) {
24983
- window2.consecutiveErrors++;
24984
- } else {
24990
+ const isTransientMatch = isTransientStatusCode || isTransientPatternMatch;
24991
+ const isTransient = !!session && isTransientMatch && window2.transientRetryCount < cfg.max_transient_retries;
24992
+ const isDegraded = !isTransient && typeof errorContent === "string" && DEGRADED_ERROR_PATTERN.test(errorContent);
24993
+ if (isTransient) {
24985
24994
  window2.transientRetryCount++;
24995
+ } else if (isDegraded) {
24996
+ const isContentFilter = typeof errorContent === "string" && CONTENT_FILTER_PATTERN.test(errorContent);
24997
+ if (session && !session.modelFallbackExhausted) {
24998
+ session.model_fallback_index++;
24999
+ const baseAgentName = session.agentName ? session.agentName.replace(/^[^_]+[_]/, "") : "";
25000
+ const swarmAgents = getSwarmAgents();
25001
+ const fallbackModels = swarmAgents?.[baseAgentName]?.fallback_models;
25002
+ session.modelFallbackExhausted = !fallbackModels || session.model_fallback_index > fallbackModels.length;
25003
+ session.pendingAdvisoryMessages ??= [];
25004
+ if (isContentFilter) {
25005
+ session.pendingAdvisoryMessages.push(`DEGRADED: Content policy violation detected (content filter). Fallback model ${session.model_fallback_index}/${fallbackModels?.length ?? 0} considered. ` + `The input may need content modification to comply with provider policies.`);
25006
+ } else {
25007
+ session.pendingAdvisoryMessages.push(`DEGRADED: Context-limit or token-limit error detected. Fallback model ${session.model_fallback_index}/${fallbackModels?.length ?? 0} considered. ` + `Consider reducing input size or using /swarm handoff to switch models.`);
25008
+ }
25009
+ } else if (session) {
25010
+ session.pendingAdvisoryMessages ??= [];
25011
+ if (isContentFilter) {
25012
+ session.pendingAdvisoryMessages.push(`DEGRADED: Content policy violation detected (content filter). No fallback models available. ` + `The input may need content modification to comply with provider policies.`);
25013
+ } else {
25014
+ session.pendingAdvisoryMessages.push(`DEGRADED: Context-limit or token-limit error detected. No fallback models available. ` + `Consider reducing input size or add "fallback_models" config.`);
25015
+ }
25016
+ }
25017
+ } else {
25018
+ window2.consecutiveErrors++;
24986
25019
  }
24987
- if (session && isTransientPatternMatch && !session.modelFallbackExhausted) {
25020
+ if (session && isTransientMatch && !session.modelFallbackExhausted && !isDegraded) {
24988
25021
  session.model_fallback_index++;
24989
25022
  const baseAgentName = session.agentName ? session.agentName.replace(/^[^_]+[_]/, "") : "";
24990
25023
  const swarmAgents = getSwarmAgents();
@@ -25005,6 +25038,12 @@ function createGuardrailsHooks(directory, directoryOrConfig, config2, authorityC
25005
25038
  telemetry.modelFallback(input.sessionID, session.agentName, primaryModel, fallbackModel ?? "none", "transient_model_error");
25006
25039
  swarmState.pendingEvents++;
25007
25040
  }
25041
+ if (session && isTransient && isTransientMatch) {
25042
+ session.pendingAdvisoryMessages ??= [];
25043
+ if (!session.pendingAdvisoryMessages.some((m) => m.startsWith("TRANSIENT ERROR:"))) {
25044
+ session.pendingAdvisoryMessages.push(`TRANSIENT ERROR: Provider error detected (attempt ${window2.transientRetryCount}/${cfg.max_transient_retries ?? 5}). Retrying...`);
25045
+ }
25046
+ }
25008
25047
  } else {
25009
25048
  window2.consecutiveErrors = 0;
25010
25049
  window2.transientRetryCount = 0;
@@ -25582,7 +25621,7 @@ function checkFileAuthorityWithRules(agentName, filePath, cwd, effectiveRules, o
25582
25621
  }
25583
25622
  return { allowed: true };
25584
25623
  }
25585
- var import_picomatch, storedInputArgs, TRANSIENT_MODEL_ERROR_PATTERN, toolCallsSinceLastWrite, noOpWarningIssued, consecutiveNoToolTurns, DC_MAX_UNWRAP_DEPTH = 5, DC_SAFE_TARGETS, DC_BLOCKED_ABSOLUTE_PREFIXES, DC_FS_ROOTS, DC_REMOTE_PREFIXES, pathNormalizationCache, globMatcherCache, DEFAULT_AGENT_AUTHORITY_RULES;
25624
+ var import_picomatch, storedInputArgs, TRANSIENT_STATUS_CODES, TRANSIENT_MODEL_ERROR_PATTERN, DEGRADED_ERROR_PATTERN, CONTENT_FILTER_PATTERN, toolCallsSinceLastWrite, noOpWarningIssued, consecutiveNoToolTurns, DC_MAX_UNWRAP_DEPTH = 5, DC_SAFE_TARGETS, DC_BLOCKED_ABSOLUTE_PREFIXES, DC_FS_ROOTS, DC_REMOTE_PREFIXES, pathNormalizationCache, globMatcherCache, DEFAULT_AGENT_AUTHORITY_RULES;
25586
25625
  var init_guardrails = __esm(() => {
25587
25626
  init_quick_lru();
25588
25627
  init_agents2();
@@ -25603,7 +25642,10 @@ var init_guardrails = __esm(() => {
25603
25642
  init_normalize_tool_name();
25604
25643
  import_picomatch = __toESM(require_picomatch2(), 1);
25605
25644
  storedInputArgs = new Map;
25606
- TRANSIENT_MODEL_ERROR_PATTERN = /rate.?limit|429|503|529|timeout|overloaded|model.?not.?found|temporarily unavailable|server error/i;
25645
+ TRANSIENT_STATUS_CODES = new Set([408, 429, 500, 502, 503, 504, 529]);
25646
+ TRANSIENT_MODEL_ERROR_PATTERN = /rate.?limit|429|500|502|503|504|529|timeout|overloaded|model.?not.?found|temporarily.?unavailable|server.?error|connection.?(refused|reset|timeout)|bad.?gateway|gateway.?timeout|internal.?server.?error|service.?unavailable/i;
25647
+ DEGRADED_ERROR_PATTERN = /context.?length|token.?(limit|budget)|input.?too.?long|content.?filter|exceeds?.?(maximum.?)?tokens|maximum.?context|context.?window|too.?many.?tokens|prompt.?too.?long|message.?too.?long|request.?too.?large|max.?tokens/i;
25648
+ CONTENT_FILTER_PATTERN = /content.?filter/i;
25607
25649
  toolCallsSinceLastWrite = new Map;
25608
25650
  noOpWarningIssued = new Set;
25609
25651
  consecutiveNoToolTurns = new Map;
@@ -57491,6 +57533,14 @@ var init_write_retro2 = __esm(() => {
57491
57533
  init_write_retro();
57492
57534
  });
57493
57535
 
57536
+ // src/commands/command-names.ts
57537
+ var COMMAND_NAMES, COMMAND_NAME_SET;
57538
+ var init_command_names = __esm(() => {
57539
+ init_registry();
57540
+ COMMAND_NAMES = Object.freeze(Object.keys(COMMAND_REGISTRY));
57541
+ COMMAND_NAME_SET = new Set(COMMAND_NAMES);
57542
+ });
57543
+
57494
57544
  // src/commands/index.ts
57495
57545
  var exports_commands = {};
57496
57546
  __export(exports_commands, {
@@ -57538,7 +57588,9 @@ __export(exports_commands, {
57538
57588
  createSwarmCommandHandler: () => createSwarmCommandHandler,
57539
57589
  buildHelpText: () => buildHelpText,
57540
57590
  VALID_COMMANDS: () => VALID_COMMANDS,
57541
- COMMAND_REGISTRY: () => COMMAND_REGISTRY
57591
+ COMMAND_REGISTRY: () => COMMAND_REGISTRY,
57592
+ COMMAND_NAME_SET: () => COMMAND_NAME_SET,
57593
+ COMMAND_NAMES: () => COMMAND_NAMES
57542
57594
  });
57543
57595
  import fs30 from "node:fs";
57544
57596
  import path46 from "node:path";
@@ -57718,6 +57770,7 @@ var init_commands = __esm(() => {
57718
57770
  init_benchmark();
57719
57771
  init_checkpoint2();
57720
57772
  init_close();
57773
+ init_command_names();
57721
57774
  init_config2();
57722
57775
  init_council();
57723
57776
  init_curate();
@@ -57975,11 +58028,19 @@ var init_registry = __esm(() => {
57975
58028
  category: "core",
57976
58029
  clashesWithNativeCcCommand: "/status"
57977
58030
  },
58031
+ "show-plan": {
58032
+ handler: (ctx) => handlePlanCommand(ctx.directory, ctx.args),
58033
+ description: "Show current plan (optionally filter by phase number)",
58034
+ category: "core",
58035
+ args: "[phase-number]"
58036
+ },
57978
58037
  plan: {
57979
58038
  handler: (ctx) => handlePlanCommand(ctx.directory, ctx.args),
57980
- description: "Show plan (optionally filter by phase number)",
58039
+ description: "Show current plan (deprecated alias for /swarm show-plan)",
57981
58040
  category: "core",
57982
- clashesWithNativeCcCommand: "/plan"
58041
+ clashesWithNativeCcCommand: "/plan",
58042
+ aliasOf: "show-plan",
58043
+ deprecated: true
57983
58044
  },
57984
58045
  agents: {
57985
58046
  handler: (ctx) => Promise.resolve(handleAgentsCommand(ctx.agents, undefined)),
@@ -58149,13 +58210,22 @@ var init_registry = __esm(() => {
58149
58210
  args: "--threshold <number>, --min-commits <number>",
58150
58211
  category: "diagnostics"
58151
58212
  },
58152
- close: {
58213
+ finalize: {
58153
58214
  handler: (ctx) => handleCloseCommand(ctx.directory, ctx.args),
58154
- description: "Use /swarm close to close the swarm project and archive evidence",
58215
+ description: "Use /swarm finalize to finalize the swarm project and archive evidence",
58155
58216
  details: "Idempotent 4-stage terminal finalization: (1) finalize writes retrospectives for in-progress phases, (2) archive creates timestamped bundle of swarm artifacts and evidence, (3) clean removes active-state files for a clean slate, (4) align performs safe git ff-only to main. Resets agent sessions and delegation chains. Reads .swarm/close-lessons.md for explicit lessons and runs curation.",
58156
58217
  args: "--prune-branches",
58157
58218
  category: "core"
58158
58219
  },
58220
+ close: {
58221
+ handler: (ctx) => handleCloseCommand(ctx.directory, ctx.args),
58222
+ description: "Use /swarm close (deprecated alias) to finalize and archive swarm state",
58223
+ details: "Deprecated alias for /swarm finalize. Preserved for backward compatibility.",
58224
+ args: "--prune-branches",
58225
+ category: "core",
58226
+ aliasOf: "finalize",
58227
+ deprecated: true
58228
+ },
58159
58229
  simulate: {
58160
58230
  handler: (ctx) => handleSimulateCommand(ctx.directory, ctx.args),
58161
58231
  description: "Dry-run hidden coupling analysis with configurable thresholds",
@@ -58189,9 +58259,9 @@ var init_registry = __esm(() => {
58189
58259
  },
58190
58260
  council: {
58191
58261
  handler: (ctx) => handleCouncilCommand(ctx.directory, ctx.args),
58192
- description: "Enter architect MODE: COUNCIL — multi-model deliberation [question] [--spec-review]",
58193
- args: "<question> [--spec-review]",
58194
- details: "Triggers the architect to convene a three-agent General Council: Generalist (reviewer model), Skeptic (critic model), and Domain Expert (SME model). " + "The architect first runs 1–3 targeted web searches and passes a compiled RESEARCH CONTEXT " + "to all three agents before dispatching them in parallel. Agents deliberate using the NSED peer-review protocol (Round 1 independent analysis, Round 2 MAINTAIN/CONCEDE/NUANCE for disagreements). The architect synthesizes the final answer directly from convene_general_council output. --spec-review switches to single-pass advisory mode for spec review. Requires council.general.enabled: true and a search API key in opencode-swarm.json.",
58262
+ description: "Enter architect MODE: COUNCIL — multi-model deliberation [question] [--preset <name>] [--spec-review]",
58263
+ args: "<question> [--preset <name>] [--spec-review]",
58264
+ details: "Triggers the architect to convene a three-agent General Council: Generalist (reviewer model), Skeptic (critic model), and Domain Expert (SME model). Use --preset <name> to choose a named member preset from council.general.presets. " + "The architect first runs 1–3 targeted web searches and passes a compiled RESEARCH CONTEXT " + "to all three agents before dispatching them in parallel. Agents deliberate using the NSED peer-review protocol (Round 1 independent analysis, Round 2 MAINTAIN/CONCEDE/NUANCE for disagreements). The architect synthesizes the final answer directly from convene_general_council output. --spec-review switches to single-pass advisory mode for spec review. Requires council.general.enabled: true and a search API key in opencode-swarm.json.",
58195
58265
  category: "agent"
58196
58266
  },
58197
58267
  "pr-review": {
@@ -58511,7 +58581,7 @@ function buildSlashCommandsList() {
58511
58581
  "history",
58512
58582
  "agents",
58513
58583
  "config",
58514
- "plan",
58584
+ "show-plan",
58515
58585
  "benchmark",
58516
58586
  "export",
58517
58587
  "retrieve"
@@ -58527,7 +58597,7 @@ function buildSlashCommandsList() {
58527
58597
  ];
58528
58598
  const COMMANDS_BY_CATEGORY = {
58529
58599
  "Session Lifecycle": [
58530
- "close",
58600
+ "finalize",
58531
58601
  "reset",
58532
58602
  "reset-session",
58533
58603
  "handoff",
@@ -58537,7 +58607,7 @@ function buildSlashCommandsList() {
58537
58607
  "specify",
58538
58608
  "clarify",
58539
58609
  "analyze",
58540
- "plan",
58610
+ "show-plan",
58541
58611
  "sync-plan",
58542
58612
  "acknowledge-spec-drift",
58543
58613
  "council"
@@ -58692,7 +58762,7 @@ All swarm commands are invoked as /swarm <subcommand>.
58692
58762
  NEVER invoke a bare slash command that shares a name with a swarm subcommand.
58693
58763
 
58694
58764
  CRITICAL CONFLICTS — bare CC command = catastrophic:
58695
- /plan (CC) → Blocks all execution. /swarm plan → Reads .swarm/plan.md. USE THIS.
58765
+ /plan (CC) → Blocks all execution. /swarm show-plan → Reads .swarm/plan.md. USE THIS.
58696
58766
  /reset (CC) → WIPES conversation context. /swarm reset → Clears .swarm (--confirm). USE THIS.
58697
58767
  /checkpoint (CC) → Reverts your work. /swarm checkpoint → Project snapshots. USE THIS.
58698
58768
 
@@ -59650,7 +59720,7 @@ GREENFIELD EXEMPTION: If the work is purely greenfield (new project, no existing
59650
59720
 
59651
59721
  ### MODE: COUNCIL
59652
59722
 
59653
- Activates when: user invokes \`/swarm council <question>\` (optionally with \`--spec-review\`).
59723
+ Activates when: user invokes \`/swarm council <question>\` (optionally with \`--preset <name>\` and/or \`--spec-review\`).
59654
59724
 
59655
59725
  Purpose: convene a fixed three-agent multi-model General Council (generalist / skeptic / domain expert) for an advisory deliberation. The architect runs a curated web research pass upfront, dispatches the three agents in parallel with the gathered RESEARCH CONTEXT, routes any disagreements back for one targeted reconciliation round, and synthesizes the final user-facing answer directly.
59656
59726
 
@@ -68659,12 +68729,12 @@ ${content.substring(endIndex + 1)}`;
68659
68729
  // src/commands/conflict-registry.ts
68660
68730
  var CLAUDE_CODE_CONFLICTS = [
68661
68731
  {
68662
- swarmCommand: "plan",
68732
+ swarmCommand: "show-plan",
68663
68733
  ccCommand: "/plan",
68664
68734
  severity: "CRITICAL",
68665
68735
  ccBehavior: "Enters Claude Code plan mode — Claude proposes all actions before executing them",
68666
68736
  swarmBehavior: "Displays the current .swarm/plan.md task list",
68667
- disambiguationNote: "Use /swarm plan to read the swarm task plan. NEVER invoke the bare /plan command — it enters Claude Code plan mode and blocks execution."
68737
+ disambiguationNote: "Use /swarm show-plan to read the swarm task plan. NEVER invoke the bare /plan command — it enters Claude Code plan mode and blocks execution."
68668
68738
  },
68669
68739
  {
68670
68740
  swarmCommand: "reset",
@@ -81827,10 +81897,6 @@ function writeCouncilEvidence(workingDir, synthesis) {
81827
81897
  }
81828
81898
  }
81829
81899
 
81830
- // src/council/council-service.ts
81831
- import fs65 from "node:fs";
81832
- import path87 from "node:path";
81833
-
81834
81900
  // src/council/types.ts
81835
81901
  var COUNCIL_DEFAULTS = {
81836
81902
  enabled: false,
@@ -81955,7 +82021,7 @@ function buildUnifiedFeedback(taskId, verdict, vetoedBy, requiredFixes, advisory
81955
82021
  return lines.join(`
81956
82022
  `);
81957
82023
  }
81958
- function synthesizePhaseCouncilAdvisory(phaseNumber, phaseSummary, verdicts, roundNumber, config3 = {}, workingDir) {
82024
+ function synthesizePhaseCouncilAdvisory(phaseNumber, phaseSummary, verdicts, roundNumber, config3 = {}, _workingDir) {
81959
82025
  const cfg = { ...COUNCIL_DEFAULTS, ...config3 };
81960
82026
  const timestamp = new Date().toISOString();
81961
82027
  const scope = "phase";
@@ -81988,47 +82054,6 @@ function synthesizePhaseCouncilAdvisory(phaseNumber, phaseSummary, verdicts, rou
81988
82054
  const allCriteriaMet = allUnmetIds.size === 0 && verdicts.length > 0;
81989
82055
  const unifiedFeedbackMd = buildPhaseCouncilFeedback(phaseNumber, phaseSummary, overallVerdict, rejectingMembers, requiredFixes, advisoryFindings, unresolvedConflicts, roundNumber, cfg.maxRounds);
81990
82056
  const evidencePath = `.swarm/evidence/${phaseNumber}/phase-council.json`;
81991
- const baseDir = workingDir ?? process.cwd();
81992
- const evidenceDir = path87.join(baseDir, ".swarm", "evidence", String(phaseNumber));
81993
- fs65.mkdirSync(evidenceDir, { recursive: true });
81994
- const evidenceFile = path87.join(evidenceDir, "phase-council.json");
81995
- const evidenceBundle = {
81996
- entries: [
81997
- {
81998
- type: "phase-council",
81999
- phase_number: phaseNumber,
82000
- scope: "phase",
82001
- timestamp,
82002
- verdict: overallVerdict,
82003
- quorumSize,
82004
- phaseSummary,
82005
- requiredFixes: requiredFixes.map((f) => ({
82006
- severity: f.severity,
82007
- category: f.category,
82008
- location: f.location,
82009
- detail: f.detail,
82010
- evidence: f.evidence
82011
- })),
82012
- advisoryNotes,
82013
- advisoryFindings: advisoryFindings.map((f) => ({
82014
- severity: f.severity,
82015
- category: f.category,
82016
- location: f.location,
82017
- detail: f.detail,
82018
- evidence: f.evidence
82019
- })),
82020
- roundNumber,
82021
- allCriteriaMet
82022
- }
82023
- ]
82024
- };
82025
- try {
82026
- const tempFile = `${evidenceFile}.tmp-${Date.now()}`;
82027
- fs65.writeFileSync(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
82028
- fs65.renameSync(tempFile, evidenceFile);
82029
- } catch (writeErr) {
82030
- console.warn(`[phase-council] Failed to write phase-council evidence to ${evidenceFile}: ${writeErr instanceof Error ? writeErr.message : String(writeErr)}`);
82031
- }
82032
82057
  return {
82033
82058
  phaseNumber,
82034
82059
  scope,
@@ -82260,8 +82285,8 @@ var submit_council_verdicts = createSwarmTool({
82260
82285
  // src/tools/convene-general-council.ts
82261
82286
  init_zod();
82262
82287
  init_loader();
82263
- import * as fs66 from "node:fs";
82264
- import * as path88 from "node:path";
82288
+ import * as fs65 from "node:fs";
82289
+ import * as path87 from "node:path";
82265
82290
 
82266
82291
  // src/council/general-council-advisory.ts
82267
82292
  var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
@@ -82689,13 +82714,13 @@ var convene_general_council = createSwarmTool({
82689
82714
  const round1 = input.round1Responses;
82690
82715
  const round2 = input.round2Responses ?? [];
82691
82716
  const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
82692
- const evidenceDir = path88.join(workingDir, ".swarm", "council", "general");
82717
+ const evidenceDir = path87.join(workingDir, ".swarm", "council", "general");
82693
82718
  const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
82694
82719
  const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
82695
- const evidencePath = path88.join(evidenceDir, evidenceFile);
82720
+ const evidencePath = path87.join(evidenceDir, evidenceFile);
82696
82721
  try {
82697
- await fs66.promises.mkdir(evidenceDir, { recursive: true });
82698
- await fs66.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
82722
+ await fs65.promises.mkdir(evidenceDir, { recursive: true });
82723
+ await fs65.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
82699
82724
  } catch (err2) {
82700
82725
  const message = err2 instanceof Error ? err2.message : String(err2);
82701
82726
  console.warn(`[convene_general_council] Failed to write evidence to ${evidencePath}: ${message}`);
@@ -82936,8 +82961,8 @@ init_scope_persistence();
82936
82961
  init_state();
82937
82962
  init_task_id();
82938
82963
  init_create_tool();
82939
- import * as fs67 from "node:fs";
82940
- import * as path89 from "node:path";
82964
+ import * as fs66 from "node:fs";
82965
+ import * as path88 from "node:path";
82941
82966
  function validateTaskIdFormat2(taskId) {
82942
82967
  return validateTaskIdFormat(taskId);
82943
82968
  }
@@ -83011,8 +83036,8 @@ async function executeDeclareScope(args2, fallbackDir) {
83011
83036
  };
83012
83037
  }
83013
83038
  }
83014
- normalizedDir = path89.normalize(args2.working_directory);
83015
- const pathParts = normalizedDir.split(path89.sep);
83039
+ normalizedDir = path88.normalize(args2.working_directory);
83040
+ const pathParts = normalizedDir.split(path88.sep);
83016
83041
  if (pathParts.includes("..")) {
83017
83042
  return {
83018
83043
  success: false,
@@ -83022,11 +83047,11 @@ async function executeDeclareScope(args2, fallbackDir) {
83022
83047
  ]
83023
83048
  };
83024
83049
  }
83025
- const resolvedDir = path89.resolve(normalizedDir);
83050
+ const resolvedDir = path88.resolve(normalizedDir);
83026
83051
  try {
83027
- const realPath = fs67.realpathSync(resolvedDir);
83028
- const planPath2 = path89.join(realPath, ".swarm", "plan.json");
83029
- if (!fs67.existsSync(planPath2)) {
83052
+ const realPath = fs66.realpathSync(resolvedDir);
83053
+ const planPath2 = path88.join(realPath, ".swarm", "plan.json");
83054
+ if (!fs66.existsSync(planPath2)) {
83030
83055
  return {
83031
83056
  success: false,
83032
83057
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -83049,8 +83074,8 @@ async function executeDeclareScope(args2, fallbackDir) {
83049
83074
  console.warn("[declare-scope] fallbackDir is undefined, falling back to process.cwd()");
83050
83075
  }
83051
83076
  const directory = normalizedDir || fallbackDir;
83052
- const planPath = path89.resolve(directory, ".swarm", "plan.json");
83053
- if (!fs67.existsSync(planPath)) {
83077
+ const planPath = path88.resolve(directory, ".swarm", "plan.json");
83078
+ if (!fs66.existsSync(planPath)) {
83054
83079
  return {
83055
83080
  success: false,
83056
83081
  message: "No plan found",
@@ -83059,7 +83084,7 @@ async function executeDeclareScope(args2, fallbackDir) {
83059
83084
  }
83060
83085
  let planContent;
83061
83086
  try {
83062
- planContent = JSON.parse(fs67.readFileSync(planPath, "utf-8"));
83087
+ planContent = JSON.parse(fs66.readFileSync(planPath, "utf-8"));
83063
83088
  } catch {
83064
83089
  return {
83065
83090
  success: false,
@@ -83089,8 +83114,8 @@ async function executeDeclareScope(args2, fallbackDir) {
83089
83114
  const normalizeErrors = [];
83090
83115
  const dir = normalizedDir || fallbackDir || process.cwd();
83091
83116
  const mergedFiles = rawMergedFiles.map((file3) => {
83092
- if (path89.isAbsolute(file3)) {
83093
- const relativePath = path89.relative(dir, file3).replace(/\\/g, "/");
83117
+ if (path88.isAbsolute(file3)) {
83118
+ const relativePath = path88.relative(dir, file3).replace(/\\/g, "/");
83094
83119
  if (relativePath.startsWith("..")) {
83095
83120
  normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
83096
83121
  return file3;
@@ -83150,8 +83175,8 @@ var declare_scope = createSwarmTool({
83150
83175
  // src/tools/diff.ts
83151
83176
  init_zod();
83152
83177
  import * as child_process7 from "node:child_process";
83153
- import * as fs68 from "node:fs";
83154
- import * as path90 from "node:path";
83178
+ import * as fs67 from "node:fs";
83179
+ import * as path89 from "node:path";
83155
83180
  init_create_tool();
83156
83181
  var MAX_DIFF_LINES = 500;
83157
83182
  var DIFF_TIMEOUT_MS = 30000;
@@ -83180,20 +83205,20 @@ function validateBase(base) {
83180
83205
  function validatePaths(paths) {
83181
83206
  if (!paths)
83182
83207
  return null;
83183
- for (const path91 of paths) {
83184
- if (!path91 || path91.length === 0) {
83208
+ for (const path90 of paths) {
83209
+ if (!path90 || path90.length === 0) {
83185
83210
  return "empty path not allowed";
83186
83211
  }
83187
- if (path91.length > MAX_PATH_LENGTH) {
83212
+ if (path90.length > MAX_PATH_LENGTH) {
83188
83213
  return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
83189
83214
  }
83190
- if (SHELL_METACHARACTERS2.test(path91)) {
83215
+ if (SHELL_METACHARACTERS2.test(path90)) {
83191
83216
  return "path contains shell metacharacters";
83192
83217
  }
83193
- if (path91.startsWith("-")) {
83218
+ if (path90.startsWith("-")) {
83194
83219
  return 'path cannot start with "-" (option-like arguments not allowed)';
83195
83220
  }
83196
- if (CONTROL_CHAR_PATTERN2.test(path91)) {
83221
+ if (CONTROL_CHAR_PATTERN2.test(path90)) {
83197
83222
  return "path contains control characters";
83198
83223
  }
83199
83224
  }
@@ -83301,8 +83326,8 @@ var diff = createSwarmTool({
83301
83326
  if (parts2.length >= 3) {
83302
83327
  const additions = parseInt(parts2[0], 10) || 0;
83303
83328
  const deletions = parseInt(parts2[1], 10) || 0;
83304
- const path91 = parts2[2];
83305
- files.push({ path: path91, additions, deletions });
83329
+ const path90 = parts2[2];
83330
+ files.push({ path: path90, additions, deletions });
83306
83331
  }
83307
83332
  }
83308
83333
  const contractChanges = [];
@@ -83342,7 +83367,7 @@ var diff = createSwarmTool({
83342
83367
  } else if (base === "unstaged") {
83343
83368
  const oldRef = `:${file3.path}`;
83344
83369
  oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
83345
- newContent = fs68.readFileSync(path90.join(directory, file3.path), "utf-8");
83370
+ newContent = fs67.readFileSync(path89.join(directory, file3.path), "utf-8");
83346
83371
  } else {
83347
83372
  const oldRef = `${base}:${file3.path}`;
83348
83373
  oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
@@ -83416,8 +83441,8 @@ var diff = createSwarmTool({
83416
83441
  // src/tools/diff-summary.ts
83417
83442
  init_zod();
83418
83443
  import * as child_process8 from "node:child_process";
83419
- import * as fs69 from "node:fs";
83420
- import * as path91 from "node:path";
83444
+ import * as fs68 from "node:fs";
83445
+ import * as path90 from "node:path";
83421
83446
  init_create_tool();
83422
83447
  var diff_summary = createSwarmTool({
83423
83448
  description: "Generate a filtered semantic diff summary from AST analysis. Returns SemanticDiffSummary with optional filtering by classification or riskLevel.",
@@ -83465,7 +83490,7 @@ var diff_summary = createSwarmTool({
83465
83490
  }
83466
83491
  try {
83467
83492
  let oldContent;
83468
- const newContent = fs69.readFileSync(path91.join(workingDir, filePath), "utf-8");
83493
+ const newContent = fs68.readFileSync(path90.join(workingDir, filePath), "utf-8");
83469
83494
  if (fileExistsInHead) {
83470
83495
  oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
83471
83496
  encoding: "utf-8",
@@ -83693,8 +83718,8 @@ Use these as DOMAIN values when delegating to @sme.`;
83693
83718
  init_zod();
83694
83719
  init_create_tool();
83695
83720
  init_path_security();
83696
- import * as fs70 from "node:fs";
83697
- import * as path92 from "node:path";
83721
+ import * as fs69 from "node:fs";
83722
+ import * as path91 from "node:path";
83698
83723
  var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
83699
83724
  var MAX_EVIDENCE_FILES = 1000;
83700
83725
  var EVIDENCE_DIR3 = ".swarm/evidence";
@@ -83721,9 +83746,9 @@ function validateRequiredTypes(input) {
83721
83746
  return null;
83722
83747
  }
83723
83748
  function isPathWithinSwarm2(filePath, cwd) {
83724
- const normalizedCwd = path92.resolve(cwd);
83725
- const swarmPath = path92.join(normalizedCwd, ".swarm");
83726
- const normalizedPath = path92.resolve(filePath);
83749
+ const normalizedCwd = path91.resolve(cwd);
83750
+ const swarmPath = path91.join(normalizedCwd, ".swarm");
83751
+ const normalizedPath = path91.resolve(filePath);
83727
83752
  return normalizedPath.startsWith(swarmPath);
83728
83753
  }
83729
83754
  function parseCompletedTasks(planContent) {
@@ -83739,12 +83764,12 @@ function parseCompletedTasks(planContent) {
83739
83764
  }
83740
83765
  function readEvidenceFiles(evidenceDir, _cwd) {
83741
83766
  const evidence = [];
83742
- if (!fs70.existsSync(evidenceDir) || !fs70.statSync(evidenceDir).isDirectory()) {
83767
+ if (!fs69.existsSync(evidenceDir) || !fs69.statSync(evidenceDir).isDirectory()) {
83743
83768
  return evidence;
83744
83769
  }
83745
83770
  let files;
83746
83771
  try {
83747
- files = fs70.readdirSync(evidenceDir);
83772
+ files = fs69.readdirSync(evidenceDir);
83748
83773
  } catch {
83749
83774
  return evidence;
83750
83775
  }
@@ -83753,14 +83778,14 @@ function readEvidenceFiles(evidenceDir, _cwd) {
83753
83778
  if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
83754
83779
  continue;
83755
83780
  }
83756
- const filePath = path92.join(evidenceDir, filename);
83781
+ const filePath = path91.join(evidenceDir, filename);
83757
83782
  try {
83758
- const resolvedPath = path92.resolve(filePath);
83759
- const evidenceDirResolved = path92.resolve(evidenceDir);
83783
+ const resolvedPath = path91.resolve(filePath);
83784
+ const evidenceDirResolved = path91.resolve(evidenceDir);
83760
83785
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
83761
83786
  continue;
83762
83787
  }
83763
- const stat7 = fs70.lstatSync(filePath);
83788
+ const stat7 = fs69.lstatSync(filePath);
83764
83789
  if (!stat7.isFile()) {
83765
83790
  continue;
83766
83791
  }
@@ -83769,7 +83794,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
83769
83794
  }
83770
83795
  let fileStat;
83771
83796
  try {
83772
- fileStat = fs70.statSync(filePath);
83797
+ fileStat = fs69.statSync(filePath);
83773
83798
  if (fileStat.size > MAX_FILE_SIZE_BYTES6) {
83774
83799
  continue;
83775
83800
  }
@@ -83778,7 +83803,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
83778
83803
  }
83779
83804
  let content;
83780
83805
  try {
83781
- content = fs70.readFileSync(filePath, "utf-8");
83806
+ content = fs69.readFileSync(filePath, "utf-8");
83782
83807
  } catch {
83783
83808
  continue;
83784
83809
  }
@@ -83874,7 +83899,7 @@ var evidence_check = createSwarmTool({
83874
83899
  return JSON.stringify(errorResult, null, 2);
83875
83900
  }
83876
83901
  const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
83877
- const planPath = path92.join(cwd, PLAN_FILE);
83902
+ const planPath = path91.join(cwd, PLAN_FILE);
83878
83903
  if (!isPathWithinSwarm2(planPath, cwd)) {
83879
83904
  const errorResult = {
83880
83905
  error: "plan file path validation failed",
@@ -83888,7 +83913,7 @@ var evidence_check = createSwarmTool({
83888
83913
  }
83889
83914
  let planContent;
83890
83915
  try {
83891
- planContent = fs70.readFileSync(planPath, "utf-8");
83916
+ planContent = fs69.readFileSync(planPath, "utf-8");
83892
83917
  } catch {
83893
83918
  const result2 = {
83894
83919
  message: "No completed tasks found in plan.",
@@ -83906,7 +83931,7 @@ var evidence_check = createSwarmTool({
83906
83931
  };
83907
83932
  return JSON.stringify(result2, null, 2);
83908
83933
  }
83909
- const evidenceDir = path92.join(cwd, EVIDENCE_DIR3);
83934
+ const evidenceDir = path91.join(cwd, EVIDENCE_DIR3);
83910
83935
  const evidence = readEvidenceFiles(evidenceDir, cwd);
83911
83936
  const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
83912
83937
  const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
@@ -83923,8 +83948,8 @@ var evidence_check = createSwarmTool({
83923
83948
  // src/tools/file-extractor.ts
83924
83949
  init_zod();
83925
83950
  init_create_tool();
83926
- import * as fs71 from "node:fs";
83927
- import * as path93 from "node:path";
83951
+ import * as fs70 from "node:fs";
83952
+ import * as path92 from "node:path";
83928
83953
  var EXT_MAP = {
83929
83954
  python: ".py",
83930
83955
  py: ".py",
@@ -83986,8 +84011,8 @@ var extract_code_blocks = createSwarmTool({
83986
84011
  execute: async (args2, directory) => {
83987
84012
  const { content, output_dir, prefix } = args2;
83988
84013
  const targetDir = output_dir || directory;
83989
- if (!fs71.existsSync(targetDir)) {
83990
- fs71.mkdirSync(targetDir, { recursive: true });
84014
+ if (!fs70.existsSync(targetDir)) {
84015
+ fs70.mkdirSync(targetDir, { recursive: true });
83991
84016
  }
83992
84017
  if (!content) {
83993
84018
  return "Error: content is required";
@@ -84005,16 +84030,16 @@ var extract_code_blocks = createSwarmTool({
84005
84030
  if (prefix) {
84006
84031
  filename = `${prefix}_${filename}`;
84007
84032
  }
84008
- let filepath = path93.join(targetDir, filename);
84009
- const base = path93.basename(filepath, path93.extname(filepath));
84010
- const ext = path93.extname(filepath);
84033
+ let filepath = path92.join(targetDir, filename);
84034
+ const base = path92.basename(filepath, path92.extname(filepath));
84035
+ const ext = path92.extname(filepath);
84011
84036
  let counter = 1;
84012
- while (fs71.existsSync(filepath)) {
84013
- filepath = path93.join(targetDir, `${base}_${counter}${ext}`);
84037
+ while (fs70.existsSync(filepath)) {
84038
+ filepath = path92.join(targetDir, `${base}_${counter}${ext}`);
84014
84039
  counter++;
84015
84040
  }
84016
84041
  try {
84017
- fs71.writeFileSync(filepath, code.trim(), "utf-8");
84042
+ fs70.writeFileSync(filepath, code.trim(), "utf-8");
84018
84043
  savedFiles.push(filepath);
84019
84044
  } catch (error93) {
84020
84045
  errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
@@ -84267,8 +84292,8 @@ var gitingest = createSwarmTool({
84267
84292
  init_zod();
84268
84293
  init_create_tool();
84269
84294
  init_path_security();
84270
- import * as fs72 from "node:fs";
84271
- import * as path94 from "node:path";
84295
+ import * as fs71 from "node:fs";
84296
+ import * as path93 from "node:path";
84272
84297
  var MAX_FILE_PATH_LENGTH2 = 500;
84273
84298
  var MAX_SYMBOL_LENGTH = 256;
84274
84299
  var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
@@ -84316,7 +84341,7 @@ function validateSymbolInput(symbol3) {
84316
84341
  return null;
84317
84342
  }
84318
84343
  function isBinaryFile2(filePath, buffer) {
84319
- const ext = path94.extname(filePath).toLowerCase();
84344
+ const ext = path93.extname(filePath).toLowerCase();
84320
84345
  if (ext === ".json" || ext === ".md" || ext === ".txt") {
84321
84346
  return false;
84322
84347
  }
@@ -84340,15 +84365,15 @@ function parseImports(content, targetFile, targetSymbol) {
84340
84365
  const imports = [];
84341
84366
  let _resolvedTarget;
84342
84367
  try {
84343
- _resolvedTarget = path94.resolve(targetFile);
84368
+ _resolvedTarget = path93.resolve(targetFile);
84344
84369
  } catch {
84345
84370
  _resolvedTarget = targetFile;
84346
84371
  }
84347
- const targetBasename = path94.basename(targetFile, path94.extname(targetFile));
84372
+ const targetBasename = path93.basename(targetFile, path93.extname(targetFile));
84348
84373
  const targetWithExt = targetFile;
84349
84374
  const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
84350
- const normalizedTargetWithExt = path94.normalize(targetWithExt).replace(/\\/g, "/");
84351
- const normalizedTargetWithoutExt = path94.normalize(targetWithoutExt).replace(/\\/g, "/");
84375
+ const normalizedTargetWithExt = path93.normalize(targetWithExt).replace(/\\/g, "/");
84376
+ const normalizedTargetWithoutExt = path93.normalize(targetWithoutExt).replace(/\\/g, "/");
84352
84377
  const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
84353
84378
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
84354
84379
  const modulePath = match[1] || match[2] || match[3];
@@ -84371,9 +84396,9 @@ function parseImports(content, targetFile, targetSymbol) {
84371
84396
  }
84372
84397
  const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
84373
84398
  let isMatch = false;
84374
- const _targetDir = path94.dirname(targetFile);
84375
- const targetExt = path94.extname(targetFile);
84376
- const targetBasenameNoExt = path94.basename(targetFile, targetExt);
84399
+ const _targetDir = path93.dirname(targetFile);
84400
+ const targetExt = path93.extname(targetFile);
84401
+ const targetBasenameNoExt = path93.basename(targetFile, targetExt);
84377
84402
  const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
84378
84403
  const moduleName = modulePath.split(/[/\\]/).pop() || "";
84379
84404
  const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
@@ -84430,7 +84455,7 @@ var SKIP_DIRECTORIES4 = new Set([
84430
84455
  function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
84431
84456
  let entries;
84432
84457
  try {
84433
- entries = fs72.readdirSync(dir);
84458
+ entries = fs71.readdirSync(dir);
84434
84459
  } catch (e) {
84435
84460
  stats.fileErrors.push({
84436
84461
  path: dir,
@@ -84441,13 +84466,13 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
84441
84466
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
84442
84467
  for (const entry of entries) {
84443
84468
  if (SKIP_DIRECTORIES4.has(entry)) {
84444
- stats.skippedDirs.push(path94.join(dir, entry));
84469
+ stats.skippedDirs.push(path93.join(dir, entry));
84445
84470
  continue;
84446
84471
  }
84447
- const fullPath = path94.join(dir, entry);
84472
+ const fullPath = path93.join(dir, entry);
84448
84473
  let stat7;
84449
84474
  try {
84450
- stat7 = fs72.statSync(fullPath);
84475
+ stat7 = fs71.statSync(fullPath);
84451
84476
  } catch (e) {
84452
84477
  stats.fileErrors.push({
84453
84478
  path: fullPath,
@@ -84458,7 +84483,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
84458
84483
  if (stat7.isDirectory()) {
84459
84484
  findSourceFiles2(fullPath, files, stats);
84460
84485
  } else if (stat7.isFile()) {
84461
- const ext = path94.extname(fullPath).toLowerCase();
84486
+ const ext = path93.extname(fullPath).toLowerCase();
84462
84487
  if (SUPPORTED_EXTENSIONS3.includes(ext)) {
84463
84488
  files.push(fullPath);
84464
84489
  }
@@ -84515,8 +84540,8 @@ var imports = createSwarmTool({
84515
84540
  return JSON.stringify(errorResult, null, 2);
84516
84541
  }
84517
84542
  try {
84518
- const targetFile = path94.resolve(file3);
84519
- if (!fs72.existsSync(targetFile)) {
84543
+ const targetFile = path93.resolve(file3);
84544
+ if (!fs71.existsSync(targetFile)) {
84520
84545
  const errorResult = {
84521
84546
  error: `target file not found: ${file3}`,
84522
84547
  target: file3,
@@ -84526,7 +84551,7 @@ var imports = createSwarmTool({
84526
84551
  };
84527
84552
  return JSON.stringify(errorResult, null, 2);
84528
84553
  }
84529
- const targetStat = fs72.statSync(targetFile);
84554
+ const targetStat = fs71.statSync(targetFile);
84530
84555
  if (!targetStat.isFile()) {
84531
84556
  const errorResult = {
84532
84557
  error: "target must be a file, not a directory",
@@ -84537,7 +84562,7 @@ var imports = createSwarmTool({
84537
84562
  };
84538
84563
  return JSON.stringify(errorResult, null, 2);
84539
84564
  }
84540
- const baseDir = path94.dirname(targetFile);
84565
+ const baseDir = path93.dirname(targetFile);
84541
84566
  const scanStats = {
84542
84567
  skippedDirs: [],
84543
84568
  skippedFiles: 0,
@@ -84552,12 +84577,12 @@ var imports = createSwarmTool({
84552
84577
  if (consumers.length >= MAX_CONSUMERS)
84553
84578
  break;
84554
84579
  try {
84555
- const stat7 = fs72.statSync(filePath);
84580
+ const stat7 = fs71.statSync(filePath);
84556
84581
  if (stat7.size > MAX_FILE_SIZE_BYTES7) {
84557
84582
  skippedFileCount++;
84558
84583
  continue;
84559
84584
  }
84560
- const buffer = fs72.readFileSync(filePath);
84585
+ const buffer = fs71.readFileSync(filePath);
84561
84586
  if (isBinaryFile2(filePath, buffer)) {
84562
84587
  skippedFileCount++;
84563
84588
  continue;
@@ -85133,30 +85158,30 @@ init_config();
85133
85158
  init_schema();
85134
85159
  init_qa_gate_profile();
85135
85160
  init_manager2();
85136
- import * as fs75 from "node:fs";
85137
- import * as path97 from "node:path";
85161
+ import * as fs74 from "node:fs";
85162
+ import * as path96 from "node:path";
85138
85163
 
85139
85164
  // src/full-auto/phase-approval.ts
85140
85165
  init_utils2();
85141
85166
  init_logger();
85142
85167
  init_state2();
85143
- import * as fs73 from "node:fs";
85144
- import * as path95 from "node:path";
85168
+ import * as fs72 from "node:fs";
85169
+ import * as path94 from "node:path";
85145
85170
  var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
85146
85171
  function readEvidenceDir(directory, phase) {
85147
85172
  try {
85148
- const dirPath = validateSwarmPath(directory, path95.posix.join("evidence", String(phase)));
85149
- if (!fs73.existsSync(dirPath))
85173
+ const dirPath = validateSwarmPath(directory, path94.posix.join("evidence", String(phase)));
85174
+ if (!fs72.existsSync(dirPath))
85150
85175
  return [];
85151
- const entries = fs73.readdirSync(dirPath);
85152
- return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path95.join(dirPath, e));
85176
+ const entries = fs72.readdirSync(dirPath);
85177
+ return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path94.join(dirPath, e));
85153
85178
  } catch {
85154
85179
  return [];
85155
85180
  }
85156
85181
  }
85157
85182
  function parseEvidence(filePath) {
85158
85183
  try {
85159
- const raw = fs73.readFileSync(filePath, "utf-8");
85184
+ const raw = fs72.readFileSync(filePath, "utf-8");
85160
85185
  const parsed = JSON.parse(raw);
85161
85186
  return parsed;
85162
85187
  } catch (error93) {
@@ -85245,9 +85270,9 @@ function verifyFullAutoPhaseApproval(directory, sessionID, phase, config3) {
85245
85270
  function phaseIsExplicitlyNonCode(directory, phase) {
85246
85271
  try {
85247
85272
  const planPath = validateSwarmPath(directory, "plan.json");
85248
- if (!fs73.existsSync(planPath))
85273
+ if (!fs72.existsSync(planPath))
85249
85274
  return false;
85250
- const raw = fs73.readFileSync(planPath, "utf-8");
85275
+ const raw = fs72.readFileSync(planPath, "utf-8");
85251
85276
  const plan = JSON.parse(raw);
85252
85277
  const phases = Array.isArray(plan.phases) ? plan.phases : [];
85253
85278
  const entry = phases.find((p) => p.id === phase || p.phase === phase);
@@ -85287,20 +85312,20 @@ init_file_locks();
85287
85312
  init_plan_schema();
85288
85313
  init_ledger();
85289
85314
  init_manager();
85290
- import * as fs74 from "node:fs";
85291
- import * as path96 from "node:path";
85315
+ import * as fs73 from "node:fs";
85316
+ import * as path95 from "node:path";
85292
85317
  async function writeCheckpoint(directory) {
85293
85318
  try {
85294
85319
  const plan = await loadPlan(directory);
85295
85320
  if (!plan)
85296
85321
  return;
85297
- const swarmDir = path96.join(directory, ".swarm");
85298
- fs74.mkdirSync(swarmDir, { recursive: true });
85299
- const jsonPath = path96.join(swarmDir, "SWARM_PLAN.json");
85300
- const mdPath = path96.join(swarmDir, "SWARM_PLAN.md");
85301
- fs74.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
85322
+ const swarmDir = path95.join(directory, ".swarm");
85323
+ fs73.mkdirSync(swarmDir, { recursive: true });
85324
+ const jsonPath = path95.join(swarmDir, "SWARM_PLAN.json");
85325
+ const mdPath = path95.join(swarmDir, "SWARM_PLAN.md");
85326
+ fs73.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
85302
85327
  const md = derivePlanMarkdown(plan);
85303
- fs74.writeFileSync(mdPath, md, "utf8");
85328
+ fs73.writeFileSync(mdPath, md, "utf8");
85304
85329
  } catch (error93) {
85305
85330
  console.warn(`[checkpoint] Failed to write SWARM_PLAN checkpoint: ${error93 instanceof Error ? error93.message : String(error93)}`);
85306
85331
  }
@@ -85532,8 +85557,8 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
85532
85557
  let driftCheckEnabled = true;
85533
85558
  let driftHasSpecMd = false;
85534
85559
  try {
85535
- const specMdPath = path97.join(dir, ".swarm", "spec.md");
85536
- driftHasSpecMd = fs75.existsSync(specMdPath);
85560
+ const specMdPath = path96.join(dir, ".swarm", "spec.md");
85561
+ driftHasSpecMd = fs74.existsSync(specMdPath);
85537
85562
  const gatePlan = await loadPlan(dir);
85538
85563
  if (gatePlan) {
85539
85564
  const gatePlanId = derivePlanId(gatePlan);
@@ -85554,9 +85579,9 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
85554
85579
  } else {
85555
85580
  let phaseType;
85556
85581
  try {
85557
- const planPath = path97.join(dir, ".swarm", "plan.json");
85558
- if (fs75.existsSync(planPath)) {
85559
- const planRaw = fs75.readFileSync(planPath, "utf-8");
85582
+ const planPath = path96.join(dir, ".swarm", "plan.json");
85583
+ if (fs74.existsSync(planPath)) {
85584
+ const planRaw = fs74.readFileSync(planPath, "utf-8");
85560
85585
  const plan = JSON.parse(planRaw);
85561
85586
  const targetPhase = plan.phases?.find((p) => p.id === phase);
85562
85587
  phaseType = targetPhase?.type;
@@ -85567,11 +85592,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
85567
85592
  warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
85568
85593
  } else {
85569
85594
  try {
85570
- const driftEvidencePath = path97.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
85595
+ const driftEvidencePath = path96.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
85571
85596
  let driftVerdictFound = false;
85572
85597
  let driftVerdictApproved = false;
85573
85598
  try {
85574
- const driftEvidenceContent = fs75.readFileSync(driftEvidencePath, "utf-8");
85599
+ const driftEvidenceContent = fs74.readFileSync(driftEvidencePath, "utf-8");
85575
85600
  const driftEvidence = JSON.parse(driftEvidenceContent);
85576
85601
  const entries = driftEvidence.entries ?? [];
85577
85602
  for (const entry of entries) {
@@ -85605,9 +85630,9 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
85605
85630
  let incompleteTaskCount = 0;
85606
85631
  let planParseable = false;
85607
85632
  try {
85608
- const planPath = path97.join(dir, ".swarm", "plan.json");
85609
- if (fs75.existsSync(planPath)) {
85610
- const planRaw = fs75.readFileSync(planPath, "utf-8");
85633
+ const planPath = path96.join(dir, ".swarm", "plan.json");
85634
+ if (fs74.existsSync(planPath)) {
85635
+ const planRaw = fs74.readFileSync(planPath, "utf-8");
85611
85636
  const plan = JSON.parse(planRaw);
85612
85637
  planParseable = true;
85613
85638
  const planPhase = plan.phases?.find((p) => p.id === phase);
@@ -85672,11 +85697,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
85672
85697
  const overrides = session2?.qaGateSessionOverrides ?? {};
85673
85698
  const effective = getEffectiveGates(profile, overrides);
85674
85699
  if (effective.hallucination_guard === true) {
85675
- const hgPath = path97.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
85700
+ const hgPath = path96.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
85676
85701
  let hgVerdictFound = false;
85677
85702
  let hgVerdictApproved = false;
85678
85703
  try {
85679
- const hgContent = fs75.readFileSync(hgPath, "utf-8");
85704
+ const hgContent = fs74.readFileSync(hgPath, "utf-8");
85680
85705
  const hgBundle = JSON.parse(hgContent);
85681
85706
  for (const entry of hgBundle.entries ?? []) {
85682
85707
  if (typeof entry.type === "string" && entry.type.includes("hallucination") && typeof entry.verdict === "string") {
@@ -85744,11 +85769,11 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
85744
85769
  const overrides = session2?.qaGateSessionOverrides ?? {};
85745
85770
  const effective = getEffectiveGates(profile, overrides);
85746
85771
  if (effective.mutation_test === true) {
85747
- const mgPath = path97.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
85772
+ const mgPath = path96.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
85748
85773
  let mgVerdictFound = false;
85749
85774
  let mgVerdict;
85750
85775
  try {
85751
- const mgContent = fs75.readFileSync(mgPath, "utf-8");
85776
+ const mgContent = fs74.readFileSync(mgPath, "utf-8");
85752
85777
  const mgBundle = JSON.parse(mgContent);
85753
85778
  for (const entry of mgBundle.entries ?? []) {
85754
85779
  if (typeof entry.type === "string" && entry.type === "mutation-gate" && typeof entry.verdict === "string") {
@@ -85818,14 +85843,14 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
85818
85843
  const effective = getEffectiveGates(profile, overrides);
85819
85844
  if (effective.council_mode === true) {
85820
85845
  councilModeEnabled = true;
85821
- const pcPath = path97.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
85846
+ const pcPath = path96.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
85822
85847
  let pcVerdictFound = false;
85823
85848
  let _pcVerdict;
85824
85849
  let pcQuorumSize;
85825
85850
  let pcTimestamp;
85826
85851
  let pcPhaseNumber;
85827
85852
  try {
85828
- const pcContent = fs75.readFileSync(pcPath, "utf-8");
85853
+ const pcContent = fs74.readFileSync(pcPath, "utf-8");
85829
85854
  const pcBundle = JSON.parse(pcContent);
85830
85855
  for (const entry of pcBundle.entries ?? []) {
85831
85856
  if (typeof entry.type === "string" && entry.type === "phase-council" && typeof entry.verdict === "string") {
@@ -86026,11 +86051,11 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
86026
86051
  const effective = getEffectiveGates(profile, overrides);
86027
86052
  if (effective.final_council === true) {
86028
86053
  finalCouncilEnabled = true;
86029
- const fcPath = path97.join(dir, ".swarm", "evidence", "final-council.json");
86054
+ const fcPath = path96.join(dir, ".swarm", "evidence", "final-council.json");
86030
86055
  let fcVerdictFound = false;
86031
86056
  let _fcVerdict;
86032
86057
  try {
86033
- const fcContent = fs75.readFileSync(fcPath, "utf-8");
86058
+ const fcContent = fs74.readFileSync(fcPath, "utf-8");
86034
86059
  const fcBundle = JSON.parse(fcContent);
86035
86060
  for (const entry of fcBundle.entries ?? []) {
86036
86061
  if (typeof entry.type === "string" && entry.type === "final-council" && typeof entry.verdict === "string") {
@@ -86158,7 +86183,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
86158
86183
  }
86159
86184
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
86160
86185
  try {
86161
- const projectName = path97.basename(dir);
86186
+ const projectName = path96.basename(dir);
86162
86187
  const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
86163
86188
  if (curationResult) {
86164
86189
  const sessionState = swarmState.agentSessions.get(sessionID);
@@ -86238,7 +86263,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
86238
86263
  let phaseRequiredAgents;
86239
86264
  try {
86240
86265
  const planPath = validateSwarmPath(dir, "plan.json");
86241
- const planRaw = fs75.readFileSync(planPath, "utf-8");
86266
+ const planRaw = fs74.readFileSync(planPath, "utf-8");
86242
86267
  const plan = JSON.parse(planRaw);
86243
86268
  const phaseObj = plan.phases.find((p) => p.id === phase);
86244
86269
  phaseRequiredAgents = phaseObj?.required_agents;
@@ -86253,7 +86278,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
86253
86278
  if (agentsMissing.length > 0) {
86254
86279
  try {
86255
86280
  const planPath = validateSwarmPath(dir, "plan.json");
86256
- const planRaw = fs75.readFileSync(planPath, "utf-8");
86281
+ const planRaw = fs74.readFileSync(planPath, "utf-8");
86257
86282
  const plan = JSON.parse(planRaw);
86258
86283
  const targetPhase = plan.phases.find((p) => p.id === phase);
86259
86284
  if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
@@ -86293,7 +86318,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
86293
86318
  if (phaseCompleteConfig.regression_sweep?.enforce) {
86294
86319
  try {
86295
86320
  const planPath = validateSwarmPath(dir, "plan.json");
86296
- const planRaw = fs75.readFileSync(planPath, "utf-8");
86321
+ const planRaw = fs74.readFileSync(planPath, "utf-8");
86297
86322
  const plan = JSON.parse(planRaw);
86298
86323
  const targetPhase = plan.phases.find((p) => p.id === phase);
86299
86324
  if (targetPhase) {
@@ -86347,7 +86372,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
86347
86372
  }
86348
86373
  try {
86349
86374
  const eventsPath = validateSwarmPath(dir, "events.jsonl");
86350
- fs75.appendFileSync(eventsPath, `${JSON.stringify(event)}
86375
+ fs74.appendFileSync(eventsPath, `${JSON.stringify(event)}
86351
86376
  `, "utf-8");
86352
86377
  } catch (writeError) {
86353
86378
  warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
@@ -86422,12 +86447,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
86422
86447
  warnings.push(`Warning: failed to update plan.json phase status`);
86423
86448
  try {
86424
86449
  const planPath = validateSwarmPath(dir, "plan.json");
86425
- const planRaw = fs75.readFileSync(planPath, "utf-8");
86450
+ const planRaw = fs74.readFileSync(planPath, "utf-8");
86426
86451
  const plan2 = JSON.parse(planRaw);
86427
86452
  const phaseObj = plan2.phases.find((p) => p.id === phase);
86428
86453
  if (phaseObj) {
86429
86454
  phaseObj.status = "complete";
86430
- fs75.writeFileSync(planPath, JSON.stringify(plan2, null, 2), "utf-8");
86455
+ fs74.writeFileSync(planPath, JSON.stringify(plan2, null, 2), "utf-8");
86431
86456
  }
86432
86457
  } catch {}
86433
86458
  } else if (plan) {
@@ -86464,12 +86489,12 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
86464
86489
  warnings.push(`Warning: failed to update plan.json phase status`);
86465
86490
  try {
86466
86491
  const planPath = validateSwarmPath(dir, "plan.json");
86467
- const planRaw = fs75.readFileSync(planPath, "utf-8");
86492
+ const planRaw = fs74.readFileSync(planPath, "utf-8");
86468
86493
  const plan = JSON.parse(planRaw);
86469
86494
  const phaseObj = plan.phases.find((p) => p.id === phase);
86470
86495
  if (phaseObj) {
86471
86496
  phaseObj.status = "complete";
86472
- fs75.writeFileSync(planPath, JSON.stringify(plan, null, 2), "utf-8");
86497
+ fs74.writeFileSync(planPath, JSON.stringify(plan, null, 2), "utf-8");
86473
86498
  }
86474
86499
  } catch {}
86475
86500
  }
@@ -86527,8 +86552,8 @@ init_discovery();
86527
86552
  init_utils();
86528
86553
  init_bun_compat();
86529
86554
  init_create_tool();
86530
- import * as fs76 from "node:fs";
86531
- import * as path98 from "node:path";
86555
+ import * as fs75 from "node:fs";
86556
+ import * as path97 from "node:path";
86532
86557
  var MAX_OUTPUT_BYTES5 = 52428800;
86533
86558
  var AUDIT_TIMEOUT_MS = 120000;
86534
86559
  function isValidEcosystem(value) {
@@ -86556,31 +86581,31 @@ function validateArgs3(args2) {
86556
86581
  function detectEcosystems(directory) {
86557
86582
  const ecosystems = [];
86558
86583
  const cwd = directory;
86559
- if (fs76.existsSync(path98.join(cwd, "package.json"))) {
86584
+ if (fs75.existsSync(path97.join(cwd, "package.json"))) {
86560
86585
  ecosystems.push("npm");
86561
86586
  }
86562
- if (fs76.existsSync(path98.join(cwd, "pyproject.toml")) || fs76.existsSync(path98.join(cwd, "requirements.txt"))) {
86587
+ if (fs75.existsSync(path97.join(cwd, "pyproject.toml")) || fs75.existsSync(path97.join(cwd, "requirements.txt"))) {
86563
86588
  ecosystems.push("pip");
86564
86589
  }
86565
- if (fs76.existsSync(path98.join(cwd, "Cargo.toml"))) {
86590
+ if (fs75.existsSync(path97.join(cwd, "Cargo.toml"))) {
86566
86591
  ecosystems.push("cargo");
86567
86592
  }
86568
- if (fs76.existsSync(path98.join(cwd, "go.mod"))) {
86593
+ if (fs75.existsSync(path97.join(cwd, "go.mod"))) {
86569
86594
  ecosystems.push("go");
86570
86595
  }
86571
86596
  try {
86572
- const files = fs76.readdirSync(cwd);
86597
+ const files = fs75.readdirSync(cwd);
86573
86598
  if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
86574
86599
  ecosystems.push("dotnet");
86575
86600
  }
86576
86601
  } catch {}
86577
- if (fs76.existsSync(path98.join(cwd, "Gemfile")) || fs76.existsSync(path98.join(cwd, "Gemfile.lock"))) {
86602
+ if (fs75.existsSync(path97.join(cwd, "Gemfile")) || fs75.existsSync(path97.join(cwd, "Gemfile.lock"))) {
86578
86603
  ecosystems.push("ruby");
86579
86604
  }
86580
- if (fs76.existsSync(path98.join(cwd, "pubspec.yaml"))) {
86605
+ if (fs75.existsSync(path97.join(cwd, "pubspec.yaml"))) {
86581
86606
  ecosystems.push("dart");
86582
86607
  }
86583
- if (fs76.existsSync(path98.join(cwd, "composer.lock"))) {
86608
+ if (fs75.existsSync(path97.join(cwd, "composer.lock"))) {
86584
86609
  ecosystems.push("composer");
86585
86610
  }
86586
86611
  return ecosystems;
@@ -87715,8 +87740,8 @@ var pkg_audit = createSwarmTool({
87715
87740
  // src/tools/placeholder-scan.ts
87716
87741
  init_zod();
87717
87742
  init_manager2();
87718
- import * as fs77 from "node:fs";
87719
- import * as path99 from "node:path";
87743
+ import * as fs76 from "node:fs";
87744
+ import * as path98 from "node:path";
87720
87745
  init_utils();
87721
87746
  init_create_tool();
87722
87747
  var MAX_FILE_SIZE = 1024 * 1024;
@@ -87839,7 +87864,7 @@ function isScaffoldFile(filePath) {
87839
87864
  if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
87840
87865
  return true;
87841
87866
  }
87842
- const filename = path99.basename(filePath);
87867
+ const filename = path98.basename(filePath);
87843
87868
  if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
87844
87869
  return true;
87845
87870
  }
@@ -87856,7 +87881,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
87856
87881
  if (regex.test(normalizedPath)) {
87857
87882
  return true;
87858
87883
  }
87859
- const filename = path99.basename(filePath);
87884
+ const filename = path98.basename(filePath);
87860
87885
  const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
87861
87886
  if (filenameRegex.test(filename)) {
87862
87887
  return true;
@@ -87865,7 +87890,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
87865
87890
  return false;
87866
87891
  }
87867
87892
  function isParserSupported(filePath) {
87868
- const ext = path99.extname(filePath).toLowerCase();
87893
+ const ext = path98.extname(filePath).toLowerCase();
87869
87894
  return SUPPORTED_PARSER_EXTENSIONS.has(ext);
87870
87895
  }
87871
87896
  function isPlanFile(filePath) {
@@ -88112,28 +88137,28 @@ async function placeholderScan(input, directory) {
88112
88137
  let filesScanned = 0;
88113
88138
  const filesWithFindings = new Set;
88114
88139
  for (const filePath of changed_files) {
88115
- const fullPath = path99.isAbsolute(filePath) ? filePath : path99.resolve(directory, filePath);
88116
- const resolvedDirectory = path99.resolve(directory);
88117
- if (!fullPath.startsWith(resolvedDirectory + path99.sep) && fullPath !== resolvedDirectory) {
88140
+ const fullPath = path98.isAbsolute(filePath) ? filePath : path98.resolve(directory, filePath);
88141
+ const resolvedDirectory = path98.resolve(directory);
88142
+ if (!fullPath.startsWith(resolvedDirectory + path98.sep) && fullPath !== resolvedDirectory) {
88118
88143
  continue;
88119
88144
  }
88120
- if (!fs77.existsSync(fullPath)) {
88145
+ if (!fs76.existsSync(fullPath)) {
88121
88146
  continue;
88122
88147
  }
88123
88148
  if (isAllowedByGlobs(filePath, allow_globs)) {
88124
88149
  continue;
88125
88150
  }
88126
- const relativeFilePath = path99.relative(directory, fullPath).replace(/\\/g, "/");
88151
+ const relativeFilePath = path98.relative(directory, fullPath).replace(/\\/g, "/");
88127
88152
  if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
88128
88153
  continue;
88129
88154
  }
88130
88155
  let content;
88131
88156
  try {
88132
- const stat7 = fs77.statSync(fullPath);
88157
+ const stat7 = fs76.statSync(fullPath);
88133
88158
  if (stat7.size > MAX_FILE_SIZE) {
88134
88159
  continue;
88135
88160
  }
88136
- content = fs77.readFileSync(fullPath, "utf-8");
88161
+ content = fs76.readFileSync(fullPath, "utf-8");
88137
88162
  } catch {
88138
88163
  continue;
88139
88164
  }
@@ -88194,8 +88219,8 @@ var placeholder_scan = createSwarmTool({
88194
88219
  }
88195
88220
  });
88196
88221
  // src/tools/pre-check-batch.ts
88197
- import * as fs81 from "node:fs";
88198
- import * as path103 from "node:path";
88222
+ import * as fs80 from "node:fs";
88223
+ import * as path102 from "node:path";
88199
88224
  init_zod();
88200
88225
  init_manager2();
88201
88226
  init_utils();
@@ -88335,8 +88360,8 @@ var _internals30 = {
88335
88360
  init_zod();
88336
88361
  init_manager2();
88337
88362
  init_detector();
88338
- import * as fs80 from "node:fs";
88339
- import * as path102 from "node:path";
88363
+ import * as fs79 from "node:fs";
88364
+ import * as path101 from "node:path";
88340
88365
  import { extname as extname18 } from "node:path";
88341
88366
 
88342
88367
  // src/sast/rules/c.ts
@@ -89051,8 +89076,8 @@ function executeRulesSync(filePath, content, language) {
89051
89076
 
89052
89077
  // src/sast/semgrep.ts
89053
89078
  import * as child_process9 from "node:child_process";
89054
- import * as fs78 from "node:fs";
89055
- import * as path100 from "node:path";
89079
+ import * as fs77 from "node:fs";
89080
+ import * as path99 from "node:path";
89056
89081
  var semgrepAvailableCache = null;
89057
89082
  var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
89058
89083
  var DEFAULT_TIMEOUT_MS3 = 30000;
@@ -89239,14 +89264,14 @@ async function runSemgrep(options) {
89239
89264
  }
89240
89265
  function getRulesDirectory(projectRoot) {
89241
89266
  if (projectRoot) {
89242
- return path100.resolve(projectRoot, DEFAULT_RULES_DIR);
89267
+ return path99.resolve(projectRoot, DEFAULT_RULES_DIR);
89243
89268
  }
89244
89269
  return DEFAULT_RULES_DIR;
89245
89270
  }
89246
89271
  function hasBundledRules(projectRoot) {
89247
89272
  const rulesDir = getRulesDirectory(projectRoot);
89248
89273
  try {
89249
- return fs78.existsSync(rulesDir);
89274
+ return fs77.existsSync(rulesDir);
89250
89275
  } catch {
89251
89276
  return false;
89252
89277
  }
@@ -89259,25 +89284,25 @@ init_create_tool();
89259
89284
  // src/tools/sast-baseline.ts
89260
89285
  init_utils2();
89261
89286
  import * as crypto9 from "node:crypto";
89262
- import * as fs79 from "node:fs";
89263
- import * as path101 from "node:path";
89287
+ import * as fs78 from "node:fs";
89288
+ import * as path100 from "node:path";
89264
89289
  var BASELINE_SCHEMA_VERSION = "1.0.0";
89265
89290
  var MAX_BASELINE_FINDINGS = 2000;
89266
89291
  var MAX_BASELINE_BYTES = 2 * 1048576;
89267
89292
  var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
89268
89293
  function normalizeFindingPath(directory, file3) {
89269
- const resolved = path101.isAbsolute(file3) ? file3 : path101.resolve(directory, file3);
89270
- const rel = path101.relative(path101.resolve(directory), resolved);
89294
+ const resolved = path100.isAbsolute(file3) ? file3 : path100.resolve(directory, file3);
89295
+ const rel = path100.relative(path100.resolve(directory), resolved);
89271
89296
  return rel.replace(/\\/g, "/");
89272
89297
  }
89273
89298
  function baselineRelPath(phase) {
89274
- return path101.join("evidence", String(phase), "sast-baseline.json");
89299
+ return path100.join("evidence", String(phase), "sast-baseline.json");
89275
89300
  }
89276
89301
  function tempRelPath(phase) {
89277
- return path101.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
89302
+ return path100.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
89278
89303
  }
89279
89304
  function lockRelPath(phase) {
89280
- return path101.join("evidence", String(phase), "sast-baseline.json.lock");
89305
+ return path100.join("evidence", String(phase), "sast-baseline.json.lock");
89281
89306
  }
89282
89307
  function getLine(lines, idx) {
89283
89308
  if (idx < 0 || idx >= lines.length)
@@ -89294,7 +89319,7 @@ function fingerprintFinding(finding, directory, occurrenceIndex) {
89294
89319
  }
89295
89320
  const lineNum = finding.location.line;
89296
89321
  try {
89297
- const content = fs79.readFileSync(finding.location.file, "utf-8");
89322
+ const content = fs78.readFileSync(finding.location.file, "utf-8");
89298
89323
  const lines = content.split(`
89299
89324
  `);
89300
89325
  const idx = lineNum - 1;
@@ -89325,7 +89350,7 @@ function assignOccurrenceIndices(findings, directory) {
89325
89350
  try {
89326
89351
  if (relFile.startsWith(".."))
89327
89352
  throw new Error("escapes workspace");
89328
- const content = fs79.readFileSync(finding.location.file, "utf-8");
89353
+ const content = fs78.readFileSync(finding.location.file, "utf-8");
89329
89354
  const lines = content.split(`
89330
89355
  `);
89331
89356
  const idx = lineNum - 1;
@@ -89354,11 +89379,11 @@ function assignOccurrenceIndices(findings, directory) {
89354
89379
  async function acquireLock(lockPath) {
89355
89380
  for (let attempt = 0;attempt <= LOCK_RETRY_DELAYS_MS.length; attempt++) {
89356
89381
  try {
89357
- const fd = fs79.openSync(lockPath, "wx");
89358
- fs79.closeSync(fd);
89382
+ const fd = fs78.openSync(lockPath, "wx");
89383
+ fs78.closeSync(fd);
89359
89384
  return () => {
89360
89385
  try {
89361
- fs79.unlinkSync(lockPath);
89386
+ fs78.unlinkSync(lockPath);
89362
89387
  } catch {}
89363
89388
  };
89364
89389
  } catch {
@@ -89398,13 +89423,13 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
89398
89423
  message: e instanceof Error ? e.message : "Path validation failed"
89399
89424
  };
89400
89425
  }
89401
- fs79.mkdirSync(path101.dirname(baselinePath), { recursive: true });
89402
- fs79.mkdirSync(path101.dirname(tempPath), { recursive: true });
89426
+ fs78.mkdirSync(path100.dirname(baselinePath), { recursive: true });
89427
+ fs78.mkdirSync(path100.dirname(tempPath), { recursive: true });
89403
89428
  const releaseLock = await acquireLock(lockPath);
89404
89429
  try {
89405
89430
  let existing = null;
89406
89431
  try {
89407
- const raw = fs79.readFileSync(baselinePath, "utf-8");
89432
+ const raw = fs78.readFileSync(baselinePath, "utf-8");
89408
89433
  const parsed = JSON.parse(raw);
89409
89434
  if (parsed.schema_version === BASELINE_SCHEMA_VERSION) {
89410
89435
  existing = parsed;
@@ -89464,8 +89489,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
89464
89489
  message: `Baseline would exceed size cap (${json4.length} bytes > ${MAX_BASELINE_BYTES})`
89465
89490
  };
89466
89491
  }
89467
- fs79.writeFileSync(tempPath, json4, "utf-8");
89468
- fs79.renameSync(tempPath, baselinePath);
89492
+ fs78.writeFileSync(tempPath, json4, "utf-8");
89493
+ fs78.renameSync(tempPath, baselinePath);
89469
89494
  return {
89470
89495
  status: "merged",
89471
89496
  path: baselinePath,
@@ -89496,8 +89521,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
89496
89521
  message: `Baseline would exceed size cap (${json3.length} bytes > ${MAX_BASELINE_BYTES})`
89497
89522
  };
89498
89523
  }
89499
- fs79.writeFileSync(tempPath, json3, "utf-8");
89500
- fs79.renameSync(tempPath, baselinePath);
89524
+ fs78.writeFileSync(tempPath, json3, "utf-8");
89525
+ fs78.renameSync(tempPath, baselinePath);
89501
89526
  return {
89502
89527
  status: "written",
89503
89528
  path: baselinePath,
@@ -89522,7 +89547,7 @@ function loadBaseline(directory, phase) {
89522
89547
  };
89523
89548
  }
89524
89549
  try {
89525
- const raw = fs79.readFileSync(baselinePath, "utf-8");
89550
+ const raw = fs78.readFileSync(baselinePath, "utf-8");
89526
89551
  const parsed = JSON.parse(raw);
89527
89552
  if (parsed.schema_version !== BASELINE_SCHEMA_VERSION) {
89528
89553
  return {
@@ -89570,17 +89595,17 @@ var SEVERITY_ORDER = {
89570
89595
  };
89571
89596
  function shouldSkipFile(filePath) {
89572
89597
  try {
89573
- const stats = fs80.statSync(filePath);
89598
+ const stats = fs79.statSync(filePath);
89574
89599
  if (stats.size > MAX_FILE_SIZE_BYTES8) {
89575
89600
  return { skip: true, reason: "file too large" };
89576
89601
  }
89577
89602
  if (stats.size === 0) {
89578
89603
  return { skip: true, reason: "empty file" };
89579
89604
  }
89580
- const fd = fs80.openSync(filePath, "r");
89605
+ const fd = fs79.openSync(filePath, "r");
89581
89606
  const buffer = Buffer.alloc(8192);
89582
- const bytesRead = fs80.readSync(fd, buffer, 0, 8192, 0);
89583
- fs80.closeSync(fd);
89607
+ const bytesRead = fs79.readSync(fd, buffer, 0, 8192, 0);
89608
+ fs79.closeSync(fd);
89584
89609
  if (bytesRead > 0) {
89585
89610
  let nullCount = 0;
89586
89611
  for (let i2 = 0;i2 < bytesRead; i2++) {
@@ -89619,7 +89644,7 @@ function countBySeverity(findings) {
89619
89644
  }
89620
89645
  function scanFileWithTierA(filePath, language) {
89621
89646
  try {
89622
- const content = fs80.readFileSync(filePath, "utf-8");
89647
+ const content = fs79.readFileSync(filePath, "utf-8");
89623
89648
  const findings = executeRulesSync(filePath, content, language);
89624
89649
  return findings.map((f) => ({
89625
89650
  rule_id: f.rule_id,
@@ -89672,13 +89697,13 @@ async function sastScan(input, directory, config3) {
89672
89697
  _filesSkipped++;
89673
89698
  continue;
89674
89699
  }
89675
- const resolvedPath = path102.isAbsolute(filePath) ? filePath : path102.resolve(directory, filePath);
89676
- const resolvedDirectory = path102.resolve(directory);
89677
- if (!resolvedPath.startsWith(resolvedDirectory + path102.sep) && resolvedPath !== resolvedDirectory) {
89700
+ const resolvedPath = path101.isAbsolute(filePath) ? filePath : path101.resolve(directory, filePath);
89701
+ const resolvedDirectory = path101.resolve(directory);
89702
+ if (!resolvedPath.startsWith(resolvedDirectory + path101.sep) && resolvedPath !== resolvedDirectory) {
89678
89703
  _filesSkipped++;
89679
89704
  continue;
89680
89705
  }
89681
- if (!fs80.existsSync(resolvedPath)) {
89706
+ if (!fs79.existsSync(resolvedPath)) {
89682
89707
  _filesSkipped++;
89683
89708
  continue;
89684
89709
  }
@@ -89989,18 +90014,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
89989
90014
  let resolved;
89990
90015
  const isWinAbs = isWindowsAbsolutePath(inputPath);
89991
90016
  if (isWinAbs) {
89992
- resolved = path103.win32.resolve(inputPath);
89993
- } else if (path103.isAbsolute(inputPath)) {
89994
- resolved = path103.resolve(inputPath);
90017
+ resolved = path102.win32.resolve(inputPath);
90018
+ } else if (path102.isAbsolute(inputPath)) {
90019
+ resolved = path102.resolve(inputPath);
89995
90020
  } else {
89996
- resolved = path103.resolve(baseDir, inputPath);
90021
+ resolved = path102.resolve(baseDir, inputPath);
89997
90022
  }
89998
- const workspaceResolved = path103.resolve(workspaceDir);
90023
+ const workspaceResolved = path102.resolve(workspaceDir);
89999
90024
  let relative22;
90000
90025
  if (isWinAbs) {
90001
- relative22 = path103.win32.relative(workspaceResolved, resolved);
90026
+ relative22 = path102.win32.relative(workspaceResolved, resolved);
90002
90027
  } else {
90003
- relative22 = path103.relative(workspaceResolved, resolved);
90028
+ relative22 = path102.relative(workspaceResolved, resolved);
90004
90029
  }
90005
90030
  if (relative22.startsWith("..")) {
90006
90031
  return "path traversal detected";
@@ -90065,7 +90090,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
90065
90090
  if (typeof file3 !== "string") {
90066
90091
  continue;
90067
90092
  }
90068
- const resolvedPath = path103.resolve(file3);
90093
+ const resolvedPath = path102.resolve(file3);
90069
90094
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
90070
90095
  if (validationError) {
90071
90096
  continue;
@@ -90222,7 +90247,7 @@ async function runSecretscanWithFiles(files, directory) {
90222
90247
  skippedFiles++;
90223
90248
  continue;
90224
90249
  }
90225
- const resolvedPath = path103.resolve(file3);
90250
+ const resolvedPath = path102.resolve(file3);
90226
90251
  const validationError = validatePath(resolvedPath, directory, directory);
90227
90252
  if (validationError) {
90228
90253
  skippedFiles++;
@@ -90240,14 +90265,14 @@ async function runSecretscanWithFiles(files, directory) {
90240
90265
  };
90241
90266
  }
90242
90267
  for (const file3 of validatedFiles) {
90243
- const ext = path103.extname(file3).toLowerCase();
90268
+ const ext = path102.extname(file3).toLowerCase();
90244
90269
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
90245
90270
  skippedFiles++;
90246
90271
  continue;
90247
90272
  }
90248
90273
  let stat7;
90249
90274
  try {
90250
- stat7 = fs81.statSync(file3);
90275
+ stat7 = fs80.statSync(file3);
90251
90276
  } catch {
90252
90277
  skippedFiles++;
90253
90278
  continue;
@@ -90258,7 +90283,7 @@ async function runSecretscanWithFiles(files, directory) {
90258
90283
  }
90259
90284
  let content;
90260
90285
  try {
90261
- const buffer = fs81.readFileSync(file3);
90286
+ const buffer = fs80.readFileSync(file3);
90262
90287
  if (buffer.includes(0)) {
90263
90288
  skippedFiles++;
90264
90289
  continue;
@@ -90459,7 +90484,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
90459
90484
  const preexistingFindings = [];
90460
90485
  for (const finding of findings) {
90461
90486
  const filePath = finding.location.file;
90462
- const normalised = path103.relative(directory, filePath).replace(/\\/g, "/");
90487
+ const normalised = path102.relative(directory, filePath).replace(/\\/g, "/");
90463
90488
  const changedLines = changedLineRanges.get(normalised);
90464
90489
  if (changedLines?.has(finding.location.line)) {
90465
90490
  newFindings.push(finding);
@@ -90510,7 +90535,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
90510
90535
  warn(`pre_check_batch: Invalid file path: ${file3}`);
90511
90536
  continue;
90512
90537
  }
90513
- changedFiles.push(path103.resolve(directory, file3));
90538
+ changedFiles.push(path102.resolve(directory, file3));
90514
90539
  }
90515
90540
  if (changedFiles.length === 0) {
90516
90541
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -90711,7 +90736,7 @@ var pre_check_batch = createSwarmTool({
90711
90736
  };
90712
90737
  return JSON.stringify(errorResult, null, 2);
90713
90738
  }
90714
- const resolvedDirectory = path103.resolve(typedArgs.directory);
90739
+ const resolvedDirectory = path102.resolve(typedArgs.directory);
90715
90740
  const workspaceAnchor = resolvedDirectory;
90716
90741
  const dirError = validateDirectory2(resolvedDirectory, workspaceAnchor);
90717
90742
  if (dirError) {
@@ -90752,7 +90777,7 @@ var pre_check_batch = createSwarmTool({
90752
90777
  });
90753
90778
  // src/tools/repo-map.ts
90754
90779
  init_zod();
90755
- import * as path104 from "node:path";
90780
+ import * as path103 from "node:path";
90756
90781
  init_path_security();
90757
90782
  init_create_tool();
90758
90783
  var VALID_ACTIONS = [
@@ -90777,7 +90802,7 @@ function validateFile(p) {
90777
90802
  return "file contains control characters";
90778
90803
  if (containsPathTraversal(p))
90779
90804
  return "file contains path traversal";
90780
- if (path104.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
90805
+ if (path103.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
90781
90806
  return "file must be a workspace-relative path, not absolute";
90782
90807
  }
90783
90808
  return null;
@@ -90800,8 +90825,8 @@ function ok(action, payload) {
90800
90825
  }
90801
90826
  function toRelativeGraphPath(input, workspaceRoot) {
90802
90827
  const normalized = input.replace(/\\/g, "/");
90803
- if (path104.isAbsolute(normalized)) {
90804
- const rel = path104.relative(workspaceRoot, normalized).replace(/\\/g, "/");
90828
+ if (path103.isAbsolute(normalized)) {
90829
+ const rel = path103.relative(workspaceRoot, normalized).replace(/\\/g, "/");
90805
90830
  return normalizeGraphPath2(rel);
90806
90831
  }
90807
90832
  return normalizeGraphPath2(normalized);
@@ -90945,8 +90970,8 @@ var repo_map = createSwarmTool({
90945
90970
  // src/tools/req-coverage.ts
90946
90971
  init_zod();
90947
90972
  init_create_tool();
90948
- import * as fs82 from "node:fs";
90949
- import * as path105 from "node:path";
90973
+ import * as fs81 from "node:fs";
90974
+ import * as path104 from "node:path";
90950
90975
  var SPEC_FILE = ".swarm/spec.md";
90951
90976
  var EVIDENCE_DIR4 = ".swarm/evidence";
90952
90977
  var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
@@ -91005,19 +91030,19 @@ function extractObligationAndText(id, lineText) {
91005
91030
  var PHASE_TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
91006
91031
  function readTouchedFiles(evidenceDir, phase, cwd) {
91007
91032
  const touchedFiles = new Set;
91008
- if (!fs82.existsSync(evidenceDir) || !fs82.statSync(evidenceDir).isDirectory()) {
91033
+ if (!fs81.existsSync(evidenceDir) || !fs81.statSync(evidenceDir).isDirectory()) {
91009
91034
  return [];
91010
91035
  }
91011
91036
  let entries;
91012
91037
  try {
91013
- entries = fs82.readdirSync(evidenceDir);
91038
+ entries = fs81.readdirSync(evidenceDir);
91014
91039
  } catch {
91015
91040
  return [];
91016
91041
  }
91017
91042
  for (const entry of entries) {
91018
- const entryPath = path105.join(evidenceDir, entry);
91043
+ const entryPath = path104.join(evidenceDir, entry);
91019
91044
  try {
91020
- const stat7 = fs82.statSync(entryPath);
91045
+ const stat7 = fs81.statSync(entryPath);
91021
91046
  if (!stat7.isDirectory()) {
91022
91047
  continue;
91023
91048
  }
@@ -91031,14 +91056,14 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
91031
91056
  if (entryPhase !== String(phase)) {
91032
91057
  continue;
91033
91058
  }
91034
- const evidenceFilePath = path105.join(entryPath, "evidence.json");
91059
+ const evidenceFilePath = path104.join(entryPath, "evidence.json");
91035
91060
  try {
91036
- const resolvedPath = path105.resolve(evidenceFilePath);
91037
- const evidenceDirResolved = path105.resolve(evidenceDir);
91038
- if (!resolvedPath.startsWith(evidenceDirResolved + path105.sep)) {
91061
+ const resolvedPath = path104.resolve(evidenceFilePath);
91062
+ const evidenceDirResolved = path104.resolve(evidenceDir);
91063
+ if (!resolvedPath.startsWith(evidenceDirResolved + path104.sep)) {
91039
91064
  continue;
91040
91065
  }
91041
- const stat7 = fs82.lstatSync(evidenceFilePath);
91066
+ const stat7 = fs81.lstatSync(evidenceFilePath);
91042
91067
  if (!stat7.isFile()) {
91043
91068
  continue;
91044
91069
  }
@@ -91050,7 +91075,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
91050
91075
  }
91051
91076
  let content;
91052
91077
  try {
91053
- content = fs82.readFileSync(evidenceFilePath, "utf-8");
91078
+ content = fs81.readFileSync(evidenceFilePath, "utf-8");
91054
91079
  } catch {
91055
91080
  continue;
91056
91081
  }
@@ -91069,7 +91094,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
91069
91094
  if (Array.isArray(diffEntry.files_changed)) {
91070
91095
  for (const file3 of diffEntry.files_changed) {
91071
91096
  if (typeof file3 === "string") {
91072
- touchedFiles.add(path105.resolve(cwd, file3));
91097
+ touchedFiles.add(path104.resolve(cwd, file3));
91073
91098
  }
91074
91099
  }
91075
91100
  }
@@ -91082,12 +91107,12 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
91082
91107
  }
91083
91108
  function searchFileForKeywords(filePath, keywords, cwd) {
91084
91109
  try {
91085
- const resolvedPath = path105.resolve(filePath);
91086
- const cwdResolved = path105.resolve(cwd);
91110
+ const resolvedPath = path104.resolve(filePath);
91111
+ const cwdResolved = path104.resolve(cwd);
91087
91112
  if (!resolvedPath.startsWith(cwdResolved)) {
91088
91113
  return false;
91089
91114
  }
91090
- const content = fs82.readFileSync(resolvedPath, "utf-8");
91115
+ const content = fs81.readFileSync(resolvedPath, "utf-8");
91091
91116
  for (const keyword of keywords) {
91092
91117
  const regex = new RegExp(`\\b${keyword}\\b`, "i");
91093
91118
  if (regex.test(content)) {
@@ -91217,10 +91242,10 @@ var req_coverage = createSwarmTool({
91217
91242
  }, null, 2);
91218
91243
  }
91219
91244
  const cwd = inputDirectory || directory;
91220
- const specPath = path105.join(cwd, SPEC_FILE);
91245
+ const specPath = path104.join(cwd, SPEC_FILE);
91221
91246
  let specContent;
91222
91247
  try {
91223
- specContent = fs82.readFileSync(specPath, "utf-8");
91248
+ specContent = fs81.readFileSync(specPath, "utf-8");
91224
91249
  } catch (readError) {
91225
91250
  return JSON.stringify({
91226
91251
  success: false,
@@ -91244,7 +91269,7 @@ var req_coverage = createSwarmTool({
91244
91269
  message: "No FR requirements found in spec.md"
91245
91270
  }, null, 2);
91246
91271
  }
91247
- const evidenceDir = path105.join(cwd, EVIDENCE_DIR4);
91272
+ const evidenceDir = path104.join(cwd, EVIDENCE_DIR4);
91248
91273
  const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
91249
91274
  const analyzedRequirements = [];
91250
91275
  let coveredCount = 0;
@@ -91270,12 +91295,12 @@ var req_coverage = createSwarmTool({
91270
91295
  requirements: analyzedRequirements
91271
91296
  };
91272
91297
  const reportFilename = `req-coverage-phase-${phase}.json`;
91273
- const reportPath = path105.join(evidenceDir, reportFilename);
91298
+ const reportPath = path104.join(evidenceDir, reportFilename);
91274
91299
  try {
91275
- if (!fs82.existsSync(evidenceDir)) {
91276
- fs82.mkdirSync(evidenceDir, { recursive: true });
91300
+ if (!fs81.existsSync(evidenceDir)) {
91301
+ fs81.mkdirSync(evidenceDir, { recursive: true });
91277
91302
  }
91278
- fs82.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8");
91303
+ fs81.writeFileSync(reportPath, JSON.stringify(result, null, 2), "utf-8");
91279
91304
  } catch (writeError) {
91280
91305
  console.warn(`Failed to write coverage report: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
91281
91306
  }
@@ -91357,8 +91382,8 @@ init_plan_schema();
91357
91382
  init_qa_gate_profile();
91358
91383
  init_file_locks();
91359
91384
  import * as crypto10 from "node:crypto";
91360
- import * as fs83 from "node:fs";
91361
- import * as path106 from "node:path";
91385
+ import * as fs82 from "node:fs";
91386
+ import * as path105 from "node:path";
91362
91387
  init_ledger();
91363
91388
  init_manager();
91364
91389
  init_state();
@@ -91436,17 +91461,17 @@ async function executeSavePlan(args2, fallbackDir) {
91436
91461
  };
91437
91462
  }
91438
91463
  if (args2.working_directory && fallbackDir) {
91439
- const resolvedTarget = path106.resolve(args2.working_directory);
91440
- const resolvedRoot = path106.resolve(fallbackDir);
91464
+ const resolvedTarget = path105.resolve(args2.working_directory);
91465
+ const resolvedRoot = path105.resolve(fallbackDir);
91441
91466
  let fallbackExists = false;
91442
91467
  try {
91443
- fs83.accessSync(resolvedRoot, fs83.constants.F_OK);
91468
+ fs82.accessSync(resolvedRoot, fs82.constants.F_OK);
91444
91469
  fallbackExists = true;
91445
91470
  } catch {
91446
91471
  fallbackExists = false;
91447
91472
  }
91448
91473
  if (fallbackExists) {
91449
- const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path106.sep);
91474
+ const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path105.sep);
91450
91475
  if (isSubdirectory) {
91451
91476
  return {
91452
91477
  success: false,
@@ -91462,11 +91487,11 @@ async function executeSavePlan(args2, fallbackDir) {
91462
91487
  let specMtime;
91463
91488
  let specHash;
91464
91489
  if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
91465
- const specPath = path106.join(targetWorkspace, ".swarm", "spec.md");
91490
+ const specPath = path105.join(targetWorkspace, ".swarm", "spec.md");
91466
91491
  try {
91467
- const stat7 = await fs83.promises.stat(specPath);
91492
+ const stat7 = await fs82.promises.stat(specPath);
91468
91493
  specMtime = stat7.mtime.toISOString();
91469
- const content = await fs83.promises.readFile(specPath, "utf8");
91494
+ const content = await fs82.promises.readFile(specPath, "utf8");
91470
91495
  specHash = crypto10.createHash("sha256").update(content).digest("hex");
91471
91496
  } catch {
91472
91497
  return {
@@ -91478,10 +91503,10 @@ async function executeSavePlan(args2, fallbackDir) {
91478
91503
  }
91479
91504
  }
91480
91505
  if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
91481
- const contextPath = path106.join(targetWorkspace, ".swarm", "context.md");
91506
+ const contextPath = path105.join(targetWorkspace, ".swarm", "context.md");
91482
91507
  let contextContent = "";
91483
91508
  try {
91484
- contextContent = await fs83.promises.readFile(contextPath, "utf8");
91509
+ contextContent = await fs82.promises.readFile(contextPath, "utf8");
91485
91510
  } catch {}
91486
91511
  const hasPendingSection = contextContent.includes("## Pending QA Gate Selection");
91487
91512
  if (!hasPendingSection) {
@@ -91631,14 +91656,14 @@ async function executeSavePlan(args2, fallbackDir) {
91631
91656
  }
91632
91657
  await writeCheckpoint(dir).catch(() => {});
91633
91658
  try {
91634
- const markerPath = path106.join(dir, ".swarm", ".plan-write-marker");
91659
+ const markerPath = path105.join(dir, ".swarm", ".plan-write-marker");
91635
91660
  const marker = JSON.stringify({
91636
91661
  source: "save_plan",
91637
91662
  timestamp: new Date().toISOString(),
91638
91663
  phases_count: plan.phases.length,
91639
91664
  tasks_count: tasksCount
91640
91665
  });
91641
- await fs83.promises.writeFile(markerPath, marker, "utf8");
91666
+ await fs82.promises.writeFile(markerPath, marker, "utf8");
91642
91667
  } catch {}
91643
91668
  const warnings = [];
91644
91669
  let criticReviewFound = false;
@@ -91654,7 +91679,7 @@ async function executeSavePlan(args2, fallbackDir) {
91654
91679
  return {
91655
91680
  success: true,
91656
91681
  message: "Plan saved successfully",
91657
- plan_path: path106.join(dir, ".swarm", "plan.json"),
91682
+ plan_path: path105.join(dir, ".swarm", "plan.json"),
91658
91683
  phases_count: plan.phases.length,
91659
91684
  tasks_count: tasksCount,
91660
91685
  ...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
@@ -91706,8 +91731,8 @@ var save_plan = createSwarmTool({
91706
91731
  // src/tools/sbom-generate.ts
91707
91732
  init_zod();
91708
91733
  init_manager2();
91709
- import * as fs84 from "node:fs";
91710
- import * as path107 from "node:path";
91734
+ import * as fs83 from "node:fs";
91735
+ import * as path106 from "node:path";
91711
91736
 
91712
91737
  // src/sbom/detectors/index.ts
91713
91738
  init_utils();
@@ -92555,9 +92580,9 @@ function findManifestFiles(rootDir) {
92555
92580
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
92556
92581
  function searchDir(dir) {
92557
92582
  try {
92558
- const entries = fs84.readdirSync(dir, { withFileTypes: true });
92583
+ const entries = fs83.readdirSync(dir, { withFileTypes: true });
92559
92584
  for (const entry of entries) {
92560
- const fullPath = path107.join(dir, entry.name);
92585
+ const fullPath = path106.join(dir, entry.name);
92561
92586
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
92562
92587
  continue;
92563
92588
  }
@@ -92566,7 +92591,7 @@ function findManifestFiles(rootDir) {
92566
92591
  } else if (entry.isFile()) {
92567
92592
  for (const pattern of patterns) {
92568
92593
  if (simpleGlobToRegex(pattern).test(entry.name)) {
92569
- manifestFiles.push(path107.relative(rootDir, fullPath));
92594
+ manifestFiles.push(path106.relative(rootDir, fullPath));
92570
92595
  break;
92571
92596
  }
92572
92597
  }
@@ -92582,13 +92607,13 @@ function findManifestFilesInDirs(directories, workingDir) {
92582
92607
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
92583
92608
  for (const dir of directories) {
92584
92609
  try {
92585
- const entries = fs84.readdirSync(dir, { withFileTypes: true });
92610
+ const entries = fs83.readdirSync(dir, { withFileTypes: true });
92586
92611
  for (const entry of entries) {
92587
- const fullPath = path107.join(dir, entry.name);
92612
+ const fullPath = path106.join(dir, entry.name);
92588
92613
  if (entry.isFile()) {
92589
92614
  for (const pattern of patterns) {
92590
92615
  if (simpleGlobToRegex(pattern).test(entry.name)) {
92591
- found.push(path107.relative(workingDir, fullPath));
92616
+ found.push(path106.relative(workingDir, fullPath));
92592
92617
  break;
92593
92618
  }
92594
92619
  }
@@ -92601,11 +92626,11 @@ function findManifestFilesInDirs(directories, workingDir) {
92601
92626
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
92602
92627
  const dirs = new Set;
92603
92628
  for (const file3 of changedFiles) {
92604
- let currentDir = path107.dirname(file3);
92629
+ let currentDir = path106.dirname(file3);
92605
92630
  while (true) {
92606
- if (currentDir && currentDir !== "." && currentDir !== path107.sep) {
92607
- dirs.add(path107.join(workingDir, currentDir));
92608
- const parent = path107.dirname(currentDir);
92631
+ if (currentDir && currentDir !== "." && currentDir !== path106.sep) {
92632
+ dirs.add(path106.join(workingDir, currentDir));
92633
+ const parent = path106.dirname(currentDir);
92609
92634
  if (parent === currentDir)
92610
92635
  break;
92611
92636
  currentDir = parent;
@@ -92619,7 +92644,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
92619
92644
  }
92620
92645
  function ensureOutputDir(outputDir) {
92621
92646
  try {
92622
- fs84.mkdirSync(outputDir, { recursive: true });
92647
+ fs83.mkdirSync(outputDir, { recursive: true });
92623
92648
  } catch (error93) {
92624
92649
  if (!error93 || error93.code !== "EEXIST") {
92625
92650
  throw error93;
@@ -92689,7 +92714,7 @@ var sbom_generate = createSwarmTool({
92689
92714
  const changedFiles = obj.changed_files;
92690
92715
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
92691
92716
  const workingDir = directory;
92692
- const outputDir = path107.isAbsolute(relativeOutputDir) ? relativeOutputDir : path107.join(workingDir, relativeOutputDir);
92717
+ const outputDir = path106.isAbsolute(relativeOutputDir) ? relativeOutputDir : path106.join(workingDir, relativeOutputDir);
92693
92718
  let manifestFiles = [];
92694
92719
  if (scope === "all") {
92695
92720
  manifestFiles = findManifestFiles(workingDir);
@@ -92712,11 +92737,11 @@ var sbom_generate = createSwarmTool({
92712
92737
  const processedFiles = [];
92713
92738
  for (const manifestFile of manifestFiles) {
92714
92739
  try {
92715
- const fullPath = path107.isAbsolute(manifestFile) ? manifestFile : path107.join(workingDir, manifestFile);
92716
- if (!fs84.existsSync(fullPath)) {
92740
+ const fullPath = path106.isAbsolute(manifestFile) ? manifestFile : path106.join(workingDir, manifestFile);
92741
+ if (!fs83.existsSync(fullPath)) {
92717
92742
  continue;
92718
92743
  }
92719
- const content = fs84.readFileSync(fullPath, "utf-8");
92744
+ const content = fs83.readFileSync(fullPath, "utf-8");
92720
92745
  const components = detectComponents(manifestFile, content);
92721
92746
  processedFiles.push(manifestFile);
92722
92747
  if (components.length > 0) {
@@ -92729,8 +92754,8 @@ var sbom_generate = createSwarmTool({
92729
92754
  const bom = generateCycloneDX(allComponents);
92730
92755
  const bomJson = serializeCycloneDX(bom);
92731
92756
  const filename = generateSbomFilename();
92732
- const outputPath = path107.join(outputDir, filename);
92733
- fs84.writeFileSync(outputPath, bomJson, "utf-8");
92757
+ const outputPath = path106.join(outputDir, filename);
92758
+ fs83.writeFileSync(outputPath, bomJson, "utf-8");
92734
92759
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
92735
92760
  try {
92736
92761
  const timestamp = new Date().toISOString();
@@ -92772,8 +92797,8 @@ var sbom_generate = createSwarmTool({
92772
92797
  // src/tools/schema-drift.ts
92773
92798
  init_zod();
92774
92799
  init_create_tool();
92775
- import * as fs85 from "node:fs";
92776
- import * as path108 from "node:path";
92800
+ import * as fs84 from "node:fs";
92801
+ import * as path107 from "node:path";
92777
92802
  var SPEC_CANDIDATES = [
92778
92803
  "openapi.json",
92779
92804
  "openapi.yaml",
@@ -92805,28 +92830,28 @@ function normalizePath4(p) {
92805
92830
  }
92806
92831
  function discoverSpecFile(cwd, specFileArg) {
92807
92832
  if (specFileArg) {
92808
- const resolvedPath = path108.resolve(cwd, specFileArg);
92809
- const normalizedCwd = cwd.endsWith(path108.sep) ? cwd : cwd + path108.sep;
92833
+ const resolvedPath = path107.resolve(cwd, specFileArg);
92834
+ const normalizedCwd = cwd.endsWith(path107.sep) ? cwd : cwd + path107.sep;
92810
92835
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
92811
92836
  throw new Error("Invalid spec_file: path traversal detected");
92812
92837
  }
92813
- const ext = path108.extname(resolvedPath).toLowerCase();
92838
+ const ext = path107.extname(resolvedPath).toLowerCase();
92814
92839
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
92815
92840
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
92816
92841
  }
92817
- const stats = fs85.statSync(resolvedPath);
92842
+ const stats = fs84.statSync(resolvedPath);
92818
92843
  if (stats.size > MAX_SPEC_SIZE) {
92819
92844
  throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
92820
92845
  }
92821
- if (!fs85.existsSync(resolvedPath)) {
92846
+ if (!fs84.existsSync(resolvedPath)) {
92822
92847
  throw new Error(`Spec file not found: ${resolvedPath}`);
92823
92848
  }
92824
92849
  return resolvedPath;
92825
92850
  }
92826
92851
  for (const candidate of SPEC_CANDIDATES) {
92827
- const candidatePath = path108.resolve(cwd, candidate);
92828
- if (fs85.existsSync(candidatePath)) {
92829
- const stats = fs85.statSync(candidatePath);
92852
+ const candidatePath = path107.resolve(cwd, candidate);
92853
+ if (fs84.existsSync(candidatePath)) {
92854
+ const stats = fs84.statSync(candidatePath);
92830
92855
  if (stats.size <= MAX_SPEC_SIZE) {
92831
92856
  return candidatePath;
92832
92857
  }
@@ -92835,8 +92860,8 @@ function discoverSpecFile(cwd, specFileArg) {
92835
92860
  return null;
92836
92861
  }
92837
92862
  function parseSpec(specFile) {
92838
- const content = fs85.readFileSync(specFile, "utf-8");
92839
- const ext = path108.extname(specFile).toLowerCase();
92863
+ const content = fs84.readFileSync(specFile, "utf-8");
92864
+ const ext = path107.extname(specFile).toLowerCase();
92840
92865
  if (ext === ".json") {
92841
92866
  return parseJsonSpec(content);
92842
92867
  }
@@ -92907,12 +92932,12 @@ function extractRoutes(cwd) {
92907
92932
  function walkDir(dir) {
92908
92933
  let entries;
92909
92934
  try {
92910
- entries = fs85.readdirSync(dir, { withFileTypes: true });
92935
+ entries = fs84.readdirSync(dir, { withFileTypes: true });
92911
92936
  } catch {
92912
92937
  return;
92913
92938
  }
92914
92939
  for (const entry of entries) {
92915
- const fullPath = path108.join(dir, entry.name);
92940
+ const fullPath = path107.join(dir, entry.name);
92916
92941
  if (entry.isSymbolicLink()) {
92917
92942
  continue;
92918
92943
  }
@@ -92922,7 +92947,7 @@ function extractRoutes(cwd) {
92922
92947
  }
92923
92948
  walkDir(fullPath);
92924
92949
  } else if (entry.isFile()) {
92925
- const ext = path108.extname(entry.name).toLowerCase();
92950
+ const ext = path107.extname(entry.name).toLowerCase();
92926
92951
  const baseName = entry.name.toLowerCase();
92927
92952
  if (![".ts", ".js", ".mjs"].includes(ext)) {
92928
92953
  continue;
@@ -92940,7 +92965,7 @@ function extractRoutes(cwd) {
92940
92965
  }
92941
92966
  function extractRoutesFromFile(filePath) {
92942
92967
  const routes = [];
92943
- const content = fs85.readFileSync(filePath, "utf-8");
92968
+ const content = fs84.readFileSync(filePath, "utf-8");
92944
92969
  const lines = content.split(/\r?\n/);
92945
92970
  const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
92946
92971
  const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
@@ -93089,8 +93114,8 @@ init_zod();
93089
93114
  init_bun_compat();
93090
93115
  init_path_security();
93091
93116
  init_create_tool();
93092
- import * as fs86 from "node:fs";
93093
- import * as path109 from "node:path";
93117
+ import * as fs85 from "node:fs";
93118
+ import * as path108 from "node:path";
93094
93119
  var DEFAULT_MAX_RESULTS = 100;
93095
93120
  var DEFAULT_MAX_LINES = 200;
93096
93121
  var REGEX_TIMEOUT_MS = 5000;
@@ -93126,11 +93151,11 @@ function containsWindowsAttacks3(str) {
93126
93151
  }
93127
93152
  function isPathInWorkspace3(filePath, workspace) {
93128
93153
  try {
93129
- const resolvedPath = path109.resolve(workspace, filePath);
93130
- const realWorkspace = fs86.realpathSync(workspace);
93131
- const realResolvedPath = fs86.realpathSync(resolvedPath);
93132
- const relativePath = path109.relative(realWorkspace, realResolvedPath);
93133
- if (relativePath.startsWith("..") || path109.isAbsolute(relativePath)) {
93154
+ const resolvedPath = path108.resolve(workspace, filePath);
93155
+ const realWorkspace = fs85.realpathSync(workspace);
93156
+ const realResolvedPath = fs85.realpathSync(resolvedPath);
93157
+ const relativePath = path108.relative(realWorkspace, realResolvedPath);
93158
+ if (relativePath.startsWith("..") || path108.isAbsolute(relativePath)) {
93134
93159
  return false;
93135
93160
  }
93136
93161
  return true;
@@ -93143,12 +93168,12 @@ function validatePathForRead2(filePath, workspace) {
93143
93168
  }
93144
93169
  function findRgInEnvPath() {
93145
93170
  const searchPath = process.env.PATH ?? "";
93146
- for (const dir of searchPath.split(path109.delimiter)) {
93171
+ for (const dir of searchPath.split(path108.delimiter)) {
93147
93172
  if (!dir)
93148
93173
  continue;
93149
93174
  const isWindows = process.platform === "win32";
93150
- const candidate = path109.join(dir, isWindows ? "rg.exe" : "rg");
93151
- if (fs86.existsSync(candidate))
93175
+ const candidate = path108.join(dir, isWindows ? "rg.exe" : "rg");
93176
+ if (fs85.existsSync(candidate))
93152
93177
  return candidate;
93153
93178
  }
93154
93179
  return null;
@@ -93275,10 +93300,10 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
93275
93300
  return files;
93276
93301
  }
93277
93302
  try {
93278
- const entries = fs86.readdirSync(dir, { withFileTypes: true });
93303
+ const entries = fs85.readdirSync(dir, { withFileTypes: true });
93279
93304
  for (const entry of entries) {
93280
- const fullPath = path109.join(dir, entry.name);
93281
- const relativePath = path109.relative(workspace, fullPath);
93305
+ const fullPath = path108.join(dir, entry.name);
93306
+ const relativePath = path108.relative(workspace, fullPath);
93282
93307
  if (!validatePathForRead2(fullPath, workspace)) {
93283
93308
  continue;
93284
93309
  }
@@ -93319,13 +93344,13 @@ async function fallbackSearch(opts) {
93319
93344
  const matches = [];
93320
93345
  let total = 0;
93321
93346
  for (const file3 of files) {
93322
- const fullPath = path109.join(opts.workspace, file3);
93347
+ const fullPath = path108.join(opts.workspace, file3);
93323
93348
  if (!validatePathForRead2(fullPath, opts.workspace)) {
93324
93349
  continue;
93325
93350
  }
93326
93351
  let stats;
93327
93352
  try {
93328
- stats = fs86.statSync(fullPath);
93353
+ stats = fs85.statSync(fullPath);
93329
93354
  if (stats.size > MAX_FILE_SIZE_BYTES10) {
93330
93355
  continue;
93331
93356
  }
@@ -93334,7 +93359,7 @@ async function fallbackSearch(opts) {
93334
93359
  }
93335
93360
  let content;
93336
93361
  try {
93337
- content = fs86.readFileSync(fullPath, "utf-8");
93362
+ content = fs85.readFileSync(fullPath, "utf-8");
93338
93363
  } catch {
93339
93364
  continue;
93340
93365
  }
@@ -93446,7 +93471,7 @@ var search = createSwarmTool({
93446
93471
  message: "Exclude pattern contains invalid Windows-specific sequence"
93447
93472
  }, null, 2);
93448
93473
  }
93449
- if (!fs86.existsSync(directory)) {
93474
+ if (!fs85.existsSync(directory)) {
93450
93475
  return JSON.stringify({
93451
93476
  error: true,
93452
93477
  type: "unknown",
@@ -93626,7 +93651,7 @@ init_schema();
93626
93651
  init_knowledge_store();
93627
93652
  import { existsSync as existsSync64 } from "node:fs";
93628
93653
  import { mkdir as mkdir17, rename as rename6, writeFile as writeFile14 } from "node:fs/promises";
93629
- import * as path111 from "node:path";
93654
+ import * as path110 from "node:path";
93630
93655
 
93631
93656
  // src/hooks/skill-improver-llm-factory.ts
93632
93657
  init_state();
@@ -93742,7 +93767,7 @@ init_skill_generator();
93742
93767
  var import_proper_lockfile7 = __toESM(require_proper_lockfile(), 1);
93743
93768
  import { existsSync as existsSync63 } from "node:fs";
93744
93769
  import { mkdir as mkdir16, readFile as readFile15, rename as rename5, writeFile as writeFile13 } from "node:fs/promises";
93745
- import * as path110 from "node:path";
93770
+ import * as path109 from "node:path";
93746
93771
  var LOCK_ACQUIRE_TIMEOUT_MS = 1e4;
93747
93772
  var LOCK_RETRY_OPTS = {
93748
93773
  retries: {
@@ -93770,7 +93795,7 @@ async function acquireLock2(dir) {
93770
93795
  }
93771
93796
  }
93772
93797
  function resolveQuotaPath(directory) {
93773
- return path110.join(directory, ".swarm", "skill-improver-quota.json");
93798
+ return path109.join(directory, ".swarm", "skill-improver-quota.json");
93774
93799
  }
93775
93800
  function todayKey(window2, now = new Date) {
93776
93801
  if (window2 === "utc") {
@@ -93796,7 +93821,7 @@ async function readState(filePath) {
93796
93821
  }
93797
93822
  }
93798
93823
  async function writeState(filePath, state) {
93799
- await mkdir16(path110.dirname(filePath), { recursive: true });
93824
+ await mkdir16(path109.dirname(filePath), { recursive: true });
93800
93825
  const tmp = `${filePath}.tmp-${process.pid}`;
93801
93826
  await writeFile13(tmp, JSON.stringify(state, null, 2), "utf-8");
93802
93827
  await rename5(tmp, filePath);
@@ -93819,10 +93844,10 @@ async function getQuotaState(directory, opts) {
93819
93844
  }
93820
93845
  async function reserveQuota(directory, opts) {
93821
93846
  const filePath = resolveQuotaPath(directory);
93822
- await mkdir16(path110.dirname(filePath), { recursive: true });
93847
+ await mkdir16(path109.dirname(filePath), { recursive: true });
93823
93848
  let release = null;
93824
93849
  try {
93825
- release = await acquireLock2(path110.dirname(filePath));
93850
+ release = await acquireLock2(path109.dirname(filePath));
93826
93851
  const state = await getQuotaState(directory, opts);
93827
93852
  if (state.calls_used + opts.nCalls > opts.maxCalls) {
93828
93853
  return {
@@ -93849,10 +93874,10 @@ async function reserveQuota(directory, opts) {
93849
93874
  }
93850
93875
  async function releaseQuota(directory, opts) {
93851
93876
  const filePath = resolveQuotaPath(directory);
93852
- await mkdir16(path110.dirname(filePath), { recursive: true });
93877
+ await mkdir16(path109.dirname(filePath), { recursive: true });
93853
93878
  let release = null;
93854
93879
  try {
93855
- release = await acquireLock2(path110.dirname(filePath));
93880
+ release = await acquireLock2(path109.dirname(filePath));
93856
93881
  const state = await getQuotaState(directory, opts);
93857
93882
  const next = {
93858
93883
  ...state,
@@ -93875,7 +93900,7 @@ function timestampSlug(d) {
93875
93900
  return d.toISOString().replace(/[:.]/g, "-");
93876
93901
  }
93877
93902
  async function atomicWrite4(p, content) {
93878
- await mkdir17(path111.dirname(p), { recursive: true });
93903
+ await mkdir17(path110.dirname(p), { recursive: true });
93879
93904
  const tmp = `${p}.tmp-${process.pid}-${Date.now()}`;
93880
93905
  await writeFile14(tmp, content, "utf-8");
93881
93906
  await rename6(tmp, p);
@@ -94075,8 +94100,8 @@ async function runSkillImprover(req) {
94075
94100
  sourceKnowledgeIds: w.sourceKnowledgeIds
94076
94101
  }));
94077
94102
  }
94078
- const proposalDir = path111.join(req.directory, ".swarm", "skill-improver", "proposals");
94079
- const proposalFile = path111.join(proposalDir, `${timestampSlug(now)}.md`);
94103
+ const proposalDir = path110.join(req.directory, ".swarm", "skill-improver", "proposals");
94104
+ const proposalFile = path110.join(proposalDir, `${timestampSlug(now)}.md`);
94080
94105
  const finalBody = source === "llm" ? buildLLMProposalFrame({
94081
94106
  body: body2,
94082
94107
  targets,
@@ -94169,7 +94194,7 @@ init_config();
94169
94194
  init_schema();
94170
94195
  init_create_tool();
94171
94196
  import { mkdir as mkdir18, rename as rename7, writeFile as writeFile15 } from "node:fs/promises";
94172
- import * as path112 from "node:path";
94197
+ import * as path111 from "node:path";
94173
94198
  var MAX_SPEC_BYTES = 256 * 1024;
94174
94199
  var spec_write = createSwarmTool({
94175
94200
  description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
@@ -94210,14 +94235,14 @@ var spec_write = createSwarmTool({
94210
94235
  reason: 'spec must contain at least one top-level "# Heading"'
94211
94236
  }, null, 2);
94212
94237
  }
94213
- const target = path112.join(directory, ".swarm", "spec.md");
94214
- await mkdir18(path112.dirname(target), { recursive: true });
94238
+ const target = path111.join(directory, ".swarm", "spec.md");
94239
+ await mkdir18(path111.dirname(target), { recursive: true });
94215
94240
  const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
94216
94241
  let finalContent = content;
94217
94242
  if (mode === "append") {
94218
94243
  try {
94219
- const fs87 = await import("node:fs/promises");
94220
- const prior = await fs87.readFile(target, "utf-8");
94244
+ const fs86 = await import("node:fs/promises");
94245
+ const prior = await fs86.readFile(target, "utf-8");
94221
94246
  finalContent = `${prior.replace(/\s+$/, "")}
94222
94247
 
94223
94248
  ${content}
@@ -94238,6 +94263,15 @@ ${content}
94238
94263
  // src/tools/submit-phase-council-verdicts.ts
94239
94264
  init_zod();
94240
94265
  init_loader();
94266
+ import {
94267
+ existsSync as existsSync65,
94268
+ mkdirSync as mkdirSync28,
94269
+ readFileSync as readFileSync55,
94270
+ renameSync as renameSync18,
94271
+ unlinkSync as unlinkSync14,
94272
+ writeFileSync as writeFileSync22
94273
+ } from "node:fs";
94274
+ import path112 from "node:path";
94241
94275
  init_create_tool();
94242
94276
  init_resolve_working_directory();
94243
94277
  var VerdictSchema2 = exports_external.object({
@@ -94340,6 +94374,12 @@ var submit_phase_council_verdicts = createSwarmTool({
94340
94374
  }, null, 2);
94341
94375
  }
94342
94376
  const synthesis = synthesizePhaseCouncilAdvisory(input.phaseNumber, input.phaseSummary, input.verdicts, input.roundNumber ?? 1, config3.council, workingDir);
94377
+ const existingMutationGapFinding = input.verdicts.some((verdict) => verdict.findings.some((finding) => finding.category === "mutation_gap"));
94378
+ const mutationGapFinding = existingMutationGapFinding ? null : getPhaseMutationGapFinding(input.phaseNumber, workingDir);
94379
+ if (mutationGapFinding) {
94380
+ addMutationGapFindingToSynthesis(synthesis, mutationGapFinding);
94381
+ }
94382
+ writePhaseCouncilEvidence(workingDir, synthesis);
94343
94383
  return JSON.stringify({
94344
94384
  success: true,
94345
94385
  overallVerdict: synthesis.overallVerdict,
@@ -94350,6 +94390,7 @@ var submit_phase_council_verdicts = createSwarmTool({
94350
94390
  advisoryFindingsCount: synthesis.advisoryFindings?.length ?? 0,
94351
94391
  unresolvedConflictsCount: synthesis.unresolvedConflicts?.length ?? 0,
94352
94392
  advisoryNotes: synthesis.advisoryNotes ?? [],
94393
+ mutationGapEmitted: mutationGapFinding !== null,
94353
94394
  membersVoted,
94354
94395
  membersAbsent,
94355
94396
  quorumSize: membersVoted.length,
@@ -94359,11 +94400,132 @@ var submit_phase_council_verdicts = createSwarmTool({
94359
94400
  }, null, 2);
94360
94401
  }
94361
94402
  });
94403
+ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
94404
+ const mutationGatePath = path112.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
94405
+ try {
94406
+ const raw = readFileSync55(mutationGatePath, "utf-8");
94407
+ const parsed = JSON.parse(raw);
94408
+ const gateEntry = (parsed.entries ?? []).find((entry) => entry?.type === "mutation-gate");
94409
+ if (!gateEntry) {
94410
+ return {
94411
+ severity: "HIGH",
94412
+ category: "mutation_gap",
94413
+ location: `.swarm/evidence/${phaseNumber}/mutation-gate.json`,
94414
+ detail: "Mutation gate evidence is missing a mutation-gate entry for this phase.",
94415
+ evidence: 'Expected entries[].type="mutation-gate" with verdict in mutation-gate.json.'
94416
+ };
94417
+ }
94418
+ if (gateEntry.verdict === "skip") {
94419
+ return {
94420
+ severity: "MEDIUM",
94421
+ category: "mutation_gap",
94422
+ location: `.swarm/evidence/${phaseNumber}/mutation-gate.json`,
94423
+ detail: "Mutation testing was skipped for this phase; coverage is unverified.",
94424
+ evidence: 'mutation-gate.json recorded verdict="skip". Run mutation_test and write_mutation_evidence.'
94425
+ };
94426
+ }
94427
+ if (gateEntry.verdict === "warn") {
94428
+ return {
94429
+ severity: "LOW",
94430
+ category: "mutation_gap",
94431
+ location: `.swarm/evidence/${phaseNumber}/mutation-gate.json`,
94432
+ detail: "Mutation gate reported WARN; mutation coverage may be insufficient.",
94433
+ evidence: 'mutation-gate.json recorded verdict="warn" indicating below-pass mutation quality.'
94434
+ };
94435
+ }
94436
+ if (gateEntry.verdict === "fail") {
94437
+ return {
94438
+ severity: "HIGH",
94439
+ category: "mutation_gap",
94440
+ location: `.swarm/evidence/${phaseNumber}/mutation-gate.json`,
94441
+ detail: "Mutation gate reported FAIL; mutation testing quality is below the required threshold.",
94442
+ evidence: 'mutation-gate.json recorded verdict="fail" indicating insufficient mutation kill rate.'
94443
+ };
94444
+ }
94445
+ return null;
94446
+ } catch (error93) {
94447
+ if (error93.code === "ENOENT") {
94448
+ return {
94449
+ severity: "HIGH",
94450
+ category: "mutation_gap",
94451
+ location: `.swarm/evidence/${phaseNumber}/mutation-gate.json`,
94452
+ detail: "Mutation gate evidence file is missing for this phase, so mutation coverage cannot be verified.",
94453
+ evidence: "No .swarm/evidence/{phase}/mutation-gate.json was found at council synthesis time."
94454
+ };
94455
+ }
94456
+ return {
94457
+ severity: "MEDIUM",
94458
+ category: "mutation_gap",
94459
+ location: `.swarm/evidence/${phaseNumber}/mutation-gate.json`,
94460
+ detail: "Mutation gate evidence could not be read, so mutation coverage cannot be verified.",
94461
+ evidence: error93 instanceof Error ? error93.message : String(error93)
94462
+ };
94463
+ }
94464
+ }
94465
+ function writePhaseCouncilEvidence(workingDir, synthesis) {
94466
+ const evidenceDir = path112.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
94467
+ mkdirSync28(evidenceDir, { recursive: true });
94468
+ const evidenceFile = path112.join(evidenceDir, "phase-council.json");
94469
+ const evidenceBundle = {
94470
+ entries: [
94471
+ {
94472
+ type: "phase-council",
94473
+ phase_number: synthesis.phaseNumber,
94474
+ scope: "phase",
94475
+ timestamp: synthesis.timestamp,
94476
+ verdict: synthesis.overallVerdict,
94477
+ quorumSize: synthesis.quorumSize,
94478
+ phaseSummary: synthesis.phaseSummary ?? "",
94479
+ requiredFixes: synthesis.requiredFixes.map((finding) => ({
94480
+ severity: finding.severity,
94481
+ category: finding.category,
94482
+ location: finding.location,
94483
+ detail: finding.detail,
94484
+ evidence: finding.evidence
94485
+ })),
94486
+ advisoryNotes: synthesis.advisoryNotes,
94487
+ advisoryFindings: synthesis.advisoryFindings.map((finding) => ({
94488
+ severity: finding.severity,
94489
+ category: finding.category,
94490
+ location: finding.location,
94491
+ detail: finding.detail,
94492
+ evidence: finding.evidence
94493
+ })),
94494
+ roundNumber: synthesis.roundNumber,
94495
+ allCriteriaMet: synthesis.allCriteriaMet
94496
+ }
94497
+ ]
94498
+ };
94499
+ const tempFile = `${evidenceFile}.tmp-${Date.now()}`;
94500
+ try {
94501
+ writeFileSync22(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
94502
+ renameSync18(tempFile, evidenceFile);
94503
+ } finally {
94504
+ if (existsSync65(tempFile)) {
94505
+ unlinkSync14(tempFile);
94506
+ }
94507
+ }
94508
+ }
94509
+ function addMutationGapFindingToSynthesis(synthesis, finding) {
94510
+ if (finding.severity === "HIGH" || finding.severity === "MEDIUM") {
94511
+ synthesis.requiredFixes.push(finding);
94512
+ } else {
94513
+ synthesis.advisoryFindings.push(finding);
94514
+ }
94515
+ synthesis.unifiedFeedbackMd += formatMutationGapFeedback(finding);
94516
+ }
94517
+ function formatMutationGapFeedback(finding) {
94518
+ return `
94519
+
94520
+ ### Mutation Coverage Gap
94521
+ - **[${finding.severity}]** \`${finding.location}\` (${finding.category}) — ${finding.detail}
94522
+ _Evidence:_ ${finding.evidence}`;
94523
+ }
94362
94524
  // src/tools/suggest-patch.ts
94363
94525
  init_zod();
94364
94526
  init_path_security();
94365
94527
  init_create_tool();
94366
- import * as fs87 from "node:fs";
94528
+ import * as fs86 from "node:fs";
94367
94529
  import * as path113 from "node:path";
94368
94530
  var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
94369
94531
  function containsWindowsAttacks4(str) {
@@ -94379,11 +94541,11 @@ function containsWindowsAttacks4(str) {
94379
94541
  function isPathInWorkspace4(filePath, workspace) {
94380
94542
  try {
94381
94543
  const resolvedPath = path113.resolve(workspace, filePath);
94382
- if (!fs87.existsSync(resolvedPath)) {
94544
+ if (!fs86.existsSync(resolvedPath)) {
94383
94545
  return true;
94384
94546
  }
94385
- const realWorkspace = fs87.realpathSync(workspace);
94386
- const realResolvedPath = fs87.realpathSync(resolvedPath);
94547
+ const realWorkspace = fs86.realpathSync(workspace);
94548
+ const realResolvedPath = fs86.realpathSync(resolvedPath);
94387
94549
  const relativePath = path113.relative(realWorkspace, realResolvedPath);
94388
94550
  if (relativePath.startsWith("..") || path113.isAbsolute(relativePath)) {
94389
94551
  return false;
@@ -94557,7 +94719,7 @@ var suggestPatch = createSwarmTool({
94557
94719
  message: "changes cannot be empty"
94558
94720
  }, null, 2);
94559
94721
  }
94560
- if (!fs87.existsSync(directory)) {
94722
+ if (!fs86.existsSync(directory)) {
94561
94723
  return JSON.stringify({
94562
94724
  success: false,
94563
94725
  error: true,
@@ -94594,7 +94756,7 @@ var suggestPatch = createSwarmTool({
94594
94756
  continue;
94595
94757
  }
94596
94758
  const fullPath = path113.resolve(directory, change.file);
94597
- if (!fs87.existsSync(fullPath)) {
94759
+ if (!fs86.existsSync(fullPath)) {
94598
94760
  errors5.push({
94599
94761
  success: false,
94600
94762
  error: true,
@@ -94608,7 +94770,7 @@ var suggestPatch = createSwarmTool({
94608
94770
  }
94609
94771
  let content;
94610
94772
  try {
94611
- content = fs87.readFileSync(fullPath, "utf-8");
94773
+ content = fs86.readFileSync(fullPath, "utf-8");
94612
94774
  } catch (err3) {
94613
94775
  errors5.push({
94614
94776
  success: false,
@@ -94855,7 +95017,7 @@ var generate_mutants = createSwarmTool({
94855
95017
  // src/tools/lint-spec.ts
94856
95018
  init_spec_schema();
94857
95019
  init_create_tool();
94858
- import * as fs88 from "node:fs";
95020
+ import * as fs87 from "node:fs";
94859
95021
  import * as path114 from "node:path";
94860
95022
  var SPEC_FILE_NAME = "spec.md";
94861
95023
  var SWARM_DIR2 = ".swarm";
@@ -94910,7 +95072,7 @@ var lint_spec = createSwarmTool({
94910
95072
  const errors5 = [];
94911
95073
  const warnings = [];
94912
95074
  const specPath = path114.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
94913
- if (!fs88.existsSync(specPath)) {
95075
+ if (!fs87.existsSync(specPath)) {
94914
95076
  const result2 = {
94915
95077
  valid: false,
94916
95078
  specMtime: null,
@@ -94929,12 +95091,12 @@ var lint_spec = createSwarmTool({
94929
95091
  }
94930
95092
  let specMtime = null;
94931
95093
  try {
94932
- const stats = fs88.statSync(specPath);
95094
+ const stats = fs87.statSync(specPath);
94933
95095
  specMtime = stats.mtime.toISOString();
94934
95096
  } catch {}
94935
95097
  let content;
94936
95098
  try {
94937
- content = fs88.readFileSync(specPath, "utf-8");
95099
+ content = fs87.readFileSync(specPath, "utf-8");
94938
95100
  } catch (e) {
94939
95101
  const result2 = {
94940
95102
  valid: false,
@@ -94979,12 +95141,12 @@ var lint_spec = createSwarmTool({
94979
95141
  });
94980
95142
  // src/tools/mutation-test.ts
94981
95143
  init_zod();
94982
- import * as fs89 from "node:fs";
95144
+ import * as fs88 from "node:fs";
94983
95145
  import * as path116 from "node:path";
94984
95146
 
94985
95147
  // src/mutation/engine.ts
94986
95148
  import { spawnSync as spawnSync3 } from "node:child_process";
94987
- import { unlinkSync as unlinkSync14, writeFileSync as writeFileSync22 } from "node:fs";
95149
+ import { unlinkSync as unlinkSync15, writeFileSync as writeFileSync23 } from "node:fs";
94988
95150
  import * as path115 from "node:path";
94989
95151
 
94990
95152
  // src/mutation/equivalence.ts
@@ -95127,7 +95289,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
95127
95289
  const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
95128
95290
  patchFile = path115.join(workingDir, `.mutation_patch_${safeId2}.diff`);
95129
95291
  try {
95130
- writeFileSync22(patchFile, patch.patch);
95292
+ writeFileSync23(patchFile, patch.patch);
95131
95293
  } catch (writeErr) {
95132
95294
  error93 = `Failed to write patch file: ${writeErr}`;
95133
95295
  outcome = "error";
@@ -95223,7 +95385,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
95223
95385
  revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
95224
95386
  }
95225
95387
  try {
95226
- unlinkSync14(patchFile);
95388
+ unlinkSync15(patchFile);
95227
95389
  } catch (_unlinkErr) {}
95228
95390
  }
95229
95391
  }
@@ -95525,7 +95687,7 @@ var mutation_test = createSwarmTool({
95525
95687
  for (const filePath of uniquePaths) {
95526
95688
  try {
95527
95689
  const resolvedPath = path116.resolve(cwd, filePath);
95528
- sourceFiles.set(filePath, fs89.readFileSync(resolvedPath, "utf-8"));
95690
+ sourceFiles.set(filePath, fs88.readFileSync(resolvedPath, "utf-8"));
95529
95691
  } catch {}
95530
95692
  }
95531
95693
  const report = await executeMutationSuite(typedArgs.patches, typedArgs.test_command, typedArgs.files, cwd, undefined, undefined, sourceFiles.size > 0 ? sourceFiles : undefined);
@@ -95543,7 +95705,7 @@ var mutation_test = createSwarmTool({
95543
95705
  init_zod();
95544
95706
  init_manager2();
95545
95707
  init_detector();
95546
- import * as fs90 from "node:fs";
95708
+ import * as fs89 from "node:fs";
95547
95709
  import * as path117 from "node:path";
95548
95710
  init_create_tool();
95549
95711
  var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
@@ -95653,7 +95815,7 @@ async function syntaxCheck(input, directory, config3) {
95653
95815
  }
95654
95816
  let content;
95655
95817
  try {
95656
- content = fs90.readFileSync(fullPath, "utf8");
95818
+ content = fs89.readFileSync(fullPath, "utf8");
95657
95819
  } catch {
95658
95820
  result.skipped_reason = "file_read_error";
95659
95821
  skippedCount++;
@@ -95764,7 +95926,7 @@ init_zod();
95764
95926
  init_utils();
95765
95927
  init_create_tool();
95766
95928
  init_path_security();
95767
- import * as fs91 from "node:fs";
95929
+ import * as fs90 from "node:fs";
95768
95930
  import * as path118 from "node:path";
95769
95931
  var MAX_TEXT_LENGTH = 200;
95770
95932
  var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
@@ -95855,7 +96017,7 @@ function isSupportedExtension(filePath) {
95855
96017
  function findSourceFiles3(dir, files = []) {
95856
96018
  let entries;
95857
96019
  try {
95858
- entries = fs91.readdirSync(dir);
96020
+ entries = fs90.readdirSync(dir);
95859
96021
  } catch {
95860
96022
  return files;
95861
96023
  }
@@ -95867,7 +96029,7 @@ function findSourceFiles3(dir, files = []) {
95867
96029
  const fullPath = path118.join(dir, entry);
95868
96030
  let stat7;
95869
96031
  try {
95870
- stat7 = fs91.statSync(fullPath);
96032
+ stat7 = fs90.statSync(fullPath);
95871
96033
  } catch {
95872
96034
  continue;
95873
96035
  }
@@ -95960,7 +96122,7 @@ var todo_extract = createSwarmTool({
95960
96122
  return JSON.stringify(errorResult, null, 2);
95961
96123
  }
95962
96124
  const scanPath = resolvedPath;
95963
- if (!fs91.existsSync(scanPath)) {
96125
+ if (!fs90.existsSync(scanPath)) {
95964
96126
  const errorResult = {
95965
96127
  error: `path not found: ${pathsInput}`,
95966
96128
  total: 0,
@@ -95970,7 +96132,7 @@ var todo_extract = createSwarmTool({
95970
96132
  return JSON.stringify(errorResult, null, 2);
95971
96133
  }
95972
96134
  const filesToScan = [];
95973
- const stat7 = fs91.statSync(scanPath);
96135
+ const stat7 = fs90.statSync(scanPath);
95974
96136
  if (stat7.isFile()) {
95975
96137
  if (isSupportedExtension(scanPath)) {
95976
96138
  filesToScan.push(scanPath);
@@ -95989,11 +96151,11 @@ var todo_extract = createSwarmTool({
95989
96151
  const allEntries = [];
95990
96152
  for (const filePath of filesToScan) {
95991
96153
  try {
95992
- const fileStat = fs91.statSync(filePath);
96154
+ const fileStat = fs90.statSync(filePath);
95993
96155
  if (fileStat.size > MAX_FILE_SIZE_BYTES11) {
95994
96156
  continue;
95995
96157
  }
95996
- const content = fs91.readFileSync(filePath, "utf-8");
96158
+ const content = fs90.readFileSync(filePath, "utf-8");
95997
96159
  const entries = parseTodoComments(content, filePath, tagsSet);
95998
96160
  allEntries.push(...entries);
95999
96161
  } catch {}
@@ -96024,17 +96186,17 @@ init_loader();
96024
96186
  init_schema();
96025
96187
  init_qa_gate_profile();
96026
96188
  init_gate_evidence();
96027
- import * as fs94 from "node:fs";
96189
+ import * as fs93 from "node:fs";
96028
96190
  import * as path121 from "node:path";
96029
96191
 
96030
96192
  // src/hooks/diff-scope.ts
96031
96193
  init_bun_compat();
96032
- import * as fs93 from "node:fs";
96194
+ import * as fs92 from "node:fs";
96033
96195
  import * as path120 from "node:path";
96034
96196
 
96035
96197
  // src/utils/gitignore-warning.ts
96036
96198
  init_bun_compat();
96037
- import * as fs92 from "node:fs";
96199
+ import * as fs91 from "node:fs";
96038
96200
  import * as path119 from "node:path";
96039
96201
  var _internals36 = { bunSpawn };
96040
96202
  var _swarmGitExcludedChecked = false;
@@ -96112,13 +96274,13 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
96112
96274
  const excludePath = path119.isAbsolute(excludeRelPath) ? excludeRelPath : path119.join(directory, excludeRelPath);
96113
96275
  if (checkIgnoreExitCode !== 0) {
96114
96276
  try {
96115
- fs92.mkdirSync(path119.dirname(excludePath), { recursive: true });
96277
+ fs91.mkdirSync(path119.dirname(excludePath), { recursive: true });
96116
96278
  let existing = "";
96117
96279
  try {
96118
- existing = fs92.readFileSync(excludePath, "utf8");
96280
+ existing = fs91.readFileSync(excludePath, "utf8");
96119
96281
  } catch {}
96120
96282
  if (!fileCoversSwarm(existing)) {
96121
- fs92.appendFileSync(excludePath, `
96283
+ fs91.appendFileSync(excludePath, `
96122
96284
  # opencode-swarm local runtime state
96123
96285
  .swarm/
96124
96286
  `, "utf8");
@@ -96157,9 +96319,9 @@ var _internals37 = { bunSpawn };
96157
96319
  function getDeclaredScope(taskId, directory) {
96158
96320
  try {
96159
96321
  const planPath = path120.join(directory, ".swarm", "plan.json");
96160
- if (!fs93.existsSync(planPath))
96322
+ if (!fs92.existsSync(planPath))
96161
96323
  return null;
96162
- const raw = fs93.readFileSync(planPath, "utf-8");
96324
+ const raw = fs92.readFileSync(planPath, "utf-8");
96163
96325
  const plan = JSON.parse(raw);
96164
96326
  for (const phase of plan.phases ?? []) {
96165
96327
  for (const task of phase.tasks ?? []) {
@@ -96308,7 +96470,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
96308
96470
  const resolvedDir2 = workingDirectory;
96309
96471
  try {
96310
96472
  const planPath = path121.join(resolvedDir2, ".swarm", "plan.json");
96311
- const planRaw = fs94.readFileSync(planPath, "utf-8");
96473
+ const planRaw = fs93.readFileSync(planPath, "utf-8");
96312
96474
  const plan = JSON.parse(planRaw);
96313
96475
  for (const planPhase of plan.phases ?? []) {
96314
96476
  for (const task of planPhase.tasks ?? []) {
@@ -96375,7 +96537,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
96375
96537
  try {
96376
96538
  const resolvedDir2 = workingDirectory;
96377
96539
  const planPath = path121.join(resolvedDir2, ".swarm", "plan.json");
96378
- const planRaw = fs94.readFileSync(planPath, "utf-8");
96540
+ const planRaw = fs93.readFileSync(planPath, "utf-8");
96379
96541
  const plan = JSON.parse(planRaw);
96380
96542
  for (const planPhase of plan.phases ?? []) {
96381
96543
  for (const task of planPhase.tasks ?? []) {
@@ -96572,9 +96734,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
96572
96734
  }
96573
96735
  const resolvedDir = path121.resolve(normalizedDir);
96574
96736
  try {
96575
- const realPath = fs94.realpathSync(resolvedDir);
96737
+ const realPath = fs93.realpathSync(resolvedDir);
96576
96738
  const planPath = path121.join(realPath, ".swarm", "plan.json");
96577
- if (!fs94.existsSync(planPath)) {
96739
+ if (!fs93.existsSync(planPath)) {
96578
96740
  return {
96579
96741
  success: false,
96580
96742
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -96606,21 +96768,21 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
96606
96768
  if (args2.status === "in_progress") {
96607
96769
  try {
96608
96770
  const evidencePath = path121.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
96609
- fs94.mkdirSync(path121.dirname(evidencePath), { recursive: true });
96610
- const fd = fs94.openSync(evidencePath, "wx");
96771
+ fs93.mkdirSync(path121.dirname(evidencePath), { recursive: true });
96772
+ const fd = fs93.openSync(evidencePath, "wx");
96611
96773
  let writeOk = false;
96612
96774
  try {
96613
- fs94.writeSync(fd, JSON.stringify({
96775
+ fs93.writeSync(fd, JSON.stringify({
96614
96776
  taskId: args2.task_id,
96615
96777
  required_gates: ["reviewer", "test_engineer"],
96616
96778
  gates: {}
96617
96779
  }, null, 2));
96618
96780
  writeOk = true;
96619
96781
  } finally {
96620
- fs94.closeSync(fd);
96782
+ fs93.closeSync(fd);
96621
96783
  if (!writeOk) {
96622
96784
  try {
96623
- fs94.unlinkSync(evidencePath);
96785
+ fs93.unlinkSync(evidencePath);
96624
96786
  } catch {}
96625
96787
  }
96626
96788
  }
@@ -96631,7 +96793,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
96631
96793
  let phaseRequiresReviewer = true;
96632
96794
  try {
96633
96795
  const planPath = path121.join(directory, ".swarm", "plan.json");
96634
- const planRaw = fs94.readFileSync(planPath, "utf-8");
96796
+ const planRaw = fs93.readFileSync(planPath, "utf-8");
96635
96797
  const plan = JSON.parse(planRaw);
96636
96798
  const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
96637
96799
  if (taskPhase?.required_agents && !taskPhase.required_agents.includes("reviewer")) {
@@ -96941,7 +97103,7 @@ init_utils2();
96941
97103
  init_ledger();
96942
97104
  init_manager();
96943
97105
  init_create_tool();
96944
- import fs95 from "node:fs";
97106
+ import fs94 from "node:fs";
96945
97107
  import path122 from "node:path";
96946
97108
  function normalizeVerdict(verdict) {
96947
97109
  switch (verdict) {
@@ -97003,10 +97165,10 @@ async function executeWriteDriftEvidence(args2, directory) {
97003
97165
  }
97004
97166
  const evidenceDir = path122.dirname(validatedPath);
97005
97167
  try {
97006
- await fs95.promises.mkdir(evidenceDir, { recursive: true });
97168
+ await fs94.promises.mkdir(evidenceDir, { recursive: true });
97007
97169
  const tempPath = path122.join(evidenceDir, `.${filename}.tmp`);
97008
- await fs95.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
97009
- await fs95.promises.rename(tempPath, validatedPath);
97170
+ await fs94.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
97171
+ await fs94.promises.rename(tempPath, validatedPath);
97010
97172
  let snapshotInfo;
97011
97173
  let snapshotError;
97012
97174
  let qaProfileLocked;
@@ -97101,7 +97263,7 @@ init_zod();
97101
97263
  init_utils2();
97102
97264
  init_manager();
97103
97265
  init_create_tool();
97104
- import fs96 from "node:fs";
97266
+ import fs95 from "node:fs";
97105
97267
  import path123 from "node:path";
97106
97268
  function normalizeVerdict2(verdict) {
97107
97269
  switch (verdict) {
@@ -97166,10 +97328,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
97166
97328
  }
97167
97329
  const evidenceDir = path123.dirname(validatedPath);
97168
97330
  try {
97169
- await fs96.promises.mkdir(evidenceDir, { recursive: true });
97331
+ await fs95.promises.mkdir(evidenceDir, { recursive: true });
97170
97332
  const tempPath = path123.join(evidenceDir, `.${filename}.tmp`);
97171
- await fs96.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
97172
- await fs96.promises.rename(tempPath, validatedPath);
97333
+ await fs95.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
97334
+ await fs95.promises.rename(tempPath, validatedPath);
97173
97335
  return JSON.stringify({
97174
97336
  success: true,
97175
97337
  phase,
@@ -97213,7 +97375,7 @@ var write_final_council_evidence = createSwarmTool({
97213
97375
  init_zod();
97214
97376
  init_utils2();
97215
97377
  init_create_tool();
97216
- import fs97 from "node:fs";
97378
+ import fs96 from "node:fs";
97217
97379
  import path124 from "node:path";
97218
97380
  function normalizeVerdict3(verdict) {
97219
97381
  switch (verdict) {
@@ -97275,10 +97437,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
97275
97437
  }
97276
97438
  const evidenceDir = path124.dirname(validatedPath);
97277
97439
  try {
97278
- await fs97.promises.mkdir(evidenceDir, { recursive: true });
97440
+ await fs96.promises.mkdir(evidenceDir, { recursive: true });
97279
97441
  const tempPath = path124.join(evidenceDir, `.${filename}.tmp`);
97280
- await fs97.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
97281
- await fs97.promises.rename(tempPath, validatedPath);
97442
+ await fs96.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
97443
+ await fs96.promises.rename(tempPath, validatedPath);
97282
97444
  return JSON.stringify({
97283
97445
  success: true,
97284
97446
  phase,
@@ -97324,7 +97486,7 @@ var write_hallucination_evidence = createSwarmTool({
97324
97486
  init_zod();
97325
97487
  init_utils2();
97326
97488
  init_create_tool();
97327
- import fs98 from "node:fs";
97489
+ import fs97 from "node:fs";
97328
97490
  import path125 from "node:path";
97329
97491
  function normalizeVerdict4(verdict) {
97330
97492
  switch (verdict) {
@@ -97412,10 +97574,10 @@ async function executeWriteMutationEvidence(args2, directory) {
97412
97574
  }
97413
97575
  const evidenceDir = path125.dirname(validatedPath);
97414
97576
  try {
97415
- await fs98.promises.mkdir(evidenceDir, { recursive: true });
97577
+ await fs97.promises.mkdir(evidenceDir, { recursive: true });
97416
97578
  const tempPath = path125.join(evidenceDir, `.${filename}.tmp`);
97417
- await fs98.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
97418
- await fs98.promises.rename(tempPath, validatedPath);
97579
+ await fs97.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
97580
+ await fs97.promises.rename(tempPath, validatedPath);
97419
97581
  return JSON.stringify({
97420
97582
  success: true,
97421
97583
  phase,
@@ -97901,15 +98063,19 @@ async function initializeOpenCodeSwarm(ctx) {
97901
98063
  ...opencodeConfig.command || {},
97902
98064
  swarm: {
97903
98065
  template: "/swarm $ARGUMENTS",
97904
- description: "Swarm management commands: /swarm [status|plan|agents|history|config|evidence|handoff|archive|diagnose|diagnosis|preflight|sync-plan|benchmark|export|reset|rollback|retrieve|clarify|analyze|specify|brainstorm|council|pr-review|issue|qa-gates|dark-matter|knowledge|curate|turbo|full-auto|write-retro|reset-session|simulate|promote|checkpoint|acknowledge-spec-drift|doctor-tools|close]"
98066
+ description: "Swarm management commands: /swarm [status|show-plan|plan|agents|history|config|help|evidence|handoff|archive|diagnose|diagnosis|preflight|sync-plan|benchmark|export|reset|rollback|retrieve|clarify|analyze|specify|brainstorm|council|pr-review|issue|qa-gates|dark-matter|knowledge|curate|turbo|full-auto|write-retro|reset-session|simulate|promote|checkpoint|acknowledge-spec-drift|doctor tools|finalize|close]"
97905
98067
  },
97906
98068
  "swarm-status": {
97907
98069
  template: "/swarm status",
97908
98070
  description: "Use /swarm status to show current swarm status and active phase"
97909
98071
  },
98072
+ "swarm-show-plan": {
98073
+ template: "/swarm show-plan $ARGUMENTS",
98074
+ description: "Use /swarm show-plan to view or filter the current execution plan"
98075
+ },
97910
98076
  "swarm-plan": {
97911
98077
  template: "/swarm plan $ARGUMENTS",
97912
- description: "Use /swarm plan to view or filter the current execution plan"
98078
+ description: "Deprecated alias for /swarm show-plan"
97913
98079
  },
97914
98080
  "swarm-agents": {
97915
98081
  template: "/swarm agents",
@@ -97989,7 +98155,7 @@ async function initializeOpenCodeSwarm(ctx) {
97989
98155
  },
97990
98156
  "swarm-council": {
97991
98157
  template: "/swarm council $ARGUMENTS",
97992
- description: "Use /swarm council <question> to convene a multi-model General Council deliberation (generalist / skeptic / domain expert) [--spec-review]"
98158
+ description: "Use /swarm council <question> to convene a multi-model General Council deliberation (generalist / skeptic / domain expert) [--preset <name>] [--spec-review]"
97993
98159
  },
97994
98160
  "swarm-pr-review": {
97995
98161
  template: "/swarm pr-review $ARGUMENTS",
@@ -98051,9 +98217,13 @@ async function initializeOpenCodeSwarm(ctx) {
98051
98217
  template: "/swarm evidence summary",
98052
98218
  description: "Use /swarm evidence summary to generate evidence summaries"
98053
98219
  },
98220
+ "swarm-finalize": {
98221
+ template: "/swarm finalize",
98222
+ description: "Use /swarm finalize to archive the swarm project and close active state"
98223
+ },
98054
98224
  "swarm-close": {
98055
98225
  template: "/swarm close",
98056
- description: "Use /swarm close to close the swarm project and archive state"
98226
+ description: "Deprecated alias for /swarm finalize"
98057
98227
  },
98058
98228
  "swarm-acknowledge-spec-drift": {
98059
98229
  template: "/swarm acknowledge-spec-drift",