opencode-swarm 6.33.1 → 6.33.3

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
@@ -14146,7 +14146,7 @@ var init_zod = __esm(() => {
14146
14146
  });
14147
14147
 
14148
14148
  // src/config/evidence-schema.ts
14149
- var EVIDENCE_MAX_JSON_BYTES, EVIDENCE_MAX_PATCH_BYTES, EVIDENCE_MAX_TASK_BYTES, EvidenceTypeSchema, EvidenceVerdictSchema, BaseEvidenceSchema, ReviewEvidenceSchema, TestEvidenceSchema, DiffEvidenceSchema, ApprovalEvidenceSchema, NoteEvidenceSchema, RetrospectiveEvidenceSchema, SyntaxEvidenceSchema, PlaceholderEvidenceSchema, SastEvidenceSchema, SbomEvidenceSchema, BuildEvidenceSchema, QualityBudgetEvidenceSchema, EvidenceSchema, EvidenceBundleSchema;
14149
+ var EVIDENCE_MAX_JSON_BYTES, EVIDENCE_MAX_PATCH_BYTES, EVIDENCE_MAX_TASK_BYTES, EvidenceTypeSchema, EvidenceVerdictSchema, BaseEvidenceSchema, ReviewEvidenceSchema, TestEvidenceSchema, DiffEvidenceSchema, ApprovalEvidenceSchema, NoteEvidenceSchema, RetrospectiveEvidenceSchema, SyntaxEvidenceSchema, PlaceholderEvidenceSchema, SastEvidenceSchema, SbomEvidenceSchema, BuildEvidenceSchema, QualityBudgetEvidenceSchema, SecretscanEvidenceSchema, EvidenceSchema, EvidenceBundleSchema;
14150
14150
  var init_evidence_schema = __esm(() => {
14151
14151
  init_zod();
14152
14152
  EVIDENCE_MAX_JSON_BYTES = 500 * 1024;
@@ -14164,7 +14164,8 @@ var init_evidence_schema = __esm(() => {
14164
14164
  "sast",
14165
14165
  "sbom",
14166
14166
  "build",
14167
- "quality_budget"
14167
+ "quality_budget",
14168
+ "secretscan"
14168
14169
  ]);
14169
14170
  EvidenceVerdictSchema = exports_external.enum([
14170
14171
  "pass",
@@ -14245,7 +14246,14 @@ var init_evidence_schema = __esm(() => {
14245
14246
  approach: exports_external.string().min(1),
14246
14247
  result: exports_external.enum(["success", "failure", "partial"]),
14247
14248
  abandoned_reason: exports_external.string().optional()
14248
- })).max(10).default([])
14249
+ })).max(10).default([]),
14250
+ error_taxonomy: exports_external.array(exports_external.enum([
14251
+ "planning_error",
14252
+ "interface_mismatch",
14253
+ "logic_error",
14254
+ "scope_creep",
14255
+ "gate_evasion"
14256
+ ])).default([])
14249
14257
  });
14250
14258
  SyntaxEvidenceSchema = BaseEvidenceSchema.extend({
14251
14259
  type: exports_external.literal("syntax"),
@@ -14356,6 +14364,13 @@ var init_evidence_schema = __esm(() => {
14356
14364
  })).default([]),
14357
14365
  files_analyzed: exports_external.array(exports_external.string())
14358
14366
  });
