opencode-swarm 6.29.1 → 6.29.2

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
@@ -14217,7 +14217,7 @@ var init_evidence_schema = __esm(() => {
14217
14217
  });
14218
14218
  RetrospectiveEvidenceSchema = BaseEvidenceSchema.extend({
14219
14219
  type: exports_external.literal("retrospective"),
14220
- phase_number: exports_external.number().int().min(0).max(99),
14220
+ phase_number: exports_external.number().int().min(1).max(99),
14221
14221
  total_tool_calls: exports_external.number().int().min(0).max(9999),
14222
14222
  coder_revisions: exports_external.number().int().min(0).max(999),
14223
14223
  reviewer_rejections: exports_external.number().int().min(0).max(999),
@@ -14882,7 +14882,7 @@ var init_schema = __esm(() => {
14882
14882
  });
14883
14883
  IncrementalVerifyConfigSchema = exports_external.object({
14884
14884
  enabled: exports_external.boolean().default(true),
14885
- command: exports_external.string().nullable().default(null),
14885
+ command: exports_external.union([exports_external.string(), exports_external.array(exports_external.string())]).nullable().default(null),
14886
14886
  timeoutMs: exports_external.number().int().min(1000).max(300000).default(30000),
14887
14887
  triggerAgents: exports_external.array(exports_external.string()).default(["coder"])
14888
14888
  });
@@ -37601,11 +37601,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
37601
37601
  throw toThrow;
37602
37602
  }, "quit_");
37603
37603
  var scriptDirectory = "";
37604
- function locateFile(path45) {
37604
+ function locateFile(path46) {
37605
37605
  if (Module["locateFile"]) {
37606
- return Module["locateFile"](path45, scriptDirectory);
37606
+ return Module["locateFile"](path46, scriptDirectory);
37607
37607
  }
37608
- return scriptDirectory + path45;
37608
+ return scriptDirectory + path46;
37609
37609
  }
37610
37610
  __name(locateFile, "locateFile");
37611
37611
  var readAsync, readBinary;
@@ -39353,7 +39353,7 @@ var init_runtime = __esm(() => {
39353
39353
  });
39354
39354
 
39355
39355
  // src/index.ts
39356
- import * as path55 from "path";
39356
+ import * as path56 from "path";
39357
39357
 
39358
39358
  // src/agents/index.ts
39359
39359
  init_config();
@@ -40183,6 +40183,7 @@ Activates when: user asks to "specify", "define requirements", "write a spec", o
40183
40183
  - Refine \u2192 delegate to MODE: CLARIFY-SPEC
40184
40184
  - If NO: proceed to generation (step 2)
40185
40185
  - If this is called from the stale spec archival path (MODE: PLAN option 1) \u2014 archival was already completed; skip this check and proceed directly to generation (step 2)
40186
+ 1b. Run CODEBASE REALITY CHECK for any codebase references mentioned by the user or implied by the feature. Skip if work is purely greenfield (no existing codebase to check). Report discrepancies before proceeding to explorer.
40186
40187
  2. Delegate to \`{{AGENT_PREFIX}}explorer\` to scan the codebase for relevant context (existing patterns, related code, affected areas).
40187
40188
  3. Delegate to \`{{AGENT_PREFIX}}sme\` for domain research on the feature area to surface known constraints, best practices, and integration concerns.
40188
40189
  4. Generate \`.swarm/spec.md\` capturing:
@@ -40209,22 +40210,23 @@ Each requirement must be independently testable.
40209
40210
  Prefer informed defaults over asking the user \u2014 use \`[NEEDS CLARIFICATION]\` only when uncertainty could change scope, security, or core behavior.
40210
40211
 
40211
40212
  EXTERNAL PLAN IMPORT PATH \u2014 when the user provides an existing implementation plan (markdown content, pasted text, or a reference to a file):
40212
- 1. Read and parse the provided plan content.
40213
- 2. Reverse-engineer \`.swarm/spec.md\` from the plan:
40213
+ 1. Run CODEBASE REALITY CHECK scoped to every file, function, API, and behavioral assumption in the provided plan. Report discrepancies to user before proceeding.
40214
+ 2. Read and parse the provided plan content.
40215
+ 3. Reverse-engineer \`.swarm/spec.md\` from the plan:
40214
40216
  - Derive FR-### functional requirements from task descriptions
40215
40217
  - Derive SC-### success criteria from acceptance criteria in tasks
40216
40218
  - Identify user scenarios from the plan's phase/feature groupings
40217
40219
  - Surface implicit assumptions as \`[NEEDS CLARIFICATION]\` markers
40218
- 3. Validate the provided plan against swarm task format requirements:
40220
+ 4. Validate the provided plan against swarm task format requirements:
40219
40221
  - Every task should have FILE, TASK, CONSTRAINT, and ACCEPTANCE fields
40220
40222
  - No task should touch more than 2 files
40221
40223
  - No compound verbs in TASK lines ("implement X and add Y" = 2 tasks)
40222
40224
  - Dependencies should be declared explicitly
40223
40225
  - Phase structure should match \`.swarm/plan.md\` format
40224
- 4. Report gaps, format issues, and improvement suggestions to the user.
40225
- 5. Ask: "Should I also flesh out any areas that seem underspecified?"
40226
+ 5. Report gaps, format issues, and improvement suggestions to the user.
40227
+ 6. Ask: "Should I also flesh out any areas that seem underspecified?"
40226
40228
  - If yes: delegate to \`{{AGENT_PREFIX}}sme\` for targeted research on weak areas, then propose specific improvements.
40227
- 6. Output: both a \`.swarm/spec.md\` (extracted from the plan) and a validated version of the user's plan.
40229
+ 7. Output: both a \`.swarm/spec.md\` (extracted from the plan) and a validated version of the user's plan.
40228
40230
 
40229
40231
  EXTERNAL PLAN RULES:
40230
40232
  - Surface ALL changes as suggestions \u2014 do not silently rewrite the user's plan.
@@ -40327,6 +40329,34 @@ User directives carried forward: {list any persistent directives}
40327
40329
 
40328
40330
  This briefing is a HARD REQUIREMENT for ALL phases. Skipping it is a process violation.
40329
40331
 
40332
+ ### CODEBASE REALITY CHECK (Required Before Speccing or Planning)
40333
+
40334
+ Before any spec generation, plan creation, or plan ingestion begins, the Architect must dispatch the Explorer agent in targeted, scoped chunks \u2014 one per logical area of the codebase referenced by the work (e.g., per module, per hook, per config surface). Each chunk must be explored with full depth rather than a broad surface pass.
40335
+
40336
+ For each scoped chunk, Explorer must determine:
40337
+ - Does this file/module/function already exist?
40338
+ - If it exists, what is its current state? Does it already implement any part of what the plan or spec describes?
40339
+ - Is the plan's or user's assumption about the current state accurate? Flag any discrepancy between what is expected and what actually exists.
40340
+ - Has any portion of this work already been applied (partially or fully) in a prior session or commit?
40341
+
40342
+ Explorer outputs a CODEBASE REALITY REPORT before any other agent proceeds. The report must list every referenced item with one of:
40343
+ NOT STARTED | PARTIALLY DONE | ALREADY COMPLETE | ASSUMPTION INCORRECT
40344
+
40345
+ Format:
40346
+ REALITY CHECK: [N] references verified, [M] discrepancies found.
40347
+ \u2713 src/hooks/incremental-verify.ts \u2014 exists, line 69 confirmed Bun.spawn
40348
+ \u2717 src/services/status-service.ts \u2014 ASSUMPTION INCORRECT: compactionCount is no longer hardcoded (fixed in v6.29.1)
40349
+ \u2713 src/config/evidence-schema.ts:107 \u2014 confirmed phase_number min(0)
40350
+
40351
+ No implementation agent (coder, reviewer, test-engineer) may begin until this report is finalized.
40352
+
40353
+ This check fires automatically in:
40354
+ - MODE: SPECIFY \u2014 before explorer dispatch for context (step 2)
40355
+ - MODE: PLAN \u2014 before plan generation or validation
40356
+ - EXTERNAL PLAN IMPORT PATH \u2014 before parsing the provided plan
40357
+
40358
+ GREENFIELD EXEMPTION: If the work is purely greenfield (new project, no existing codebase references), skip this check.
40359
+
40330
40360
  ### MODE: PLAN
40331
40361
 
40332
40362
  SPEC GATE (soft \u2014 check before planning):
@@ -40356,6 +40386,8 @@ SPEC GATE (soft \u2014 check before planning):
40356
40386
 
40357
40387
  This is a SOFT gate. When the user chooses "Skip and plan directly", proceed to the steps below exactly as before \u2014 do NOT modify any planning behavior.
40358
40388
 
40389
+ Run CODEBASE REALITY CHECK scoped to codebase elements referenced in spec.md or user constraints. Discrepancies must be reflected in the generated plan.
40390
+
40359
40391
  Use the \`save_plan\` tool to create the implementation plan. Required parameters:
40360
40392
  - \`title\`: The real project name from the spec (NOT a placeholder like [Project])
40361
40393
  - \`swarm_id\`: The swarm identifier (e.g. "mega", "local", "paid")
@@ -52432,53 +52464,110 @@ function createDarkMatterDetectorHook(directory) {
52432
52464
  // src/hooks/incremental-verify.ts
52433
52465
  import * as fs20 from "fs";
52434
52466
  import * as path32 from "path";
52467
+
52468
+ // src/hooks/spawn-helper.ts
52469
+ import { spawn } from "child_process";
52470
+ function spawnAsync(command, cwd, timeoutMs) {
52471
+ return new Promise((resolve11) => {
52472
+ try {
52473
+ const [cmd, ...args2] = command;
52474
+ const proc = spawn(cmd, args2, { cwd, stdio: ["ignore", "pipe", "pipe"] });
52475
+ let stdout = "";
52476
+ let stderr = "";
52477
+ let done = false;
52478
+ proc.stdout.on("data", (d) => {
52479
+ stdout += d;
52480
+ });
52481
+ proc.stderr.on("data", (d) => {
52482
+ stderr += d;
52483
+ });
52484
+ const timer = setTimeout(() => {
52485
+ if (done)
52486
+ return;
52487
+ done = true;
52488
+ try {
52489
+ proc.stdout.destroy();
52490
+ } catch {}
52491
+ try {
52492
+ proc.stderr.destroy();
52493
+ } catch {}
52494
+ try {
52495
+ proc.kill();
52496
+ } catch {}
52497
+ resolve11(null);
52498
+ }, timeoutMs);
52499
+ proc.on("close", (code) => {
52500
+ if (done)
52501
+ return;
52502
+ done = true;
52503
+ clearTimeout(timer);
52504
+ resolve11({ exitCode: code ?? 1, stdout, stderr });
52505
+ });
52506
+ proc.on("error", () => {
52507
+ if (done)
52508
+ return;
52509
+ done = true;
52510
+ clearTimeout(timer);
52511
+ resolve11(null);
52512
+ });
52513
+ } catch {
52514
+ resolve11(null);
52515
+ }
52516
+ });
52517
+ }
52518
+
52519
+ // src/hooks/incremental-verify.ts
52520
+ var emittedSkipAdvisories = new Set;
52435
52521
  function detectTypecheckCommand(projectDir) {
52436
52522
  const pkgPath = path32.join(projectDir, "package.json");
52437
- if (!fs20.existsSync(pkgPath))
52438
- return null;
52439
- try {
52440
- const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf8"));
52441
- const scripts = pkg.scripts;
52442
- if (scripts?.typecheck)
52443
- return ["bun", "run", "typecheck"];
52444
- if (scripts?.["type-check"])
52445
- return ["bun", "run", "type-check"];
52446
- const deps = {
52447
- ...pkg.dependencies,
52448
- ...pkg.devDependencies
52449
- };
52450
- if (!deps?.typescript && !fs20.existsSync(path32.join(projectDir, "tsconfig.json"))) {
52523
+ if (fs20.existsSync(pkgPath)) {
52524
+ try {
52525
+ const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf8"));
52526
+ const scripts = pkg.scripts;
52527
+ if (scripts?.typecheck)
52528
+ return { command: ["bun", "run", "typecheck"], language: "typescript" };
52529
+ if (scripts?.["type-check"])
52530
+ return {
52531
+ command: ["bun", "run", "type-check"],
52532
+ language: "typescript"
52533
+ };
52534
+ const deps = {
52535
+ ...pkg.dependencies,
52536
+ ...pkg.devDependencies
52537
+ };
52538
+ if (!deps?.typescript && !fs20.existsSync(path32.join(projectDir, "tsconfig.json"))) {
52539
+ return null;
52540
+ }
52541
+ return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
52542
+ } catch {
52451
52543
  return null;
52452
52544
  }
52453
- return ["npx", "tsc", "--noEmit"];
52454
- } catch {
52455
- return null;
52456
52545
  }
52457
- }
52458
- async function runWithTimeout(command, cwd, timeoutMs) {
52546
+ if (fs20.existsSync(path32.join(projectDir, "go.mod"))) {
52547
+ return { command: ["go", "vet", "./..."], language: "go" };
52548
+ }
52549
+ if (fs20.existsSync(path32.join(projectDir, "Cargo.toml"))) {
52550
+ return { command: ["cargo", "check"], language: "rust" };
52551
+ }
52552
+ if (fs20.existsSync(path32.join(projectDir, "pyproject.toml")) || fs20.existsSync(path32.join(projectDir, "requirements.txt")) || fs20.existsSync(path32.join(projectDir, "setup.py"))) {
52553
+ return { command: null, language: "python" };
52554
+ }
52459
52555
  try {
52460
- const proc = Bun.spawn(command, {
52461
- cwd,
52462
- stdout: "pipe",
52463
- stderr: "pipe"
52464
- });
52465
- const timeoutHandle = setTimeout(() => {
52466
- try {
52467
- proc.kill();
52468
- } catch {}
52469
- }, timeoutMs);
52470
- try {
52471
- const [exitCode, stderr] = await Promise.all([
52472
- proc.exited,
52473
- new Response(proc.stderr).text()
52474
- ]);
52475
- return { exitCode, stderr };
52476
- } finally {
52477
- clearTimeout(timeoutHandle);
52556
+ const entries = fs20.readdirSync(projectDir);
52557
+ if (entries.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
52558
+ return {
52559
+ command: ["dotnet", "build", "--no-restore"],
52560
+ language: "csharp"
52561
+ };
52478
52562
  }
52479
- } catch {
52563
+ } catch {}
52564
+ return null;
52565
+ }
52566
+ async function runWithTimeout(command, cwd, timeoutMs) {
52567
+ const result = await spawnAsync(command, cwd, timeoutMs);
52568
+ if (result === null)
52480
52569
  return null;
52481
- }
52570
+ return { exitCode: result.exitCode, stderr: result.stderr };
52482
52571
  }
52483
52572
  function createIncrementalVerifyHook(config3, projectDir, injectMessage) {
52484
52573
  return {
@@ -52493,10 +52582,27 @@ function createIncrementalVerifyHook(config3, projectDir, injectMessage) {
52493
52582
  if (!config3.triggerAgents.includes(agentName) && !config3.triggerAgents.includes(subagentType)) {
52494
52583
  return;
52495
52584
  }
52496
- const command = config3.command != null ? config3.command.split(" ") : detectTypecheckCommand(projectDir);
52497
- if (!command)
52585
+ let commandToRun = null;
52586
+ if (config3.command != null) {
52587
+ commandToRun = Array.isArray(config3.command) ? config3.command : config3.command.split(" ");
52588
+ } else {
52589
+ const detected = detectTypecheckCommand(projectDir);
52590
+ if (detected === null) {
52591
+ return;
52592
+ }
52593
+ if (detected.command === null) {
52594
+ const dedupKey = `${input.sessionID}:${detected.language}`;
52595
+ if (!emittedSkipAdvisories.has(dedupKey)) {
52596
+ emittedSkipAdvisories.add(dedupKey);
52597
+ injectMessage(input.sessionID, `POST-CODER CHECK SKIPPED: ${detected.language} project detected but no default checker available. Set incremental_verify.command in .swarm/config.json to enable.`);
52598
+ }
52599
+ return;
52600
+ }
52601
+ commandToRun = detected.command;
52602
+ }
52603
+ if (commandToRun === null)
52498
52604
  return;
52499
- const result = await runWithTimeout(command, projectDir, config3.timeoutMs);
52605
+ const result = await runWithTimeout(commandToRun, projectDir, config3.timeoutMs);
52500
52606
  if (result === null) {
52501
52607
  return;
52502
52608
  }
@@ -53422,6 +53528,8 @@ ${cachedInjectionText}`;
53422
53528
  }