14367
+ SecretscanEvidenceSchema = BaseEvidenceSchema.extend({
14368
+ type: exports_external.literal("secretscan"),
14369
+ findings_count: exports_external.number().int().min(0).default(0),
14370
+ scan_directory: exports_external.string().optional(),
14371
+ files_scanned: exports_external.number().int().min(0).default(0),
14372
+ skipped_files: exports_external.number().int().min(0).default(0)
14373
+ });
14359
14374
  EvidenceSchema = exports_external.discriminatedUnion("type", [
14360
14375
  ReviewEvidenceSchema,
14361
14376
  TestEvidenceSchema,
@@ -14368,7 +14383,8 @@ var init_evidence_schema = __esm(() => {
14368
14383
  SastEvidenceSchema,
14369
14384
  SbomEvidenceSchema,
14370
14385
  BuildEvidenceSchema,
14371
- QualityBudgetEvidenceSchema
14386
+ QualityBudgetEvidenceSchema,
14387
+ SecretscanEvidenceSchema
14372
14388
  ]);
14373
14389
  EvidenceBundleSchema = exports_external.object({
14374
14390
  schema_version: exports_external.literal("1.0.0"),
@@ -14458,7 +14474,8 @@ var init_schema = __esm(() => {
14458
14474
  AgentOverrideConfigSchema = exports_external.object({
14459
14475
  model: exports_external.string().optional(),
14460
14476
  temperature: exports_external.number().min(0).max(2).optional(),
14461
- disabled: exports_external.boolean().optional()
14477
+ disabled: exports_external.boolean().optional(),
14478
+ fallback_models: exports_external.array(exports_external.string()).max(3).optional()
14462
14479
  });
14463
14480
  SwarmConfigSchema = exports_external.object({
14464
14481
  name: exports_external.string().optional(),
@@ -14799,6 +14816,7 @@ var init_schema = __esm(() => {
14799
14816
  warning_threshold: exports_external.number().min(0.1).max(0.9).default(0.75),
14800
14817
  idle_timeout_minutes: exports_external.number().min(5).max(240).default(60),
14801
14818
  no_op_warning_threshold: exports_external.number().min(1).max(100).default(15),
14819
+ max_coder_revisions: exports_external.number().int().min(1).max(20).default(5),
14802
14820
  qa_gates: exports_external.object({
14803
14821
  required_tools: exports_external.array(exports_external.string().min(1)).default([
14804
14822
  "diff",
@@ -15400,6 +15418,9 @@ import * as path4 from "path";
15400
15418
  function isValidEvidenceType(type) {
15401
15419
  return VALID_EVIDENCE_TYPES.includes(type);
15402
15420
  }
15421
+ function isSecretscanEvidence(evidence) {
15422
+ return evidence.type === "secretscan";
15423
+ }
15403
15424
  function sanitizeTaskId(taskId) {
15404
15425
  if (!taskId || taskId.length === 0) {
15405
15426
  throw new Error("Invalid task ID: empty string");
@@ -15652,11 +15673,12 @@ var init_manager = __esm(() => {
15652
15673
  "sast",
15653
15674
  "sbom",
15654
15675
  "build",
15655
- "quality_budget"
15676
+ "quality_budget",
15677
+ "secretscan"
15656
15678
  ];
15657
15679
  TASK_ID_REGEX = /^\d+\.\d+(\.\d+)*$/;
15658
15680
  RETRO_TASK_ID_REGEX = /^retro-\d+$/;
15659
- INTERNAL_TOOL_ID_REGEX = /^(?:sast_scan|quality_budget|syntax_check|placeholder_scan|sbom_generate|build)$/;
15681
+ INTERNAL_TOOL_ID_REGEX = /^(?:sast_scan|quality_budget|syntax_check|placeholder_scan|sbom_generate|build|secretscan)$/;
15660
15682
  LEGACY_TASK_COMPLEXITY_MAP = {
15661
15683
  low: "simple",
15662
15684
  medium: "moderate",
@@ -36250,7 +36272,7 @@ __export(exports_gate_evidence, {
36250
36272
  deriveRequiredGates: () => deriveRequiredGates,
36251
36273
  DEFAULT_REQUIRED_GATES: () => DEFAULT_REQUIRED_GATES
36252
36274
  });
36253
- import { mkdirSync as mkdirSync9, readFileSync as readFileSync14, renameSync as renameSync8, unlinkSync as unlinkSync5 } from "fs";
36275
+ import { mkdirSync as mkdirSync9, readFileSync as readFileSync14, renameSync as renameSync9, unlinkSync as unlinkSync5 } from "fs";
36254
36276
  import * as path30 from "path";
36255
36277
  function isValidTaskId2(taskId) {
36256
36278
  if (!taskId)
@@ -36315,7 +36337,7 @@ async function atomicWrite(targetPath, content) {
36315
36337
  const tempPath = `${targetPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
36316
36338
  try {
36317
36339
  await Bun.write(tempPath, content);
36318
- renameSync8(tempPath, targetPath);
36340
+ renameSync9(tempPath, targetPath);
36319
36341
  } finally {
36320
36342
  try {
36321
36343
  unlinkSync5(tempPath);
@@ -37910,11 +37932,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
37910
37932
  throw toThrow;
37911
37933
  }, "quit_");
37912
37934
  var scriptDirectory = "";
37913
- function locateFile(path47) {
37935
+ function locateFile(path48) {
37914
37936
  if (Module["locateFile"]) {
37915
- return Module["locateFile"](path47, scriptDirectory);
37937
+ return Module["locateFile"](path48, scriptDirectory);
37916
37938
  }
37917
- return scriptDirectory + path47;
37939
+ return scriptDirectory + path48;
37918
37940
  }
37919
37941
  __name(locateFile, "locateFile");
37920
37942
  var readAsync, readBinary;
@@ -39662,7 +39684,7 @@ var init_runtime = __esm(() => {
39662
39684
  });
39663
39685
 
39664
39686
  // src/index.ts
39665
- import * as path57 from "path";
39687
+ import * as path58 from "path";
39666
39688
 
39667
39689
  // src/agents/index.ts
39668
39690
  init_config();
@@ -39729,6 +39751,10 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, dire
39729
39751
  scopeViolationDetected: false,
39730
39752
  modifiedFilesThisCoderTask: [],
39731
39753
  turboMode: false,
39754
+ model_fallback_index: 0,
39755
+ modelFallbackExhausted: false,
39756
+ coderRevisions: 0,
39757
+ revisionLimitHit: false,
39732
39758
  loopDetectionWindow: [],
39733
39759
  pendingAdvisoryMessages: []
39734
39760
  };
@@ -39837,12 +39863,24 @@ function ensureAgentSession(sessionId, agentName, directory) {
39837
39863
  if (session.turboMode === undefined) {
39838
39864
  session.turboMode = false;
39839
39865
  }
39866
+ if (session.model_fallback_index === undefined) {
39867
+ session.model_fallback_index = 0;
39868
+ }
39869
+ if (session.modelFallbackExhausted === undefined) {
39870
+ session.modelFallbackExhausted = false;
39871
+ }
39840
39872
  if (session.loopDetectionWindow === undefined) {
39841
39873
  session.loopDetectionWindow = [];
39842
39874
  }
39843
39875
  if (session.pendingAdvisoryMessages === undefined) {
39844
39876
  session.pendingAdvisoryMessages = [];
39845
39877
  }
39878
+ if (session.coderRevisions === undefined) {
39879
+ session.coderRevisions = 0;
39880
+ }
39881
+ if (session.revisionLimitHit === undefined) {
39882
+ session.revisionLimitHit = false;
39883
+ }
39846
39884
  session.lastToolCallTime = now;
39847
39885
  return session;
39848
39886
  }
@@ -44112,14 +44150,18 @@ async function readCuratorSummary(directory) {
44112
44150
  }
44113
44151
  return parsed;
44114
44152
  } catch {
44115
- console.warn("Failed to parse curator-summary.json: invalid JSON");
44153
+ if (process.env.DEBUG_SWARM) {
44154
+ console.warn("Failed to parse curator-summary.json: invalid JSON");
44155
+ }
44116
44156
  return null;
44117
44157
  }
44118
44158
  }
44119
44159
  async function writeCuratorSummary(directory, summary) {
44120
44160
  const resolvedPath = validateSwarmPath(directory, "curator-summary.json");
44121
44161
  fs7.mkdirSync(path12.dirname(resolvedPath), { recursive: true });
44122
- await Bun.write(resolvedPath, JSON.stringify(summary, null, 2));
44162
+ const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
44163
+ await Bun.write(tempPath, JSON.stringify(summary, null, 2));
44164
+ fs7.renameSync(tempPath, resolvedPath);
44123
44165
  }
44124
44166
  function normalizeAgentName(name2) {
44125
44167
  return name2.toLowerCase().replace(/^(mega|paid|local|lowtier|modelrelay)_/, "");
@@ -44143,7 +44185,9 @@ function filterPhaseEvents(eventsJsonl, phase, sinceTimestamp) {
44143
44185
  }
44144
44186
  }
44145
44187
  } catch {
44146
- console.warn("filterPhaseEvents: skipping malformed line");
44188
+ if (process.env.DEBUG_SWARM) {
44189
+ console.warn("filterPhaseEvents: skipping malformed line");
44190
+ }
44147
44191
  }
44148
44192
  }
44149
44193
  return filtered;
@@ -46473,7 +46517,7 @@ async function handleExportCommand(directory, _args) {
46473
46517
  // src/commands/handoff.ts
46474
46518
  init_utils2();
46475
46519
  import crypto3 from "crypto";
46476
- import { renameSync as renameSync5 } from "fs";
46520
+ import { renameSync as renameSync6 } from "fs";
46477
46521
 
46478
46522
  // src/services/handoff-service.ts
46479
46523
  init_utils2();
@@ -46774,7 +46818,7 @@ function formatHandoffMarkdown(data) {
46774
46818
 
46775
46819
  // src/session/snapshot-writer.ts
46776
46820
  init_utils2();
46777
- import { mkdirSync as mkdirSync7, renameSync as renameSync4 } from "fs";
46821
+ import { mkdirSync as mkdirSync7, renameSync as renameSync5 } from "fs";
46778
46822
  import * as path19 from "path";
46779
46823
  var pendingWrite = null;
46780
46824
  var lastWritePromise = Promise.resolve();
@@ -46839,13 +46883,17 @@ function serializeAgentSession(s) {
46839
46883
  taskWorkflowStates: Object.fromEntries(s.taskWorkflowStates ?? new Map),
46840
46884
  ...s.scopeViolationDetected !== undefined && {
46841
46885
  scopeViolationDetected: s.scopeViolationDetected
46842
- }
46886
+ },
46887
+ model_fallback_index: s.model_fallback_index ?? 0,
46888
+ modelFallbackExhausted: s.modelFallbackExhausted ?? false,
46889
+ coderRevisions: s.coderRevisions ?? 0,
46890
+ revisionLimitHit: s.revisionLimitHit ?? false
46843
46891
  };
46844
46892
  }
46845
46893
  async function writeSnapshot(directory, state) {
46846
46894
  try {
46847
46895
  const snapshot = {
46848
- version: 1,
46896
+ version: 2,
46849
46897
  writtenAt: Date.now(),
46850
46898
  toolAggregates: Object.fromEntries(state.toolAggregates),
46851
46899
  activeAgent: Object.fromEntries(state.activeAgent),
@@ -46861,9 +46909,11 @@ async function writeSnapshot(directory, state) {
46861
46909
  mkdirSync7(dir, { recursive: true });
46862
46910
  const tempPath = `${resolvedPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
46863
46911
  await Bun.write(tempPath, content);
46864
- renameSync4(tempPath, resolvedPath);
46912
+ renameSync5(tempPath, resolvedPath);
46865
46913
  } catch (error93) {
46866
- console.warn("[snapshot-writer] write failed:", error93 instanceof Error ? error93.message : String(error93));
46914
+ if (process.env.DEBUG_SWARM) {
46915
+ console.warn("[snapshot-writer] write failed:", error93 instanceof Error ? error93.message : String(error93));
46916
+ }
46867
46917
  }
46868
46918
  }
46869
46919
  function createSnapshotWriterHook(directory) {
@@ -46893,7 +46943,7 @@ async function handleHandoffCommand(directory, _args) {
46893
46943
  const resolvedPath = validateSwarmPath(directory, "handoff.md");
46894
46944
  const tempPath = `${resolvedPath}.tmp.${crypto3.randomUUID()}`;
46895
46945
  await Bun.write(tempPath, markdown);
46896
- renameSync5(tempPath, resolvedPath);
46946
+ renameSync6(tempPath, resolvedPath);
46897
46947
  await writeSnapshot(directory, swarmState);
46898
46948
  await flushPendingSnapshot(directory);
46899
46949
  return `## Handoff Brief Written
@@ -47639,7 +47689,7 @@ async function handleResetSessionCommand(directory, _args) {
47639
47689
  // src/summaries/manager.ts
47640
47690
  init_utils2();
47641
47691
  init_utils();
47642
- import { mkdirSync as mkdirSync8, readdirSync as readdirSync7, renameSync as renameSync6, rmSync as rmSync3, statSync as statSync7 } from "fs";
47692
+ import { mkdirSync as mkdirSync8, readdirSync as readdirSync7, renameSync as renameSync7, rmSync as rmSync3, statSync as statSync7 } from "fs";
47643
47693
  import * as path26 from "path";
47644
47694
  var SUMMARY_ID_REGEX = /^S\d+$/;
47645
47695
  function sanitizeSummaryId(id) {
@@ -47683,7 +47733,7 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
47683
47733
  const tempPath = path26.join(summaryDir, `${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);
47684
47734
  try {
47685
47735
  await Bun.write(tempPath, entryJson);
47686
- renameSync6(tempPath, summaryPath);
47736
+ renameSync7(tempPath, summaryPath);
47687
47737
  } catch (error93) {
47688
47738
  try {
47689
47739
  rmSync3(tempPath, { force: true });
@@ -48863,8 +48913,46 @@ async function executeWriteRetro(args2, directory) {
48863
48913
  top_rejection_reasons: args2.top_rejection_reasons ?? [],
48864
48914
  lessons_learned: (args2.lessons_learned ?? []).slice(0, 5),
48865
48915
  user_directives: [],
48866
- approaches_tried: []
48916
+ approaches_tried: [],
48917
+ error_taxonomy: []
48867
48918
  };
48919
+ const taxonomy = [];
48920
+ try {
48921
+ for (const taskSuffix of ["1", "2", "3", "4", "5"]) {
48922
+ const phaseTaskId = `${phase}.${taskSuffix}`;
48923
+ const result = await loadEvidence(directory, phaseTaskId);
48924
+ if (result.status !== "found")
48925
+ continue;
48926
+ const bundle = result.bundle;
48927
+ for (const entry of bundle.entries) {
48928
+ const e = entry;
48929
+ if (e.type === "review" && e.verdict === "fail") {
48930
+ const reasonParts = [];
48931
+ if (typeof e.summary === "string")
48932
+ reasonParts.push(e.summary);
48933
+ if (Array.isArray(e.issues)) {
48934
+ for (const iss of e.issues) {
48935
+ if (typeof iss.message === "string")
48936
+ reasonParts.push(iss.message);
48937
+ }
48938
+ }
48939
+ const reason = reasonParts.join(" ");
48940
+ if (/signature|type|contract|interface/i.test(reason)) {
48941
+ taxonomy.push("interface_mismatch");
48942
+ } else {
48943
+ taxonomy.push("logic_error");
48944
+ }
48945
+ } else if (e.type === "test" && e.verdict === "fail") {
48946
+ taxonomy.push("logic_error");
48947
+ } else if (e.agent === "scope_guard" && e.verdict === "fail") {
48948
+ taxonomy.push("scope_creep");
48949
+ } else if (e.agent === "loop_detector" && e.verdict === "fail") {
48950
+ taxonomy.push("gate_evasion");
48951
+ }
48952
+ }
48953
+ }
48954
+ } catch {}
48955
+ retroEntry.error_taxonomy = [...new Set(taxonomy)];
48868
48956
  try {
48869
48957
  await saveEvidence(directory, taskId, retroEntry);
48870
48958
  return JSON.stringify({
@@ -49187,7 +49275,7 @@ init_constants();
49187
49275
  init_schema();
49188
49276
 
49189
49277
  // src/hooks/agent-activity.ts
49190
- import { renameSync as renameSync7, unlinkSync as unlinkSync4 } from "fs";
49278
+ import { renameSync as renameSync8, unlinkSync as unlinkSync4 } from "fs";
49191
49279
  init_utils();
49192
49280
  init_utils2();
49193
49281
  function createAgentActivityHooks(config3, directory) {
@@ -49261,7 +49349,7 @@ async function doFlush(directory) {
49261
49349
  const tempPath = `${path29}.tmp`;
49262
49350
  try {
49263
49351
  await Bun.write(tempPath, updated);
49264
- renameSync7(tempPath, path29);
49352
+ renameSync8(tempPath, path29);
49265
49353
  } catch (writeError) {
49266
49354
  try {
49267
49355
  unlinkSync4(tempPath);
@@ -49895,6 +49983,7 @@ function detectLoop(sessionId, toolName, args2) {
49895
49983
 
49896
49984
  // src/hooks/guardrails.ts
49897
49985
  var storedInputArgs = new Map;
49986
+ var TRANSIENT_MODEL_ERROR_PATTERN = /rate.?limit|429|503|timeout|overloaded|model.?not.?found|temporarily unavailable|server error/i;
49898
49987
  function getStoredInputArgs(callID) {
49899
49988
  return storedInputArgs.get(callID);
49900
49989
  }
@@ -50072,6 +50161,9 @@ function createGuardrailsHooks(directory, directoryOrConfig, config3) {
50072
50161
  const coderSession = swarmState.agentSessions.get(input.sessionID);
50073
50162
  if (coderSession) {
50074
50163
  coderSession.modifiedFilesThisCoderTask = [];
50164
+ if (!coderSession.revisionLimitHit) {
50165
+ coderSession.coderRevisions = 0;
50166
+ }
50075
50167
  }
50076
50168
  }
50077
50169
  }
@@ -50080,7 +50172,7 @@ function createGuardrailsHooks(directory, directoryOrConfig, config3) {
50080
50172
  const loopResult = detectLoop(input.sessionID, input.tool, loopArgs);
50081
50173
  if (loopResult.count >= 5) {
50082
50174
  throw new Error(`CIRCUIT BREAKER: Delegation loop detected (${loopResult.count} identical patterns). Session paused. Ask the user for guidance.`);
50083
- } else if (loopResult.count === 3) {
50175
+ } else if (loopResult.count >= 3 && loopResult.count < 5) {
50084
50176
  const agentName2 = typeof loopArgs?.subagent_type === "string" ? loopArgs.subagent_type : "agent";
50085
50177
  const loopSession = swarmState.agentSessions.get(input.sessionID);
50086
50178
  if (loopSession) {
@@ -50411,6 +50503,16 @@ function createGuardrailsHooks(directory, directoryOrConfig, config3) {
50411
50503
  }
50412
50504
  if (delegation.isDelegation && delegation.targetAgent === "coder" && session.lastCoderDelegationTaskId) {
50413
50505
  session.currentTaskId = session.lastCoderDelegationTaskId;
50506
+ if (!session.revisionLimitHit) {
50507
+ session.coderRevisions++;
50508
+ const maxRevisions = cfg.max_coder_revisions ?? 5;
50509
+ if (session.coderRevisions >= maxRevisions) {
50510
+ session.revisionLimitHit = true;
50511
+ session.pendingAdvisoryMessages ??= [];
50512
+ session.pendingAdvisoryMessages.push(`CODER REVISION LIMIT: Agent has been revised ${session.coderRevisions} times ` + `(max: ${maxRevisions}) for task ${session.currentTaskId ?? "unknown"}. ` + `Escalate to user or consider a fundamentally different approach.`);
50513
+ swarmState.pendingEvents++;
50514
+ }
50515
+ }
50414
50516
  session.partialGateWarningsIssuedForTask?.delete(session.currentTaskId);
50415
50517
  if (session.declaredCoderScope !== null) {
50416
50518
  const undeclaredFiles = session.modifiedFilesThisCoderTask.map((f) => f.replace(/[\r\n\t]/g, "_")).filter((f) => !isInDeclaredScope(f, session.declaredCoderScope));
@@ -50442,9 +50544,26 @@ function createGuardrailsHooks(directory, directoryOrConfig, config3) {
50442
50544
  const hasError = output.output === null || output.output === undefined;
50443
50545
  if (hasError) {
50444
50546
  window2.consecutiveErrors++;
50547
+ if (session) {
50548
+ const outputStr = typeof output.output === "string" ? output.output : "";
50549
+ const errorContent = output.error ?? outputStr;
50550
+ if (typeof errorContent === "string" && TRANSIENT_MODEL_ERROR_PATTERN.test(errorContent) && !session.modelFallbackExhausted) {
50551
+ session.model_fallback_index++;
50552
+ session.modelFallbackExhausted = true;
50553
+ session.pendingAdvisoryMessages ??= [];
50554
+ session.pendingAdvisoryMessages.push(`MODEL FALLBACK: Transient model error detected (attempt ${session.model_fallback_index}). ` + `The agent model may be rate-limited, overloaded, or temporarily unavailable. ` + `Consider retrying with a fallback model or waiting before retrying.`);
50555
+ swarmState.pendingEvents++;
50556
+ }
50557
+ }
50445
50558
  } else {
50446
50559
  window2.consecutiveErrors = 0;
50447
50560
  window2.lastSuccessTimeMs = Date.now();
50561
+ if (session) {
50562
+ if (session.model_fallback_index > 0) {
50563
+ session.model_fallback_index = 0;
50564
+ session.modelFallbackExhausted = false;
50565
+ }
50566
+ }
50448
50567
  }
50449
50568
  },
50450
50569
  messagesTransform: async (_input, output) => {
@@ -50740,7 +50859,7 @@ function extractPlanTaskId(text) {
50740
50859
  function getSeedTaskId(session) {
50741
50860
  return session.currentTaskId ?? session.lastCoderDelegationTaskId;
50742
50861
  }
50743
- function getEvidenceTaskId(session, directory) {
50862
+ async function getEvidenceTaskId(session, directory) {
50744
50863
  const primary = session.currentTaskId ?? session.lastCoderDelegationTaskId;
50745
50864
  if (primary)
50746
50865
  return primary;
@@ -50757,7 +50876,7 @@ function getEvidenceTaskId(session, directory) {
50757
50876
  if (!resolvedPlanPath.startsWith(resolvedDirectory + path31.sep) && resolvedPlanPath !== resolvedDirectory) {
50758
50877
  return null;
50759
50878
  }
50760
- const planContent = fs19.readFileSync(resolvedPlanPath, "utf-8");
50879
+ const planContent = await fs19.promises.readFile(resolvedPlanPath, "utf-8");
50761
50880
  const plan = JSON.parse(planContent);
50762
50881
  if (!plan || !Array.isArray(plan.phases)) {
50763
50882
  return null;
@@ -50877,7 +50996,7 @@ function createDelegationGateHook(config3, directory) {
50877
50996
  }
50878
50997
  if (typeof subagentType === "string") {
50879
50998
  const rawTaskId = directArgs?.task_id;
50880
- const evidenceTaskId = typeof rawTaskId === "string" && rawTaskId.length <= 20 && /^\d+\.\d+$/.test(rawTaskId.trim()) ? rawTaskId.trim() : getEvidenceTaskId(session, directory);
50999
+ const evidenceTaskId = typeof rawTaskId === "string" && rawTaskId.length <= 20 && /^\d+\.\d+$/.test(rawTaskId.trim()) ? rawTaskId.trim() : await getEvidenceTaskId(session, directory);
50881
51000
  if (evidenceTaskId) {
50882
51001
  try {
50883
51002
  const turbo = hasActiveTurboMode();
@@ -50997,7 +51116,7 @@ function createDelegationGateHook(config3, directory) {
50997
51116
  }
50998
51117
  {
50999
51118
  const rawTaskId = directArgs?.task_id;
51000
- const evidenceTaskId = typeof rawTaskId === "string" && rawTaskId.length <= 20 && /^\d+\.\d+$/.test(rawTaskId.trim()) ? rawTaskId.trim() : getEvidenceTaskId(session, directory);
51119
+ const evidenceTaskId = typeof rawTaskId === "string" && rawTaskId.length <= 20 && /^\d+\.\d+$/.test(rawTaskId.trim()) ? rawTaskId.trim() : await getEvidenceTaskId(session, directory);
51001
51120
  if (evidenceTaskId) {
51002
51121
  try {
51003
51122
  const turbo = hasActiveTurboMode();
@@ -51094,7 +51213,7 @@ ${trimComment}${after}`;
51094
51213
  const currentTaskId = planTaskId ?? taskIdFromLine;
51095
51214
  const coderDelegationPattern = /(?:^|\n)\s*(?:\w+_)?coder\s*\n\s*TASK:/i;
51096
51215
  const isCoderDelegation = coderDelegationPattern.test(text);
51097
- const priorCoderTaskId = sessionID ? ensureAgentSession(sessionID).lastCoderDelegationTaskId ?? null : null;
51216
+ const priorCoderTaskId = sessionID ? swarmState.agentSessions.get(sessionID)?.lastCoderDelegationTaskId ?? null : null;
51098
51217
  if (sessionID && isCoderDelegation && currentTaskId) {
51099
51218
  const session = ensureAgentSession(sessionID);
51100
51219
  session.lastCoderDelegationTaskId = currentTaskId;
@@ -54872,7 +54991,11 @@ function deserializeAgentSession(s) {
54872
54991
  lastScopeViolation: null,
54873
54992
  scopeViolationDetected: s.scopeViolationDetected,
54874
54993
  modifiedFilesThisCoderTask: [],
54875
- pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? []
54994
+ pendingAdvisoryMessages: s.pendingAdvisoryMessages ?? [],
54995
+ model_fallback_index: s.model_fallback_index ?? 0,
54996
+ modelFallbackExhausted: s.modelFallbackExhausted ?? false,
54997
+ coderRevisions: s.coderRevisions ?? 0,
54998
+ revisionLimitHit: s.revisionLimitHit ?? false
54876
54999
  };
54877
55000
  }
54878
55001
  async function readSnapshot(directory) {
@@ -54888,7 +55011,7 @@ async function readSnapshot(directory) {
54888
55011
  return;
54889
55012
  return value;
54890
55013
  });
54891
- if (parsed.version !== 1) {
55014
+ if (parsed.version !== 1 && parsed.version !== 2) {
54892
55015
  return null;
54893
55016
  }
54894
55017
  return parsed;
@@ -55115,6 +55238,7 @@ var build_check = createSwarmTool({
55115
55238
  });
55116
55239
  // src/tools/check-gate-status.ts
55117
55240
  init_dist();
55241
+ init_manager();
55118
55242
  init_create_tool();
55119
55243
  import * as fs27 from "fs";
55120
55244
  import * as path39 from "path";
@@ -55238,13 +55362,37 @@ var check_gate_status = createSwarmTool({
55238
55362
  missingGates.push(requiredGate);
55239
55363
  }
55240
55364
  }
55241
- const status = missingGates.length === 0 ? "all_passed" : "incomplete";
55365
+ let status = missingGates.length === 0 ? "all_passed" : "incomplete";
55242
55366
  let message;
55243
55367
  if (status === "all_passed") {
55244
55368
  message = `All required gates have passed for task "${taskIdInput}".`;
55245
55369
  } else {
55246
55370
  message = `Task "${taskIdInput}" is incomplete. Missing gates: ${missingGates.join(", ")}.`;
55247
55371
  }
55372
+ let secretscanVerdict = "not_run";
55373
+ try {
55374
+ const evidenceResult = await loadEvidence(directory, taskIdInput);
55375
+ if (evidenceResult.status === "found") {
55376
+ const secretscanEntries = evidenceResult.bundle.entries.filter((entry) => entry.type === "secretscan");
55377
+ if (secretscanEntries.length > 0) {
55378
+ const lastSecretscan = secretscanEntries[secretscanEntries.length - 1];
55379
+ if (isSecretscanEvidence(lastSecretscan)) {
55380
+ if (lastSecretscan.verdict === "fail" || lastSecretscan.verdict === "rejected") {
55381
+ secretscanVerdict = "fail";
55382
+ missingGates.push("secretscan (BLOCKED \u2014 secrets detected)");
55383
+ if (status === "all_passed") {
55384
+ status = "incomplete";
55385
+ }
55386
+ message = `BLOCKED: Secretscan found secrets in prior scan. ${message}`;
55387
+ } else if (lastSecretscan.verdict === "pass" || lastSecretscan.verdict === "approved" || lastSecretscan.verdict === "info") {
55388
+ secretscanVerdict = "pass";
55389
+ }
55390
+ }
55391
+ } else {
55392
+ message += " Advisory: No secretscan evidence found for this task. Consider running secretscan.";
55393
+ }
55394
+ }
55395
+ } catch {}
55248
55396
  const todoScan = evidenceData.todo_scan;
55249
55397
  const result = {
55250
55398
  taskId: taskIdInput,
@@ -55254,7 +55402,8 @@ var check_gate_status = createSwarmTool({
55254
55402
  missing_gates: missingGates,
55255
55403
  gates: gatesMap,
55256
55404
  message,
55257
- todo_scan: todoScan ?? null
55405
+ todo_scan: todoScan ?? null,
55406
+ secretscan_verdict: secretscanVerdict
55258
55407
  };
55259
55408
  return JSON.stringify(result, null, 2);
55260
55409
  }
@@ -55980,6 +56129,391 @@ var diff = createSwarmTool({
55980
56129
  }
55981
56130
  }
55982
56131
  });
56132
+ // src/tools/doc-scan.ts
56133
+ init_dist();
56134
+ init_schema();
56135
+ import * as crypto4 from "crypto";
56136
+ import * as fs30 from "fs";
56137
+ import { mkdir as mkdir5, readFile as readFile6, writeFile as writeFile5 } from "fs/promises";
56138
+ import * as path42 from "path";
56139
+ init_create_tool();
56140
+ var SKIP_DIRECTORIES2 = new Set([
56141
+ "node_modules",
56142
+ ".git",
56143
+ ".swarm",
56144
+ "dist",
56145
+ "build",
56146
+ ".next",
56147
+ "vendor"
56148
+ ]);
56149
+ var SKIP_PATTERNS = [/\.test\./, /\.spec\./, /\.d\.ts$/];
56150
+ var MAX_SUMMARY_LENGTH = 200;
56151
+ var MAX_INDEXED_FILES = 100;
56152
+ var READ_LINES_LIMIT = 30;
56153
+ var MIN_LESSON_LENGTH = 15;
56154
+ var MAX_CONSTRAINTS_PER_DOC = 5;
56155
+ var MAX_CONSTRAINT_LENGTH = 200;
56156
+ var RELEVANCE_THRESHOLD = 0.1;
56157
+ var DEDUP_THRESHOLD = 0.6;
56158
+ function normalizeSeparators(filePath) {
56159
+ return filePath.replace(/\\/g, "/");
56160
+ }
56161
+ function matchesDocPattern(filePath, patterns) {
56162
+ const normalizedPath = normalizeSeparators(filePath);
56163
+ const basename5 = path42.basename(filePath);
56164
+ for (const pattern of patterns) {
56165
+ if (!pattern.includes("/") && !pattern.includes("\\")) {
56166
+ if (basename5 === pattern) {
56167
+ return true;
56168
+ }
56169
+ continue;
56170
+ }
56171
+ if (pattern.startsWith("**/")) {
56172
+ const filenamePattern = pattern.slice(3);
56173
+ if (basename5 === filenamePattern) {
56174
+ return true;
56175
+ }
56176
+ continue;
56177
+ }
56178
+ const patternNormalized = normalizeSeparators(pattern);
56179
+ const dirPrefix = patternNormalized.replace(/\/\*\*.*$/, "").replace(/\/\*.*$/, "");
56180
+ if (normalizedPath.startsWith(dirPrefix + "/") || normalizedPath === dirPrefix) {
56181
+ return true;
56182
+ }
56183
+ }
56184
+ return false;
56185
+ }
56186
+ function extractTitleAndSummary(content, filename) {
56187
+ const lines = content.split(`
56188
+ `);
56189
+ let title = filename;
56190
+ let summary = "";
56191
+ let foundTitle = false;
56192
+ const potentialSummaryLines = [];
56193
+ for (let i2 = 0;i2 < lines.length && i2 < READ_LINES_LIMIT; i2++) {
56194
+ const line = lines[i2].trim();
56195
+ if (!foundTitle && line.startsWith("# ")) {
56196
+ title = line.slice(2).trim();
56197
+ foundTitle = true;
56198
+ continue;
56199
+ }
56200
+ if (line && !line.startsWith("#")) {
56201
+ potentialSummaryLines.push(line);
56202
+ }
56203
+ }
56204
+ for (const line of potentialSummaryLines) {
56205
+ summary += (summary ? " " : "") + line;
56206
+ if (summary.length >= MAX_SUMMARY_LENGTH) {
56207
+ break;
56208
+ }
56209
+ }
56210
+ if (summary.length > MAX_SUMMARY_LENGTH) {
56211
+ summary = summary.slice(0, MAX_SUMMARY_LENGTH - 3) + "...";
56212
+ }
56213
+ return { title, summary };
56214
+ }
56215
+ function stripMarkdown(text) {
56216
+ return text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s*[-*\u2022]\s+/gm, "").replace(/^\s*\d+\.\s+/gm, "").trim();
56217
+ }
56218
+ async function scanDocIndex(directory) {
56219
+ const manifestPath = path42.join(directory, ".swarm", "doc-manifest.json");
56220
+ const defaultPatterns = DocsConfigSchema.parse({}).doc_patterns;
56221
+ const extraPatterns = [
56222
+ "ARCHITECTURE.md",
56223
+ "CLAUDE.md",
56224
+ "AGENTS.md",
56225
+ ".github/*.md",
56226
+ "doc/**/*.md"
56227
+ ];
56228
+ const allPatterns = [...defaultPatterns, ...extraPatterns];
56229
+ try {
56230
+ const manifestContent = await readFile6(manifestPath, "utf-8");
56231
+ const existingManifest = JSON.parse(manifestContent);
56232
+ if (existingManifest.schema_version === 1 && existingManifest.files) {
56233
+ let cacheValid = true;
56234
+ for (const file3 of existingManifest.files) {
56235
+ try {
56236
+ const fullPath = path42.join(directory, file3.path);
56237
+ const stat2 = fs30.statSync(fullPath);
56238
+ if (stat2.mtimeMs > new Date(existingManifest.scanned_at).getTime()) {
56239
+ cacheValid = false;
56240
+ break;
56241
+ }
56242
+ } catch {
56243
+ cacheValid = false;
56244
+ break;
56245
+ }
56246
+ }
56247
+ if (cacheValid) {
56248
+ return { manifest: existingManifest, cached: true };
56249
+ }
56250
+ }
56251
+ } catch {}
56252
+ const discoveredFiles = [];
56253
+ let rawEntries;
56254
+ try {
56255
+ rawEntries = fs30.readdirSync(directory, { recursive: true });
56256
+ } catch {
56257
+ const manifest2 = {
56258
+ schema_version: 1,
56259
+ scanned_at: new Date().toISOString(),
56260
+ files: []
56261
+ };
56262
+ return { manifest: manifest2, cached: false };
56263
+ }
56264
+ const entries = rawEntries.filter((e) => typeof e === "string");
56265
+ for (const entry of entries) {
56266
+ const fullPath = path42.join(directory, entry);
56267
+ let stat2;
56268
+ try {
56269
+ stat2 = fs30.statSync(fullPath);
56270
+ } catch {
56271
+ continue;
56272
+ }
56273
+ if (!stat2.isFile())
56274
+ continue;
56275
+ const pathParts = normalizeSeparators(entry).split("/");
56276
+ let skipThisFile = false;
56277
+ for (const part of pathParts) {
56278
+ if (SKIP_DIRECTORIES2.has(part)) {
56279
+ skipThisFile = true;
56280
+ break;
56281
+ }
56282
+ }
56283
+ if (skipThisFile)
56284
+ continue;
56285
+ for (const pattern of SKIP_PATTERNS) {
56286
+ if (pattern.test(entry)) {
56287
+ skipThisFile = true;
56288
+ break;
56289
+ }
56290
+ }
56291
+ if (skipThisFile)
56292
+ continue;
56293
+ if (!matchesDocPattern(entry, allPatterns)) {
56294
+ continue;
56295
+ }
56296
+ let content;
56297
+ try {
56298
+ content = fs30.readFileSync(fullPath, "utf-8");
56299
+ } catch {
56300
+ continue;
56301
+ }
56302
+ const { title, summary } = extractTitleAndSummary(content, path42.basename(entry));
56303
+ const lineCount = content.split(`
56304
+ `).length;
56305
+ discoveredFiles.push({
56306
+ path: entry,
56307
+ title,
56308
+ summary,
56309
+ lines: lineCount,
56310
+ mtime: stat2.mtimeMs
56311
+ });
56312
+ }
56313
+ discoveredFiles.sort((a, b) => a.path.toLowerCase().localeCompare(b.path.toLowerCase()));
56314
+ let truncated = false;
56315
+ if (discoveredFiles.length > MAX_INDEXED_FILES) {
56316
+ discoveredFiles.splice(MAX_INDEXED_FILES);
56317
+ truncated = true;
56318
+ }
56319
+ if (truncated && discoveredFiles.length > 0) {
56320
+ discoveredFiles[0].summary = `[Warning: ${MAX_INDEXED_FILES}+ docs found, listing first ${MAX_INDEXED_FILES}] ` + discoveredFiles[0].summary;
56321
+ }
56322
+ const manifest = {
56323
+ schema_version: 1,
56324
+ scanned_at: new Date().toISOString(),
56325
+ files: discoveredFiles
56326
+ };
56327
+ try {
56328
+ await mkdir5(path42.dirname(manifestPath), { recursive: true });
56329
+ await writeFile5(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
56330
+ } catch {}
56331
+ return { manifest, cached: false };
56332
+ }
56333
+ var CONSTRAINT_PATTERNS = [
56334
+ /\bMUST\b/,
56335
+ /\bMUST NOT\b/,
56336
+ /\bSHOULD\b/,
56337
+ /\bSHOULD NOT\b/,
56338
+ /\bDO NOT\b/,
56339
+ /\bALWAYS\b/,
56340
+ /\bNEVER\b/,
56341
+ /\bREQUIRED\b/
56342
+ ];
56343
+ var ACTION_WORDS = /\b(must|should|don't|avoid|ensure|use|follow)\b/i;
56344
+ function isConstraintLine(line) {
56345
+ const upperLine = line.toUpperCase();
56346
+ for (const pattern of CONSTRAINT_PATTERNS) {
56347
+ if (pattern.test(upperLine)) {
56348
+ return true;
56349
+ }
56350
+ }
56351
+ if (/^\s*[-*\u2022]/.test(line) && ACTION_WORDS.test(line)) {
56352
+ return true;
56353
+ }
56354
+ return false;
56355
+ }
56356
+ function extractConstraintsFromContent(content) {
56357
+ const lines = content.split(`
56358
+ `);
56359
+ const constraints = [];
56360
+ for (const line of lines) {
56361
+ if (constraints.length >= MAX_CONSTRAINTS_PER_DOC) {
56362
+ break;
56363
+ }
56364
+ const trimmed = line.trim();
56365
+ if (!trimmed)
56366
+ continue;
56367
+ if (isConstraintLine(trimmed)) {
56368
+ const cleaned = stripMarkdown(trimmed);
56369
+ const len = cleaned.length;
56370
+ if (len >= MIN_LESSON_LENGTH && len <= MAX_CONSTRAINT_LENGTH) {
56371
+ constraints.push(cleaned);
56372
+ }
56373
+ }
56374
+ }
56375
+ return constraints;
56376
+ }
56377
+ async function extractDocConstraints(directory, taskFiles, taskDescription) {
56378
+ const manifestPath = path42.join(directory, ".swarm", "doc-manifest.json");
56379
+ let manifest;
56380
+ try {
56381
+ const content = await readFile6(manifestPath, "utf-8");
56382
+ manifest = JSON.parse(content);
56383
+ } catch {
56384
+ const result = await scanDocIndex(directory);
56385
+ manifest = result.manifest;
56386
+ }
56387
+ const knowledgePath = resolveSwarmKnowledgePath(directory);
56388
+ const existingEntries = await readKnowledge(knowledgePath);
56389
+ const taskContext = [...taskFiles, taskDescription].join(" ");
56390
+ const taskBigrams = wordBigrams(normalize2(taskContext));
56391
+ let extractedCount = 0;
56392
+ let skippedCount = 0;
56393
+ const details = [];
56394
+ for (const docFile of manifest.files) {
56395
+ const docContext = `${docFile.path} ${docFile.title} ${docFile.summary}`;
56396
+ const docBigrams = wordBigrams(normalize2(docContext));
56397
+ const score = jaccardBigram(taskBigrams, docBigrams);
56398
+ if (score <= RELEVANCE_THRESHOLD) {
56399
+ skippedCount++;
56400
+ continue;
56401
+ }
56402
+ let fullContent;
56403
+ try {
56404
+ fullContent = await readFile6(path42.join(directory, docFile.path), "utf-8");
56405
+ } catch {
56406
+ skippedCount++;
56407
+ continue;
56408
+ }
56409
+ const constraints = extractConstraintsFromContent(fullContent);
56410
+ if (constraints.length === 0) {
56411
+ skippedCount++;
56412
+ continue;
56413
+ }
56414
+ const docDetails = {
56415
+ path: docFile.path,
56416
+ score,
56417
+ constraints: []
56418
+ };
56419
+ for (const constraint of constraints) {
56420
+ const duplicate = findNearDuplicate(constraint, existingEntries, DEDUP_THRESHOLD);
56421
+ if (!duplicate) {
56422
+ const entry = {
56423
+ id: crypto4.randomUUID(),
56424
+ tier: "swarm",
56425
+ lesson: constraint,
56426
+ category: "architecture",
56427
+ tags: ["doc-scan", path42.basename(docFile.path)],
56428
+ scope: "global",
56429
+ confidence: 0.5,
56430
+ status: "candidate",
56431
+ confirmed_by: [],
56432
+ project_name: "",
56433
+ retrieval_outcomes: {
56434
+ applied_count: 0,
56435
+ succeeded_after_count: 0,
56436
+ failed_after_count: 0
56437
+ },
56438
+ schema_version: 1,
56439
+ created_at: new Date().toISOString(),
56440
+ updated_at: new Date().toISOString(),
56441
+ auto_generated: true,
56442
+ hive_eligible: false
56443
+ };
56444
+ await appendKnowledge(knowledgePath, entry);
56445
+ existingEntries.push(entry);
56446
+ extractedCount++;
56447
+ docDetails.constraints.push(constraint);
56448
+ }
56449
+ }
56450
+ if (docDetails.constraints.length > 0) {
56451
+ details.push(docDetails);
56452
+ } else {
56453
+ skippedCount++;
56454
+ }
56455
+ }
56456
+ return { extracted: extractedCount, skipped: skippedCount, details };
56457
+ }
56458
+ var doc_scan = createSwarmTool({
56459
+ description: "Scan project documentation files and build an index manifest. Caches results in .swarm/doc-manifest.json for fast subsequent scans.",
56460
+ args: {
56461
+ force: tool.schema.boolean().optional().describe("Force re-scan even if cache is valid")
56462
+ },
56463
+ execute: async (args2, directory) => {
56464
+ let force = false;
56465
+ try {
56466
+ if (args2 && typeof args2 === "object") {
56467
+ const obj = args2;
56468
+ if (obj.force === true)
56469
+ force = true;
56470
+ }
56471
+ } catch {}
56472
+ if (force) {
56473
+ const manifestPath = path42.join(directory, ".swarm", "doc-manifest.json");
56474
+ try {
56475
+ fs30.unlinkSync(manifestPath);
56476
+ } catch {}
56477
+ }
56478
+ const { manifest, cached: cached3 } = await scanDocIndex(directory);
56479
+ return JSON.stringify({
56480
+ success: true,
56481
+ files_count: manifest.files.length,
56482
+ cached: cached3,
56483
+ manifest
56484
+ }, null, 2);
56485
+ }
56486
+ });
56487
+ var doc_extract = createSwarmTool({
56488
+ description: "Extract actionable constraints from project documentation relevant to the current task. Scans docs via doc-manifest, scores relevance via Jaccard bigram similarity, and stores non-duplicate constraints in .swarm/knowledge.jsonl.",
56489
+ args: {
56490
+ task_files: tool.schema.array(tool.schema.string()).describe("List of file paths involved in the current task"),
56491
+ task_description: tool.schema.string().describe("Description of the current task")
56492
+ },
56493
+ execute: async (args2, directory) => {
56494
+ let taskFiles = [];
56495
+ let taskDescription = "";
56496
+ try {
56497
+ if (args2 && typeof args2 === "object") {
56498
+ const obj = args2;
56499
+ if (Array.isArray(obj.task_files)) {
56500
+ taskFiles = obj.task_files.filter((f) => typeof f === "string");
56501
+ }
56502
+ if (typeof obj.task_description === "string") {
56503
+ taskDescription = obj.task_description;
56504
+ }
56505
+ }
56506
+ } catch {}
56507
+ if (taskFiles.length === 0 && !taskDescription) {
56508
+ return JSON.stringify({
56509
+ success: false,
56510
+ error: "task_files or task_description is required"
56511
+ });
56512
+ }
56513
+ const result = await extractDocConstraints(directory, taskFiles, taskDescription);
56514
+ return JSON.stringify({ success: true, ...result }, null, 2);
56515
+ }
56516
+ });
55983
56517
  // src/tools/domain-detector.ts
55984
56518
  init_tool();
55985
56519
  var DOMAIN_PATTERNS = {
@@ -56163,8 +56697,8 @@ Use these as DOMAIN values when delegating to @sme.`;
56163
56697
  // src/tools/evidence-check.ts
56164
56698
  init_dist();
56165
56699
  init_create_tool();
56166
- import * as fs30 from "fs";
56167
- import * as path42 from "path";
56700
+ import * as fs31 from "fs";
56701
+ import * as path43 from "path";
56168
56702
  var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
56169
56703
  var MAX_EVIDENCE_FILES = 1000;
56170
56704
  var EVIDENCE_DIR2 = ".swarm/evidence";
@@ -56194,9 +56728,9 @@ function validateRequiredTypes(input) {
56194
56728
  return null;
56195
56729
  }
56196
56730
  function isPathWithinSwarm2(filePath, cwd) {
56197
- const normalizedCwd = path42.resolve(cwd);
56198
- const swarmPath = path42.join(normalizedCwd, ".swarm");
56199
- const normalizedPath = path42.resolve(filePath);
56731
+ const normalizedCwd = path43.resolve(cwd);
56732
+ const swarmPath = path43.join(normalizedCwd, ".swarm");
56733
+ const normalizedPath = path43.resolve(filePath);
56200
56734
  return normalizedPath.startsWith(swarmPath);
56201
56735
  }
56202
56736
  function parseCompletedTasks(planContent) {
@@ -56212,12 +56746,12 @@ function parseCompletedTasks(planContent) {
56212
56746
  }
56213
56747
  function readEvidenceFiles(evidenceDir, _cwd) {
56214
56748
  const evidence = [];
56215
- if (!fs30.existsSync(evidenceDir) || !fs30.statSync(evidenceDir).isDirectory()) {
56749
+ if (!fs31.existsSync(evidenceDir) || !fs31.statSync(evidenceDir).isDirectory()) {
56216
56750
  return evidence;
56217
56751
  }
56218
56752
  let files;
56219
56753
  try {
56220
- files = fs30.readdirSync(evidenceDir);
56754
+ files = fs31.readdirSync(evidenceDir);
56221
56755
  } catch {
56222
56756
  return evidence;
56223
56757
  }
@@ -56226,14 +56760,14 @@ function readEvidenceFiles(evidenceDir, _cwd) {
56226
56760
  if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
56227
56761
  continue;
56228
56762
  }
56229
- const filePath = path42.join(evidenceDir, filename);
56763
+ const filePath = path43.join(evidenceDir, filename);
56230
56764
  try {
56231
- const resolvedPath = path42.resolve(filePath);
56232
- const evidenceDirResolved = path42.resolve(evidenceDir);
56765
+ const resolvedPath = path43.resolve(filePath);
56766
+ const evidenceDirResolved = path43.resolve(evidenceDir);
56233
56767
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
56234
56768
  continue;
56235
56769
  }
56236
- const stat2 = fs30.lstatSync(filePath);
56770
+ const stat2 = fs31.lstatSync(filePath);
56237
56771
  if (!stat2.isFile()) {
56238
56772
  continue;
56239
56773
  }
@@ -56242,7 +56776,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
56242
56776
  }
56243
56777
  let fileStat;
56244
56778
  try {
56245
- fileStat = fs30.statSync(filePath);
56779
+ fileStat = fs31.statSync(filePath);
56246
56780
  if (fileStat.size > MAX_FILE_SIZE_BYTES3) {
56247
56781
  continue;
56248
56782
  }
@@ -56251,7 +56785,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
56251
56785
  }
56252
56786
  let content;
56253
56787
  try {
56254
- content = fs30.readFileSync(filePath, "utf-8");
56788
+ content = fs31.readFileSync(filePath, "utf-8");
56255
56789
  } catch {
56256
56790
  continue;
56257
56791
  }
@@ -56347,7 +56881,7 @@ var evidence_check = createSwarmTool({
56347
56881
  return JSON.stringify(errorResult, null, 2);
56348
56882
  }
56349
56883
  const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
56350
- const planPath = path42.join(cwd, PLAN_FILE);
56884
+ const planPath = path43.join(cwd, PLAN_FILE);
56351
56885
  if (!isPathWithinSwarm2(planPath, cwd)) {
56352
56886
  const errorResult = {
56353
56887
  error: "plan file path validation failed",
@@ -56361,7 +56895,7 @@ var evidence_check = createSwarmTool({
56361
56895
  }
56362
56896
  let planContent;
56363
56897
  try {
56364
- planContent = fs30.readFileSync(planPath, "utf-8");
56898
+ planContent = fs31.readFileSync(planPath, "utf-8");
56365
56899
  } catch {
56366
56900
  const result2 = {
56367
56901
  message: "No completed tasks found in plan.",
@@ -56379,7 +56913,7 @@ var evidence_check = createSwarmTool({
56379
56913
  };
56380
56914
  return JSON.stringify(result2, null, 2);
56381
56915
  }
56382
- const evidenceDir = path42.join(cwd, EVIDENCE_DIR2);
56916
+ const evidenceDir = path43.join(cwd, EVIDENCE_DIR2);
56383
56917
  const evidence = readEvidenceFiles(evidenceDir, cwd);
56384
56918
  const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
56385
56919
  const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
@@ -56396,8 +56930,8 @@ var evidence_check = createSwarmTool({
56396
56930
  // src/tools/file-extractor.ts
56397
56931
  init_tool();
56398
56932
  init_create_tool();
56399
- import * as fs31 from "fs";
56400
- import * as path43 from "path";
56933
+ import * as fs32 from "fs";
56934
+ import * as path44 from "path";
56401
56935
  var EXT_MAP = {
56402
56936
  python: ".py",
56403
56937
  py: ".py",
@@ -56459,8 +56993,8 @@ var extract_code_blocks = createSwarmTool({
56459
56993
  execute: async (args2, directory) => {
56460
56994
  const { content, output_dir, prefix } = args2;
56461
56995
  const targetDir = output_dir || directory;
56462
- if (!fs31.existsSync(targetDir)) {
56463
- fs31.mkdirSync(targetDir, { recursive: true });
56996
+ if (!fs32.existsSync(targetDir)) {
56997
+ fs32.mkdirSync(targetDir, { recursive: true });
56464
56998
  }
56465
56999
  if (!content) {
56466
57000
  return "Error: content is required";
@@ -56478,16 +57012,16 @@ var extract_code_blocks = createSwarmTool({
56478
57012
  if (prefix) {
56479
57013
  filename = `${prefix}_${filename}`;
56480
57014
  }
56481
- let filepath = path43.join(targetDir, filename);
56482
- const base = path43.basename(filepath, path43.extname(filepath));
56483
- const ext = path43.extname(filepath);
57015
+ let filepath = path44.join(targetDir, filename);
57016
+ const base = path44.basename(filepath, path44.extname(filepath));
57017
+ const ext = path44.extname(filepath);
56484
57018
  let counter = 1;
56485
- while (fs31.existsSync(filepath)) {
56486
- filepath = path43.join(targetDir, `${base}_${counter}${ext}`);
57019
+ while (fs32.existsSync(filepath)) {
57020
+ filepath = path44.join(targetDir, `${base}_${counter}${ext}`);
56487
57021
  counter++;
56488
57022
  }
56489
57023
  try {
56490
- fs31.writeFileSync(filepath, code.trim(), "utf-8");
57024
+ fs32.writeFileSync(filepath, code.trim(), "utf-8");
56491
57025
  savedFiles.push(filepath);
56492
57026
  } catch (error93) {
56493
57027
  errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
@@ -56603,8 +57137,8 @@ var gitingest = createSwarmTool({
56603
57137
  // src/tools/imports.ts
56604
57138
  init_dist();
56605
57139
  init_create_tool();
56606
- import * as fs32 from "fs";
56607
- import * as path44 from "path";
57140
+ import * as fs33 from "fs";
57141
+ import * as path45 from "path";
56608
57142
  var MAX_FILE_PATH_LENGTH2 = 500;
56609
57143
  var MAX_SYMBOL_LENGTH = 256;
56610
57144
  var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
@@ -56658,7 +57192,7 @@ function validateSymbolInput(symbol3) {
56658
57192
  return null;
56659
57193
  }
56660
57194
  function isBinaryFile2(filePath, buffer) {
56661
- const ext = path44.extname(filePath).toLowerCase();
57195
+ const ext = path45.extname(filePath).toLowerCase();
56662
57196
  if (ext === ".json" || ext === ".md" || ext === ".txt") {
56663
57197
  return false;
56664
57198
  }
@@ -56682,15 +57216,15 @@ function parseImports(content, targetFile, targetSymbol) {
56682
57216
  const imports = [];
56683
57217
  let _resolvedTarget;
56684
57218
  try {
56685
- _resolvedTarget = path44.resolve(targetFile);
57219
+ _resolvedTarget = path45.resolve(targetFile);
56686
57220
  } catch {
56687
57221
  _resolvedTarget = targetFile;
56688
57222
  }
56689
- const targetBasename = path44.basename(targetFile, path44.extname(targetFile));
57223
+ const targetBasename = path45.basename(targetFile, path45.extname(targetFile));
56690
57224
  const targetWithExt = targetFile;
56691
57225
  const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
56692
- const normalizedTargetWithExt = path44.normalize(targetWithExt).replace(/\\/g, "/");
56693
- const normalizedTargetWithoutExt = path44.normalize(targetWithoutExt).replace(/\\/g, "/");
57226
+ const normalizedTargetWithExt = path45.normalize(targetWithExt).replace(/\\/g, "/");
57227
+ const normalizedTargetWithoutExt = path45.normalize(targetWithoutExt).replace(/\\/g, "/");
56694
57228
  const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
56695
57229
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
56696
57230
  const modulePath = match[1] || match[2] || match[3];
@@ -56713,9 +57247,9 @@ function parseImports(content, targetFile, targetSymbol) {
56713
57247
  }
56714
57248
  const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
56715
57249
  let isMatch = false;
56716
- const _targetDir = path44.dirname(targetFile);
56717
- const targetExt = path44.extname(targetFile);
56718
- const targetBasenameNoExt = path44.basename(targetFile, targetExt);
57250
+ const _targetDir = path45.dirname(targetFile);
57251
+ const targetExt = path45.extname(targetFile);
57252
+ const targetBasenameNoExt = path45.basename(targetFile, targetExt);
56719
57253
  const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
56720
57254
  const moduleName = modulePath.split(/[/\\]/).pop() || "";
56721
57255
  const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
@@ -56755,7 +57289,7 @@ function parseImports(content, targetFile, targetSymbol) {
56755
57289
  }
56756
57290
  return imports;
56757
57291
  }
56758
- var SKIP_DIRECTORIES2 = new Set([
57292
+ var SKIP_DIRECTORIES3 = new Set([
56759
57293
  "node_modules",
56760
57294
  ".git",
56761
57295
  "dist",
@@ -56772,7 +57306,7 @@ var SKIP_DIRECTORIES2 = new Set([
56772
57306
  function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
56773
57307
  let entries;
56774
57308
  try {
56775
- entries = fs32.readdirSync(dir);
57309
+ entries = fs33.readdirSync(dir);
56776
57310
  } catch (e) {
56777
57311
  stats.fileErrors.push({
56778
57312
  path: dir,
@@ -56782,14 +57316,14 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
56782
57316
  }
56783
57317
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
56784
57318
  for (const entry of entries) {
56785
- if (SKIP_DIRECTORIES2.has(entry)) {
56786
- stats.skippedDirs.push(path44.join(dir, entry));
57319
+ if (SKIP_DIRECTORIES3.has(entry)) {
57320
+ stats.skippedDirs.push(path45.join(dir, entry));
56787
57321
  continue;
56788
57322
  }
56789
- const fullPath = path44.join(dir, entry);
57323
+ const fullPath = path45.join(dir, entry);
56790
57324
  let stat2;
56791
57325
  try {
56792
- stat2 = fs32.statSync(fullPath);
57326
+ stat2 = fs33.statSync(fullPath);
56793
57327
  } catch (e) {
56794
57328
  stats.fileErrors.push({
56795
57329
  path: fullPath,
@@ -56800,7 +57334,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
56800
57334
  if (stat2.isDirectory()) {
56801
57335
  findSourceFiles(fullPath, files, stats);
56802
57336
  } else if (stat2.isFile()) {
56803
- const ext = path44.extname(fullPath).toLowerCase();
57337
+ const ext = path45.extname(fullPath).toLowerCase();
56804
57338
  if (SUPPORTED_EXTENSIONS.includes(ext)) {
56805
57339
  files.push(fullPath);
56806
57340
  }
@@ -56857,8 +57391,8 @@ var imports = createSwarmTool({
56857
57391
  return JSON.stringify(errorResult, null, 2);
56858
57392
  }
56859
57393
  try {
56860
- const targetFile = path44.resolve(file3);
56861
- if (!fs32.existsSync(targetFile)) {
57394
+ const targetFile = path45.resolve(file3);
57395
+ if (!fs33.existsSync(targetFile)) {
56862
57396
  const errorResult = {
56863
57397
  error: `target file not found: ${file3}`,
56864
57398
  target: file3,
@@ -56868,7 +57402,7 @@ var imports = createSwarmTool({
56868
57402
  };
56869
57403
  return JSON.stringify(errorResult, null, 2);
56870
57404
  }
56871
- const targetStat = fs32.statSync(targetFile);
57405
+ const targetStat = fs33.statSync(targetFile);
56872
57406
  if (!targetStat.isFile()) {
56873
57407
  const errorResult = {
56874
57408
  error: "target must be a file, not a directory",
@@ -56879,7 +57413,7 @@ var imports = createSwarmTool({
56879
57413
  };
56880
57414
  return JSON.stringify(errorResult, null, 2);
56881
57415
  }
56882
- const baseDir = path44.dirname(targetFile);
57416
+ const baseDir = path45.dirname(targetFile);
56883
57417
  const scanStats = {
56884
57418
  skippedDirs: [],
56885
57419
  skippedFiles: 0,
@@ -56894,12 +57428,12 @@ var imports = createSwarmTool({
56894
57428
  if (consumers.length >= MAX_CONSUMERS)
56895
57429
  break;
56896
57430
  try {
56897
- const stat2 = fs32.statSync(filePath);
57431
+ const stat2 = fs33.statSync(filePath);
56898
57432
  if (stat2.size > MAX_FILE_SIZE_BYTES4) {
56899
57433
  skippedFileCount++;
56900
57434
  continue;
56901
57435
  }
56902
- const buffer = fs32.readFileSync(filePath);
57436
+ const buffer = fs33.readFileSync(filePath);
56903
57437
  if (isBinaryFile2(filePath, buffer)) {
56904
57438
  skippedFileCount++;
56905
57439
  continue;
@@ -57448,8 +57982,8 @@ init_dist();
57448
57982
  init_config();
57449
57983
  init_schema();
57450
57984
  init_manager();
57451
- import * as fs33 from "fs";
57452
- import * as path45 from "path";
57985
+ import * as fs34 from "fs";
57986
+ import * as path46 from "path";
57453
57987
  init_utils2();
57454
57988
  init_create_tool();
57455
57989
  function safeWarn(message, error93) {
@@ -57668,7 +58202,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
57668
58202
  };
57669
58203
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
57670
58204
  try {
57671
- const projectName = path45.basename(dir);
58205
+ const projectName = path46.basename(dir);
57672
58206
  await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
57673
58207
  } catch (error93) {
57674
58208
  safeWarn("[phase_complete] Failed to curate lessons from retrospective:", error93);
@@ -57708,7 +58242,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
57708
58242
  if (agentsMissing.length > 0) {
57709
58243
  try {
57710
58244
  const planPath = validateSwarmPath(dir, "plan.json");
57711
- const planRaw = fs33.readFileSync(planPath, "utf-8");
58245
+ const planRaw = fs34.readFileSync(planPath, "utf-8");
57712
58246
  const plan = JSON.parse(planRaw);
57713
58247
  const targetPhase = plan.phases.find((p) => p.id === phase);
57714
58248
  if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
@@ -57739,7 +58273,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
57739
58273
  if (phaseCompleteConfig.regression_sweep?.enforce) {
57740
58274
  try {
57741
58275
  const planPath = validateSwarmPath(dir, "plan.json");
57742
- const planRaw = fs33.readFileSync(planPath, "utf-8");
58276
+ const planRaw = fs34.readFileSync(planPath, "utf-8");
57743
58277
  const plan = JSON.parse(planRaw);
57744
58278
  const targetPhase = plan.phases.find((p) => p.id === phase);
57745
58279
  if (targetPhase) {
@@ -57777,7 +58311,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
57777
58311
  };
57778
58312
  try {
57779
58313
  const eventsPath = validateSwarmPath(dir, "events.jsonl");
57780
- fs33.appendFileSync(eventsPath, `${JSON.stringify(event)}
58314
+ fs34.appendFileSync(eventsPath, `${JSON.stringify(event)}
57781
58315
  `, "utf-8");
57782
58316
  } catch (writeError) {
57783
58317
  warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
@@ -57796,12 +58330,12 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
57796
58330
  }
57797
58331
  try {
57798
58332
  const planPath = validateSwarmPath(dir, "plan.json");
57799
- const planJson = fs33.readFileSync(planPath, "utf-8");
58333
+ const planJson = fs34.readFileSync(planPath, "utf-8");
57800
58334
  const plan = JSON.parse(planJson);
57801
58335
  const phaseObj = plan.phases.find((p) => p.id === phase);
57802
58336
  if (phaseObj) {
57803
58337
  phaseObj.status = "completed";
57804
- fs33.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
58338
+ fs34.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
57805
58339
  `, "utf-8");
57806
58340
  }
57807
58341
  } catch (error93) {
@@ -57855,8 +58389,8 @@ init_dist();
57855
58389
  init_discovery();
57856
58390
  init_utils();
57857
58391
  init_create_tool();
57858
- import * as fs34 from "fs";
57859
- import * as path46 from "path";
58392
+ import * as fs35 from "fs";
58393
+ import * as path47 from "path";
57860
58394
  var MAX_OUTPUT_BYTES5 = 52428800;
57861
58395
  var AUDIT_TIMEOUT_MS = 120000;
57862
58396
  function isValidEcosystem(value) {
@@ -57874,28 +58408,28 @@ function validateArgs3(args2) {
57874
58408
  function detectEcosystems(directory) {
57875
58409
  const ecosystems = [];
57876
58410
  const cwd = directory;
57877
- if (fs34.existsSync(path46.join(cwd, "package.json"))) {
58411
+ if (fs35.existsSync(path47.join(cwd, "package.json"))) {
57878
58412
  ecosystems.push("npm");
57879
58413
  }
57880
- if (fs34.existsSync(path46.join(cwd, "pyproject.toml")) || fs34.existsSync(path46.join(cwd, "requirements.txt"))) {
58414
+ if (fs35.existsSync(path47.join(cwd, "pyproject.toml")) || fs35.existsSync(path47.join(cwd, "requirements.txt"))) {
57881
58415
  ecosystems.push("pip");
57882
58416
  }
57883
- if (fs34.existsSync(path46.join(cwd, "Cargo.toml"))) {
58417
+ if (fs35.existsSync(path47.join(cwd, "Cargo.toml"))) {
57884
58418
  ecosystems.push("cargo");
57885
58419
  }
57886
- if (fs34.existsSync(path46.join(cwd, "go.mod"))) {
58420
+ if (fs35.existsSync(path47.join(cwd, "go.mod"))) {
57887
58421
  ecosystems.push("go");
57888
58422
  }
57889
58423
  try {
57890
- const files = fs34.readdirSync(cwd);
58424
+ const files = fs35.readdirSync(cwd);
57891
58425
  if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
57892
58426
  ecosystems.push("dotnet");
57893
58427
  }
57894
58428
  } catch {}
57895
- if (fs34.existsSync(path46.join(cwd, "Gemfile")) || fs34.existsSync(path46.join(cwd, "Gemfile.lock"))) {
58429
+ if (fs35.existsSync(path47.join(cwd, "Gemfile")) || fs35.existsSync(path47.join(cwd, "Gemfile.lock"))) {
57896
58430
  ecosystems.push("ruby");
57897
58431
  }
57898
- if (fs34.existsSync(path46.join(cwd, "pubspec.yaml"))) {
58432
+ if (fs35.existsSync(path47.join(cwd, "pubspec.yaml"))) {
57899
58433
  ecosystems.push("dart");
57900
58434
  }
57901
58435
  return ecosystems;
@@ -58957,8 +59491,8 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
58957
59491
  ]);
58958
59492
  // src/tools/pre-check-batch.ts
58959
59493
  init_dist();
58960
- import * as fs37 from "fs";
58961
- import * as path49 from "path";
59494
+ import * as fs38 from "fs";
59495
+ import * as path50 from "path";
58962
59496
 
58963
59497
  // node_modules/yocto-queue/index.js
58964
59498
  class Node2 {
@@ -59103,8 +59637,8 @@ function pLimit(concurrency) {
59103
59637
  },
59104
59638
  map: {
59105
59639
  async value(iterable, function_) {
59106
- const promises3 = Array.from(iterable, (value, index) => this(function_, value, index));
59107
- return Promise.all(promises3);
59640
+ const promises4 = Array.from(iterable, (value, index) => this(function_, value, index));
59641
+ return Promise.all(promises4);
59108
59642
  }
59109
59643
  }
59110
59644
  });
@@ -59117,6 +59651,7 @@ function validateConcurrency(concurrency) {
59117
59651
  }
59118
59652
 
59119
59653
  // src/tools/pre-check-batch.ts
59654
+ init_manager();
59120
59655
  init_utils();
59121
59656
  init_create_tool();
59122
59657
  init_lint();
@@ -59125,8 +59660,8 @@ init_lint();
59125
59660
  init_manager();
59126
59661
 
59127
59662
  // src/quality/metrics.ts
59128
- import * as fs35 from "fs";
59129
- import * as path47 from "path";
59663
+ import * as fs36 from "fs";
59664
+ import * as path48 from "path";
59130
59665
  var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
59131
59666
  var MIN_DUPLICATION_LINES = 10;
59132
59667
  function estimateCyclomaticComplexity(content) {
@@ -59164,11 +59699,11 @@ function estimateCyclomaticComplexity(content) {
59164
59699
  }
59165
59700
  function getComplexityForFile2(filePath) {
59166
59701
  try {
59167
- const stat2 = fs35.statSync(filePath);
59702
+ const stat2 = fs36.statSync(filePath);
59168
59703
  if (stat2.size > MAX_FILE_SIZE_BYTES5) {
59169
59704
  return null;
59170
59705
  }
59171
- const content = fs35.readFileSync(filePath, "utf-8");
59706
+ const content = fs36.readFileSync(filePath, "utf-8");
59172
59707
  return estimateCyclomaticComplexity(content);
59173
59708
  } catch {
59174
59709
  return null;
@@ -59178,8 +59713,8 @@ async function computeComplexityDelta(files, workingDir) {
59178
59713
  let totalComplexity = 0;
59179
59714
  const analyzedFiles = [];
59180
59715
  for (const file3 of files) {
59181
- const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
59182
- if (!fs35.existsSync(fullPath)) {
59716
+ const fullPath = path48.isAbsolute(file3) ? file3 : path48.join(workingDir, file3);
59717
+ if (!fs36.existsSync(fullPath)) {
59183
59718
  continue;
59184
59719
  }
59185
59720
  const complexity = getComplexityForFile2(fullPath);
@@ -59300,8 +59835,8 @@ function countGoExports(content) {
59300
59835
  }
59301
59836
  function getExportCountForFile(filePath) {
59302
59837
  try {
59303
- const content = fs35.readFileSync(filePath, "utf-8");
59304
- const ext = path47.extname(filePath).toLowerCase();
59838
+ const content = fs36.readFileSync(filePath, "utf-8");
59839
+ const ext = path48.extname(filePath).toLowerCase();
59305
59840
  switch (ext) {
59306
59841
  case ".ts":
59307
59842
  case ".tsx":
@@ -59327,8 +59862,8 @@ async function computePublicApiDelta(files, workingDir) {
59327
59862
  let totalExports = 0;
59328
59863
  const analyzedFiles = [];
59329
59864
  for (const file3 of files) {
59330
- const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
59331
- if (!fs35.existsSync(fullPath)) {
59865
+ const fullPath = path48.isAbsolute(file3) ? file3 : path48.join(workingDir, file3);
59866
+ if (!fs36.existsSync(fullPath)) {
59332
59867
  continue;
59333
59868
  }
59334
59869
  const exports = getExportCountForFile(fullPath);
@@ -59361,16 +59896,16 @@ async function computeDuplicationRatio(files, workingDir) {
59361
59896
  let duplicateLines = 0;
59362
59897
  const analyzedFiles = [];
59363
59898
  for (const file3 of files) {
59364
- const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
59365
- if (!fs35.existsSync(fullPath)) {
59899
+ const fullPath = path48.isAbsolute(file3) ? file3 : path48.join(workingDir, file3);
59900
+ if (!fs36.existsSync(fullPath)) {
59366
59901
  continue;
59367
59902
  }
59368
59903
  try {
59369
- const stat2 = fs35.statSync(fullPath);
59904
+ const stat2 = fs36.statSync(fullPath);
59370
59905
  if (stat2.size > MAX_FILE_SIZE_BYTES5) {
59371
59906
  continue;
59372
59907
  }
59373
- const content = fs35.readFileSync(fullPath, "utf-8");
59908
+ const content = fs36.readFileSync(fullPath, "utf-8");
59374
59909
  const lines = content.split(`
59375
59910
  `).filter((line) => line.trim().length > 0);
59376
59911
  if (lines.length < MIN_DUPLICATION_LINES) {
@@ -59394,8 +59929,8 @@ function countCodeLines(content) {
59394
59929
  return lines.length;
59395
59930
  }
59396
59931
  function isTestFile(filePath) {
59397
- const basename8 = path47.basename(filePath);
59398
- const _ext = path47.extname(filePath).toLowerCase();
59932
+ const basename9 = path48.basename(filePath);
59933
+ const _ext = path48.extname(filePath).toLowerCase();
59399
59934
  const testPatterns = [
59400
59935
  ".test.",
59401
59936
  ".spec.",
@@ -59410,7 +59945,7 @@ function isTestFile(filePath) {
59410
59945
  ".spec.jsx"
59411
59946
  ];
59412
59947
  for (const pattern of testPatterns) {
59413
- if (basename8.includes(pattern)) {
59948
+ if (basename9.includes(pattern)) {
59414
59949
  return true;
59415
59950
  }
59416
59951
  }
@@ -59476,8 +60011,8 @@ function matchGlobSegment(globSegments, pathSegments) {
59476
60011
  }
59477
60012
  return gIndex === globSegments.length && pIndex === pathSegments.length;
59478
60013
  }
59479
- function matchesGlobSegment(path48, glob) {
59480
- const normalizedPath = path48.replace(/\\/g, "/");
60014
+ function matchesGlobSegment(path49, glob) {
60015
+ const normalizedPath = path49.replace(/\\/g, "/");
59481
60016
  const normalizedGlob = glob.replace(/\\/g, "/");
59482
60017
  if (normalizedPath.includes("//")) {
59483
60018
  return false;
@@ -59508,8 +60043,8 @@ function simpleGlobToRegex2(glob) {
59508
60043
  function hasGlobstar(glob) {
59509
60044
  return glob.includes("**");
59510
60045
  }
59511
- function globMatches(path48, glob) {
59512
- const normalizedPath = path48.replace(/\\/g, "/");
60046
+ function globMatches(path49, glob) {
60047
+ const normalizedPath = path49.replace(/\\/g, "/");
59513
60048
  if (!glob || glob === "") {
59514
60049
  if (normalizedPath.includes("//")) {
59515
60050
  return false;
@@ -59545,31 +60080,31 @@ function shouldExcludeFile(filePath, excludeGlobs) {
59545
60080
  async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
59546
60081
  let testLines = 0;
59547
60082
  let codeLines = 0;
59548
- const srcDir = path47.join(workingDir, "src");
59549
- if (fs35.existsSync(srcDir)) {
60083
+ const srcDir = path48.join(workingDir, "src");
60084
+ if (fs36.existsSync(srcDir)) {
59550
60085
  await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
59551
60086
  codeLines += lines;
59552
60087
  });
59553
60088
  }
59554
60089
  const possibleSrcDirs = ["lib", "app", "source", "core"];
59555
60090
  for (const dir of possibleSrcDirs) {
59556
- const dirPath = path47.join(workingDir, dir);
59557
- if (fs35.existsSync(dirPath)) {
60091
+ const dirPath = path48.join(workingDir, dir);
60092
+ if (fs36.existsSync(dirPath)) {
59558
60093
  await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
59559
60094
  codeLines += lines;
59560
60095
  });
59561
60096
  }
59562
60097
  }
59563
- const testsDir = path47.join(workingDir, "tests");
59564
- if (fs35.existsSync(testsDir)) {
60098
+ const testsDir = path48.join(workingDir, "tests");
60099
+ if (fs36.existsSync(testsDir)) {
59565
60100
  await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
59566
60101
  testLines += lines;
59567
60102
  });
59568
60103
  }
59569
60104
  const possibleTestDirs = ["test", "__tests__", "specs"];
59570
60105
  for (const dir of possibleTestDirs) {
59571
- const dirPath = path47.join(workingDir, dir);
59572
- if (fs35.existsSync(dirPath) && dirPath !== testsDir) {
60106
+ const dirPath = path48.join(workingDir, dir);
60107
+ if (fs36.existsSync(dirPath) && dirPath !== testsDir) {
59573
60108
  await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
59574
60109
  testLines += lines;
59575
60110
  });
@@ -59581,9 +60116,9 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
59581
60116
  }
59582
60117
  async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
59583
60118
  try {
59584
- const entries = fs35.readdirSync(dirPath, { withFileTypes: true });
60119
+ const entries = fs36.readdirSync(dirPath, { withFileTypes: true });
59585
60120
  for (const entry of entries) {
59586
- const fullPath = path47.join(dirPath, entry.name);
60121
+ const fullPath = path48.join(dirPath, entry.name);
59587
60122
  if (entry.isDirectory()) {
59588
60123
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
59589
60124
  continue;
@@ -59591,7 +60126,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
59591
60126
  await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
59592
60127
  } else if (entry.isFile()) {
59593
60128
  const relativePath = fullPath.replace(`${dirPath}/`, "");
59594
- const ext = path47.extname(entry.name).toLowerCase();
60129
+ const ext = path48.extname(entry.name).toLowerCase();
59595
60130
  const validExts = [
59596
60131
  ".ts",
59597
60132
  ".tsx",
@@ -59627,7 +60162,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
59627
60162
  continue;
59628
60163
  }
59629
60164
  try {
59630
- const content = fs35.readFileSync(fullPath, "utf-8");
60165
+ const content = fs36.readFileSync(fullPath, "utf-8");
59631
60166
  const lines = countCodeLines(content);
59632
60167
  callback(lines);
59633
60168
  } catch {}
@@ -59841,8 +60376,8 @@ async function qualityBudget(input, directory) {
59841
60376
  init_dist();
59842
60377
  init_manager();
59843
60378
  init_detector();
59844
- import * as fs36 from "fs";
59845
- import * as path48 from "path";
60379
+ import * as fs37 from "fs";
60380
+ import * as path49 from "path";
59846
60381
  import { extname as extname9 } from "path";
59847
60382
 
59848
60383
  // src/sast/rules/c.ts
@@ -60709,17 +61244,17 @@ var SEVERITY_ORDER = {
60709
61244
  };
60710
61245
  function shouldSkipFile(filePath) {
60711
61246
  try {
60712
- const stats = fs36.statSync(filePath);
61247
+ const stats = fs37.statSync(filePath);
60713
61248
  if (stats.size > MAX_FILE_SIZE_BYTES6) {
60714
61249
  return { skip: true, reason: "file too large" };
60715
61250
  }
60716
61251
  if (stats.size === 0) {
60717
61252
  return { skip: true, reason: "empty file" };
60718
61253
  }
60719
- const fd = fs36.openSync(filePath, "r");
61254
+ const fd = fs37.openSync(filePath, "r");
60720
61255
  const buffer = Buffer.alloc(8192);
60721
- const bytesRead = fs36.readSync(fd, buffer, 0, 8192, 0);
60722
- fs36.closeSync(fd);
61256
+ const bytesRead = fs37.readSync(fd, buffer, 0, 8192, 0);
61257
+ fs37.closeSync(fd);
60723
61258
  if (bytesRead > 0) {
60724
61259
  let nullCount = 0;
60725
61260
  for (let i2 = 0;i2 < bytesRead; i2++) {
@@ -60758,7 +61293,7 @@ function countBySeverity(findings) {
60758
61293
  }
60759
61294
  function scanFileWithTierA(filePath, language) {
60760
61295
  try {
60761
- const content = fs36.readFileSync(filePath, "utf-8");
61296
+ const content = fs37.readFileSync(filePath, "utf-8");
60762
61297
  const findings = executeRulesSync(filePath, content, language);
60763
61298
  return findings.map((f) => ({
60764
61299
  rule_id: f.rule_id,
@@ -60805,8 +61340,8 @@ async function sastScan(input, directory, config3) {
60805
61340
  _filesSkipped++;
60806
61341
  continue;
60807
61342
  }
60808
- const resolvedPath = path48.isAbsolute(filePath) ? filePath : path48.resolve(directory, filePath);
60809
- if (!fs36.existsSync(resolvedPath)) {
61343
+ const resolvedPath = path49.isAbsolute(filePath) ? filePath : path49.resolve(directory, filePath);
61344
+ if (!fs37.existsSync(resolvedPath)) {
60810
61345
  _filesSkipped++;
60811
61346
  continue;
60812
61347
  }
@@ -61004,18 +61539,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
61004
61539
  let resolved;
61005
61540
  const isWinAbs = isWindowsAbsolutePath(inputPath);
61006
61541
  if (isWinAbs) {
61007
- resolved = path49.win32.resolve(inputPath);
61008
- } else if (path49.isAbsolute(inputPath)) {
61009
- resolved = path49.resolve(inputPath);
61542
+ resolved = path50.win32.resolve(inputPath);
61543
+ } else if (path50.isAbsolute(inputPath)) {
61544
+ resolved = path50.resolve(inputPath);
61010
61545
  } else {
61011
- resolved = path49.resolve(baseDir, inputPath);
61546
+ resolved = path50.resolve(baseDir, inputPath);
61012
61547
  }
61013
- const workspaceResolved = path49.resolve(workspaceDir);
61548
+ const workspaceResolved = path50.resolve(workspaceDir);
61014
61549
  let relative6;
61015
61550
  if (isWinAbs) {
61016
- relative6 = path49.win32.relative(workspaceResolved, resolved);
61551
+ relative6 = path50.win32.relative(workspaceResolved, resolved);
61017
61552
  } else {
61018
- relative6 = path49.relative(workspaceResolved, resolved);
61553
+ relative6 = path50.relative(workspaceResolved, resolved);
61019
61554
  }
61020
61555
  if (relative6.startsWith("..")) {
61021
61556
  return "path traversal detected";
@@ -61076,13 +61611,13 @@ async function runLintWrapped(files, directory, _config) {
61076
61611
  }
61077
61612
  async function runLintOnFiles(linter, files, workspaceDir) {
61078
61613
  const isWindows = process.platform === "win32";
61079
- const binDir = path49.join(workspaceDir, "node_modules", ".bin");
61614
+ const binDir = path50.join(workspaceDir, "node_modules", ".bin");
61080
61615
  const validatedFiles = [];
61081
61616
  for (const file3 of files) {
61082
61617
  if (typeof file3 !== "string") {
61083
61618
  continue;
61084
61619
  }
61085
- const resolvedPath = path49.resolve(file3);
61620
+ const resolvedPath = path50.resolve(file3);
61086
61621
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
61087
61622
  if (validationError) {
61088
61623
  continue;
@@ -61100,10 +61635,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
61100
61635
  }
61101
61636
  let command;
61102
61637
  if (linter === "biome") {
61103
- const biomeBin = isWindows ? path49.join(binDir, "biome.EXE") : path49.join(binDir, "biome");
61638
+ const biomeBin = isWindows ? path50.join(binDir, "biome.EXE") : path50.join(binDir, "biome");
61104
61639
  command = [biomeBin, "check", ...validatedFiles];
61105
61640
  } else {
61106
- const eslintBin = isWindows ? path49.join(binDir, "eslint.cmd") : path49.join(binDir, "eslint");
61641
+ const eslintBin = isWindows ? path50.join(binDir, "eslint.cmd") : path50.join(binDir, "eslint");
61107
61642
  command = [eslintBin, ...validatedFiles];
61108
61643
  }
61109
61644
  try {
@@ -61240,7 +61775,7 @@ async function runSecretscanWithFiles(files, directory) {
61240
61775
  skippedFiles++;
61241
61776
  continue;
61242
61777
  }
61243
- const resolvedPath = path49.resolve(file3);
61778
+ const resolvedPath = path50.resolve(file3);
61244
61779
  const validationError = validatePath(resolvedPath, directory, directory);
61245
61780
  if (validationError) {
61246
61781
  skippedFiles++;
@@ -61258,14 +61793,14 @@ async function runSecretscanWithFiles(files, directory) {
61258
61793
  };
61259
61794
  }
61260
61795
  for (const file3 of validatedFiles) {
61261
- const ext = path49.extname(file3).toLowerCase();
61796
+ const ext = path50.extname(file3).toLowerCase();
61262
61797
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
61263
61798
  skippedFiles++;
61264
61799
  continue;
61265
61800
  }
61266
61801
  let stat2;
61267
61802
  try {
61268
- stat2 = fs37.statSync(file3);
61803
+ stat2 = fs38.statSync(file3);
61269
61804
  } catch {
61270
61805
  skippedFiles++;
61271
61806
  continue;
@@ -61276,7 +61811,7 @@ async function runSecretscanWithFiles(files, directory) {
61276
61811
  }
61277
61812
  let content;
61278
61813
  try {
61279
- const buffer = fs37.readFileSync(file3);
61814
+ const buffer = fs38.readFileSync(file3);
61280
61815
  if (buffer.includes(0)) {
61281
61816
  skippedFiles++;
61282
61817
  continue;
@@ -61417,7 +61952,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
61417
61952
  warn(`pre_check_batch: Invalid file path: ${file3}`);
61418
61953
  continue;
61419
61954
  }
61420
- changedFiles.push(path49.resolve(directory, file3));
61955
+ changedFiles.push(path50.resolve(directory, file3));
61421
61956
  }
61422
61957
  if (changedFiles.length === 0) {
61423
61958
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -61464,6 +61999,26 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
61464
61999
  gatesPassed = false;
61465
62000
  warn(`pre_check_batch: Secretscan error - GATE FAILED: ${secretscanResult.error}`);
61466
62001
  }
62002
+ if (secretscanResult.ran && secretscanResult.result) {
62003
+ try {
62004
+ const scanResult = secretscanResult.result;
62005
+ const secretscanEvidence = {
62006
+ task_id: "secretscan",
62007
+ type: "secretscan",
62008
+ timestamp: new Date().toISOString(),
62009
+ agent: "pre_check_batch",
62010
+ verdict: scanResult.count > 0 ? "fail" : "pass",
62011
+ summary: `Secretscan: ${scanResult.count} finding(s), ${scanResult.files_scanned ?? 0} files scanned, ${scanResult.skipped_files ?? 0} skipped`,
62012
+ findings_count: scanResult.count,
62013
+ scan_directory: scanResult.scan_dir,
62014
+ files_scanned: scanResult.files_scanned,
62015
+ skipped_files: scanResult.skipped_files
62016
+ };
62017
+ await saveEvidence(directory, "secretscan", secretscanEvidence);
62018
+ } catch (e) {
62019
+ warn(`Failed to persist secretscan evidence: ${e instanceof Error ? e.message : String(e)}`);
62020
+ }
62021
+ }
61467
62022
  if (sastScanResult.ran && sastScanResult.result) {
61468
62023
  if (sastScanResult.result.verdict === "fail") {
61469
62024
  gatesPassed = false;
@@ -61568,7 +62123,7 @@ var pre_check_batch = createSwarmTool({
61568
62123
  };
61569
62124
  return JSON.stringify(errorResult, null, 2);
61570
62125
  }
61571
- const resolvedDirectory = path49.resolve(typedArgs.directory);
62126
+ const resolvedDirectory = path50.resolve(typedArgs.directory);
61572
62127
  const workspaceAnchor = resolvedDirectory;
61573
62128
  const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
61574
62129
  if (dirError) {
@@ -61676,8 +62231,8 @@ ${paginatedContent}`;
61676
62231
  init_tool();
61677
62232
  init_manager2();
61678
62233
  init_create_tool();
61679
- import * as fs38 from "fs";
61680
- import * as path50 from "path";
62234
+ import * as fs39 from "fs";
62235
+ import * as path51 from "path";
61681
62236
  function detectPlaceholderContent(args2) {
61682
62237
  const issues = [];
61683
62238
  const placeholderPattern = /^\[\w[\w\s]*\]$/;
@@ -61781,19 +62336,19 @@ async function executeSavePlan(args2, fallbackDir) {
61781
62336
  try {
61782
62337
  await savePlan(dir, plan);
61783
62338
  try {
61784
- const markerPath = path50.join(dir, ".swarm", ".plan-write-marker");
62339
+ const markerPath = path51.join(dir, ".swarm", ".plan-write-marker");
61785
62340
  const marker = JSON.stringify({
61786
62341
  source: "save_plan",
61787
62342
  timestamp: new Date().toISOString(),
61788
62343
  phases_count: plan.phases.length,
61789
62344
  tasks_count: tasksCount
61790
62345
  });
61791
- await fs38.promises.writeFile(markerPath, marker, "utf8");
62346
+ await fs39.promises.writeFile(markerPath, marker, "utf8");
61792
62347
  } catch {}
61793
62348
  return {
61794
62349
  success: true,
61795
62350
  message: "Plan saved successfully",
61796
- plan_path: path50.join(dir, ".swarm", "plan.json"),
62351
+ plan_path: path51.join(dir, ".swarm", "plan.json"),
61797
62352
  phases_count: plan.phases.length,
61798
62353
  tasks_count: tasksCount
61799
62354
  };
@@ -61831,8 +62386,8 @@ var save_plan = createSwarmTool({
61831
62386
  // src/tools/sbom-generate.ts
61832
62387
  init_dist();
61833
62388
  init_manager();
61834
- import * as fs39 from "fs";
61835
- import * as path51 from "path";
62389
+ import * as fs40 from "fs";
62390
+ import * as path52 from "path";
61836
62391
 
61837
62392
  // src/sbom/detectors/index.ts
61838
62393
  init_utils();
@@ -62678,9 +63233,9 @@ function findManifestFiles(rootDir) {
62678
63233
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
62679
63234
  function searchDir(dir) {
62680
63235
  try {
62681
- const entries = fs39.readdirSync(dir, { withFileTypes: true });
63236
+ const entries = fs40.readdirSync(dir, { withFileTypes: true });
62682
63237
  for (const entry of entries) {
62683
- const fullPath = path51.join(dir, entry.name);
63238
+ const fullPath = path52.join(dir, entry.name);
62684
63239
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
62685
63240
  continue;
62686
63241
  }
@@ -62689,7 +63244,7 @@ function findManifestFiles(rootDir) {
62689
63244
  } else if (entry.isFile()) {
62690
63245
  for (const pattern of patterns) {
62691
63246
  if (simpleGlobToRegex(pattern).test(entry.name)) {
62692
- manifestFiles.push(path51.relative(rootDir, fullPath));
63247
+ manifestFiles.push(path52.relative(rootDir, fullPath));
62693
63248
  break;
62694
63249
  }
62695
63250
  }
@@ -62705,13 +63260,13 @@ function findManifestFilesInDirs(directories, workingDir) {
62705
63260
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
62706
63261
  for (const dir of directories) {
62707
63262
  try {
62708
- const entries = fs39.readdirSync(dir, { withFileTypes: true });
63263
+ const entries = fs40.readdirSync(dir, { withFileTypes: true });
62709
63264
  for (const entry of entries) {
62710
- const fullPath = path51.join(dir, entry.name);
63265
+ const fullPath = path52.join(dir, entry.name);
62711
63266
  if (entry.isFile()) {
62712
63267
  for (const pattern of patterns) {
62713
63268
  if (simpleGlobToRegex(pattern).test(entry.name)) {
62714
- found.push(path51.relative(workingDir, fullPath));
63269
+ found.push(path52.relative(workingDir, fullPath));
62715
63270
  break;
62716
63271
  }
62717
63272
  }
@@ -62724,11 +63279,11 @@ function findManifestFilesInDirs(directories, workingDir) {
62724
63279
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
62725
63280
  const dirs = new Set;
62726
63281
  for (const file3 of changedFiles) {
62727
- let currentDir = path51.dirname(file3);
63282
+ let currentDir = path52.dirname(file3);
62728
63283
  while (true) {
62729
- if (currentDir && currentDir !== "." && currentDir !== path51.sep) {
62730
- dirs.add(path51.join(workingDir, currentDir));
62731
- const parent = path51.dirname(currentDir);
63284
+ if (currentDir && currentDir !== "." && currentDir !== path52.sep) {
63285
+ dirs.add(path52.join(workingDir, currentDir));
63286
+ const parent = path52.dirname(currentDir);
62732
63287
  if (parent === currentDir)
62733
63288
  break;
62734
63289
  currentDir = parent;
@@ -62742,7 +63297,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
62742
63297
  }
62743
63298
  function ensureOutputDir(outputDir) {
62744
63299
  try {
62745
- fs39.mkdirSync(outputDir, { recursive: true });
63300
+ fs40.mkdirSync(outputDir, { recursive: true });
62746
63301
  } catch (error93) {
62747
63302
  if (!error93 || error93.code !== "EEXIST") {
62748
63303
  throw error93;
@@ -62812,7 +63367,7 @@ var sbom_generate = createSwarmTool({
62812
63367
  const changedFiles = obj.changed_files;
62813
63368
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
62814
63369
  const workingDir = directory;
62815
- const outputDir = path51.isAbsolute(relativeOutputDir) ? relativeOutputDir : path51.join(workingDir, relativeOutputDir);
63370
+ const outputDir = path52.isAbsolute(relativeOutputDir) ? relativeOutputDir : path52.join(workingDir, relativeOutputDir);
62816
63371
  let manifestFiles = [];
62817
63372
  if (scope === "all") {
62818
63373
  manifestFiles = findManifestFiles(workingDir);
@@ -62835,11 +63390,11 @@ var sbom_generate = createSwarmTool({
62835
63390
  const processedFiles = [];
62836
63391
  for (const manifestFile of manifestFiles) {
62837
63392
  try {
62838
- const fullPath = path51.isAbsolute(manifestFile) ? manifestFile : path51.join(workingDir, manifestFile);
62839
- if (!fs39.existsSync(fullPath)) {
63393
+ const fullPath = path52.isAbsolute(manifestFile) ? manifestFile : path52.join(workingDir, manifestFile);
63394
+ if (!fs40.existsSync(fullPath)) {
62840
63395
  continue;
62841
63396
  }
62842
- const content = fs39.readFileSync(fullPath, "utf-8");
63397
+ const content = fs40.readFileSync(fullPath, "utf-8");
62843
63398
  const components = detectComponents(manifestFile, content);
62844
63399
  processedFiles.push(manifestFile);
62845
63400
  if (components.length > 0) {
@@ -62852,8 +63407,8 @@ var sbom_generate = createSwarmTool({
62852
63407
  const bom = generateCycloneDX(allComponents);
62853
63408
  const bomJson = serializeCycloneDX(bom);
62854
63409
  const filename = generateSbomFilename();
62855
- const outputPath = path51.join(outputDir, filename);
62856
- fs39.writeFileSync(outputPath, bomJson, "utf-8");
63410
+ const outputPath = path52.join(outputDir, filename);
63411
+ fs40.writeFileSync(outputPath, bomJson, "utf-8");
62857
63412
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
62858
63413
  try {
62859
63414
  const timestamp = new Date().toISOString();
@@ -62895,8 +63450,8 @@ var sbom_generate = createSwarmTool({
62895
63450
  // src/tools/schema-drift.ts
62896
63451
  init_dist();
62897
63452
  init_create_tool();
62898
- import * as fs40 from "fs";
62899
- import * as path52 from "path";
63453
+ import * as fs41 from "fs";
63454
+ import * as path53 from "path";
62900
63455
  var SPEC_CANDIDATES = [
62901
63456
  "openapi.json",
62902
63457
  "openapi.yaml",
@@ -62928,28 +63483,28 @@ function normalizePath2(p) {
62928
63483
  }
62929
63484
  function discoverSpecFile(cwd, specFileArg) {
62930
63485
  if (specFileArg) {
62931
- const resolvedPath = path52.resolve(cwd, specFileArg);
62932
- const normalizedCwd = cwd.endsWith(path52.sep) ? cwd : cwd + path52.sep;
63486
+ const resolvedPath = path53.resolve(cwd, specFileArg);
63487
+ const normalizedCwd = cwd.endsWith(path53.sep) ? cwd : cwd + path53.sep;
62933
63488
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
62934
63489
  throw new Error("Invalid spec_file: path traversal detected");
62935
63490
  }
62936
- const ext = path52.extname(resolvedPath).toLowerCase();
63491
+ const ext = path53.extname(resolvedPath).toLowerCase();
62937
63492
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
62938
63493
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
62939
63494
  }
62940
- const stats = fs40.statSync(resolvedPath);
63495
+ const stats = fs41.statSync(resolvedPath);
62941
63496
  if (stats.size > MAX_SPEC_SIZE) {
62942
63497
  throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
62943
63498
  }
62944
- if (!fs40.existsSync(resolvedPath)) {
63499
+ if (!fs41.existsSync(resolvedPath)) {
62945
63500
  throw new Error(`Spec file not found: ${resolvedPath}`);
62946
63501
  }
62947
63502
  return resolvedPath;
62948
63503
  }
62949
63504
  for (const candidate of SPEC_CANDIDATES) {
62950
- const candidatePath = path52.resolve(cwd, candidate);
62951
- if (fs40.existsSync(candidatePath)) {
62952
- const stats = fs40.statSync(candidatePath);
63505
+ const candidatePath = path53.resolve(cwd, candidate);
63506
+ if (fs41.existsSync(candidatePath)) {
63507
+ const stats = fs41.statSync(candidatePath);
62953
63508
  if (stats.size <= MAX_SPEC_SIZE) {
62954
63509
  return candidatePath;
62955
63510
  }
@@ -62958,8 +63513,8 @@ function discoverSpecFile(cwd, specFileArg) {
62958
63513
  return null;
62959
63514
  }
62960
63515
  function parseSpec(specFile) {
62961
- const content = fs40.readFileSync(specFile, "utf-8");
62962
- const ext = path52.extname(specFile).toLowerCase();
63516
+ const content = fs41.readFileSync(specFile, "utf-8");
63517
+ const ext = path53.extname(specFile).toLowerCase();
62963
63518
  if (ext === ".json") {
62964
63519
  return parseJsonSpec(content);
62965
63520
  }
@@ -63030,12 +63585,12 @@ function extractRoutes(cwd) {
63030
63585
  function walkDir(dir) {
63031
63586
  let entries;
63032
63587
  try {
63033
- entries = fs40.readdirSync(dir, { withFileTypes: true });
63588
+ entries = fs41.readdirSync(dir, { withFileTypes: true });
63034
63589
  } catch {
63035
63590
  return;
63036
63591
  }
63037
63592
  for (const entry of entries) {
63038
- const fullPath = path52.join(dir, entry.name);
63593
+ const fullPath = path53.join(dir, entry.name);
63039
63594
  if (entry.isSymbolicLink()) {
63040
63595
  continue;
63041
63596
  }
@@ -63045,7 +63600,7 @@ function extractRoutes(cwd) {
63045
63600
  }
63046
63601
  walkDir(fullPath);
63047
63602
  } else if (entry.isFile()) {
63048
- const ext = path52.extname(entry.name).toLowerCase();
63603
+ const ext = path53.extname(entry.name).toLowerCase();
63049
63604
  const baseName = entry.name.toLowerCase();
63050
63605
  if (![".ts", ".js", ".mjs"].includes(ext)) {
63051
63606
  continue;
@@ -63063,7 +63618,7 @@ function extractRoutes(cwd) {
63063
63618
  }
63064
63619
  function extractRoutesFromFile(filePath) {
63065
63620
  const routes = [];
63066
- const content = fs40.readFileSync(filePath, "utf-8");
63621
+ const content = fs41.readFileSync(filePath, "utf-8");
63067
63622
  const lines = content.split(/\r?\n/);
63068
63623
  const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
63069
63624
  const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
@@ -63214,8 +63769,8 @@ init_secretscan();
63214
63769
  // src/tools/symbols.ts
63215
63770
  init_tool();
63216
63771
  init_create_tool();
63217
- import * as fs41 from "fs";
63218
- import * as path53 from "path";
63772
+ import * as fs42 from "fs";
63773
+ import * as path54 from "path";
63219
63774
  var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
63220
63775
  var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
63221
63776
  function containsControlCharacters(str) {
@@ -63244,11 +63799,11 @@ function containsWindowsAttacks(str) {
63244
63799
  }
63245
63800
  function isPathInWorkspace(filePath, workspace) {
63246
63801
  try {
63247
- const resolvedPath = path53.resolve(workspace, filePath);
63248
- const realWorkspace = fs41.realpathSync(workspace);
63249
- const realResolvedPath = fs41.realpathSync(resolvedPath);
63250
- const relativePath = path53.relative(realWorkspace, realResolvedPath);
63251
- if (relativePath.startsWith("..") || path53.isAbsolute(relativePath)) {
63802
+ const resolvedPath = path54.resolve(workspace, filePath);
63803
+ const realWorkspace = fs42.realpathSync(workspace);
63804
+ const realResolvedPath = fs42.realpathSync(resolvedPath);
63805
+ const relativePath = path54.relative(realWorkspace, realResolvedPath);
63806
+ if (relativePath.startsWith("..") || path54.isAbsolute(relativePath)) {
63252
63807
  return false;
63253
63808
  }
63254
63809
  return true;
@@ -63260,17 +63815,17 @@ function validatePathForRead(filePath, workspace) {
63260
63815
  return isPathInWorkspace(filePath, workspace);
63261
63816
  }
63262
63817
  function extractTSSymbols(filePath, cwd) {
63263
- const fullPath = path53.join(cwd, filePath);
63818
+ const fullPath = path54.join(cwd, filePath);
63264
63819
  if (!validatePathForRead(fullPath, cwd)) {
63265
63820
  return [];
63266
63821
  }
63267
63822
  let content;
63268
63823
  try {
63269
- const stats = fs41.statSync(fullPath);
63824
+ const stats = fs42.statSync(fullPath);
63270
63825
  if (stats.size > MAX_FILE_SIZE_BYTES7) {
63271
63826
  throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
63272
63827
  }
63273
- content = fs41.readFileSync(fullPath, "utf-8");
63828
+ content = fs42.readFileSync(fullPath, "utf-8");
63274
63829
  } catch {
63275
63830
  return [];
63276
63831
  }
@@ -63412,17 +63967,17 @@ function extractTSSymbols(filePath, cwd) {
63412
63967
  });
63413
63968
  }
63414
63969
  function extractPythonSymbols(filePath, cwd) {
63415
- const fullPath = path53.join(cwd, filePath);
63970
+ const fullPath = path54.join(cwd, filePath);
63416
63971
  if (!validatePathForRead(fullPath, cwd)) {
63417
63972
  return [];
63418
63973
  }
63419
63974
  let content;
63420
63975
  try {
63421
- const stats = fs41.statSync(fullPath);
63976
+ const stats = fs42.statSync(fullPath);
63422
63977
  if (stats.size > MAX_FILE_SIZE_BYTES7) {
63423
63978
  throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
63424
63979
  }
63425
- content = fs41.readFileSync(fullPath, "utf-8");
63980
+ content = fs42.readFileSync(fullPath, "utf-8");
63426
63981
  } catch {
63427
63982
  return [];
63428
63983
  }
@@ -63495,7 +64050,7 @@ var symbols = createSwarmTool({
63495
64050
  }, null, 2);
63496
64051
  }
63497
64052
  const cwd = directory;
63498
- const ext = path53.extname(file3);
64053
+ const ext = path54.extname(file3);
63499
64054
  if (containsControlCharacters(file3)) {
63500
64055
  return JSON.stringify({
63501
64056
  file: file3,
@@ -63566,8 +64121,8 @@ init_test_runner();
63566
64121
  init_dist();
63567
64122
  init_utils();
63568
64123
  init_create_tool();
63569
- import * as fs42 from "fs";
63570
- import * as path54 from "path";
64124
+ import * as fs43 from "fs";
64125
+ import * as path55 from "path";
63571
64126
  var MAX_TEXT_LENGTH = 200;
63572
64127
  var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
63573
64128
  var SUPPORTED_EXTENSIONS2 = new Set([
@@ -63589,7 +64144,7 @@ var SUPPORTED_EXTENSIONS2 = new Set([
63589
64144
  ".swift",
63590
64145
  ".kt"
63591
64146
  ]);
63592
- var SKIP_DIRECTORIES3 = new Set([
64147
+ var SKIP_DIRECTORIES4 = new Set([
63593
64148
  "node_modules",
63594
64149
  "dist",
63595
64150
  "build",
@@ -63638,9 +64193,9 @@ function validatePathsInput(paths, cwd) {
63638
64193
  return { error: "paths contains path traversal", resolvedPath: null };
63639
64194
  }
63640
64195
  try {
63641
- const resolvedPath = path54.resolve(paths);
63642
- const normalizedCwd = path54.resolve(cwd);
63643
- const normalizedResolved = path54.resolve(resolvedPath);
64196
+ const resolvedPath = path55.resolve(paths);
64197
+ const normalizedCwd = path55.resolve(cwd);
64198
+ const normalizedResolved = path55.resolve(resolvedPath);
63644
64199
  if (!normalizedResolved.startsWith(normalizedCwd)) {
63645
64200
  return {
63646
64201
  error: "paths must be within the current working directory",
@@ -63656,25 +64211,25 @@ function validatePathsInput(paths, cwd) {
63656
64211
  }
63657
64212
  }
63658
64213
  function isSupportedExtension(filePath) {
63659
- const ext = path54.extname(filePath).toLowerCase();
64214
+ const ext = path55.extname(filePath).toLowerCase();
63660
64215
  return SUPPORTED_EXTENSIONS2.has(ext);
63661
64216
  }
63662
64217
  function findSourceFiles2(dir, files = []) {
63663
64218
  let entries;
63664
64219
  try {
63665
- entries = fs42.readdirSync(dir);
64220
+ entries = fs43.readdirSync(dir);
63666
64221
  } catch {
63667
64222
  return files;
63668
64223
  }
63669
64224
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
63670
64225
  for (const entry of entries) {
63671
- if (SKIP_DIRECTORIES3.has(entry)) {
64226
+ if (SKIP_DIRECTORIES4.has(entry)) {
63672
64227
  continue;
63673
64228
  }
63674
- const fullPath = path54.join(dir, entry);
64229
+ const fullPath = path55.join(dir, entry);
63675
64230
  let stat2;
63676
64231
  try {
63677
- stat2 = fs42.statSync(fullPath);
64232
+ stat2 = fs43.statSync(fullPath);
63678
64233
  } catch {
63679
64234
  continue;
63680
64235
  }
@@ -63767,7 +64322,7 @@ var todo_extract = createSwarmTool({
63767
64322
  return JSON.stringify(errorResult, null, 2);
63768
64323
  }
63769
64324
  const scanPath = resolvedPath;
63770
- if (!fs42.existsSync(scanPath)) {
64325
+ if (!fs43.existsSync(scanPath)) {
63771
64326
  const errorResult = {
63772
64327
  error: `path not found: ${pathsInput}`,
63773
64328
  total: 0,
@@ -63777,13 +64332,13 @@ var todo_extract = createSwarmTool({
63777
64332
  return JSON.stringify(errorResult, null, 2);
63778
64333
  }
63779
64334
  const filesToScan = [];
63780
- const stat2 = fs42.statSync(scanPath);
64335
+ const stat2 = fs43.statSync(scanPath);
63781
64336
  if (stat2.isFile()) {
63782
64337
  if (isSupportedExtension(scanPath)) {
63783
64338
  filesToScan.push(scanPath);
63784
64339
  } else {
63785
64340
  const errorResult = {
63786
- error: `unsupported file extension: ${path54.extname(scanPath)}`,
64341
+ error: `unsupported file extension: ${path55.extname(scanPath)}`,
63787
64342
  total: 0,
63788
64343
  byPriority: { high: 0, medium: 0, low: 0 },
63789
64344
  entries: []
@@ -63796,11 +64351,11 @@ var todo_extract = createSwarmTool({
63796
64351
  const allEntries = [];
63797
64352
  for (const filePath of filesToScan) {
63798
64353
  try {
63799
- const fileStat = fs42.statSync(filePath);
64354
+ const fileStat = fs43.statSync(filePath);
63800
64355
  if (fileStat.size > MAX_FILE_SIZE_BYTES8) {
63801
64356
  continue;
63802
64357
  }
63803
- const content = fs42.readFileSync(filePath, "utf-8");
64358
+ const content = fs43.readFileSync(filePath, "utf-8");
63804
64359
  const entries = parseTodoComments(content, filePath, tagsSet);
63805
64360
  allEntries.push(...entries);
63806
64361
  } catch {}
@@ -63828,18 +64383,18 @@ var todo_extract = createSwarmTool({
63828
64383
  // src/tools/update-task-status.ts
63829
64384
  init_tool();
63830
64385
  init_schema();
63831
- import * as fs44 from "fs";
63832
- import * as path56 from "path";
64386
+ import * as fs45 from "fs";
64387
+ import * as path57 from "path";
63833
64388
 
63834
64389
  // src/hooks/diff-scope.ts
63835
- import * as fs43 from "fs";
63836
- import * as path55 from "path";
64390
+ import * as fs44 from "fs";
64391
+ import * as path56 from "path";
63837
64392
  function getDeclaredScope(taskId, directory) {
63838
64393
  try {
63839
- const planPath = path55.join(directory, ".swarm", "plan.json");
63840
- if (!fs43.existsSync(planPath))
64394
+ const planPath = path56.join(directory, ".swarm", "plan.json");
64395
+ if (!fs44.existsSync(planPath))
63841
64396
  return null;
63842
- const raw = fs43.readFileSync(planPath, "utf-8");
64397
+ const raw = fs44.readFileSync(planPath, "utf-8");
63843
64398
  const plan = JSON.parse(raw);
63844
64399
  for (const phase of plan.phases ?? []) {
63845
64400
  for (const task of phase.tasks ?? []) {
@@ -63951,7 +64506,7 @@ var TIER_3_PATTERNS = [
63951
64506
  ];
63952
64507
  function matchesTier3Pattern(files) {
63953
64508
  for (const file3 of files) {
63954
- const fileName = path56.basename(file3);
64509
+ const fileName = path57.basename(file3);
63955
64510
  for (const pattern of TIER_3_PATTERNS) {
63956
64511
  if (pattern.test(fileName)) {
63957
64512
  return true;
@@ -63973,8 +64528,8 @@ function checkReviewerGate(taskId, workingDirectory) {
63973
64528
  if (hasActiveTurboMode2()) {
63974
64529
  const resolvedDir2 = workingDirectory;
63975
64530
  try {
63976
- const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
63977
- const planRaw = fs44.readFileSync(planPath, "utf-8");
64531
+ const planPath = path57.join(resolvedDir2, ".swarm", "plan.json");
64532
+ const planRaw = fs45.readFileSync(planPath, "utf-8");
63978
64533
  const plan = JSON.parse(planRaw);
63979
64534
  for (const planPhase of plan.phases ?? []) {
63980
64535
  for (const task of planPhase.tasks ?? []) {
@@ -63993,8 +64548,8 @@ function checkReviewerGate(taskId, workingDirectory) {
63993
64548
  }
63994
64549
  const resolvedDir = workingDirectory;
63995
64550
  try {
63996
- const evidencePath = path56.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
63997
- const raw = fs44.readFileSync(evidencePath, "utf-8");
64551
+ const evidencePath = path57.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
64552
+ const raw = fs45.readFileSync(evidencePath, "utf-8");
63998
64553
  const evidence = JSON.parse(raw);
63999
64554
  if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
64000
64555
  const allGatesMet = evidence.required_gates.every((gate) => evidence.gates[gate] != null);
@@ -64034,8 +64589,8 @@ function checkReviewerGate(taskId, workingDirectory) {
64034
64589
  }
64035
64590
  try {
64036
64591
  const resolvedDir2 = workingDirectory;
64037
- const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
64038
- const planRaw = fs44.readFileSync(planPath, "utf-8");
64592
+ const planPath = path57.join(resolvedDir2, ".swarm", "plan.json");
64593
+ const planRaw = fs45.readFileSync(planPath, "utf-8");
64039
64594
  const plan = JSON.parse(planRaw);
64040
64595
  for (const planPhase of plan.phases ?? []) {
64041
64596
  for (const task of planPhase.tasks ?? []) {
@@ -64216,8 +64771,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
64216
64771
  };
64217
64772
  }
64218
64773
  }
64219
- normalizedDir = path56.normalize(args2.working_directory);
64220
- const pathParts = normalizedDir.split(path56.sep);
64774
+ normalizedDir = path57.normalize(args2.working_directory);
64775
+ const pathParts = normalizedDir.split(path57.sep);
64221
64776
  if (pathParts.includes("..")) {
64222
64777
  return {
64223
64778
  success: false,
@@ -64227,11 +64782,11 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
64227
64782
  ]
64228
64783
  };
64229
64784
  }
64230
- const resolvedDir = path56.resolve(normalizedDir);
64785
+ const resolvedDir = path57.resolve(normalizedDir);
64231
64786
  try {
64232
- const realPath = fs44.realpathSync(resolvedDir);
64233
- const planPath = path56.join(realPath, ".swarm", "plan.json");
64234
- if (!fs44.existsSync(planPath)) {
64787
+ const realPath = fs45.realpathSync(resolvedDir);
64788
+ const planPath = path57.join(realPath, ".swarm", "plan.json");
64789
+ if (!fs45.existsSync(planPath)) {
64235
64790
  return {
64236
64791
  success: false,
64237
64792
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -64453,7 +65008,7 @@ var OpenCodeSwarm = async (ctx) => {
64453
65008
  const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
64454
65009
  preflightTriggerManager = new PTM(automationConfig);
64455
65010
  const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
64456
- const swarmDir = path57.resolve(ctx.directory, ".swarm");
65011
+ const swarmDir = path58.resolve(ctx.directory, ".swarm");
64457
65012
  statusArtifact = new ASA(swarmDir);
64458
65013
  statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
64459
65014
  if (automationConfig.capabilities?.evidence_auto_summaries === true) {
@@ -64745,7 +65300,9 @@ var OpenCodeSwarm = async (ctx) => {
64745
65300
  await safeHook(activityHooks.toolBefore)(input, output);
64746
65301
  },
64747
65302
  "tool.execute.after": async (input, output) => {
64748
- console.debug("[hook-chain] toolAfter start sessionID=%s agent=%s tool=%s", input.sessionID, input.agent, input.tool?.name);
65303
+ if (process.env.DEBUG_SWARM) {
65304
+ console.debug("[hook-chain] toolAfter start sessionID=%s agent=%s tool=%s", input.sessionID, input.agent, input.tool?.name);
65305
+ }
64749
65306
  await activityHooks.toolAfter(input, output);
64750
65307
  await guardrailsHooks.toolAfter(input, output);
64751
65308
  await safeHook(delegationLedgerHook.toolAfter)(input, output);
@@ -64805,7 +65362,9 @@ var OpenCodeSwarm = async (ctx) => {
64805
65362
  deleteStoredInputArgs(input.callID);
64806
65363
  },
64807
65364
  "chat.message": safeHook(async (input, output) => {
64808
- console.debug("[session] chat.message sessionID=%s agent=%s", input.sessionID, input.agent);
65365
+ if (process.env.DEBUG_SWARM) {
65366
+ console.debug("[session] chat.message sessionID=%s agent=%s", input.sessionID, input.agent);
65367
+ }
64809
65368
  await delegationHandler(input, output);
64810
65369
  }),
64811
65370
  automation: automationManager