53423
53529
 
53424
53530
  // src/hooks/slop-detector.ts
53531
+ import * as fs22 from "fs";
53532
+ import * as path35 from "path";
53425
53533
  var WRITE_EDIT_TOOLS = new Set([
53426
53534
  "write",
53427
53535
  "edit",
@@ -53432,7 +53540,7 @@ function countMatches(text, pattern) {
53432
53540
  return (text.match(pattern) ?? []).length;
53433
53541
  }
53434
53542
  function checkAbstractionBloat(content, threshold) {
53435
- const newClasses = countMatches(content, /^\+.*\bclass\s+\w+/gm);
53543
+ const newClasses = countMatches(content, /^\+.*\b(?:class|struct|impl)\s+\w+/gm);
53436
53544
  if (newClasses >= threshold) {
53437
53545
  return {
53438
53546
  type: "abstraction_bloat",
@@ -53442,8 +53550,8 @@ function checkAbstractionBloat(content, threshold) {
53442
53550
  return null;
53443
53551
  }
53444
53552
  function checkCommentStrip(content, threshold) {
53445
- const removedComments = countMatches(content, /^-\s*\/[/*]/gm);
53446
- const addedComments = countMatches(content, /^\+\s*\/[/*]/gm);
53553
+ const removedComments = countMatches(content, /^-\s*(?:\/[/*]|#|--)/gm);
53554
+ const addedComments = countMatches(content, /^\+\s*(?:\/[/*]|#|--)/gm);
53447
53555
  if (removedComments >= threshold && addedComments === 0) {
53448
53556
  return {
53449
53557
  type: "comment_strip",
@@ -53463,8 +53571,33 @@ function checkBoilerplateExplosion(content, taskDescription, threshold) {
53463
53571
  }
53464
53572
  return null;
53465
53573
  }
53466
- async function checkDeadExports(content, projectDir, startTime) {
53467
- const exportMatches = content.matchAll(/^(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
53574
+ function walkFiles(dir, exts, deadline) {
53575
+ const results = [];
53576
+ try {
53577
+ for (const entry of fs22.readdirSync(dir, { withFileTypes: true })) {
53578
+ if (deadline !== undefined && Date.now() > deadline)
53579
+ break;
53580
+ if (entry.isSymbolicLink())
53581
+ continue;
53582
+ const full = path35.join(dir, entry.name);
53583
+ if (entry.isDirectory()) {
53584
+ if (entry.name === "node_modules" || entry.name === ".git")
53585
+ continue;
53586
+ results.push(...walkFiles(full, exts, deadline));
53587
+ } else if (entry.isFile()) {
53588
+ if (exts.some((ext) => entry.name.endsWith(ext))) {
53589
+ results.push(full);
53590
+ }
53591
+ }
53592
+ }
53593
+ } catch {}
53594
+ return results;
53595
+ }
53596
+ function checkDeadExports(content, projectDir, startTime) {
53597
+ const hasPackageJson = fs22.existsSync(path35.join(projectDir, "package.json"));
53598
+ if (!hasPackageJson)
53599
+ return null;
53600
+ const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
53468
53601
  const newExports = [];
53469
53602
  for (const match of exportMatches) {
53470
53603
  if (match[1])
@@ -53472,19 +53605,19 @@ async function checkDeadExports(content, projectDir, startTime) {
53472
53605
  }
53473
53606
  if (newExports.length === 0)
53474
53607
  return null;
53608
+ const files = walkFiles(projectDir, [".ts", ".tsx", ".js", ".jsx"], startTime + 480);
53475
53609
  const deadExports = [];
53476
53610
  for (const name2 of newExports) {
53477
53611
  if (Date.now() - startTime > 480)
53478
53612
  break;
53479
53613
  try {
53480
53614
  const importPattern = new RegExp(`\\bimport\\b[^;]*\\b${name2}\\b`, "g");
53481
- const glob = new Bun.Glob(`src/**/*.ts`);
53482
53615
  let found = false;
53483
- for await (const file3 of glob.scan(projectDir)) {
53616
+ for (const file3 of files) {
53484
53617
  if (found || Date.now() - startTime > 480)
53485
53618
  break;
53486
53619
  try {
53487
- const text = await Bun.file(`${projectDir}/${file3}`).text();
53620
+ const text = fs22.readFileSync(file3, "utf-8");
53488
53621
  if (importPattern.test(text))
53489
53622
  found = true;
53490
53623
  importPattern.lastIndex = 0;
@@ -53538,7 +53671,7 @@ function createSlopDetectorHook(config3, projectDir, injectSystemMessage) {
53538
53671
  } catch {}
53539
53672
  if (Date.now() - startTime < 400) {
53540
53673
  try {
53541
- const dead = await checkDeadExports(content, projectDir, startTime);
53674
+ const dead = checkDeadExports(content, projectDir, startTime);
53542
53675
  if (dead)
53543
53676
  findings.push(dead);
53544
53677
  } catch {}
@@ -53557,7 +53690,7 @@ Review before proceeding.`;
53557
53690
 
53558
53691
  // src/hooks/steering-consumed.ts
53559
53692
  init_utils2();
53560
- import * as fs22 from "fs";
53693
+ import * as fs23 from "fs";
53561
53694
  function recordSteeringConsumed(directory, directiveId) {
53562
53695
  try {
53563
53696
  const eventsPath = validateSwarmPath(directory, "events.jsonl");
@@ -53566,7 +53699,7 @@ function recordSteeringConsumed(directory, directiveId) {
53566
53699
  directiveId,
53567
53700
  timestamp: new Date().toISOString()
53568
53701
  };
53569
- fs22.appendFileSync(eventsPath, `${JSON.stringify(event)}
53702
+ fs23.appendFileSync(eventsPath, `${JSON.stringify(event)}
53570
53703
  `, "utf-8");
53571
53704
  } catch {}
53572
53705
  }
@@ -53611,7 +53744,7 @@ init_config_doctor();
53611
53744
 
53612
53745
  // src/session/snapshot-reader.ts
53613
53746
  init_utils2();
53614
- import path35 from "path";
53747
+ import path36 from "path";
53615
53748
  var VALID_TASK_WORKFLOW_STATES = [
53616
53749
  "idle",
53617
53750
  "coder_delegated",
@@ -53736,7 +53869,7 @@ function rehydrateState(snapshot) {
53736
53869
  async function reconcileTaskStatesFromPlan(directory) {
53737
53870
  let raw;
53738
53871
  try {
53739
- raw = await Bun.file(path35.join(directory, ".swarm/plan.json")).text();
53872
+ raw = await Bun.file(path36.join(directory, ".swarm/plan.json")).text();
53740
53873
  } catch {
53741
53874
  return;
53742
53875
  }
@@ -53958,8 +54091,8 @@ var build_check = createSwarmTool({
53958
54091
  // src/tools/check-gate-status.ts
53959
54092
  init_dist();
53960
54093
  init_create_tool();
53961
- import * as fs23 from "fs";
53962
- import * as path36 from "path";
54094
+ import * as fs24 from "fs";
54095
+ import * as path37 from "path";
53963
54096
  var EVIDENCE_DIR = ".swarm/evidence";
53964
54097
  var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
53965
54098
  function isValidTaskId3(taskId) {
@@ -53976,18 +54109,18 @@ function isValidTaskId3(taskId) {
53976
54109
  return TASK_ID_PATTERN2.test(taskId);
53977
54110
  }
53978
54111
  function isPathWithinSwarm(filePath, workspaceRoot) {
53979
- const normalizedWorkspace = path36.resolve(workspaceRoot);
53980
- const swarmPath = path36.join(normalizedWorkspace, ".swarm", "evidence");
53981
- const normalizedPath = path36.resolve(filePath);
54112
+ const normalizedWorkspace = path37.resolve(workspaceRoot);
54113
+ const swarmPath = path37.join(normalizedWorkspace, ".swarm", "evidence");
54114
+ const normalizedPath = path37.resolve(filePath);
53982
54115
  return normalizedPath.startsWith(swarmPath);
53983
54116
  }
53984
54117
  function readEvidenceFile(evidencePath) {
53985
- if (!fs23.existsSync(evidencePath)) {
54118
+ if (!fs24.existsSync(evidencePath)) {
53986
54119
  return null;
53987
54120
  }
53988
54121
  let content;
53989
54122
  try {
53990
- content = fs23.readFileSync(evidencePath, "utf-8");
54123
+ content = fs24.readFileSync(evidencePath, "utf-8");
53991
54124
  } catch {
53992
54125
  return null;
53993
54126
  }
@@ -54039,7 +54172,7 @@ var check_gate_status = createSwarmTool({
54039
54172
  };
54040
54173
  return JSON.stringify(errorResult, null, 2);
54041
54174
  }
54042
- const evidencePath = path36.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
54175
+ const evidencePath = path37.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
54043
54176
  if (!isPathWithinSwarm(evidencePath, directory)) {
54044
54177
  const errorResult = {
54045
54178
  taskId: taskIdInput,
@@ -54099,8 +54232,8 @@ var check_gate_status = createSwarmTool({
54099
54232
  init_tool();
54100
54233
  init_create_tool();
54101
54234
  import { spawnSync } from "child_process";
54102
- import * as fs24 from "fs";
54103
- import * as path37 from "path";
54235
+ import * as fs25 from "fs";
54236
+ import * as path38 from "path";
54104
54237
  var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
54105
54238
  var MAX_LABEL_LENGTH = 100;
54106
54239
  var GIT_TIMEOUT_MS = 30000;
@@ -54151,13 +54284,13 @@ function validateLabel(label) {
54151
54284
  return null;
54152
54285
  }
54153
54286
  function getCheckpointLogPath(directory) {
54154
- return path37.join(directory, CHECKPOINT_LOG_PATH);
54287
+ return path38.join(directory, CHECKPOINT_LOG_PATH);
54155
54288
  }
54156
54289
  function readCheckpointLog(directory) {
54157
54290
  const logPath = getCheckpointLogPath(directory);
54158
54291
  try {
54159
- if (fs24.existsSync(logPath)) {
54160
- const content = fs24.readFileSync(logPath, "utf-8");
54292
+ if (fs25.existsSync(logPath)) {
54293
+ const content = fs25.readFileSync(logPath, "utf-8");
54161
54294
  const parsed = JSON.parse(content);
54162
54295
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
54163
54296
  return { version: 1, checkpoints: [] };
@@ -54169,13 +54302,13 @@ function readCheckpointLog(directory) {
54169
54302
  }
54170
54303
  function writeCheckpointLog(log2, directory) {
54171
54304
  const logPath = getCheckpointLogPath(directory);
54172
- const dir = path37.dirname(logPath);
54173
- if (!fs24.existsSync(dir)) {
54174
- fs24.mkdirSync(dir, { recursive: true });
54305
+ const dir = path38.dirname(logPath);
54306
+ if (!fs25.existsSync(dir)) {
54307
+ fs25.mkdirSync(dir, { recursive: true });
54175
54308
  }
54176
54309
  const tempPath = `${logPath}.tmp`;
54177
- fs24.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
54178
- fs24.renameSync(tempPath, logPath);
54310
+ fs25.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
54311
+ fs25.renameSync(tempPath, logPath);
54179
54312
  }
54180
54313
  function gitExec(args2) {
54181
54314
  const result = spawnSync("git", args2, {
@@ -54376,8 +54509,8 @@ var checkpoint = createSwarmTool({
54376
54509
  // src/tools/complexity-hotspots.ts
54377
54510
  init_dist();
54378
54511
  init_create_tool();
54379
- import * as fs25 from "fs";
54380
- import * as path38 from "path";
54512
+ import * as fs26 from "fs";
54513
+ import * as path39 from "path";
54381
54514
  var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
54382
54515
  var DEFAULT_DAYS = 90;
54383
54516
  var DEFAULT_TOP_N = 20;
@@ -54506,11 +54639,11 @@ function estimateComplexity(content) {
54506
54639
  }
54507
54640
  function getComplexityForFile(filePath) {
54508
54641
  try {
54509
- const stat2 = fs25.statSync(filePath);
54642
+ const stat2 = fs26.statSync(filePath);
54510
54643
  if (stat2.size > MAX_FILE_SIZE_BYTES2) {
54511
54644
  return null;
54512
54645
  }
54513
- const content = fs25.readFileSync(filePath, "utf-8");
54646
+ const content = fs26.readFileSync(filePath, "utf-8");
54514
54647
  return estimateComplexity(content);
54515
54648
  } catch {
54516
54649
  return null;
@@ -54521,7 +54654,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
54521
54654
  const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
54522
54655
  const filteredChurn = new Map;
54523
54656
  for (const [file3, count] of churnMap) {
54524
- const ext = path38.extname(file3).toLowerCase();
54657
+ const ext = path39.extname(file3).toLowerCase();
54525
54658
  if (extSet.has(ext)) {
54526
54659
  filteredChurn.set(file3, count);
54527
54660
  }
@@ -54531,8 +54664,8 @@ async function analyzeHotspots(days, topN, extensions, directory) {
54531
54664
  let analyzedFiles = 0;
54532
54665
  for (const [file3, churnCount] of filteredChurn) {
54533
54666
  let fullPath = file3;
54534
- if (!fs25.existsSync(fullPath)) {
54535
- fullPath = path38.join(cwd, file3);
54667
+ if (!fs26.existsSync(fullPath)) {
54668
+ fullPath = path39.join(cwd, file3);
54536
54669
  }
54537
54670
  const complexity = getComplexityForFile(fullPath);
54538
54671
  if (complexity !== null) {
@@ -54679,8 +54812,8 @@ var complexity_hotspots = createSwarmTool({
54679
54812
  });
54680
54813
  // src/tools/declare-scope.ts
54681
54814
  init_tool();
54682
- import * as fs26 from "fs";
54683
- import * as path39 from "path";
54815
+ import * as fs27 from "fs";
54816
+ import * as path40 from "path";
54684
54817
  init_create_tool();
54685
54818
  function validateTaskIdFormat(taskId) {
54686
54819
  const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
@@ -54759,8 +54892,8 @@ async function executeDeclareScope(args2, fallbackDir) {
54759
54892
  };
54760
54893
  }
54761
54894
  }
54762
- normalizedDir = path39.normalize(args2.working_directory);
54763
- const pathParts = normalizedDir.split(path39.sep);
54895
+ normalizedDir = path40.normalize(args2.working_directory);
54896
+ const pathParts = normalizedDir.split(path40.sep);
54764
54897
  if (pathParts.includes("..")) {
54765
54898
  return {
54766
54899
  success: false,
@@ -54770,11 +54903,11 @@ async function executeDeclareScope(args2, fallbackDir) {
54770
54903
  ]
54771
54904
  };
54772
54905
  }
54773
- const resolvedDir = path39.resolve(normalizedDir);
54906
+ const resolvedDir = path40.resolve(normalizedDir);
54774
54907
  try {
54775
- const realPath = fs26.realpathSync(resolvedDir);
54776
- const planPath2 = path39.join(realPath, ".swarm", "plan.json");
54777
- if (!fs26.existsSync(planPath2)) {
54908
+ const realPath = fs27.realpathSync(resolvedDir);
54909
+ const planPath2 = path40.join(realPath, ".swarm", "plan.json");
54910
+ if (!fs27.existsSync(planPath2)) {
54778
54911
  return {
54779
54912
  success: false,
54780
54913
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -54794,8 +54927,8 @@ async function executeDeclareScope(args2, fallbackDir) {
54794
54927
  }
54795
54928
  }
54796
54929
  const directory = normalizedDir ?? fallbackDir ?? process.cwd();
54797
- const planPath = path39.resolve(directory, ".swarm", "plan.json");
54798
- if (!fs26.existsSync(planPath)) {
54930
+ const planPath = path40.resolve(directory, ".swarm", "plan.json");
54931
+ if (!fs27.existsSync(planPath)) {
54799
54932
  return {
54800
54933
  success: false,
54801
54934
  message: "No plan found",
@@ -54804,7 +54937,7 @@ async function executeDeclareScope(args2, fallbackDir) {
54804
54937
  }
54805
54938
  let planContent;
54806
54939
  try {
54807
- planContent = JSON.parse(fs26.readFileSync(planPath, "utf-8"));
54940
+ planContent = JSON.parse(fs27.readFileSync(planPath, "utf-8"));
54808
54941
  } catch {
54809
54942
  return {
54810
54943
  success: false,
@@ -54884,20 +55017,20 @@ function validateBase(base) {
54884
55017
  function validatePaths(paths) {
54885
55018
  if (!paths)
54886
55019
  return null;
54887
- for (const path40 of paths) {
54888
- if (!path40 || path40.length === 0) {
55020
+ for (const path41 of paths) {
55021
+ if (!path41 || path41.length === 0) {
54889
55022
  return "empty path not allowed";
54890
55023
  }
54891
- if (path40.length > MAX_PATH_LENGTH) {
55024
+ if (path41.length > MAX_PATH_LENGTH) {
54892
55025
  return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
54893
55026
  }
54894
- if (SHELL_METACHARACTERS2.test(path40)) {
55027
+ if (SHELL_METACHARACTERS2.test(path41)) {
54895
55028
  return "path contains shell metacharacters";
54896
55029
  }
54897
- if (path40.startsWith("-")) {
55030
+ if (path41.startsWith("-")) {
54898
55031
  return 'path cannot start with "-" (option-like arguments not allowed)';
54899
55032
  }
54900
- if (CONTROL_CHAR_PATTERN2.test(path40)) {
55033
+ if (CONTROL_CHAR_PATTERN2.test(path41)) {
54901
55034
  return "path contains control characters";
54902
55035
  }
54903
55036
  }
@@ -54977,8 +55110,8 @@ var diff = tool({
54977
55110
  if (parts2.length >= 3) {
54978
55111
  const additions = parseInt(parts2[0], 10) || 0;
54979
55112
  const deletions = parseInt(parts2[1], 10) || 0;
54980
- const path40 = parts2[2];
54981
- files.push({ path: path40, additions, deletions });
55113
+ const path41 = parts2[2];
55114
+ files.push({ path: path41, additions, deletions });
54982
55115
  }
54983
55116
  }
54984
55117
  const contractChanges = [];
@@ -55207,8 +55340,8 @@ Use these as DOMAIN values when delegating to @sme.`;
55207
55340
  // src/tools/evidence-check.ts
55208
55341
  init_dist();
55209
55342
  init_create_tool();
55210
- import * as fs27 from "fs";
55211
- import * as path40 from "path";
55343
+ import * as fs28 from "fs";
55344
+ import * as path41 from "path";
55212
55345
  var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
55213
55346
  var MAX_EVIDENCE_FILES = 1000;
55214
55347
  var EVIDENCE_DIR2 = ".swarm/evidence";
@@ -55238,9 +55371,9 @@ function validateRequiredTypes(input) {
55238
55371
  return null;
55239
55372
  }
55240
55373
  function isPathWithinSwarm2(filePath, cwd) {
55241
- const normalizedCwd = path40.resolve(cwd);
55242
- const swarmPath = path40.join(normalizedCwd, ".swarm");
55243
- const normalizedPath = path40.resolve(filePath);
55374
+ const normalizedCwd = path41.resolve(cwd);
55375
+ const swarmPath = path41.join(normalizedCwd, ".swarm");
55376
+ const normalizedPath = path41.resolve(filePath);
55244
55377
  return normalizedPath.startsWith(swarmPath);
55245
55378
  }
55246
55379
  function parseCompletedTasks(planContent) {
@@ -55256,12 +55389,12 @@ function parseCompletedTasks(planContent) {
55256
55389
  }
55257
55390
  function readEvidenceFiles(evidenceDir, _cwd) {
55258
55391
  const evidence = [];
55259
- if (!fs27.existsSync(evidenceDir) || !fs27.statSync(evidenceDir).isDirectory()) {
55392
+ if (!fs28.existsSync(evidenceDir) || !fs28.statSync(evidenceDir).isDirectory()) {
55260
55393
  return evidence;
55261
55394
  }
55262
55395
  let files;
55263
55396
  try {
55264
- files = fs27.readdirSync(evidenceDir);
55397
+ files = fs28.readdirSync(evidenceDir);
55265
55398
  } catch {
55266
55399
  return evidence;
55267
55400
  }
@@ -55270,14 +55403,14 @@ function readEvidenceFiles(evidenceDir, _cwd) {
55270
55403
  if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
55271
55404
  continue;
55272
55405
  }
55273
- const filePath = path40.join(evidenceDir, filename);
55406
+ const filePath = path41.join(evidenceDir, filename);
55274
55407
  try {
55275
- const resolvedPath = path40.resolve(filePath);
55276
- const evidenceDirResolved = path40.resolve(evidenceDir);
55408
+ const resolvedPath = path41.resolve(filePath);
55409
+ const evidenceDirResolved = path41.resolve(evidenceDir);
55277
55410
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
55278
55411
  continue;
55279
55412
  }
55280
- const stat2 = fs27.lstatSync(filePath);
55413
+ const stat2 = fs28.lstatSync(filePath);
55281
55414
  if (!stat2.isFile()) {
55282
55415
  continue;
55283
55416
  }
@@ -55286,7 +55419,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
55286
55419
  }
55287
55420
  let fileStat;
55288
55421
  try {
55289
- fileStat = fs27.statSync(filePath);
55422
+ fileStat = fs28.statSync(filePath);
55290
55423
  if (fileStat.size > MAX_FILE_SIZE_BYTES3) {
55291
55424
  continue;
55292
55425
  }
@@ -55295,7 +55428,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
55295
55428
  }
55296
55429
  let content;
55297
55430
  try {
55298
- content = fs27.readFileSync(filePath, "utf-8");
55431
+ content = fs28.readFileSync(filePath, "utf-8");
55299
55432
  } catch {
55300
55433
  continue;
55301
55434
  }
@@ -55391,7 +55524,7 @@ var evidence_check = createSwarmTool({
55391
55524
  return JSON.stringify(errorResult, null, 2);
55392
55525
  }
55393
55526
  const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
55394
- const planPath = path40.join(cwd, PLAN_FILE);
55527
+ const planPath = path41.join(cwd, PLAN_FILE);
55395
55528
  if (!isPathWithinSwarm2(planPath, cwd)) {
55396
55529
  const errorResult = {
55397
55530
  error: "plan file path validation failed",
@@ -55405,7 +55538,7 @@ var evidence_check = createSwarmTool({
55405
55538
  }
55406
55539
  let planContent;
55407
55540
  try {
55408
- planContent = fs27.readFileSync(planPath, "utf-8");
55541
+ planContent = fs28.readFileSync(planPath, "utf-8");
55409
55542
  } catch {
55410
55543
  const result2 = {
55411
55544
  message: "No completed tasks found in plan.",
@@ -55423,7 +55556,7 @@ var evidence_check = createSwarmTool({
55423
55556
  };
55424
55557
  return JSON.stringify(result2, null, 2);
55425
55558
  }
55426
- const evidenceDir = path40.join(cwd, EVIDENCE_DIR2);
55559
+ const evidenceDir = path41.join(cwd, EVIDENCE_DIR2);
55427
55560
  const evidence = readEvidenceFiles(evidenceDir, cwd);
55428
55561
  const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
55429
55562
  const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
@@ -55440,8 +55573,8 @@ var evidence_check = createSwarmTool({
55440
55573
  // src/tools/file-extractor.ts
55441
55574
  init_tool();
55442
55575
  init_create_tool();
55443
- import * as fs28 from "fs";
55444
- import * as path41 from "path";
55576
+ import * as fs29 from "fs";
55577
+ import * as path42 from "path";
55445
55578
  var EXT_MAP = {
55446
55579
  python: ".py",
55447
55580
  py: ".py",
@@ -55503,8 +55636,8 @@ var extract_code_blocks = createSwarmTool({
55503
55636
  execute: async (args2, directory) => {
55504
55637
  const { content, output_dir, prefix } = args2;
55505
55638
  const targetDir = output_dir || directory;
55506
- if (!fs28.existsSync(targetDir)) {
55507
- fs28.mkdirSync(targetDir, { recursive: true });
55639
+ if (!fs29.existsSync(targetDir)) {
55640
+ fs29.mkdirSync(targetDir, { recursive: true });
55508
55641
  }
55509
55642
  if (!content) {
55510
55643
  return "Error: content is required";
@@ -55522,16 +55655,16 @@ var extract_code_blocks = createSwarmTool({
55522
55655
  if (prefix) {
55523
55656
  filename = `${prefix}_${filename}`;
55524
55657
  }
55525
- let filepath = path41.join(targetDir, filename);
55526
- const base = path41.basename(filepath, path41.extname(filepath));
55527
- const ext = path41.extname(filepath);
55658
+ let filepath = path42.join(targetDir, filename);
55659
+ const base = path42.basename(filepath, path42.extname(filepath));
55660
+ const ext = path42.extname(filepath);
55528
55661
  let counter = 1;
55529
- while (fs28.existsSync(filepath)) {
55530
- filepath = path41.join(targetDir, `${base}_${counter}${ext}`);
55662
+ while (fs29.existsSync(filepath)) {
55663
+ filepath = path42.join(targetDir, `${base}_${counter}${ext}`);
55531
55664
  counter++;
55532
55665
  }
55533
55666
  try {
55534
- fs28.writeFileSync(filepath, code.trim(), "utf-8");
55667
+ fs29.writeFileSync(filepath, code.trim(), "utf-8");
55535
55668
  savedFiles.push(filepath);
55536
55669
  } catch (error93) {
55537
55670
  errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
@@ -55644,8 +55777,8 @@ var gitingest = tool({
55644
55777
  });
55645
55778
  // src/tools/imports.ts
55646
55779
  init_dist();
55647
- import * as fs29 from "fs";
55648
- import * as path42 from "path";
55780
+ import * as fs30 from "fs";
55781
+ import * as path43 from "path";
55649
55782
  var MAX_FILE_PATH_LENGTH2 = 500;
55650
55783
  var MAX_SYMBOL_LENGTH = 256;
55651
55784
  var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
@@ -55699,7 +55832,7 @@ function validateSymbolInput(symbol3) {
55699
55832
  return null;
55700
55833
  }
55701
55834
  function isBinaryFile2(filePath, buffer) {
55702
- const ext = path42.extname(filePath).toLowerCase();
55835
+ const ext = path43.extname(filePath).toLowerCase();
55703
55836
  if (ext === ".json" || ext === ".md" || ext === ".txt") {
55704
55837
  return false;
55705
55838
  }
@@ -55723,15 +55856,15 @@ function parseImports(content, targetFile, targetSymbol) {
55723
55856
  const imports = [];
55724
55857
  let _resolvedTarget;
55725
55858
  try {
55726
- _resolvedTarget = path42.resolve(targetFile);
55859
+ _resolvedTarget = path43.resolve(targetFile);
55727
55860
  } catch {
55728
55861
  _resolvedTarget = targetFile;
55729
55862
  }
55730
- const targetBasename = path42.basename(targetFile, path42.extname(targetFile));
55863
+ const targetBasename = path43.basename(targetFile, path43.extname(targetFile));
55731
55864
  const targetWithExt = targetFile;
55732
55865
  const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
55733
- const normalizedTargetWithExt = path42.normalize(targetWithExt).replace(/\\/g, "/");
55734
- const normalizedTargetWithoutExt = path42.normalize(targetWithoutExt).replace(/\\/g, "/");
55866
+ const normalizedTargetWithExt = path43.normalize(targetWithExt).replace(/\\/g, "/");
55867
+ const normalizedTargetWithoutExt = path43.normalize(targetWithoutExt).replace(/\\/g, "/");
55735
55868
  const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
55736
55869
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
55737
55870
  const modulePath = match[1] || match[2] || match[3];
@@ -55754,9 +55887,9 @@ function parseImports(content, targetFile, targetSymbol) {
55754
55887
  }
55755
55888
  const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
55756
55889
  let isMatch = false;
55757
- const _targetDir = path42.dirname(targetFile);
55758
- const targetExt = path42.extname(targetFile);
55759
- const targetBasenameNoExt = path42.basename(targetFile, targetExt);
55890
+ const _targetDir = path43.dirname(targetFile);
55891
+ const targetExt = path43.extname(targetFile);
55892
+ const targetBasenameNoExt = path43.basename(targetFile, targetExt);
55760
55893
  const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
55761
55894
  const moduleName = modulePath.split(/[/\\]/).pop() || "";
55762
55895
  const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
@@ -55813,7 +55946,7 @@ var SKIP_DIRECTORIES2 = new Set([
55813
55946
  function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
55814
55947
  let entries;
55815
55948
  try {
55816
- entries = fs29.readdirSync(dir);
55949
+ entries = fs30.readdirSync(dir);
55817
55950
  } catch (e) {
55818
55951
  stats.fileErrors.push({
55819
55952
  path: dir,
@@ -55824,13 +55957,13 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
55824
55957
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
55825
55958
  for (const entry of entries) {
55826
55959
  if (SKIP_DIRECTORIES2.has(entry)) {
55827
- stats.skippedDirs.push(path42.join(dir, entry));
55960
+ stats.skippedDirs.push(path43.join(dir, entry));
55828
55961
  continue;
55829
55962
  }
55830
- const fullPath = path42.join(dir, entry);
55963
+ const fullPath = path43.join(dir, entry);
55831
55964
  let stat2;
55832
55965
  try {
55833
- stat2 = fs29.statSync(fullPath);
55966
+ stat2 = fs30.statSync(fullPath);
55834
55967
  } catch (e) {
55835
55968
  stats.fileErrors.push({
55836
55969
  path: fullPath,
@@ -55841,7 +55974,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
55841
55974
  if (stat2.isDirectory()) {
55842
55975
  findSourceFiles(fullPath, files, stats);
55843
55976
  } else if (stat2.isFile()) {
55844
- const ext = path42.extname(fullPath).toLowerCase();
55977
+ const ext = path43.extname(fullPath).toLowerCase();
55845
55978
  if (SUPPORTED_EXTENSIONS.includes(ext)) {
55846
55979
  files.push(fullPath);
55847
55980
  }
@@ -55897,8 +56030,8 @@ var imports = tool({
55897
56030
  return JSON.stringify(errorResult, null, 2);
55898
56031
  }
55899
56032
  try {
55900
- const targetFile = path42.resolve(file3);
55901
- if (!fs29.existsSync(targetFile)) {
56033
+ const targetFile = path43.resolve(file3);
56034
+ if (!fs30.existsSync(targetFile)) {
55902
56035
  const errorResult = {
55903
56036
  error: `target file not found: ${file3}`,
55904
56037
  target: file3,
@@ -55908,7 +56041,7 @@ var imports = tool({
55908
56041
  };
55909
56042
  return JSON.stringify(errorResult, null, 2);
55910
56043
  }
55911
- const targetStat = fs29.statSync(targetFile);
56044
+ const targetStat = fs30.statSync(targetFile);
55912
56045
  if (!targetStat.isFile()) {
55913
56046
  const errorResult = {
55914
56047
  error: "target must be a file, not a directory",
@@ -55919,7 +56052,7 @@ var imports = tool({
55919
56052
  };
55920
56053
  return JSON.stringify(errorResult, null, 2);
55921
56054
  }
55922
- const baseDir = path42.dirname(targetFile);
56055
+ const baseDir = path43.dirname(targetFile);
55923
56056
  const scanStats = {
55924
56057
  skippedDirs: [],
55925
56058
  skippedFiles: 0,
@@ -55934,12 +56067,12 @@ var imports = tool({
55934
56067
  if (consumers.length >= MAX_CONSUMERS)
55935
56068
  break;
55936
56069
  try {
55937
- const stat2 = fs29.statSync(filePath);
56070
+ const stat2 = fs30.statSync(filePath);
55938
56071
  if (stat2.size > MAX_FILE_SIZE_BYTES4) {
55939
56072
  skippedFileCount++;
55940
56073
  continue;
55941
56074
  }
55942
- const buffer = fs29.readFileSync(filePath);
56075
+ const buffer = fs30.readFileSync(filePath);
55943
56076
  if (isBinaryFile2(filePath, buffer)) {
55944
56077
  skippedFileCount++;
55945
56078
  continue;
@@ -56004,7 +56137,7 @@ var imports = tool({
56004
56137
  });
56005
56138
  // src/tools/knowledge-query.ts
56006
56139
  init_dist();
56007
- import { existsSync as existsSync27 } from "fs";
56140
+ import { existsSync as existsSync28 } from "fs";
56008
56141
  init_create_tool();
56009
56142
  var DEFAULT_LIMIT = 10;
56010
56143
  var MAX_LESSON_LENGTH = 200;
@@ -56074,14 +56207,14 @@ function validateLimit(limit) {
56074
56207
  }
56075
56208
  async function readSwarmKnowledge(directory) {
56076
56209
  const swarmPath = resolveSwarmKnowledgePath(directory);
56077
- if (!existsSync27(swarmPath)) {
56210
+ if (!existsSync28(swarmPath)) {
56078
56211
  return [];
56079
56212
  }
56080
56213
  return readKnowledge(swarmPath);
56081
56214
  }
56082
56215
  async function readHiveKnowledge() {
56083
56216
  const hivePath = resolveHiveKnowledgePath();
56084
- if (!existsSync27(hivePath)) {
56217
+ if (!existsSync28(hivePath)) {
56085
56218
  return [];
56086
56219
  }
56087
56220
  return readKnowledge(hivePath);
@@ -56240,8 +56373,8 @@ init_dist();
56240
56373
  init_config();
56241
56374
  init_schema();
56242
56375
  init_manager();
56243
- import * as fs30 from "fs";
56244
- import * as path43 from "path";
56376
+ import * as fs31 from "fs";
56377
+ import * as path44 from "path";
56245
56378
  init_utils2();
56246
56379
  init_create_tool();
56247
56380
  function safeWarn(message, error93) {
@@ -56436,7 +56569,7 @@ async function executePhaseComplete(args2, workingDirectory) {
56436
56569
  }
56437
56570
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
56438
56571
  try {
56439
- const projectName = path43.basename(dir);
56572
+ const projectName = path44.basename(dir);
56440
56573
  const knowledgeConfig = {
56441
56574
  enabled: true,
56442
56575
  swarm_max_entries: 100,
@@ -56484,7 +56617,7 @@ async function executePhaseComplete(args2, workingDirectory) {
56484
56617
  if (agentsMissing.length > 0) {
56485
56618
  try {
56486
56619
  const planPath = validateSwarmPath(dir, "plan.json");
56487
- const planRaw = fs30.readFileSync(planPath, "utf-8");
56620
+ const planRaw = fs31.readFileSync(planPath, "utf-8");
56488
56621
  const plan = JSON.parse(planRaw);
56489
56622
  const targetPhase = plan.phases.find((p) => p.id === phase);
56490
56623
  if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
@@ -56525,7 +56658,7 @@ async function executePhaseComplete(args2, workingDirectory) {
56525
56658
  };
56526
56659
  try {
56527
56660
  const eventsPath = validateSwarmPath(dir, "events.jsonl");
56528
- fs30.appendFileSync(eventsPath, `${JSON.stringify(event)}
56661
+ fs31.appendFileSync(eventsPath, `${JSON.stringify(event)}
56529
56662
  `, "utf-8");
56530
56663
  } catch (writeError) {
56531
56664
  warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
@@ -56544,12 +56677,12 @@ async function executePhaseComplete(args2, workingDirectory) {
56544
56677
  }
56545
56678
  try {
56546
56679
  const planPath = validateSwarmPath(dir, "plan.json");
56547
- const planJson = fs30.readFileSync(planPath, "utf-8");
56680
+ const planJson = fs31.readFileSync(planPath, "utf-8");
56548
56681
  const plan = JSON.parse(planJson);
56549
56682
  const phaseObj = plan.phases.find((p) => p.id === phase);
56550
56683
  if (phaseObj) {
56551
56684
  phaseObj.status = "completed";
56552
- fs30.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
56685
+ fs31.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
56553
56686
  `, "utf-8");
56554
56687
  }
56555
56688
  } catch (error93) {
@@ -56599,8 +56732,8 @@ init_dist();
56599
56732
  init_discovery();
56600
56733
  init_utils();
56601
56734
  init_create_tool();
56602
- import * as fs31 from "fs";
56603
- import * as path44 from "path";
56735
+ import * as fs32 from "fs";
56736
+ import * as path45 from "path";
56604
56737
  var MAX_OUTPUT_BYTES5 = 52428800;
56605
56738
  var AUDIT_TIMEOUT_MS = 120000;
56606
56739
  function isValidEcosystem(value) {
@@ -56618,28 +56751,28 @@ function validateArgs3(args2) {
56618
56751
  function detectEcosystems(directory) {
56619
56752
  const ecosystems = [];
56620
56753
  const cwd = directory;
56621
- if (fs31.existsSync(path44.join(cwd, "package.json"))) {
56754
+ if (fs32.existsSync(path45.join(cwd, "package.json"))) {
56622
56755
  ecosystems.push("npm");
56623
56756
  }
56624
- if (fs31.existsSync(path44.join(cwd, "pyproject.toml")) || fs31.existsSync(path44.join(cwd, "requirements.txt"))) {
56757
+ if (fs32.existsSync(path45.join(cwd, "pyproject.toml")) || fs32.existsSync(path45.join(cwd, "requirements.txt"))) {
56625
56758
  ecosystems.push("pip");
56626
56759
  }
56627
- if (fs31.existsSync(path44.join(cwd, "Cargo.toml"))) {
56760
+ if (fs32.existsSync(path45.join(cwd, "Cargo.toml"))) {
56628
56761
  ecosystems.push("cargo");
56629
56762
  }
56630
- if (fs31.existsSync(path44.join(cwd, "go.mod"))) {
56763
+ if (fs32.existsSync(path45.join(cwd, "go.mod"))) {
56631
56764
  ecosystems.push("go");
56632
56765
  }
56633
56766
  try {
56634
- const files = fs31.readdirSync(cwd);
56767
+ const files = fs32.readdirSync(cwd);
56635
56768
  if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
56636
56769
  ecosystems.push("dotnet");
56637
56770
  }
56638
56771
  } catch {}
56639
- if (fs31.existsSync(path44.join(cwd, "Gemfile")) || fs31.existsSync(path44.join(cwd, "Gemfile.lock"))) {
56772
+ if (fs32.existsSync(path45.join(cwd, "Gemfile")) || fs32.existsSync(path45.join(cwd, "Gemfile.lock"))) {
56640
56773
  ecosystems.push("ruby");
56641
56774
  }
56642
- if (fs31.existsSync(path44.join(cwd, "pubspec.yaml"))) {
56775
+ if (fs32.existsSync(path45.join(cwd, "pubspec.yaml"))) {
56643
56776
  ecosystems.push("dart");
56644
56777
  }
56645
56778
  return ecosystems;
@@ -57701,8 +57834,8 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
57701
57834
  ]);
57702
57835
  // src/tools/pre-check-batch.ts
57703
57836
  init_dist();
57704
- import * as fs34 from "fs";
57705
- import * as path47 from "path";
57837
+ import * as fs35 from "fs";
57838
+ import * as path48 from "path";
57706
57839
 
57707
57840
  // node_modules/yocto-queue/index.js
57708
57841
  class Node2 {
@@ -57869,8 +58002,8 @@ init_lint();
57869
58002
  init_manager();
57870
58003
 
57871
58004
  // src/quality/metrics.ts
57872
- import * as fs32 from "fs";
57873
- import * as path45 from "path";
58005
+ import * as fs33 from "fs";
58006
+ import * as path46 from "path";
57874
58007
  var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
57875
58008
  var MIN_DUPLICATION_LINES = 10;
57876
58009
  function estimateCyclomaticComplexity(content) {
@@ -57908,11 +58041,11 @@ function estimateCyclomaticComplexity(content) {
57908
58041
  }
57909
58042
  function getComplexityForFile2(filePath) {
57910
58043
  try {
57911
- const stat2 = fs32.statSync(filePath);
58044
+ const stat2 = fs33.statSync(filePath);
57912
58045
  if (stat2.size > MAX_FILE_SIZE_BYTES5) {
57913
58046
  return null;
57914
58047
  }
57915
- const content = fs32.readFileSync(filePath, "utf-8");
58048
+ const content = fs33.readFileSync(filePath, "utf-8");
57916
58049
  return estimateCyclomaticComplexity(content);
57917
58050
  } catch {
57918
58051
  return null;
@@ -57922,8 +58055,8 @@ async function computeComplexityDelta(files, workingDir) {
57922
58055
  let totalComplexity = 0;
57923
58056
  const analyzedFiles = [];
57924
58057
  for (const file3 of files) {
57925
- const fullPath = path45.isAbsolute(file3) ? file3 : path45.join(workingDir, file3);
57926
- if (!fs32.existsSync(fullPath)) {
58058
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58059
+ if (!fs33.existsSync(fullPath)) {
57927
58060
  continue;
57928
58061
  }
57929
58062
  const complexity = getComplexityForFile2(fullPath);
@@ -58044,8 +58177,8 @@ function countGoExports(content) {
58044
58177
  }
58045
58178
  function getExportCountForFile(filePath) {
58046
58179
  try {
58047
- const content = fs32.readFileSync(filePath, "utf-8");
58048
- const ext = path45.extname(filePath).toLowerCase();
58180
+ const content = fs33.readFileSync(filePath, "utf-8");
58181
+ const ext = path46.extname(filePath).toLowerCase();
58049
58182
  switch (ext) {
58050
58183
  case ".ts":
58051
58184
  case ".tsx":
@@ -58071,8 +58204,8 @@ async function computePublicApiDelta(files, workingDir) {
58071
58204
  let totalExports = 0;
58072
58205
  const analyzedFiles = [];
58073
58206
  for (const file3 of files) {
58074
- const fullPath = path45.isAbsolute(file3) ? file3 : path45.join(workingDir, file3);
58075
- if (!fs32.existsSync(fullPath)) {
58207
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58208
+ if (!fs33.existsSync(fullPath)) {
58076
58209
  continue;
58077
58210
  }
58078
58211
  const exports = getExportCountForFile(fullPath);
@@ -58105,16 +58238,16 @@ async function computeDuplicationRatio(files, workingDir) {
58105
58238
  let duplicateLines = 0;
58106
58239
  const analyzedFiles = [];
58107
58240
  for (const file3 of files) {
58108
- const fullPath = path45.isAbsolute(file3) ? file3 : path45.join(workingDir, file3);
58109
- if (!fs32.existsSync(fullPath)) {
58241
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58242
+ if (!fs33.existsSync(fullPath)) {
58110
58243
  continue;
58111
58244
  }
58112
58245
  try {
58113
- const stat2 = fs32.statSync(fullPath);
58246
+ const stat2 = fs33.statSync(fullPath);
58114
58247
  if (stat2.size > MAX_FILE_SIZE_BYTES5) {
58115
58248
  continue;
58116
58249
  }
58117
- const content = fs32.readFileSync(fullPath, "utf-8");
58250
+ const content = fs33.readFileSync(fullPath, "utf-8");
58118
58251
  const lines = content.split(`
58119
58252
  `).filter((line) => line.trim().length > 0);
58120
58253
  if (lines.length < MIN_DUPLICATION_LINES) {
@@ -58138,8 +58271,8 @@ function countCodeLines(content) {
58138
58271
  return lines.length;
58139
58272
  }
58140
58273
  function isTestFile(filePath) {
58141
- const basename8 = path45.basename(filePath);
58142
- const _ext = path45.extname(filePath).toLowerCase();
58274
+ const basename8 = path46.basename(filePath);
58275
+ const _ext = path46.extname(filePath).toLowerCase();
58143
58276
  const testPatterns = [
58144
58277
  ".test.",
58145
58278
  ".spec.",
@@ -58220,8 +58353,8 @@ function matchGlobSegment(globSegments, pathSegments) {
58220
58353
  }
58221
58354
  return gIndex === globSegments.length && pIndex === pathSegments.length;
58222
58355
  }
58223
- function matchesGlobSegment(path46, glob) {
58224
- const normalizedPath = path46.replace(/\\/g, "/");
58356
+ function matchesGlobSegment(path47, glob) {
58357
+ const normalizedPath = path47.replace(/\\/g, "/");
58225
58358
  const normalizedGlob = glob.replace(/\\/g, "/");
58226
58359
  if (normalizedPath.includes("//")) {
58227
58360
  return false;
@@ -58252,8 +58385,8 @@ function simpleGlobToRegex2(glob) {
58252
58385
  function hasGlobstar(glob) {
58253
58386
  return glob.includes("**");
58254
58387
  }
58255
- function globMatches(path46, glob) {
58256
- const normalizedPath = path46.replace(/\\/g, "/");
58388
+ function globMatches(path47, glob) {
58389
+ const normalizedPath = path47.replace(/\\/g, "/");
58257
58390
  if (!glob || glob === "") {
58258
58391
  if (normalizedPath.includes("//")) {
58259
58392
  return false;
@@ -58289,31 +58422,31 @@ function shouldExcludeFile(filePath, excludeGlobs) {
58289
58422
  async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
58290
58423
  let testLines = 0;
58291
58424
  let codeLines = 0;
58292
- const srcDir = path45.join(workingDir, "src");
58293
- if (fs32.existsSync(srcDir)) {
58425
+ const srcDir = path46.join(workingDir, "src");
58426
+ if (fs33.existsSync(srcDir)) {
58294
58427
  await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
58295
58428
  codeLines += lines;
58296
58429
  });
58297
58430
  }
58298
58431
  const possibleSrcDirs = ["lib", "app", "source", "core"];
58299
58432
  for (const dir of possibleSrcDirs) {
58300
- const dirPath = path45.join(workingDir, dir);
58301
- if (fs32.existsSync(dirPath)) {
58433
+ const dirPath = path46.join(workingDir, dir);
58434
+ if (fs33.existsSync(dirPath)) {
58302
58435
  await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
58303
58436
  codeLines += lines;
58304
58437
  });
58305
58438
  }
58306
58439
  }
58307
- const testsDir = path45.join(workingDir, "tests");
58308
- if (fs32.existsSync(testsDir)) {
58440
+ const testsDir = path46.join(workingDir, "tests");
58441
+ if (fs33.existsSync(testsDir)) {
58309
58442
  await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
58310
58443
  testLines += lines;
58311
58444
  });
58312
58445
  }
58313
58446
  const possibleTestDirs = ["test", "__tests__", "specs"];
58314
58447
  for (const dir of possibleTestDirs) {
58315
- const dirPath = path45.join(workingDir, dir);
58316
- if (fs32.existsSync(dirPath) && dirPath !== testsDir) {
58448
+ const dirPath = path46.join(workingDir, dir);
58449
+ if (fs33.existsSync(dirPath) && dirPath !== testsDir) {
58317
58450
  await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
58318
58451
  testLines += lines;
58319
58452
  });
@@ -58325,9 +58458,9 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
58325
58458
  }
58326
58459
  async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
58327
58460
  try {
58328
- const entries = fs32.readdirSync(dirPath, { withFileTypes: true });
58461
+ const entries = fs33.readdirSync(dirPath, { withFileTypes: true });
58329
58462
  for (const entry of entries) {
58330
- const fullPath = path45.join(dirPath, entry.name);
58463
+ const fullPath = path46.join(dirPath, entry.name);
58331
58464
  if (entry.isDirectory()) {
58332
58465
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
58333
58466
  continue;
@@ -58335,7 +58468,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
58335
58468
  await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
58336
58469
  } else if (entry.isFile()) {
58337
58470
  const relativePath = fullPath.replace(`${process.cwd()}/`, "");
58338
- const ext = path45.extname(entry.name).toLowerCase();
58471
+ const ext = path46.extname(entry.name).toLowerCase();
58339
58472
  const validExts = [
58340
58473
  ".ts",
58341
58474
  ".tsx",
@@ -58371,7 +58504,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
58371
58504
  continue;
58372
58505
  }
58373
58506
  try {
58374
- const content = fs32.readFileSync(fullPath, "utf-8");
58507
+ const content = fs33.readFileSync(fullPath, "utf-8");
58375
58508
  const lines = countCodeLines(content);
58376
58509
  callback(lines);
58377
58510
  } catch {}
@@ -58585,8 +58718,8 @@ async function qualityBudget(input, directory) {
58585
58718
  init_dist();
58586
58719
  init_manager();
58587
58720
  init_detector();
58588
- import * as fs33 from "fs";
58589
- import * as path46 from "path";
58721
+ import * as fs34 from "fs";
58722
+ import * as path47 from "path";
58590
58723
  import { extname as extname9 } from "path";
58591
58724
 
58592
58725
  // src/sast/rules/c.ts
@@ -59270,7 +59403,7 @@ function executeRulesSync(filePath, content, language) {
59270
59403
  }
59271
59404
 
59272
59405
  // src/sast/semgrep.ts
59273
- import { execFile as execFile2, execFileSync as execFileSync2, spawn } from "child_process";
59406
+ import { execFile as execFile2, execFileSync as execFileSync2, spawn as spawn2 } from "child_process";
59274
59407
  import { promisify as promisify2 } from "util";
59275
59408
  var _execFileAsync = promisify2(execFile2);
59276
59409
  var semgrepAvailableCache = null;
@@ -59335,7 +59468,7 @@ function mapSemgrepSeverity(severity) {
59335
59468
  }
59336
59469
  async function executeWithTimeout(command, args2, options) {
59337
59470
  return new Promise((resolve15) => {
59338
- const child = spawn(command, args2, {
59471
+ const child = spawn2(command, args2, {
59339
59472
  shell: false,
59340
59473
  cwd: options.cwd
59341
59474
  });
@@ -59453,17 +59586,17 @@ var SEVERITY_ORDER = {
59453
59586
  };
59454
59587
  function shouldSkipFile(filePath) {
59455
59588
  try {
59456
- const stats = fs33.statSync(filePath);
59589
+ const stats = fs34.statSync(filePath);
59457
59590
  if (stats.size > MAX_FILE_SIZE_BYTES6) {
59458
59591
  return { skip: true, reason: "file too large" };
59459
59592
  }
59460
59593
  if (stats.size === 0) {
59461
59594
  return { skip: true, reason: "empty file" };
59462
59595
  }
59463
- const fd = fs33.openSync(filePath, "r");
59596
+ const fd = fs34.openSync(filePath, "r");
59464
59597
  const buffer = Buffer.alloc(8192);
59465
- const bytesRead = fs33.readSync(fd, buffer, 0, 8192, 0);
59466
- fs33.closeSync(fd);
59598
+ const bytesRead = fs34.readSync(fd, buffer, 0, 8192, 0);
59599
+ fs34.closeSync(fd);
59467
59600
  if (bytesRead > 0) {
59468
59601
  let nullCount = 0;
59469
59602
  for (let i2 = 0;i2 < bytesRead; i2++) {
@@ -59502,7 +59635,7 @@ function countBySeverity(findings) {
59502
59635
  }
59503
59636
  function scanFileWithTierA(filePath, language) {
59504
59637
  try {
59505
- const content = fs33.readFileSync(filePath, "utf-8");
59638
+ const content = fs34.readFileSync(filePath, "utf-8");
59506
59639
  const findings = executeRulesSync(filePath, content, language);
59507
59640
  return findings.map((f) => ({
59508
59641
  rule_id: f.rule_id,
@@ -59549,8 +59682,8 @@ async function sastScan(input, directory, config3) {
59549
59682
  _filesSkipped++;
59550
59683
  continue;
59551
59684
  }
59552
- const resolvedPath = path46.isAbsolute(filePath) ? filePath : path46.resolve(directory, filePath);
59553
- if (!fs33.existsSync(resolvedPath)) {
59685
+ const resolvedPath = path47.isAbsolute(filePath) ? filePath : path47.resolve(directory, filePath);
59686
+ if (!fs34.existsSync(resolvedPath)) {
59554
59687
  _filesSkipped++;
59555
59688
  continue;
59556
59689
  }
@@ -59748,18 +59881,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
59748
59881
  let resolved;
59749
59882
  const isWinAbs = isWindowsAbsolutePath(inputPath);
59750
59883
  if (isWinAbs) {
59751
- resolved = path47.win32.resolve(inputPath);
59752
- } else if (path47.isAbsolute(inputPath)) {
59753
- resolved = path47.resolve(inputPath);
59884
+ resolved = path48.win32.resolve(inputPath);
59885
+ } else if (path48.isAbsolute(inputPath)) {
59886
+ resolved = path48.resolve(inputPath);
59754
59887
  } else {
59755
- resolved = path47.resolve(baseDir, inputPath);
59888
+ resolved = path48.resolve(baseDir, inputPath);
59756
59889
  }
59757
- const workspaceResolved = path47.resolve(workspaceDir);
59890
+ const workspaceResolved = path48.resolve(workspaceDir);
59758
59891
  let relative5;
59759
59892
  if (isWinAbs) {
59760
- relative5 = path47.win32.relative(workspaceResolved, resolved);
59893
+ relative5 = path48.win32.relative(workspaceResolved, resolved);
59761
59894
  } else {
59762
- relative5 = path47.relative(workspaceResolved, resolved);
59895
+ relative5 = path48.relative(workspaceResolved, resolved);
59763
59896
  }
59764
59897
  if (relative5.startsWith("..")) {
59765
59898
  return "path traversal detected";
@@ -59820,13 +59953,13 @@ async function runLintWrapped(files, directory, _config) {
59820
59953
  }
59821
59954
  async function runLintOnFiles(linter, files, workspaceDir) {
59822
59955
  const isWindows = process.platform === "win32";
59823
- const binDir = path47.join(workspaceDir, "node_modules", ".bin");
59956
+ const binDir = path48.join(workspaceDir, "node_modules", ".bin");
59824
59957
  const validatedFiles = [];
59825
59958
  for (const file3 of files) {
59826
59959
  if (typeof file3 !== "string") {
59827
59960
  continue;
59828
59961
  }
59829
- const resolvedPath = path47.resolve(file3);
59962
+ const resolvedPath = path48.resolve(file3);
59830
59963
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
59831
59964
  if (validationError) {
59832
59965
  continue;
@@ -59844,10 +59977,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
59844
59977
  }
59845
59978
  let command;
59846
59979
  if (linter === "biome") {
59847
- const biomeBin = isWindows ? path47.join(binDir, "biome.EXE") : path47.join(binDir, "biome");
59980
+ const biomeBin = isWindows ? path48.join(binDir, "biome.EXE") : path48.join(binDir, "biome");
59848
59981
  command = [biomeBin, "check", ...validatedFiles];
59849
59982
  } else {
59850
- const eslintBin = isWindows ? path47.join(binDir, "eslint.cmd") : path47.join(binDir, "eslint");
59983
+ const eslintBin = isWindows ? path48.join(binDir, "eslint.cmd") : path48.join(binDir, "eslint");
59851
59984
  command = [eslintBin, ...validatedFiles];
59852
59985
  }
59853
59986
  try {
@@ -59984,7 +60117,7 @@ async function runSecretscanWithFiles(files, directory) {
59984
60117
  skippedFiles++;
59985
60118
  continue;
59986
60119
  }
59987
- const resolvedPath = path47.resolve(file3);
60120
+ const resolvedPath = path48.resolve(file3);
59988
60121
  const validationError = validatePath(resolvedPath, directory, directory);
59989
60122
  if (validationError) {
59990
60123
  skippedFiles++;
@@ -60002,14 +60135,14 @@ async function runSecretscanWithFiles(files, directory) {
60002
60135
  };
60003
60136
  }
60004
60137
  for (const file3 of validatedFiles) {
60005
- const ext = path47.extname(file3).toLowerCase();
60138
+ const ext = path48.extname(file3).toLowerCase();
60006
60139
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
60007
60140
  skippedFiles++;
60008
60141
  continue;
60009
60142
  }
60010
60143
  let stat2;
60011
60144
  try {
60012
- stat2 = fs34.statSync(file3);
60145
+ stat2 = fs35.statSync(file3);
60013
60146
  } catch {
60014
60147
  skippedFiles++;
60015
60148
  continue;
@@ -60020,7 +60153,7 @@ async function runSecretscanWithFiles(files, directory) {
60020
60153
  }
60021
60154
  let content;
60022
60155
  try {
60023
- const buffer = fs34.readFileSync(file3);
60156
+ const buffer = fs35.readFileSync(file3);
60024
60157
  if (buffer.includes(0)) {
60025
60158
  skippedFiles++;
60026
60159
  continue;
@@ -60161,7 +60294,7 @@ async function runPreCheckBatch(input, workspaceDir) {
60161
60294
  warn(`pre_check_batch: Invalid file path: ${file3}`);
60162
60295
  continue;
60163
60296
  }
60164
- changedFiles.push(path47.resolve(directory, file3));
60297
+ changedFiles.push(path48.resolve(directory, file3));
60165
60298
  }
60166
60299
  if (changedFiles.length === 0) {
60167
60300
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -60312,7 +60445,7 @@ var pre_check_batch = createSwarmTool({
60312
60445
  };
60313
60446
  return JSON.stringify(errorResult, null, 2);
60314
60447
  }
60315
- const resolvedDirectory = path47.resolve(typedArgs.directory);
60448
+ const resolvedDirectory = path48.resolve(typedArgs.directory);
60316
60449
  const workspaceAnchor = resolvedDirectory;
60317
60450
  const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
60318
60451
  if (dirError) {
@@ -60419,8 +60552,8 @@ ${paginatedContent}`;
60419
60552
  init_tool();
60420
60553
  init_manager2();
60421
60554
  init_create_tool();
60422
- import * as fs35 from "fs";
60423
- import * as path48 from "path";
60555
+ import * as fs36 from "fs";
60556
+ import * as path49 from "path";
60424
60557
  function detectPlaceholderContent(args2) {
60425
60558
  const issues = [];
60426
60559
  const placeholderPattern = /^\[\w[\w\s]*\]$/;
@@ -60524,19 +60657,19 @@ async function executeSavePlan(args2, fallbackDir) {
60524
60657
  try {
60525
60658
  await savePlan(dir, plan);
60526
60659
  try {
60527
- const markerPath = path48.join(dir, ".swarm", ".plan-write-marker");
60660
+ const markerPath = path49.join(dir, ".swarm", ".plan-write-marker");
60528
60661
  const marker = JSON.stringify({
60529
60662
  source: "save_plan",
60530
60663
  timestamp: new Date().toISOString(),
60531
60664
  phases_count: plan.phases.length,
60532
60665
  tasks_count: tasksCount
60533
60666
  });
60534
- await fs35.promises.writeFile(markerPath, marker, "utf8");
60667
+ await fs36.promises.writeFile(markerPath, marker, "utf8");
60535
60668
  } catch {}
60536
60669
  return {
60537
60670
  success: true,
60538
60671
  message: "Plan saved successfully",
60539
- plan_path: path48.join(dir, ".swarm", "plan.json"),
60672
+ plan_path: path49.join(dir, ".swarm", "plan.json"),
60540
60673
  phases_count: plan.phases.length,
60541
60674
  tasks_count: tasksCount
60542
60675
  };
@@ -60574,8 +60707,8 @@ var save_plan = createSwarmTool({
60574
60707
  // src/tools/sbom-generate.ts
60575
60708
  init_dist();
60576
60709
  init_manager();
60577
- import * as fs36 from "fs";
60578
- import * as path49 from "path";
60710
+ import * as fs37 from "fs";
60711
+ import * as path50 from "path";
60579
60712
 
60580
60713
  // src/sbom/detectors/index.ts
60581
60714
  init_utils();
@@ -61421,9 +61554,9 @@ function findManifestFiles(rootDir) {
61421
61554
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
61422
61555
  function searchDir(dir) {
61423
61556
  try {
61424
- const entries = fs36.readdirSync(dir, { withFileTypes: true });
61557
+ const entries = fs37.readdirSync(dir, { withFileTypes: true });
61425
61558
  for (const entry of entries) {
61426
- const fullPath = path49.join(dir, entry.name);
61559
+ const fullPath = path50.join(dir, entry.name);
61427
61560
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
61428
61561
  continue;
61429
61562
  }
@@ -61432,7 +61565,7 @@ function findManifestFiles(rootDir) {
61432
61565
  } else if (entry.isFile()) {
61433
61566
  for (const pattern of patterns) {
61434
61567
  if (simpleGlobToRegex(pattern).test(entry.name)) {
61435
- manifestFiles.push(path49.relative(rootDir, fullPath));
61568
+ manifestFiles.push(path50.relative(rootDir, fullPath));
61436
61569
  break;
61437
61570
  }
61438
61571
  }
@@ -61448,13 +61581,13 @@ function findManifestFilesInDirs(directories, workingDir) {
61448
61581
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
61449
61582
  for (const dir of directories) {
61450
61583
  try {
61451
- const entries = fs36.readdirSync(dir, { withFileTypes: true });
61584
+ const entries = fs37.readdirSync(dir, { withFileTypes: true });
61452
61585
  for (const entry of entries) {
61453
- const fullPath = path49.join(dir, entry.name);
61586
+ const fullPath = path50.join(dir, entry.name);
61454
61587
  if (entry.isFile()) {
61455
61588
  for (const pattern of patterns) {
61456
61589
  if (simpleGlobToRegex(pattern).test(entry.name)) {
61457
- found.push(path49.relative(workingDir, fullPath));
61590
+ found.push(path50.relative(workingDir, fullPath));
61458
61591
  break;
61459
61592
  }
61460
61593
  }
@@ -61467,11 +61600,11 @@ function findManifestFilesInDirs(directories, workingDir) {
61467
61600
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
61468
61601
  const dirs = new Set;
61469
61602
  for (const file3 of changedFiles) {
61470
- let currentDir = path49.dirname(file3);
61603
+ let currentDir = path50.dirname(file3);
61471
61604
  while (true) {
61472
- if (currentDir && currentDir !== "." && currentDir !== path49.sep) {
61473
- dirs.add(path49.join(workingDir, currentDir));
61474
- const parent = path49.dirname(currentDir);
61605
+ if (currentDir && currentDir !== "." && currentDir !== path50.sep) {
61606
+ dirs.add(path50.join(workingDir, currentDir));
61607
+ const parent = path50.dirname(currentDir);
61475
61608
  if (parent === currentDir)
61476
61609
  break;
61477
61610
  currentDir = parent;
@@ -61485,7 +61618,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
61485
61618
  }
61486
61619
  function ensureOutputDir(outputDir) {
61487
61620
  try {
61488
- fs36.mkdirSync(outputDir, { recursive: true });
61621
+ fs37.mkdirSync(outputDir, { recursive: true });
61489
61622
  } catch (error93) {
61490
61623
  if (!error93 || error93.code !== "EEXIST") {
61491
61624
  throw error93;
@@ -61555,7 +61688,7 @@ var sbom_generate = createSwarmTool({
61555
61688
  const changedFiles = obj.changed_files;
61556
61689
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
61557
61690
  const workingDir = directory;
61558
- const outputDir = path49.isAbsolute(relativeOutputDir) ? relativeOutputDir : path49.join(workingDir, relativeOutputDir);
61691
+ const outputDir = path50.isAbsolute(relativeOutputDir) ? relativeOutputDir : path50.join(workingDir, relativeOutputDir);
61559
61692
  let manifestFiles = [];
61560
61693
  if (scope === "all") {
61561
61694
  manifestFiles = findManifestFiles(workingDir);
@@ -61578,11 +61711,11 @@ var sbom_generate = createSwarmTool({
61578
61711
  const processedFiles = [];
61579
61712
  for (const manifestFile of manifestFiles) {
61580
61713
  try {
61581
- const fullPath = path49.isAbsolute(manifestFile) ? manifestFile : path49.join(workingDir, manifestFile);
61582
- if (!fs36.existsSync(fullPath)) {
61714
+ const fullPath = path50.isAbsolute(manifestFile) ? manifestFile : path50.join(workingDir, manifestFile);
61715
+ if (!fs37.existsSync(fullPath)) {
61583
61716
  continue;
61584
61717
  }
61585
- const content = fs36.readFileSync(fullPath, "utf-8");
61718
+ const content = fs37.readFileSync(fullPath, "utf-8");
61586
61719
  const components = detectComponents(manifestFile, content);
61587
61720
  processedFiles.push(manifestFile);
61588
61721
  if (components.length > 0) {
@@ -61595,8 +61728,8 @@ var sbom_generate = createSwarmTool({
61595
61728
  const bom = generateCycloneDX(allComponents);
61596
61729
  const bomJson = serializeCycloneDX(bom);
61597
61730
  const filename = generateSbomFilename();
61598
- const outputPath = path49.join(outputDir, filename);
61599
- fs36.writeFileSync(outputPath, bomJson, "utf-8");
61731
+ const outputPath = path50.join(outputDir, filename);
61732
+ fs37.writeFileSync(outputPath, bomJson, "utf-8");
61600
61733
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
61601
61734
  try {
61602
61735
  const timestamp = new Date().toISOString();
@@ -61638,8 +61771,8 @@ var sbom_generate = createSwarmTool({
61638
61771
  // src/tools/schema-drift.ts
61639
61772
  init_dist();
61640
61773
  init_create_tool();
61641
- import * as fs37 from "fs";
61642
- import * as path50 from "path";
61774
+ import * as fs38 from "fs";
61775
+ import * as path51 from "path";
61643
61776
  var SPEC_CANDIDATES = [
61644
61777
  "openapi.json",
61645
61778
  "openapi.yaml",
@@ -61671,28 +61804,28 @@ function normalizePath2(p) {
61671
61804
  }
61672
61805
  function discoverSpecFile(cwd, specFileArg) {
61673
61806
  if (specFileArg) {
61674
- const resolvedPath = path50.resolve(cwd, specFileArg);
61675
- const normalizedCwd = cwd.endsWith(path50.sep) ? cwd : cwd + path50.sep;
61807
+ const resolvedPath = path51.resolve(cwd, specFileArg);
61808
+ const normalizedCwd = cwd.endsWith(path51.sep) ? cwd : cwd + path51.sep;
61676
61809
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
61677
61810
  throw new Error("Invalid spec_file: path traversal detected");
61678
61811
  }
61679
- const ext = path50.extname(resolvedPath).toLowerCase();
61812
+ const ext = path51.extname(resolvedPath).toLowerCase();
61680
61813
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
61681
61814
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
61682
61815
  }
61683
- const stats = fs37.statSync(resolvedPath);
61816
+ const stats = fs38.statSync(resolvedPath);
61684
61817
  if (stats.size > MAX_SPEC_SIZE) {
61685
61818
  throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
61686
61819
  }
61687
- if (!fs37.existsSync(resolvedPath)) {
61820
+ if (!fs38.existsSync(resolvedPath)) {
61688
61821
  throw new Error(`Spec file not found: ${resolvedPath}`);
61689
61822
  }
61690
61823
  return resolvedPath;
61691
61824
  }
61692
61825
  for (const candidate of SPEC_CANDIDATES) {
61693
- const candidatePath = path50.resolve(cwd, candidate);
61694
- if (fs37.existsSync(candidatePath)) {
61695
- const stats = fs37.statSync(candidatePath);
61826
+ const candidatePath = path51.resolve(cwd, candidate);
61827
+ if (fs38.existsSync(candidatePath)) {
61828
+ const stats = fs38.statSync(candidatePath);
61696
61829
  if (stats.size <= MAX_SPEC_SIZE) {
61697
61830
  return candidatePath;
61698
61831
  }
@@ -61701,8 +61834,8 @@ function discoverSpecFile(cwd, specFileArg) {
61701
61834
  return null;
61702
61835
  }
61703
61836
  function parseSpec(specFile) {
61704
- const content = fs37.readFileSync(specFile, "utf-8");
61705
- const ext = path50.extname(specFile).toLowerCase();
61837
+ const content = fs38.readFileSync(specFile, "utf-8");
61838
+ const ext = path51.extname(specFile).toLowerCase();
61706
61839
  if (ext === ".json") {
61707
61840
  return parseJsonSpec(content);
61708
61841
  }
@@ -61773,12 +61906,12 @@ function extractRoutes(cwd) {
61773
61906
  function walkDir(dir) {
61774
61907
  let entries;
61775
61908
  try {
61776
- entries = fs37.readdirSync(dir, { withFileTypes: true });
61909
+ entries = fs38.readdirSync(dir, { withFileTypes: true });
61777
61910
  } catch {
61778
61911
  return;
61779
61912
  }
61780
61913
  for (const entry of entries) {
61781
- const fullPath = path50.join(dir, entry.name);
61914
+ const fullPath = path51.join(dir, entry.name);
61782
61915
  if (entry.isSymbolicLink()) {
61783
61916
  continue;
61784
61917
  }
@@ -61788,7 +61921,7 @@ function extractRoutes(cwd) {
61788
61921
  }
61789
61922
  walkDir(fullPath);
61790
61923
  } else if (entry.isFile()) {
61791
- const ext = path50.extname(entry.name).toLowerCase();
61924
+ const ext = path51.extname(entry.name).toLowerCase();
61792
61925
  const baseName = entry.name.toLowerCase();
61793
61926
  if (![".ts", ".js", ".mjs"].includes(ext)) {
61794
61927
  continue;
@@ -61806,7 +61939,7 @@ function extractRoutes(cwd) {
61806
61939
  }
61807
61940
  function extractRoutesFromFile(filePath) {
61808
61941
  const routes = [];
61809
- const content = fs37.readFileSync(filePath, "utf-8");
61942
+ const content = fs38.readFileSync(filePath, "utf-8");
61810
61943
  const lines = content.split(/\r?\n/);
61811
61944
  const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
61812
61945
  const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
@@ -61957,8 +62090,8 @@ init_secretscan();
61957
62090
  // src/tools/symbols.ts
61958
62091
  init_tool();
61959
62092
  init_create_tool();
61960
- import * as fs38 from "fs";
61961
- import * as path51 from "path";
62093
+ import * as fs39 from "fs";
62094
+ import * as path52 from "path";
61962
62095
  var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
61963
62096
  var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
61964
62097
  function containsControlCharacters(str) {
@@ -61987,11 +62120,11 @@ function containsWindowsAttacks(str) {
61987
62120
  }
61988
62121
  function isPathInWorkspace(filePath, workspace) {
61989
62122
  try {
61990
- const resolvedPath = path51.resolve(workspace, filePath);
61991
- const realWorkspace = fs38.realpathSync(workspace);
61992
- const realResolvedPath = fs38.realpathSync(resolvedPath);
61993
- const relativePath = path51.relative(realWorkspace, realResolvedPath);
61994
- if (relativePath.startsWith("..") || path51.isAbsolute(relativePath)) {
62123
+ const resolvedPath = path52.resolve(workspace, filePath);
62124
+ const realWorkspace = fs39.realpathSync(workspace);
62125
+ const realResolvedPath = fs39.realpathSync(resolvedPath);
62126
+ const relativePath = path52.relative(realWorkspace, realResolvedPath);
62127
+ if (relativePath.startsWith("..") || path52.isAbsolute(relativePath)) {
61995
62128
  return false;
61996
62129
  }
61997
62130
  return true;
@@ -62003,17 +62136,17 @@ function validatePathForRead(filePath, workspace) {
62003
62136
  return isPathInWorkspace(filePath, workspace);
62004
62137
  }
62005
62138
  function extractTSSymbols(filePath, cwd) {
62006
- const fullPath = path51.join(cwd, filePath);
62139
+ const fullPath = path52.join(cwd, filePath);
62007
62140
  if (!validatePathForRead(fullPath, cwd)) {
62008
62141
  return [];
62009
62142
  }
62010
62143
  let content;
62011
62144
  try {
62012
- const stats = fs38.statSync(fullPath);
62145
+ const stats = fs39.statSync(fullPath);
62013
62146
  if (stats.size > MAX_FILE_SIZE_BYTES7) {
62014
62147
  throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
62015
62148
  }
62016
- content = fs38.readFileSync(fullPath, "utf-8");
62149
+ content = fs39.readFileSync(fullPath, "utf-8");
62017
62150
  } catch {
62018
62151
  return [];
62019
62152
  }
@@ -62155,17 +62288,17 @@ function extractTSSymbols(filePath, cwd) {
62155
62288
  });
62156
62289
  }
62157
62290
  function extractPythonSymbols(filePath, cwd) {
62158
- const fullPath = path51.join(cwd, filePath);
62291
+ const fullPath = path52.join(cwd, filePath);
62159
62292
  if (!validatePathForRead(fullPath, cwd)) {
62160
62293
  return [];
62161
62294
  }
62162
62295
  let content;
62163
62296
  try {
62164
- const stats = fs38.statSync(fullPath);
62297
+ const stats = fs39.statSync(fullPath);
62165
62298
  if (stats.size > MAX_FILE_SIZE_BYTES7) {
62166
62299
  throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
62167
62300
  }
62168
- content = fs38.readFileSync(fullPath, "utf-8");
62301
+ content = fs39.readFileSync(fullPath, "utf-8");
62169
62302
  } catch {
62170
62303
  return [];
62171
62304
  }
@@ -62238,7 +62371,7 @@ var symbols = createSwarmTool({
62238
62371
  }, null, 2);
62239
62372
  }
62240
62373
  const cwd = directory;
62241
- const ext = path51.extname(file3);
62374
+ const ext = path52.extname(file3);
62242
62375
  if (containsControlCharacters(file3)) {
62243
62376
  return JSON.stringify({
62244
62377
  file: file3,
@@ -62309,8 +62442,8 @@ init_test_runner();
62309
62442
  init_dist();
62310
62443
  init_utils();
62311
62444
  init_create_tool();
62312
- import * as fs39 from "fs";
62313
- import * as path52 from "path";
62445
+ import * as fs40 from "fs";
62446
+ import * as path53 from "path";
62314
62447
  var MAX_TEXT_LENGTH = 200;
62315
62448
  var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
62316
62449
  var SUPPORTED_EXTENSIONS2 = new Set([
@@ -62381,9 +62514,9 @@ function validatePathsInput(paths, cwd) {
62381
62514
  return { error: "paths contains path traversal", resolvedPath: null };
62382
62515
  }
62383
62516
  try {
62384
- const resolvedPath = path52.resolve(paths);
62385
- const normalizedCwd = path52.resolve(cwd);
62386
- const normalizedResolved = path52.resolve(resolvedPath);
62517
+ const resolvedPath = path53.resolve(paths);
62518
+ const normalizedCwd = path53.resolve(cwd);
62519
+ const normalizedResolved = path53.resolve(resolvedPath);
62387
62520
  if (!normalizedResolved.startsWith(normalizedCwd)) {
62388
62521
  return {
62389
62522
  error: "paths must be within the current working directory",
@@ -62399,13 +62532,13 @@ function validatePathsInput(paths, cwd) {
62399
62532
  }
62400
62533
  }
62401
62534
  function isSupportedExtension(filePath) {
62402
- const ext = path52.extname(filePath).toLowerCase();
62535
+ const ext = path53.extname(filePath).toLowerCase();
62403
62536
  return SUPPORTED_EXTENSIONS2.has(ext);
62404
62537
  }
62405
62538
  function findSourceFiles2(dir, files = []) {
62406
62539
  let entries;
62407
62540
  try {
62408
- entries = fs39.readdirSync(dir);
62541
+ entries = fs40.readdirSync(dir);
62409
62542
  } catch {
62410
62543
  return files;
62411
62544
  }
@@ -62414,10 +62547,10 @@ function findSourceFiles2(dir, files = []) {
62414
62547
  if (SKIP_DIRECTORIES3.has(entry)) {
62415
62548
  continue;
62416
62549
  }
62417
- const fullPath = path52.join(dir, entry);
62550
+ const fullPath = path53.join(dir, entry);
62418
62551
  let stat2;
62419
62552
  try {
62420
- stat2 = fs39.statSync(fullPath);
62553
+ stat2 = fs40.statSync(fullPath);
62421
62554
  } catch {
62422
62555
  continue;
62423
62556
  }
@@ -62510,7 +62643,7 @@ var todo_extract = createSwarmTool({
62510
62643
  return JSON.stringify(errorResult, null, 2);
62511
62644
  }
62512
62645
  const scanPath = resolvedPath;
62513
- if (!fs39.existsSync(scanPath)) {
62646
+ if (!fs40.existsSync(scanPath)) {
62514
62647
  const errorResult = {
62515
62648
  error: `path not found: ${pathsInput}`,
62516
62649
  total: 0,
@@ -62520,13 +62653,13 @@ var todo_extract = createSwarmTool({
62520
62653
  return JSON.stringify(errorResult, null, 2);
62521
62654
  }
62522
62655
  const filesToScan = [];
62523
- const stat2 = fs39.statSync(scanPath);
62656
+ const stat2 = fs40.statSync(scanPath);
62524
62657
  if (stat2.isFile()) {
62525
62658
  if (isSupportedExtension(scanPath)) {
62526
62659
  filesToScan.push(scanPath);
62527
62660
  } else {
62528
62661
  const errorResult = {
62529
- error: `unsupported file extension: ${path52.extname(scanPath)}`,
62662
+ error: `unsupported file extension: ${path53.extname(scanPath)}`,
62530
62663
  total: 0,
62531
62664
  byPriority: { high: 0, medium: 0, low: 0 },
62532
62665
  entries: []
@@ -62539,11 +62672,11 @@ var todo_extract = createSwarmTool({
62539
62672
  const allEntries = [];
62540
62673
  for (const filePath of filesToScan) {
62541
62674
  try {
62542
- const fileStat = fs39.statSync(filePath);
62675
+ const fileStat = fs40.statSync(filePath);
62543
62676
  if (fileStat.size > MAX_FILE_SIZE_BYTES8) {
62544
62677
  continue;
62545
62678
  }
62546
- const content = fs39.readFileSync(filePath, "utf-8");
62679
+ const content = fs40.readFileSync(filePath, "utf-8");
62547
62680
  const entries = parseTodoComments(content, filePath, tagsSet);
62548
62681
  allEntries.push(...entries);
62549
62682
  } catch {}
@@ -62571,18 +62704,18 @@ var todo_extract = createSwarmTool({
62571
62704
  // src/tools/update-task-status.ts
62572
62705
  init_tool();
62573
62706
  init_schema();
62574
- import * as fs41 from "fs";
62575
- import * as path54 from "path";
62707
+ import * as fs42 from "fs";
62708
+ import * as path55 from "path";
62576
62709
 
62577
62710
  // src/hooks/diff-scope.ts
62578
- import * as fs40 from "fs";
62579
- import * as path53 from "path";
62711
+ import * as fs41 from "fs";
62712
+ import * as path54 from "path";
62580
62713
  function getDeclaredScope(taskId, directory) {
62581
62714
  try {
62582
- const planPath = path53.join(directory, ".swarm", "plan.json");
62583
- if (!fs40.existsSync(planPath))
62715
+ const planPath = path54.join(directory, ".swarm", "plan.json");
62716
+ if (!fs41.existsSync(planPath))
62584
62717
  return null;
62585
- const raw = fs40.readFileSync(planPath, "utf-8");
62718
+ const raw = fs41.readFileSync(planPath, "utf-8");
62586
62719
  const plan = JSON.parse(raw);
62587
62720
  for (const phase of plan.phases ?? []) {
62588
62721
  for (const task of phase.tasks ?? []) {
@@ -62694,7 +62827,7 @@ var TIER_3_PATTERNS = [
62694
62827
  ];
62695
62828
  function matchesTier3Pattern(files) {
62696
62829
  for (const file3 of files) {
62697
- const fileName = path54.basename(file3);
62830
+ const fileName = path55.basename(file3);
62698
62831
  for (const pattern of TIER_3_PATTERNS) {
62699
62832
  if (pattern.test(fileName)) {
62700
62833
  return true;
@@ -62716,8 +62849,8 @@ function checkReviewerGate(taskId, workingDirectory) {
62716
62849
  if (hasActiveTurboMode2()) {
62717
62850
  const resolvedDir2 = workingDirectory ?? process.cwd();
62718
62851
  try {
62719
- const planPath = path54.join(resolvedDir2, ".swarm", "plan.json");
62720
- const planRaw = fs41.readFileSync(planPath, "utf-8");
62852
+ const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
62853
+ const planRaw = fs42.readFileSync(planPath, "utf-8");
62721
62854
  const plan = JSON.parse(planRaw);
62722
62855
  for (const planPhase of plan.phases ?? []) {
62723
62856
  for (const task of planPhase.tasks ?? []) {
@@ -62736,8 +62869,8 @@ function checkReviewerGate(taskId, workingDirectory) {
62736
62869
  }
62737
62870
  const resolvedDir = workingDirectory ?? process.cwd();
62738
62871
  try {
62739
- const evidencePath = path54.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
62740
- const raw = fs41.readFileSync(evidencePath, "utf-8");
62872
+ const evidencePath = path55.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
62873
+ const raw = fs42.readFileSync(evidencePath, "utf-8");
62741
62874
  const evidence = JSON.parse(raw);
62742
62875
  if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
62743
62876
  const allGatesMet = evidence.required_gates.every((gate) => evidence.gates[gate] != null);
@@ -62777,8 +62910,8 @@ function checkReviewerGate(taskId, workingDirectory) {
62777
62910
  }
62778
62911
  try {
62779
62912
  const resolvedDir2 = workingDirectory ?? process.cwd();
62780
- const planPath = path54.join(resolvedDir2, ".swarm", "plan.json");
62781
- const planRaw = fs41.readFileSync(planPath, "utf-8");
62913
+ const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
62914
+ const planRaw = fs42.readFileSync(planPath, "utf-8");
62782
62915
  const plan = JSON.parse(planRaw);
62783
62916
  for (const planPhase of plan.phases ?? []) {
62784
62917
  for (const task of planPhase.tasks ?? []) {
@@ -62959,8 +63092,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
62959
63092
  };
62960
63093
  }
62961
63094
  }
62962
- normalizedDir = path54.normalize(args2.working_directory);
62963
- const pathParts = normalizedDir.split(path54.sep);
63095
+ normalizedDir = path55.normalize(args2.working_directory);
63096
+ const pathParts = normalizedDir.split(path55.sep);
62964
63097
  if (pathParts.includes("..")) {
62965
63098
  return {
62966
63099
  success: false,
@@ -62970,11 +63103,11 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
62970
63103
  ]
62971
63104
  };
62972
63105
  }
62973
- const resolvedDir = path54.resolve(normalizedDir);
63106
+ const resolvedDir = path55.resolve(normalizedDir);
62974
63107
  try {
62975
- const realPath = fs41.realpathSync(resolvedDir);
62976
- const planPath = path54.join(realPath, ".swarm", "plan.json");
62977
- if (!fs41.existsSync(planPath)) {
63108
+ const realPath = fs42.realpathSync(resolvedDir);
63109
+ const planPath = path55.join(realPath, ".swarm", "plan.json");
63110
+ if (!fs42.existsSync(planPath)) {
62978
63111
  return {
62979
63112
  success: false,
62980
63113
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -63168,7 +63301,7 @@ var OpenCodeSwarm = async (ctx) => {
63168
63301
  const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
63169
63302
  preflightTriggerManager = new PTM(automationConfig);
63170
63303
  const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
63171
- const swarmDir = path55.resolve(ctx.directory, ".swarm");
63304
+ const swarmDir = path56.resolve(ctx.directory, ".swarm");
63172
63305
  statusArtifact = new ASA(swarmDir);
63173
63306
  statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
63174
63307
  if (automationConfig.capabilities?.evidence_auto_summaries === true) {