opencode-swarm 6.29.1 → 6.29.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -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")
@@ -45509,6 +45541,58 @@ async function checkSteeringDirectives(directory) {
45509
45541
  };
45510
45542
  }
45511
45543
  }
45544
+ async function checkCurator(directory) {
45545
+ try {
45546
+ const config3 = loadPluginConfig(directory);
45547
+ if (!config3.curator?.enabled) {
45548
+ return {
45549
+ name: "Curator",
45550
+ status: "\u2705",
45551
+ detail: "Disabled (enable via curator.enabled)"
45552
+ };
45553
+ }
45554
+ const summaryPath = path16.join(directory, ".swarm/curator-summary.json");
45555
+ if (!existsSync6(summaryPath)) {
45556
+ return {
45557
+ name: "Curator",
45558
+ status: "\u2705",
45559
+ detail: "Enabled, no summary yet (waiting for first phase)"
45560
+ };
45561
+ }
45562
+ try {
45563
+ const content = readFileSync4(summaryPath, "utf-8");
45564
+ const parsed = JSON.parse(content);
45565
+ if (typeof parsed.schema_version !== "number" || parsed.schema_version !== 1) {
45566
+ return {
45567
+ name: "Curator",
45568
+ status: "\u274C",
45569
+ detail: `curator-summary.json has invalid schema_version (expected 1, got ${JSON.stringify(parsed.schema_version)})`
45570
+ };
45571
+ }
45572
+ const phaseInfo = parsed.last_phase_covered !== undefined ? `phase ${parsed.last_phase_covered}` : "unknown phase";
45573
+ const timeInfo = parsed.last_updated ? `, updated ${parsed.last_updated}` : "";
45574
+ return {
45575
+ name: "Curator",
45576
+ status: "\u2705",
45577
+ detail: `Summary present \u2014 covering ${phaseInfo}${timeInfo}`
45578
+ };
45579
+ } catch (err2) {
45580
+ const message = err2 instanceof Error ? err2.message : "Unknown error";
45581
+ return {
45582
+ name: "Curator",
45583
+ status: "\u274C",
45584
+ detail: `curator-summary.json is corrupt or invalid: ${message}`
45585
+ };
45586
+ }
45587
+ } catch (err2) {
45588
+ const message = err2 instanceof Error ? err2.message : "Unknown error";
45589
+ return {
45590
+ name: "Curator",
45591
+ status: "\u274C",
45592
+ detail: `Could not check curator state: ${message}`
45593
+ };
45594
+ }
45595
+ }
45512
45596
  async function getDiagnoseData(directory) {
45513
45597
  const checks5 = [];
45514
45598
  const plan = await loadPlanJsonOnly(directory);
@@ -45613,6 +45697,7 @@ async function getDiagnoseData(directory) {
45613
45697
  checks5.push(await checkCheckpointManifest(directory));
45614
45698
  checks5.push(await checkEventStreamIntegrity(directory));
45615
45699
  checks5.push(await checkSteeringDirectives(directory));
45700
+ checks5.push(await checkCurator(directory));
45616
45701
  const passCount = checks5.filter((c) => c.status === "\u2705").length;
45617
45702
  const totalCount = checks5.length;
45618
45703
  const allPassed = passCount === totalCount;
@@ -52432,53 +52517,111 @@ function createDarkMatterDetectorHook(directory) {
52432
52517
  // src/hooks/incremental-verify.ts
52433
52518
  import * as fs20 from "fs";
52434
52519
  import * as path32 from "path";
52520
+
52521
+ // src/hooks/spawn-helper.ts
52522
+ import { spawn } from "child_process";
52523
+ function spawnAsync(command, cwd, timeoutMs) {
52524
+ return new Promise((resolve11) => {
52525
+ try {
52526
+ const [cmd, ...args2] = command;
52527
+ const proc = spawn(cmd, args2, { cwd, stdio: ["ignore", "pipe", "pipe"] });
52528
+ let stdout = "";
52529
+ let stderr = "";
52530
+ let done = false;
52531
+ proc.stdout.on("data", (d) => {
52532
+ stdout += d;
52533
+ });
52534
+ proc.stderr.on("data", (d) => {
52535
+ stderr += d;
52536
+ });
52537
+ const timer = setTimeout(() => {
52538
+ if (done)
52539
+ return;
52540
+ done = true;
52541
+ try {
52542
+ proc.stdout.destroy();
52543
+ } catch {}
52544
+ try {
52545
+ proc.stderr.destroy();
52546
+ } catch {}
52547
+ try {
52548
+ proc.kill();
52549
+ } catch {}
52550
+ resolve11(null);
52551
+ }, timeoutMs);
52552
+ proc.on("close", (code) => {
52553
+ if (done)
52554
+ return;
52555
+ done = true;
52556
+ clearTimeout(timer);
52557
+ resolve11({ exitCode: code ?? 1, stdout, stderr });
52558
+ });
52559
+ proc.on("error", () => {
52560
+ if (done)
52561
+ return;
52562
+ done = true;
52563
+ clearTimeout(timer);
52564
+ resolve11(null);
52565
+ });
52566
+ } catch {
52567
+ resolve11(null);
52568
+ }
52569
+ });
52570
+ }
52571
+
52572
+ // src/hooks/incremental-verify.ts
52573
+ var emittedSkipAdvisories = new Set;
52435
52574
  function detectTypecheckCommand(projectDir) {
52436
52575
  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"))) {
52576
+ if (fs20.existsSync(pkgPath)) {
52577
+ try {
52578
+ const pkg = JSON.parse(fs20.readFileSync(pkgPath, "utf8"));
52579
+ const scripts = pkg.scripts;
52580
+ if (scripts?.typecheck)
52581
+ return { command: ["bun", "run", "typecheck"], language: "typescript" };
52582
+ if (scripts?.["type-check"])
52583
+ return {
52584
+ command: ["bun", "run", "type-check"],
52585
+ language: "typescript"
52586
+ };
52587
+ const deps = {
52588
+ ...pkg.dependencies,
52589
+ ...pkg.devDependencies
52590
+ };
52591
+ if (!deps?.typescript && !fs20.existsSync(path32.join(projectDir, "tsconfig.json"))) {}
52592
+ const hasTSMarkers = deps?.typescript || fs20.existsSync(path32.join(projectDir, "tsconfig.json"));
52593
+ if (hasTSMarkers) {
52594
+ return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
52595
+ }
52596
+ } catch {
52451
52597
  return null;
52452
52598
  }
52453
- return ["npx", "tsc", "--noEmit"];
52454
- } catch {
52455
- return null;
52456
52599
  }
52457
- }
52458
- async function runWithTimeout(command, cwd, timeoutMs) {
52600
+ if (fs20.existsSync(path32.join(projectDir, "go.mod"))) {
52601
+ return { command: ["go", "vet", "./..."], language: "go" };
52602
+ }
52603
+ if (fs20.existsSync(path32.join(projectDir, "Cargo.toml"))) {
52604
+ return { command: ["cargo", "check"], language: "rust" };
52605
+ }
52606
+ if (fs20.existsSync(path32.join(projectDir, "pyproject.toml")) || fs20.existsSync(path32.join(projectDir, "requirements.txt")) || fs20.existsSync(path32.join(projectDir, "setup.py"))) {
52607
+ return { command: null, language: "python" };
52608
+ }
52459
52609
  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);
52610
+ const entries = fs20.readdirSync(projectDir);
52611
+ if (entries.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
52612
+ return {
52613
+ command: ["dotnet", "build", "--no-restore"],
52614
+ language: "csharp"
52615
+ };
52478
52616
  }
52479
- } catch {
52617
+ } catch {}
52618
+ return null;
52619
+ }
52620
+ async function runWithTimeout(command, cwd, timeoutMs) {
52621
+ const result = await spawnAsync(command, cwd, timeoutMs);
52622
+ if (result === null)
52480
52623
  return null;
52481
- }
52624
+ return { exitCode: result.exitCode, stderr: result.stderr };
52482
52625
  }
52483
52626
  function createIncrementalVerifyHook(config3, projectDir, injectMessage) {
52484
52627
  return {
@@ -52493,10 +52636,27 @@ function createIncrementalVerifyHook(config3, projectDir, injectMessage) {
52493
52636
  if (!config3.triggerAgents.includes(agentName) && !config3.triggerAgents.includes(subagentType)) {
52494
52637
  return;
52495
52638
  }
52496
- const command = config3.command != null ? config3.command.split(" ") : detectTypecheckCommand(projectDir);
52497
- if (!command)
52639
+ let commandToRun = null;
52640
+ if (config3.command != null) {
52641
+ commandToRun = Array.isArray(config3.command) ? config3.command : config3.command.split(" ");
52642
+ } else {
52643
+ const detected = detectTypecheckCommand(projectDir);
52644
+ if (detected === null) {
52645
+ return;
52646
+ }
52647
+ if (detected.command === null) {
52648
+ const dedupKey = `${input.sessionID}:${detected.language}`;
52649
+ if (!emittedSkipAdvisories.has(dedupKey)) {
52650
+ emittedSkipAdvisories.add(dedupKey);
52651
+ 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.`);
52652
+ }
52653
+ return;
52654
+ }
52655
+ commandToRun = detected.command;
52656
+ }
52657
+ if (commandToRun === null)
52498
52658
  return;
52499
- const result = await runWithTimeout(command, projectDir, config3.timeoutMs);
52659
+ const result = await runWithTimeout(commandToRun, projectDir, config3.timeoutMs);
52500
52660
  if (result === null) {
52501
52661
  return;
52502
52662
  }
@@ -53422,6 +53582,8 @@ ${cachedInjectionText}`;
53422
53582
  }
53423
53583
 
53424
53584
  // src/hooks/slop-detector.ts
53585
+ import * as fs22 from "fs";
53586
+ import * as path35 from "path";
53425
53587
  var WRITE_EDIT_TOOLS = new Set([
53426
53588
  "write",
53427
53589
  "edit",
@@ -53432,7 +53594,7 @@ function countMatches(text, pattern) {
53432
53594
  return (text.match(pattern) ?? []).length;
53433
53595
  }
53434
53596
  function checkAbstractionBloat(content, threshold) {
53435
- const newClasses = countMatches(content, /^\+.*\bclass\s+\w+/gm);
53597
+ const newClasses = countMatches(content, /^\+.*\b(?:class|struct|impl)\s+\w+/gm);
53436
53598
  if (newClasses >= threshold) {
53437
53599
  return {
53438
53600
  type: "abstraction_bloat",
@@ -53442,8 +53604,8 @@ function checkAbstractionBloat(content, threshold) {
53442
53604
  return null;
53443
53605
  }
53444
53606
  function checkCommentStrip(content, threshold) {
53445
- const removedComments = countMatches(content, /^-\s*\/[/*]/gm);
53446
- const addedComments = countMatches(content, /^\+\s*\/[/*]/gm);
53607
+ const removedComments = countMatches(content, /^-\s*(?:\/[/*]|#|--)/gm);
53608
+ const addedComments = countMatches(content, /^\+\s*(?:\/[/*]|#|--)/gm);
53447
53609
  if (removedComments >= threshold && addedComments === 0) {
53448
53610
  return {
53449
53611
  type: "comment_strip",
@@ -53463,8 +53625,33 @@ function checkBoilerplateExplosion(content, taskDescription, threshold) {
53463
53625
  }
53464
53626
  return null;
53465
53627
  }
53466
- async function checkDeadExports(content, projectDir, startTime) {
53467
- const exportMatches = content.matchAll(/^(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
53628
+ function walkFiles(dir, exts, deadline) {
53629
+ const results = [];
53630
+ try {
53631
+ for (const entry of fs22.readdirSync(dir, { withFileTypes: true })) {
53632
+ if (deadline !== undefined && Date.now() > deadline)
53633
+ break;
53634
+ if (entry.isSymbolicLink())
53635
+ continue;
53636
+ const full = path35.join(dir, entry.name);
53637
+ if (entry.isDirectory()) {
53638
+ if (entry.name === "node_modules" || entry.name === ".git")
53639
+ continue;
53640
+ results.push(...walkFiles(full, exts, deadline));
53641
+ } else if (entry.isFile()) {
53642
+ if (exts.some((ext) => entry.name.endsWith(ext))) {
53643
+ results.push(full);
53644
+ }
53645
+ }
53646
+ }
53647
+ } catch {}
53648
+ return results;
53649
+ }
53650
+ function checkDeadExports(content, projectDir, startTime) {
53651
+ const hasPackageJson = fs22.existsSync(path35.join(projectDir, "package.json"));
53652
+ if (!hasPackageJson)
53653
+ return null;
53654
+ const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
53468
53655
  const newExports = [];
53469
53656
  for (const match of exportMatches) {
53470
53657
  if (match[1])
@@ -53472,19 +53659,19 @@ async function checkDeadExports(content, projectDir, startTime) {
53472
53659
  }
53473
53660
  if (newExports.length === 0)
53474
53661
  return null;
53662
+ const files = walkFiles(projectDir, [".ts", ".tsx", ".js", ".jsx"], startTime + 480);
53475
53663
  const deadExports = [];
53476
53664
  for (const name2 of newExports) {
53477
53665
  if (Date.now() - startTime > 480)
53478
53666
  break;
53479
53667
  try {
53480
53668
  const importPattern = new RegExp(`\\bimport\\b[^;]*\\b${name2}\\b`, "g");
53481
- const glob = new Bun.Glob(`src/**/*.ts`);
53482
53669
  let found = false;
53483
- for await (const file3 of glob.scan(projectDir)) {
53670
+ for (const file3 of files) {
53484
53671
  if (found || Date.now() - startTime > 480)
53485
53672
  break;
53486
53673
  try {
53487
- const text = await Bun.file(`${projectDir}/${file3}`).text();
53674
+ const text = fs22.readFileSync(file3, "utf-8");
53488
53675
  if (importPattern.test(text))
53489
53676
  found = true;
53490
53677
  importPattern.lastIndex = 0;
@@ -53538,7 +53725,7 @@ function createSlopDetectorHook(config3, projectDir, injectSystemMessage) {
53538
53725
  } catch {}
53539
53726
  if (Date.now() - startTime < 400) {
53540
53727
  try {
53541
- const dead = await checkDeadExports(content, projectDir, startTime);
53728
+ const dead = checkDeadExports(content, projectDir, startTime);
53542
53729
  if (dead)
53543
53730
  findings.push(dead);
53544
53731
  } catch {}
@@ -53557,7 +53744,7 @@ Review before proceeding.`;
53557
53744
 
53558
53745
  // src/hooks/steering-consumed.ts
53559
53746
  init_utils2();
53560
- import * as fs22 from "fs";
53747
+ import * as fs23 from "fs";
53561
53748
  function recordSteeringConsumed(directory, directiveId) {
53562
53749
  try {
53563
53750
  const eventsPath = validateSwarmPath(directory, "events.jsonl");
@@ -53566,7 +53753,7 @@ function recordSteeringConsumed(directory, directiveId) {
53566
53753
  directiveId,
53567
53754
  timestamp: new Date().toISOString()
53568
53755
  };
53569
- fs22.appendFileSync(eventsPath, `${JSON.stringify(event)}
53756
+ fs23.appendFileSync(eventsPath, `${JSON.stringify(event)}
53570
53757
  `, "utf-8");
53571
53758
  } catch {}
53572
53759
  }
@@ -53611,7 +53798,7 @@ init_config_doctor();
53611
53798
 
53612
53799
  // src/session/snapshot-reader.ts
53613
53800
  init_utils2();
53614
- import path35 from "path";
53801
+ import path36 from "path";
53615
53802
  var VALID_TASK_WORKFLOW_STATES = [
53616
53803
  "idle",
53617
53804
  "coder_delegated",
@@ -53736,7 +53923,7 @@ function rehydrateState(snapshot) {
53736
53923
  async function reconcileTaskStatesFromPlan(directory) {
53737
53924
  let raw;
53738
53925
  try {
53739
- raw = await Bun.file(path35.join(directory, ".swarm/plan.json")).text();
53926
+ raw = await Bun.file(path36.join(directory, ".swarm/plan.json")).text();
53740
53927
  } catch {
53741
53928
  return;
53742
53929
  }
@@ -53958,8 +54145,8 @@ var build_check = createSwarmTool({
53958
54145
  // src/tools/check-gate-status.ts
53959
54146
  init_dist();
53960
54147
  init_create_tool();
53961
- import * as fs23 from "fs";
53962
- import * as path36 from "path";
54148
+ import * as fs24 from "fs";
54149
+ import * as path37 from "path";
53963
54150
  var EVIDENCE_DIR = ".swarm/evidence";
53964
54151
  var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
53965
54152
  function isValidTaskId3(taskId) {
@@ -53976,18 +54163,18 @@ function isValidTaskId3(taskId) {
53976
54163
  return TASK_ID_PATTERN2.test(taskId);
53977
54164
  }
53978
54165
  function isPathWithinSwarm(filePath, workspaceRoot) {
53979
- const normalizedWorkspace = path36.resolve(workspaceRoot);
53980
- const swarmPath = path36.join(normalizedWorkspace, ".swarm", "evidence");
53981
- const normalizedPath = path36.resolve(filePath);
54166
+ const normalizedWorkspace = path37.resolve(workspaceRoot);
54167
+ const swarmPath = path37.join(normalizedWorkspace, ".swarm", "evidence");
54168
+ const normalizedPath = path37.resolve(filePath);
53982
54169
  return normalizedPath.startsWith(swarmPath);
53983
54170
  }
53984
54171
  function readEvidenceFile(evidencePath) {
53985
- if (!fs23.existsSync(evidencePath)) {
54172
+ if (!fs24.existsSync(evidencePath)) {
53986
54173
  return null;
53987
54174
  }
53988
54175
  let content;
53989
54176
  try {
53990
- content = fs23.readFileSync(evidencePath, "utf-8");
54177
+ content = fs24.readFileSync(evidencePath, "utf-8");
53991
54178
  } catch {
53992
54179
  return null;
53993
54180
  }
@@ -54039,7 +54226,7 @@ var check_gate_status = createSwarmTool({
54039
54226
  };
54040
54227
  return JSON.stringify(errorResult, null, 2);
54041
54228
  }
54042
- const evidencePath = path36.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
54229
+ const evidencePath = path37.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
54043
54230
  if (!isPathWithinSwarm(evidencePath, directory)) {
54044
54231
  const errorResult = {
54045
54232
  taskId: taskIdInput,
@@ -54099,8 +54286,8 @@ var check_gate_status = createSwarmTool({
54099
54286
  init_tool();
54100
54287
  init_create_tool();
54101
54288
  import { spawnSync } from "child_process";
54102
- import * as fs24 from "fs";
54103
- import * as path37 from "path";
54289
+ import * as fs25 from "fs";
54290
+ import * as path38 from "path";
54104
54291
  var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
54105
54292
  var MAX_LABEL_LENGTH = 100;
54106
54293
  var GIT_TIMEOUT_MS = 30000;
@@ -54151,13 +54338,13 @@ function validateLabel(label) {
54151
54338
  return null;
54152
54339
  }
54153
54340
  function getCheckpointLogPath(directory) {
54154
- return path37.join(directory, CHECKPOINT_LOG_PATH);
54341
+ return path38.join(directory, CHECKPOINT_LOG_PATH);
54155
54342
  }
54156
54343
  function readCheckpointLog(directory) {
54157
54344
  const logPath = getCheckpointLogPath(directory);
54158
54345
  try {
54159
- if (fs24.existsSync(logPath)) {
54160
- const content = fs24.readFileSync(logPath, "utf-8");
54346
+ if (fs25.existsSync(logPath)) {
54347
+ const content = fs25.readFileSync(logPath, "utf-8");
54161
54348
  const parsed = JSON.parse(content);
54162
54349
  if (!parsed.checkpoints || !Array.isArray(parsed.checkpoints)) {
54163
54350
  return { version: 1, checkpoints: [] };
@@ -54169,13 +54356,13 @@ function readCheckpointLog(directory) {
54169
54356
  }
54170
54357
  function writeCheckpointLog(log2, directory) {
54171
54358
  const logPath = getCheckpointLogPath(directory);
54172
- const dir = path37.dirname(logPath);
54173
- if (!fs24.existsSync(dir)) {
54174
- fs24.mkdirSync(dir, { recursive: true });
54359
+ const dir = path38.dirname(logPath);
54360
+ if (!fs25.existsSync(dir)) {
54361
+ fs25.mkdirSync(dir, { recursive: true });
54175
54362
  }
54176
54363
  const tempPath = `${logPath}.tmp`;
54177
- fs24.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
54178
- fs24.renameSync(tempPath, logPath);
54364
+ fs25.writeFileSync(tempPath, JSON.stringify(log2, null, 2), "utf-8");
54365
+ fs25.renameSync(tempPath, logPath);
54179
54366
  }
54180
54367
  function gitExec(args2) {
54181
54368
  const result = spawnSync("git", args2, {
@@ -54376,8 +54563,8 @@ var checkpoint = createSwarmTool({
54376
54563
  // src/tools/complexity-hotspots.ts
54377
54564
  init_dist();
54378
54565
  init_create_tool();
54379
- import * as fs25 from "fs";
54380
- import * as path38 from "path";
54566
+ import * as fs26 from "fs";
54567
+ import * as path39 from "path";
54381
54568
  var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
54382
54569
  var DEFAULT_DAYS = 90;
54383
54570
  var DEFAULT_TOP_N = 20;
@@ -54506,11 +54693,11 @@ function estimateComplexity(content) {
54506
54693
  }
54507
54694
  function getComplexityForFile(filePath) {
54508
54695
  try {
54509
- const stat2 = fs25.statSync(filePath);
54696
+ const stat2 = fs26.statSync(filePath);
54510
54697
  if (stat2.size > MAX_FILE_SIZE_BYTES2) {
54511
54698
  return null;
54512
54699
  }
54513
- const content = fs25.readFileSync(filePath, "utf-8");
54700
+ const content = fs26.readFileSync(filePath, "utf-8");
54514
54701
  return estimateComplexity(content);
54515
54702
  } catch {
54516
54703
  return null;
@@ -54521,7 +54708,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
54521
54708
  const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
54522
54709
  const filteredChurn = new Map;
54523
54710
  for (const [file3, count] of churnMap) {
54524
- const ext = path38.extname(file3).toLowerCase();
54711
+ const ext = path39.extname(file3).toLowerCase();
54525
54712
  if (extSet.has(ext)) {
54526
54713
  filteredChurn.set(file3, count);
54527
54714
  }
@@ -54531,8 +54718,8 @@ async function analyzeHotspots(days, topN, extensions, directory) {
54531
54718
  let analyzedFiles = 0;
54532
54719
  for (const [file3, churnCount] of filteredChurn) {
54533
54720
  let fullPath = file3;
54534
- if (!fs25.existsSync(fullPath)) {
54535
- fullPath = path38.join(cwd, file3);
54721
+ if (!fs26.existsSync(fullPath)) {
54722
+ fullPath = path39.join(cwd, file3);
54536
54723
  }
54537
54724
  const complexity = getComplexityForFile(fullPath);
54538
54725
  if (complexity !== null) {
@@ -54679,8 +54866,8 @@ var complexity_hotspots = createSwarmTool({
54679
54866
  });
54680
54867
  // src/tools/declare-scope.ts
54681
54868
  init_tool();
54682
- import * as fs26 from "fs";
54683
- import * as path39 from "path";
54869
+ import * as fs27 from "fs";
54870
+ import * as path40 from "path";
54684
54871
  init_create_tool();
54685
54872
  function validateTaskIdFormat(taskId) {
54686
54873
  const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
@@ -54759,8 +54946,8 @@ async function executeDeclareScope(args2, fallbackDir) {
54759
54946
  };
54760
54947
  }
54761
54948
  }
54762
- normalizedDir = path39.normalize(args2.working_directory);
54763
- const pathParts = normalizedDir.split(path39.sep);
54949
+ normalizedDir = path40.normalize(args2.working_directory);
54950
+ const pathParts = normalizedDir.split(path40.sep);
54764
54951
  if (pathParts.includes("..")) {
54765
54952
  return {
54766
54953
  success: false,
@@ -54770,11 +54957,11 @@ async function executeDeclareScope(args2, fallbackDir) {
54770
54957
  ]
54771
54958
  };
54772
54959
  }
54773
- const resolvedDir = path39.resolve(normalizedDir);
54960
+ const resolvedDir = path40.resolve(normalizedDir);
54774
54961
  try {
54775
- const realPath = fs26.realpathSync(resolvedDir);
54776
- const planPath2 = path39.join(realPath, ".swarm", "plan.json");
54777
- if (!fs26.existsSync(planPath2)) {
54962
+ const realPath = fs27.realpathSync(resolvedDir);
54963
+ const planPath2 = path40.join(realPath, ".swarm", "plan.json");
54964
+ if (!fs27.existsSync(planPath2)) {
54778
54965
  return {
54779
54966
  success: false,
54780
54967
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -54794,8 +54981,8 @@ async function executeDeclareScope(args2, fallbackDir) {
54794
54981
  }
54795
54982
  }
54796
54983
  const directory = normalizedDir ?? fallbackDir ?? process.cwd();
54797
- const planPath = path39.resolve(directory, ".swarm", "plan.json");
54798
- if (!fs26.existsSync(planPath)) {
54984
+ const planPath = path40.resolve(directory, ".swarm", "plan.json");
54985
+ if (!fs27.existsSync(planPath)) {
54799
54986
  return {
54800
54987
  success: false,
54801
54988
  message: "No plan found",
@@ -54804,7 +54991,7 @@ async function executeDeclareScope(args2, fallbackDir) {
54804
54991
  }
54805
54992
  let planContent;
54806
54993
  try {
54807
- planContent = JSON.parse(fs26.readFileSync(planPath, "utf-8"));
54994
+ planContent = JSON.parse(fs27.readFileSync(planPath, "utf-8"));
54808
54995
  } catch {
54809
54996
  return {
54810
54997
  success: false,
@@ -54884,20 +55071,20 @@ function validateBase(base) {
54884
55071
  function validatePaths(paths) {
54885
55072
  if (!paths)
54886
55073
  return null;
54887
- for (const path40 of paths) {
54888
- if (!path40 || path40.length === 0) {
55074
+ for (const path41 of paths) {
55075
+ if (!path41 || path41.length === 0) {
54889
55076
  return "empty path not allowed";
54890
55077
  }
54891
- if (path40.length > MAX_PATH_LENGTH) {
55078
+ if (path41.length > MAX_PATH_LENGTH) {
54892
55079
  return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
54893
55080
  }
54894
- if (SHELL_METACHARACTERS2.test(path40)) {
55081
+ if (SHELL_METACHARACTERS2.test(path41)) {
54895
55082
  return "path contains shell metacharacters";
54896
55083
  }
54897
- if (path40.startsWith("-")) {
55084
+ if (path41.startsWith("-")) {
54898
55085
  return 'path cannot start with "-" (option-like arguments not allowed)';
54899
55086
  }
54900
- if (CONTROL_CHAR_PATTERN2.test(path40)) {
55087
+ if (CONTROL_CHAR_PATTERN2.test(path41)) {
54901
55088
  return "path contains control characters";
54902
55089
  }
54903
55090
  }
@@ -54977,8 +55164,8 @@ var diff = tool({
54977
55164
  if (parts2.length >= 3) {
54978
55165
  const additions = parseInt(parts2[0], 10) || 0;
54979
55166
  const deletions = parseInt(parts2[1], 10) || 0;
54980
- const path40 = parts2[2];
54981
- files.push({ path: path40, additions, deletions });
55167
+ const path41 = parts2[2];
55168
+ files.push({ path: path41, additions, deletions });
54982
55169
  }
54983
55170
  }
54984
55171
  const contractChanges = [];
@@ -55207,8 +55394,8 @@ Use these as DOMAIN values when delegating to @sme.`;
55207
55394
  // src/tools/evidence-check.ts
55208
55395
  init_dist();
55209
55396
  init_create_tool();
55210
- import * as fs27 from "fs";
55211
- import * as path40 from "path";
55397
+ import * as fs28 from "fs";
55398
+ import * as path41 from "path";
55212
55399
  var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
55213
55400
  var MAX_EVIDENCE_FILES = 1000;
55214
55401
  var EVIDENCE_DIR2 = ".swarm/evidence";
@@ -55238,9 +55425,9 @@ function validateRequiredTypes(input) {
55238
55425
  return null;
55239
55426
  }
55240
55427
  function isPathWithinSwarm2(filePath, cwd) {
55241
- const normalizedCwd = path40.resolve(cwd);
55242
- const swarmPath = path40.join(normalizedCwd, ".swarm");
55243
- const normalizedPath = path40.resolve(filePath);
55428
+ const normalizedCwd = path41.resolve(cwd);
55429
+ const swarmPath = path41.join(normalizedCwd, ".swarm");
55430
+ const normalizedPath = path41.resolve(filePath);
55244
55431
  return normalizedPath.startsWith(swarmPath);
55245
55432
  }
55246
55433
  function parseCompletedTasks(planContent) {
@@ -55256,12 +55443,12 @@ function parseCompletedTasks(planContent) {
55256
55443
  }
55257
55444
  function readEvidenceFiles(evidenceDir, _cwd) {
55258
55445
  const evidence = [];
55259
- if (!fs27.existsSync(evidenceDir) || !fs27.statSync(evidenceDir).isDirectory()) {
55446
+ if (!fs28.existsSync(evidenceDir) || !fs28.statSync(evidenceDir).isDirectory()) {
55260
55447
  return evidence;
55261
55448
  }
55262
55449
  let files;
55263
55450
  try {
55264
- files = fs27.readdirSync(evidenceDir);
55451
+ files = fs28.readdirSync(evidenceDir);
55265
55452
  } catch {
55266
55453
  return evidence;
55267
55454
  }
@@ -55270,14 +55457,14 @@ function readEvidenceFiles(evidenceDir, _cwd) {
55270
55457
  if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
55271
55458
  continue;
55272
55459
  }
55273
- const filePath = path40.join(evidenceDir, filename);
55460
+ const filePath = path41.join(evidenceDir, filename);
55274
55461
  try {
55275
- const resolvedPath = path40.resolve(filePath);
55276
- const evidenceDirResolved = path40.resolve(evidenceDir);
55462
+ const resolvedPath = path41.resolve(filePath);
55463
+ const evidenceDirResolved = path41.resolve(evidenceDir);
55277
55464
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
55278
55465
  continue;
55279
55466
  }
55280
- const stat2 = fs27.lstatSync(filePath);
55467
+ const stat2 = fs28.lstatSync(filePath);
55281
55468
  if (!stat2.isFile()) {
55282
55469
  continue;
55283
55470
  }
@@ -55286,7 +55473,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
55286
55473
  }
55287
55474
  let fileStat;
55288
55475
  try {
55289
- fileStat = fs27.statSync(filePath);
55476
+ fileStat = fs28.statSync(filePath);
55290
55477
  if (fileStat.size > MAX_FILE_SIZE_BYTES3) {
55291
55478
  continue;
55292
55479
  }
@@ -55295,7 +55482,7 @@ function readEvidenceFiles(evidenceDir, _cwd) {
55295
55482
  }
55296
55483
  let content;
55297
55484
  try {
55298
- content = fs27.readFileSync(filePath, "utf-8");
55485
+ content = fs28.readFileSync(filePath, "utf-8");
55299
55486
  } catch {
55300
55487
  continue;
55301
55488
  }
@@ -55391,7 +55578,7 @@ var evidence_check = createSwarmTool({
55391
55578
  return JSON.stringify(errorResult, null, 2);
55392
55579
  }
55393
55580
  const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
55394
- const planPath = path40.join(cwd, PLAN_FILE);
55581
+ const planPath = path41.join(cwd, PLAN_FILE);
55395
55582
  if (!isPathWithinSwarm2(planPath, cwd)) {
55396
55583
  const errorResult = {
55397
55584
  error: "plan file path validation failed",
@@ -55405,7 +55592,7 @@ var evidence_check = createSwarmTool({
55405
55592
  }
55406
55593
  let planContent;
55407
55594
  try {
55408
- planContent = fs27.readFileSync(planPath, "utf-8");
55595
+ planContent = fs28.readFileSync(planPath, "utf-8");
55409
55596
  } catch {
55410
55597
  const result2 = {
55411
55598
  message: "No completed tasks found in plan.",
@@ -55423,7 +55610,7 @@ var evidence_check = createSwarmTool({
55423
55610
  };
55424
55611
  return JSON.stringify(result2, null, 2);
55425
55612
  }
55426
- const evidenceDir = path40.join(cwd, EVIDENCE_DIR2);
55613
+ const evidenceDir = path41.join(cwd, EVIDENCE_DIR2);
55427
55614
  const evidence = readEvidenceFiles(evidenceDir, cwd);
55428
55615
  const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
55429
55616
  const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
@@ -55440,8 +55627,8 @@ var evidence_check = createSwarmTool({
55440
55627
  // src/tools/file-extractor.ts
55441
55628
  init_tool();
55442
55629
  init_create_tool();
55443
- import * as fs28 from "fs";
55444
- import * as path41 from "path";
55630
+ import * as fs29 from "fs";
55631
+ import * as path42 from "path";
55445
55632
  var EXT_MAP = {
55446
55633
  python: ".py",
55447
55634
  py: ".py",
@@ -55503,8 +55690,8 @@ var extract_code_blocks = createSwarmTool({
55503
55690
  execute: async (args2, directory) => {
55504
55691
  const { content, output_dir, prefix } = args2;
55505
55692
  const targetDir = output_dir || directory;
55506
- if (!fs28.existsSync(targetDir)) {
55507
- fs28.mkdirSync(targetDir, { recursive: true });
55693
+ if (!fs29.existsSync(targetDir)) {
55694
+ fs29.mkdirSync(targetDir, { recursive: true });
55508
55695
  }
55509
55696
  if (!content) {
55510
55697
  return "Error: content is required";
@@ -55522,16 +55709,16 @@ var extract_code_blocks = createSwarmTool({
55522
55709
  if (prefix) {
55523
55710
  filename = `${prefix}_${filename}`;
55524
55711
  }
55525
- let filepath = path41.join(targetDir, filename);
55526
- const base = path41.basename(filepath, path41.extname(filepath));
55527
- const ext = path41.extname(filepath);
55712
+ let filepath = path42.join(targetDir, filename);
55713
+ const base = path42.basename(filepath, path42.extname(filepath));
55714
+ const ext = path42.extname(filepath);
55528
55715
  let counter = 1;
55529
- while (fs28.existsSync(filepath)) {
55530
- filepath = path41.join(targetDir, `${base}_${counter}${ext}`);
55716
+ while (fs29.existsSync(filepath)) {
55717
+ filepath = path42.join(targetDir, `${base}_${counter}${ext}`);
55531
55718
  counter++;
55532
55719
  }
55533
55720
  try {
55534
- fs28.writeFileSync(filepath, code.trim(), "utf-8");
55721
+ fs29.writeFileSync(filepath, code.trim(), "utf-8");
55535
55722
  savedFiles.push(filepath);
55536
55723
  } catch (error93) {
55537
55724
  errors5.push(`Failed to save ${filename}: ${error93 instanceof Error ? error93.message : String(error93)}`);
@@ -55644,8 +55831,8 @@ var gitingest = tool({
55644
55831
  });
55645
55832
  // src/tools/imports.ts
55646
55833
  init_dist();
55647
- import * as fs29 from "fs";
55648
- import * as path42 from "path";
55834
+ import * as fs30 from "fs";
55835
+ import * as path43 from "path";
55649
55836
  var MAX_FILE_PATH_LENGTH2 = 500;
55650
55837
  var MAX_SYMBOL_LENGTH = 256;
55651
55838
  var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
@@ -55699,7 +55886,7 @@ function validateSymbolInput(symbol3) {
55699
55886
  return null;
55700
55887
  }
55701
55888
  function isBinaryFile2(filePath, buffer) {
55702
- const ext = path42.extname(filePath).toLowerCase();
55889
+ const ext = path43.extname(filePath).toLowerCase();
55703
55890
  if (ext === ".json" || ext === ".md" || ext === ".txt") {
55704
55891
  return false;
55705
55892
  }
@@ -55723,15 +55910,15 @@ function parseImports(content, targetFile, targetSymbol) {
55723
55910
  const imports = [];
55724
55911
  let _resolvedTarget;
55725
55912
  try {
55726
- _resolvedTarget = path42.resolve(targetFile);
55913
+ _resolvedTarget = path43.resolve(targetFile);
55727
55914
  } catch {
55728
55915
  _resolvedTarget = targetFile;
55729
55916
  }
55730
- const targetBasename = path42.basename(targetFile, path42.extname(targetFile));
55917
+ const targetBasename = path43.basename(targetFile, path43.extname(targetFile));
55731
55918
  const targetWithExt = targetFile;
55732
55919
  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, "/");
55920
+ const normalizedTargetWithExt = path43.normalize(targetWithExt).replace(/\\/g, "/");
55921
+ const normalizedTargetWithoutExt = path43.normalize(targetWithoutExt).replace(/\\/g, "/");
55735
55922
  const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
55736
55923
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
55737
55924
  const modulePath = match[1] || match[2] || match[3];
@@ -55754,9 +55941,9 @@ function parseImports(content, targetFile, targetSymbol) {
55754
55941
  }
55755
55942
  const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
55756
55943
  let isMatch = false;
55757
- const _targetDir = path42.dirname(targetFile);
55758
- const targetExt = path42.extname(targetFile);
55759
- const targetBasenameNoExt = path42.basename(targetFile, targetExt);
55944
+ const _targetDir = path43.dirname(targetFile);
55945
+ const targetExt = path43.extname(targetFile);
55946
+ const targetBasenameNoExt = path43.basename(targetFile, targetExt);
55760
55947
  const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
55761
55948
  const moduleName = modulePath.split(/[/\\]/).pop() || "";
55762
55949
  const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
@@ -55813,7 +56000,7 @@ var SKIP_DIRECTORIES2 = new Set([
55813
56000
  function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFiles: 0, fileErrors: [] }) {
55814
56001
  let entries;
55815
56002
  try {
55816
- entries = fs29.readdirSync(dir);
56003
+ entries = fs30.readdirSync(dir);
55817
56004
  } catch (e) {
55818
56005
  stats.fileErrors.push({
55819
56006
  path: dir,
@@ -55824,13 +56011,13 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
55824
56011
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
55825
56012
  for (const entry of entries) {
55826
56013
  if (SKIP_DIRECTORIES2.has(entry)) {
55827
- stats.skippedDirs.push(path42.join(dir, entry));
56014
+ stats.skippedDirs.push(path43.join(dir, entry));
55828
56015
  continue;
55829
56016
  }
55830
- const fullPath = path42.join(dir, entry);
56017
+ const fullPath = path43.join(dir, entry);
55831
56018
  let stat2;
55832
56019
  try {
55833
- stat2 = fs29.statSync(fullPath);
56020
+ stat2 = fs30.statSync(fullPath);
55834
56021
  } catch (e) {
55835
56022
  stats.fileErrors.push({
55836
56023
  path: fullPath,
@@ -55841,7 +56028,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
55841
56028
  if (stat2.isDirectory()) {
55842
56029
  findSourceFiles(fullPath, files, stats);
55843
56030
  } else if (stat2.isFile()) {
55844
- const ext = path42.extname(fullPath).toLowerCase();
56031
+ const ext = path43.extname(fullPath).toLowerCase();
55845
56032
  if (SUPPORTED_EXTENSIONS.includes(ext)) {
55846
56033
  files.push(fullPath);
55847
56034
  }
@@ -55897,8 +56084,8 @@ var imports = tool({
55897
56084
  return JSON.stringify(errorResult, null, 2);
55898
56085
  }
55899
56086
  try {
55900
- const targetFile = path42.resolve(file3);
55901
- if (!fs29.existsSync(targetFile)) {
56087
+ const targetFile = path43.resolve(file3);
56088
+ if (!fs30.existsSync(targetFile)) {
55902
56089
  const errorResult = {
55903
56090
  error: `target file not found: ${file3}`,
55904
56091
  target: file3,
@@ -55908,7 +56095,7 @@ var imports = tool({
55908
56095
  };
55909
56096
  return JSON.stringify(errorResult, null, 2);
55910
56097
  }
55911
- const targetStat = fs29.statSync(targetFile);
56098
+ const targetStat = fs30.statSync(targetFile);
55912
56099
  if (!targetStat.isFile()) {
55913
56100
  const errorResult = {
55914
56101
  error: "target must be a file, not a directory",
@@ -55919,7 +56106,7 @@ var imports = tool({
55919
56106
  };
55920
56107
  return JSON.stringify(errorResult, null, 2);
55921
56108
  }
55922
- const baseDir = path42.dirname(targetFile);
56109
+ const baseDir = path43.dirname(targetFile);
55923
56110
  const scanStats = {
55924
56111
  skippedDirs: [],
55925
56112
  skippedFiles: 0,
@@ -55934,12 +56121,12 @@ var imports = tool({
55934
56121
  if (consumers.length >= MAX_CONSUMERS)
55935
56122
  break;
55936
56123
  try {
55937
- const stat2 = fs29.statSync(filePath);
56124
+ const stat2 = fs30.statSync(filePath);
55938
56125
  if (stat2.size > MAX_FILE_SIZE_BYTES4) {
55939
56126
  skippedFileCount++;
55940
56127
  continue;
55941
56128
  }
55942
- const buffer = fs29.readFileSync(filePath);
56129
+ const buffer = fs30.readFileSync(filePath);
55943
56130
  if (isBinaryFile2(filePath, buffer)) {
55944
56131
  skippedFileCount++;
55945
56132
  continue;
@@ -56004,7 +56191,7 @@ var imports = tool({
56004
56191
  });
56005
56192
  // src/tools/knowledge-query.ts
56006
56193
  init_dist();
56007
- import { existsSync as existsSync27 } from "fs";
56194
+ import { existsSync as existsSync28 } from "fs";
56008
56195
  init_create_tool();
56009
56196
  var DEFAULT_LIMIT = 10;
56010
56197
  var MAX_LESSON_LENGTH = 200;
@@ -56074,14 +56261,14 @@ function validateLimit(limit) {
56074
56261
  }
56075
56262
  async function readSwarmKnowledge(directory) {
56076
56263
  const swarmPath = resolveSwarmKnowledgePath(directory);
56077
- if (!existsSync27(swarmPath)) {
56264
+ if (!existsSync28(swarmPath)) {
56078
56265
  return [];
56079
56266
  }
56080
56267
  return readKnowledge(swarmPath);
56081
56268
  }
56082
56269
  async function readHiveKnowledge() {
56083
56270
  const hivePath = resolveHiveKnowledgePath();
56084
- if (!existsSync27(hivePath)) {
56271
+ if (!existsSync28(hivePath)) {
56085
56272
  return [];
56086
56273
  }
56087
56274
  return readKnowledge(hivePath);
@@ -56240,8 +56427,8 @@ init_dist();
56240
56427
  init_config();
56241
56428
  init_schema();
56242
56429
  init_manager();
56243
- import * as fs30 from "fs";
56244
- import * as path43 from "path";
56430
+ import * as fs31 from "fs";
56431
+ import * as path44 from "path";
56245
56432
  init_utils2();
56246
56433
  init_create_tool();
56247
56434
  function safeWarn(message, error93) {
@@ -56436,7 +56623,7 @@ async function executePhaseComplete(args2, workingDirectory) {
56436
56623
  }
56437
56624
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
56438
56625
  try {
56439
- const projectName = path43.basename(dir);
56626
+ const projectName = path44.basename(dir);
56440
56627
  const knowledgeConfig = {
56441
56628
  enabled: true,
56442
56629
  swarm_max_entries: 100,
@@ -56484,7 +56671,7 @@ async function executePhaseComplete(args2, workingDirectory) {
56484
56671
  if (agentsMissing.length > 0) {
56485
56672
  try {
56486
56673
  const planPath = validateSwarmPath(dir, "plan.json");
56487
- const planRaw = fs30.readFileSync(planPath, "utf-8");
56674
+ const planRaw = fs31.readFileSync(planPath, "utf-8");
56488
56675
  const plan = JSON.parse(planRaw);
56489
56676
  const targetPhase = plan.phases.find((p) => p.id === phase);
56490
56677
  if (targetPhase && targetPhase.tasks.length > 0 && targetPhase.tasks.every((t) => t.status === "completed")) {
@@ -56525,7 +56712,7 @@ async function executePhaseComplete(args2, workingDirectory) {
56525
56712
  };
56526
56713
  try {
56527
56714
  const eventsPath = validateSwarmPath(dir, "events.jsonl");
56528
- fs30.appendFileSync(eventsPath, `${JSON.stringify(event)}
56715
+ fs31.appendFileSync(eventsPath, `${JSON.stringify(event)}
56529
56716
  `, "utf-8");
56530
56717
  } catch (writeError) {
56531
56718
  warnings.push(`Warning: failed to write phase complete event: ${writeError instanceof Error ? writeError.message : String(writeError)}`);
@@ -56544,12 +56731,12 @@ async function executePhaseComplete(args2, workingDirectory) {
56544
56731
  }
56545
56732
  try {
56546
56733
  const planPath = validateSwarmPath(dir, "plan.json");
56547
- const planJson = fs30.readFileSync(planPath, "utf-8");
56734
+ const planJson = fs31.readFileSync(planPath, "utf-8");
56548
56735
  const plan = JSON.parse(planJson);
56549
56736
  const phaseObj = plan.phases.find((p) => p.id === phase);
56550
56737
  if (phaseObj) {
56551
56738
  phaseObj.status = "completed";
56552
- fs30.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
56739
+ fs31.writeFileSync(planPath, `${JSON.stringify(plan, null, 2)}
56553
56740
  `, "utf-8");
56554
56741
  }
56555
56742
  } catch (error93) {
@@ -56599,8 +56786,8 @@ init_dist();
56599
56786
  init_discovery();
56600
56787
  init_utils();
56601
56788
  init_create_tool();
56602
- import * as fs31 from "fs";
56603
- import * as path44 from "path";
56789
+ import * as fs32 from "fs";
56790
+ import * as path45 from "path";
56604
56791
  var MAX_OUTPUT_BYTES5 = 52428800;
56605
56792
  var AUDIT_TIMEOUT_MS = 120000;
56606
56793
  function isValidEcosystem(value) {
@@ -56618,28 +56805,28 @@ function validateArgs3(args2) {
56618
56805
  function detectEcosystems(directory) {
56619
56806
  const ecosystems = [];
56620
56807
  const cwd = directory;
56621
- if (fs31.existsSync(path44.join(cwd, "package.json"))) {
56808
+ if (fs32.existsSync(path45.join(cwd, "package.json"))) {
56622
56809
  ecosystems.push("npm");
56623
56810
  }
56624
- if (fs31.existsSync(path44.join(cwd, "pyproject.toml")) || fs31.existsSync(path44.join(cwd, "requirements.txt"))) {
56811
+ if (fs32.existsSync(path45.join(cwd, "pyproject.toml")) || fs32.existsSync(path45.join(cwd, "requirements.txt"))) {
56625
56812
  ecosystems.push("pip");
56626
56813
  }
56627
- if (fs31.existsSync(path44.join(cwd, "Cargo.toml"))) {
56814
+ if (fs32.existsSync(path45.join(cwd, "Cargo.toml"))) {
56628
56815
  ecosystems.push("cargo");
56629
56816
  }
56630
- if (fs31.existsSync(path44.join(cwd, "go.mod"))) {
56817
+ if (fs32.existsSync(path45.join(cwd, "go.mod"))) {
56631
56818
  ecosystems.push("go");
56632
56819
  }
56633
56820
  try {
56634
- const files = fs31.readdirSync(cwd);
56821
+ const files = fs32.readdirSync(cwd);
56635
56822
  if (files.some((f) => f.endsWith(".csproj") || f.endsWith(".sln"))) {
56636
56823
  ecosystems.push("dotnet");
56637
56824
  }
56638
56825
  } catch {}
56639
- if (fs31.existsSync(path44.join(cwd, "Gemfile")) || fs31.existsSync(path44.join(cwd, "Gemfile.lock"))) {
56826
+ if (fs32.existsSync(path45.join(cwd, "Gemfile")) || fs32.existsSync(path45.join(cwd, "Gemfile.lock"))) {
56640
56827
  ecosystems.push("ruby");
56641
56828
  }
56642
- if (fs31.existsSync(path44.join(cwd, "pubspec.yaml"))) {
56829
+ if (fs32.existsSync(path45.join(cwd, "pubspec.yaml"))) {
56643
56830
  ecosystems.push("dart");
56644
56831
  }
56645
56832
  return ecosystems;
@@ -57701,8 +57888,8 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
57701
57888
  ]);
57702
57889
  // src/tools/pre-check-batch.ts
57703
57890
  init_dist();
57704
- import * as fs34 from "fs";
57705
- import * as path47 from "path";
57891
+ import * as fs35 from "fs";
57892
+ import * as path48 from "path";
57706
57893
 
57707
57894
  // node_modules/yocto-queue/index.js
57708
57895
  class Node2 {
@@ -57869,8 +58056,8 @@ init_lint();
57869
58056
  init_manager();
57870
58057
 
57871
58058
  // src/quality/metrics.ts
57872
- import * as fs32 from "fs";
57873
- import * as path45 from "path";
58059
+ import * as fs33 from "fs";
58060
+ import * as path46 from "path";
57874
58061
  var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
57875
58062
  var MIN_DUPLICATION_LINES = 10;
57876
58063
  function estimateCyclomaticComplexity(content) {
@@ -57908,11 +58095,11 @@ function estimateCyclomaticComplexity(content) {
57908
58095
  }
57909
58096
  function getComplexityForFile2(filePath) {
57910
58097
  try {
57911
- const stat2 = fs32.statSync(filePath);
58098
+ const stat2 = fs33.statSync(filePath);
57912
58099
  if (stat2.size > MAX_FILE_SIZE_BYTES5) {
57913
58100
  return null;
57914
58101
  }
57915
- const content = fs32.readFileSync(filePath, "utf-8");
58102
+ const content = fs33.readFileSync(filePath, "utf-8");
57916
58103
  return estimateCyclomaticComplexity(content);
57917
58104
  } catch {
57918
58105
  return null;
@@ -57922,8 +58109,8 @@ async function computeComplexityDelta(files, workingDir) {
57922
58109
  let totalComplexity = 0;
57923
58110
  const analyzedFiles = [];
57924
58111
  for (const file3 of files) {
57925
- const fullPath = path45.isAbsolute(file3) ? file3 : path45.join(workingDir, file3);
57926
- if (!fs32.existsSync(fullPath)) {
58112
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58113
+ if (!fs33.existsSync(fullPath)) {
57927
58114
  continue;
57928
58115
  }
57929
58116
  const complexity = getComplexityForFile2(fullPath);
@@ -58044,8 +58231,8 @@ function countGoExports(content) {
58044
58231
  }
58045
58232
  function getExportCountForFile(filePath) {
58046
58233
  try {
58047
- const content = fs32.readFileSync(filePath, "utf-8");
58048
- const ext = path45.extname(filePath).toLowerCase();
58234
+ const content = fs33.readFileSync(filePath, "utf-8");
58235
+ const ext = path46.extname(filePath).toLowerCase();
58049
58236
  switch (ext) {
58050
58237
  case ".ts":
58051
58238
  case ".tsx":
@@ -58071,8 +58258,8 @@ async function computePublicApiDelta(files, workingDir) {
58071
58258
  let totalExports = 0;
58072
58259
  const analyzedFiles = [];
58073
58260
  for (const file3 of files) {
58074
- const fullPath = path45.isAbsolute(file3) ? file3 : path45.join(workingDir, file3);
58075
- if (!fs32.existsSync(fullPath)) {
58261
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58262
+ if (!fs33.existsSync(fullPath)) {
58076
58263
  continue;
58077
58264
  }
58078
58265
  const exports = getExportCountForFile(fullPath);
@@ -58105,16 +58292,16 @@ async function computeDuplicationRatio(files, workingDir) {
58105
58292
  let duplicateLines = 0;
58106
58293
  const analyzedFiles = [];
58107
58294
  for (const file3 of files) {
58108
- const fullPath = path45.isAbsolute(file3) ? file3 : path45.join(workingDir, file3);
58109
- if (!fs32.existsSync(fullPath)) {
58295
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58296
+ if (!fs33.existsSync(fullPath)) {
58110
58297
  continue;
58111
58298
  }
58112
58299
  try {
58113
- const stat2 = fs32.statSync(fullPath);
58300
+ const stat2 = fs33.statSync(fullPath);
58114
58301
  if (stat2.size > MAX_FILE_SIZE_BYTES5) {
58115
58302
  continue;
58116
58303
  }
58117
- const content = fs32.readFileSync(fullPath, "utf-8");
58304
+ const content = fs33.readFileSync(fullPath, "utf-8");
58118
58305
  const lines = content.split(`
58119
58306
  `).filter((line) => line.trim().length > 0);
58120
58307
  if (lines.length < MIN_DUPLICATION_LINES) {
@@ -58138,8 +58325,8 @@ function countCodeLines(content) {
58138
58325
  return lines.length;
58139
58326
  }
58140
58327
  function isTestFile(filePath) {
58141
- const basename8 = path45.basename(filePath);
58142
- const _ext = path45.extname(filePath).toLowerCase();
58328
+ const basename8 = path46.basename(filePath);
58329
+ const _ext = path46.extname(filePath).toLowerCase();
58143
58330
  const testPatterns = [
58144
58331
  ".test.",
58145
58332
  ".spec.",
@@ -58220,8 +58407,8 @@ function matchGlobSegment(globSegments, pathSegments) {
58220
58407
  }
58221
58408
  return gIndex === globSegments.length && pIndex === pathSegments.length;
58222
58409
  }
58223
- function matchesGlobSegment(path46, glob) {
58224
- const normalizedPath = path46.replace(/\\/g, "/");
58410
+ function matchesGlobSegment(path47, glob) {
58411
+ const normalizedPath = path47.replace(/\\/g, "/");
58225
58412
  const normalizedGlob = glob.replace(/\\/g, "/");
58226
58413
  if (normalizedPath.includes("//")) {
58227
58414
  return false;
@@ -58252,8 +58439,8 @@ function simpleGlobToRegex2(glob) {
58252
58439
  function hasGlobstar(glob) {
58253
58440
  return glob.includes("**");
58254
58441
  }
58255
- function globMatches(path46, glob) {
58256
- const normalizedPath = path46.replace(/\\/g, "/");
58442
+ function globMatches(path47, glob) {
58443
+ const normalizedPath = path47.replace(/\\/g, "/");
58257
58444
  if (!glob || glob === "") {
58258
58445
  if (normalizedPath.includes("//")) {
58259
58446
  return false;
@@ -58289,31 +58476,31 @@ function shouldExcludeFile(filePath, excludeGlobs) {
58289
58476
  async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
58290
58477
  let testLines = 0;
58291
58478
  let codeLines = 0;
58292
- const srcDir = path45.join(workingDir, "src");
58293
- if (fs32.existsSync(srcDir)) {
58479
+ const srcDir = path46.join(workingDir, "src");
58480
+ if (fs33.existsSync(srcDir)) {
58294
58481
  await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
58295
58482
  codeLines += lines;
58296
58483
  });
58297
58484
  }
58298
58485
  const possibleSrcDirs = ["lib", "app", "source", "core"];
58299
58486
  for (const dir of possibleSrcDirs) {
58300
- const dirPath = path45.join(workingDir, dir);
58301
- if (fs32.existsSync(dirPath)) {
58487
+ const dirPath = path46.join(workingDir, dir);
58488
+ if (fs33.existsSync(dirPath)) {
58302
58489
  await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
58303
58490
  codeLines += lines;
58304
58491
  });
58305
58492
  }
58306
58493
  }
58307
- const testsDir = path45.join(workingDir, "tests");
58308
- if (fs32.existsSync(testsDir)) {
58494
+ const testsDir = path46.join(workingDir, "tests");
58495
+ if (fs33.existsSync(testsDir)) {
58309
58496
  await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
58310
58497
  testLines += lines;
58311
58498
  });
58312
58499
  }
58313
58500
  const possibleTestDirs = ["test", "__tests__", "specs"];
58314
58501
  for (const dir of possibleTestDirs) {
58315
- const dirPath = path45.join(workingDir, dir);
58316
- if (fs32.existsSync(dirPath) && dirPath !== testsDir) {
58502
+ const dirPath = path46.join(workingDir, dir);
58503
+ if (fs33.existsSync(dirPath) && dirPath !== testsDir) {
58317
58504
  await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
58318
58505
  testLines += lines;
58319
58506
  });
@@ -58325,9 +58512,9 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
58325
58512
  }
58326
58513
  async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTestScan, callback) {
58327
58514
  try {
58328
- const entries = fs32.readdirSync(dirPath, { withFileTypes: true });
58515
+ const entries = fs33.readdirSync(dirPath, { withFileTypes: true });
58329
58516
  for (const entry of entries) {
58330
- const fullPath = path45.join(dirPath, entry.name);
58517
+ const fullPath = path46.join(dirPath, entry.name);
58331
58518
  if (entry.isDirectory()) {
58332
58519
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
58333
58520
  continue;
@@ -58335,7 +58522,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
58335
58522
  await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
58336
58523
  } else if (entry.isFile()) {
58337
58524
  const relativePath = fullPath.replace(`${process.cwd()}/`, "");
58338
- const ext = path45.extname(entry.name).toLowerCase();
58525
+ const ext = path46.extname(entry.name).toLowerCase();
58339
58526
  const validExts = [
58340
58527
  ".ts",
58341
58528
  ".tsx",
@@ -58371,7 +58558,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
58371
58558
  continue;
58372
58559
  }
58373
58560
  try {
58374
- const content = fs32.readFileSync(fullPath, "utf-8");
58561
+ const content = fs33.readFileSync(fullPath, "utf-8");
58375
58562
  const lines = countCodeLines(content);
58376
58563
  callback(lines);
58377
58564
  } catch {}
@@ -58585,8 +58772,8 @@ async function qualityBudget(input, directory) {
58585
58772
  init_dist();
58586
58773
  init_manager();
58587
58774
  init_detector();
58588
- import * as fs33 from "fs";
58589
- import * as path46 from "path";
58775
+ import * as fs34 from "fs";
58776
+ import * as path47 from "path";
58590
58777
  import { extname as extname9 } from "path";
58591
58778
 
58592
58779
  // src/sast/rules/c.ts
@@ -59270,7 +59457,7 @@ function executeRulesSync(filePath, content, language) {
59270
59457
  }
59271
59458
 
59272
59459
  // src/sast/semgrep.ts
59273
- import { execFile as execFile2, execFileSync as execFileSync2, spawn } from "child_process";
59460
+ import { execFile as execFile2, execFileSync as execFileSync2, spawn as spawn2 } from "child_process";
59274
59461
  import { promisify as promisify2 } from "util";
59275
59462
  var _execFileAsync = promisify2(execFile2);
59276
59463
  var semgrepAvailableCache = null;
@@ -59335,7 +59522,7 @@ function mapSemgrepSeverity(severity) {
59335
59522
  }
59336
59523
  async function executeWithTimeout(command, args2, options) {
59337
59524
  return new Promise((resolve15) => {
59338
- const child = spawn(command, args2, {
59525
+ const child = spawn2(command, args2, {
59339
59526
  shell: false,
59340
59527
  cwd: options.cwd
59341
59528
  });
@@ -59453,17 +59640,17 @@ var SEVERITY_ORDER = {
59453
59640
  };
59454
59641
  function shouldSkipFile(filePath) {
59455
59642
  try {
59456
- const stats = fs33.statSync(filePath);
59643
+ const stats = fs34.statSync(filePath);
59457
59644
  if (stats.size > MAX_FILE_SIZE_BYTES6) {
59458
59645
  return { skip: true, reason: "file too large" };
59459
59646
  }
59460
59647
  if (stats.size === 0) {
59461
59648
  return { skip: true, reason: "empty file" };
59462
59649
  }
59463
- const fd = fs33.openSync(filePath, "r");
59650
+ const fd = fs34.openSync(filePath, "r");
59464
59651
  const buffer = Buffer.alloc(8192);
59465
- const bytesRead = fs33.readSync(fd, buffer, 0, 8192, 0);
59466
- fs33.closeSync(fd);
59652
+ const bytesRead = fs34.readSync(fd, buffer, 0, 8192, 0);
59653
+ fs34.closeSync(fd);
59467
59654
  if (bytesRead > 0) {
59468
59655
  let nullCount = 0;
59469
59656
  for (let i2 = 0;i2 < bytesRead; i2++) {
@@ -59502,7 +59689,7 @@ function countBySeverity(findings) {
59502
59689
  }
59503
59690
  function scanFileWithTierA(filePath, language) {
59504
59691
  try {
59505
- const content = fs33.readFileSync(filePath, "utf-8");
59692
+ const content = fs34.readFileSync(filePath, "utf-8");
59506
59693
  const findings = executeRulesSync(filePath, content, language);
59507
59694
  return findings.map((f) => ({
59508
59695
  rule_id: f.rule_id,
@@ -59549,8 +59736,8 @@ async function sastScan(input, directory, config3) {
59549
59736
  _filesSkipped++;
59550
59737
  continue;
59551
59738
  }
59552
- const resolvedPath = path46.isAbsolute(filePath) ? filePath : path46.resolve(directory, filePath);
59553
- if (!fs33.existsSync(resolvedPath)) {
59739
+ const resolvedPath = path47.isAbsolute(filePath) ? filePath : path47.resolve(directory, filePath);
59740
+ if (!fs34.existsSync(resolvedPath)) {
59554
59741
  _filesSkipped++;
59555
59742
  continue;
59556
59743
  }
@@ -59748,18 +59935,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
59748
59935
  let resolved;
59749
59936
  const isWinAbs = isWindowsAbsolutePath(inputPath);
59750
59937
  if (isWinAbs) {
59751
- resolved = path47.win32.resolve(inputPath);
59752
- } else if (path47.isAbsolute(inputPath)) {
59753
- resolved = path47.resolve(inputPath);
59938
+ resolved = path48.win32.resolve(inputPath);
59939
+ } else if (path48.isAbsolute(inputPath)) {
59940
+ resolved = path48.resolve(inputPath);
59754
59941
  } else {
59755
- resolved = path47.resolve(baseDir, inputPath);
59942
+ resolved = path48.resolve(baseDir, inputPath);
59756
59943
  }
59757
- const workspaceResolved = path47.resolve(workspaceDir);
59944
+ const workspaceResolved = path48.resolve(workspaceDir);
59758
59945
  let relative5;
59759
59946
  if (isWinAbs) {
59760
- relative5 = path47.win32.relative(workspaceResolved, resolved);
59947
+ relative5 = path48.win32.relative(workspaceResolved, resolved);
59761
59948
  } else {
59762
- relative5 = path47.relative(workspaceResolved, resolved);
59949
+ relative5 = path48.relative(workspaceResolved, resolved);
59763
59950
  }
59764
59951
  if (relative5.startsWith("..")) {
59765
59952
  return "path traversal detected";
@@ -59820,13 +60007,13 @@ async function runLintWrapped(files, directory, _config) {
59820
60007
  }
59821
60008
  async function runLintOnFiles(linter, files, workspaceDir) {
59822
60009
  const isWindows = process.platform === "win32";
59823
- const binDir = path47.join(workspaceDir, "node_modules", ".bin");
60010
+ const binDir = path48.join(workspaceDir, "node_modules", ".bin");
59824
60011
  const validatedFiles = [];
59825
60012
  for (const file3 of files) {
59826
60013
  if (typeof file3 !== "string") {
59827
60014
  continue;
59828
60015
  }
59829
- const resolvedPath = path47.resolve(file3);
60016
+ const resolvedPath = path48.resolve(file3);
59830
60017
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
59831
60018
  if (validationError) {
59832
60019
  continue;
@@ -59844,10 +60031,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
59844
60031
  }
59845
60032
  let command;
59846
60033
  if (linter === "biome") {
59847
- const biomeBin = isWindows ? path47.join(binDir, "biome.EXE") : path47.join(binDir, "biome");
60034
+ const biomeBin = isWindows ? path48.join(binDir, "biome.EXE") : path48.join(binDir, "biome");
59848
60035
  command = [biomeBin, "check", ...validatedFiles];
59849
60036
  } else {
59850
- const eslintBin = isWindows ? path47.join(binDir, "eslint.cmd") : path47.join(binDir, "eslint");
60037
+ const eslintBin = isWindows ? path48.join(binDir, "eslint.cmd") : path48.join(binDir, "eslint");
59851
60038
  command = [eslintBin, ...validatedFiles];
59852
60039
  }
59853
60040
  try {
@@ -59984,7 +60171,7 @@ async function runSecretscanWithFiles(files, directory) {
59984
60171
  skippedFiles++;
59985
60172
  continue;
59986
60173
  }
59987
- const resolvedPath = path47.resolve(file3);
60174
+ const resolvedPath = path48.resolve(file3);
59988
60175
  const validationError = validatePath(resolvedPath, directory, directory);
59989
60176
  if (validationError) {
59990
60177
  skippedFiles++;
@@ -60002,14 +60189,14 @@ async function runSecretscanWithFiles(files, directory) {
60002
60189
  };
60003
60190
  }
60004
60191
  for (const file3 of validatedFiles) {
60005
- const ext = path47.extname(file3).toLowerCase();
60192
+ const ext = path48.extname(file3).toLowerCase();
60006
60193
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
60007
60194
  skippedFiles++;
60008
60195
  continue;
60009
60196
  }
60010
60197
  let stat2;
60011
60198
  try {
60012
- stat2 = fs34.statSync(file3);
60199
+ stat2 = fs35.statSync(file3);
60013
60200
  } catch {
60014
60201
  skippedFiles++;
60015
60202
  continue;
@@ -60020,7 +60207,7 @@ async function runSecretscanWithFiles(files, directory) {
60020
60207
  }
60021
60208
  let content;
60022
60209
  try {
60023
- const buffer = fs34.readFileSync(file3);
60210
+ const buffer = fs35.readFileSync(file3);
60024
60211
  if (buffer.includes(0)) {
60025
60212
  skippedFiles++;
60026
60213
  continue;
@@ -60161,7 +60348,7 @@ async function runPreCheckBatch(input, workspaceDir) {
60161
60348
  warn(`pre_check_batch: Invalid file path: ${file3}`);
60162
60349
  continue;
60163
60350
  }
60164
- changedFiles.push(path47.resolve(directory, file3));
60351
+ changedFiles.push(path48.resolve(directory, file3));
60165
60352
  }
60166
60353
  if (changedFiles.length === 0) {
60167
60354
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -60312,7 +60499,7 @@ var pre_check_batch = createSwarmTool({
60312
60499
  };
60313
60500
  return JSON.stringify(errorResult, null, 2);
60314
60501
  }
60315
- const resolvedDirectory = path47.resolve(typedArgs.directory);
60502
+ const resolvedDirectory = path48.resolve(typedArgs.directory);
60316
60503
  const workspaceAnchor = resolvedDirectory;
60317
60504
  const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
60318
60505
  if (dirError) {
@@ -60419,8 +60606,8 @@ ${paginatedContent}`;
60419
60606
  init_tool();
60420
60607
  init_manager2();
60421
60608
  init_create_tool();
60422
- import * as fs35 from "fs";
60423
- import * as path48 from "path";
60609
+ import * as fs36 from "fs";
60610
+ import * as path49 from "path";
60424
60611
  function detectPlaceholderContent(args2) {
60425
60612
  const issues = [];
60426
60613
  const placeholderPattern = /^\[\w[\w\s]*\]$/;
@@ -60524,19 +60711,19 @@ async function executeSavePlan(args2, fallbackDir) {
60524
60711
  try {
60525
60712
  await savePlan(dir, plan);
60526
60713
  try {
60527
- const markerPath = path48.join(dir, ".swarm", ".plan-write-marker");
60714
+ const markerPath = path49.join(dir, ".swarm", ".plan-write-marker");
60528
60715
  const marker = JSON.stringify({
60529
60716
  source: "save_plan",
60530
60717
  timestamp: new Date().toISOString(),
60531
60718
  phases_count: plan.phases.length,
60532
60719
  tasks_count: tasksCount
60533
60720
  });
60534
- await fs35.promises.writeFile(markerPath, marker, "utf8");
60721
+ await fs36.promises.writeFile(markerPath, marker, "utf8");
60535
60722
  } catch {}
60536
60723
  return {
60537
60724
  success: true,
60538
60725
  message: "Plan saved successfully",
60539
- plan_path: path48.join(dir, ".swarm", "plan.json"),
60726
+ plan_path: path49.join(dir, ".swarm", "plan.json"),
60540
60727
  phases_count: plan.phases.length,
60541
60728
  tasks_count: tasksCount
60542
60729
  };
@@ -60574,8 +60761,8 @@ var save_plan = createSwarmTool({
60574
60761
  // src/tools/sbom-generate.ts
60575
60762
  init_dist();
60576
60763
  init_manager();
60577
- import * as fs36 from "fs";
60578
- import * as path49 from "path";
60764
+ import * as fs37 from "fs";
60765
+ import * as path50 from "path";
60579
60766
 
60580
60767
  // src/sbom/detectors/index.ts
60581
60768
  init_utils();
@@ -61421,9 +61608,9 @@ function findManifestFiles(rootDir) {
61421
61608
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
61422
61609
  function searchDir(dir) {
61423
61610
  try {
61424
- const entries = fs36.readdirSync(dir, { withFileTypes: true });
61611
+ const entries = fs37.readdirSync(dir, { withFileTypes: true });
61425
61612
  for (const entry of entries) {
61426
- const fullPath = path49.join(dir, entry.name);
61613
+ const fullPath = path50.join(dir, entry.name);
61427
61614
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
61428
61615
  continue;
61429
61616
  }
@@ -61432,7 +61619,7 @@ function findManifestFiles(rootDir) {
61432
61619
  } else if (entry.isFile()) {
61433
61620
  for (const pattern of patterns) {
61434
61621
  if (simpleGlobToRegex(pattern).test(entry.name)) {
61435
- manifestFiles.push(path49.relative(rootDir, fullPath));
61622
+ manifestFiles.push(path50.relative(rootDir, fullPath));
61436
61623
  break;
61437
61624
  }
61438
61625
  }
@@ -61448,13 +61635,13 @@ function findManifestFilesInDirs(directories, workingDir) {
61448
61635
  const patterns = [...new Set(allDetectors.flatMap((d) => d.patterns))];
61449
61636
  for (const dir of directories) {
61450
61637
  try {
61451
- const entries = fs36.readdirSync(dir, { withFileTypes: true });
61638
+ const entries = fs37.readdirSync(dir, { withFileTypes: true });
61452
61639
  for (const entry of entries) {
61453
- const fullPath = path49.join(dir, entry.name);
61640
+ const fullPath = path50.join(dir, entry.name);
61454
61641
  if (entry.isFile()) {
61455
61642
  for (const pattern of patterns) {
61456
61643
  if (simpleGlobToRegex(pattern).test(entry.name)) {
61457
- found.push(path49.relative(workingDir, fullPath));
61644
+ found.push(path50.relative(workingDir, fullPath));
61458
61645
  break;
61459
61646
  }
61460
61647
  }
@@ -61467,11 +61654,11 @@ function findManifestFilesInDirs(directories, workingDir) {
61467
61654
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
61468
61655
  const dirs = new Set;
61469
61656
  for (const file3 of changedFiles) {
61470
- let currentDir = path49.dirname(file3);
61657
+ let currentDir = path50.dirname(file3);
61471
61658
  while (true) {
61472
- if (currentDir && currentDir !== "." && currentDir !== path49.sep) {
61473
- dirs.add(path49.join(workingDir, currentDir));
61474
- const parent = path49.dirname(currentDir);
61659
+ if (currentDir && currentDir !== "." && currentDir !== path50.sep) {
61660
+ dirs.add(path50.join(workingDir, currentDir));
61661
+ const parent = path50.dirname(currentDir);
61475
61662
  if (parent === currentDir)
61476
61663
  break;
61477
61664
  currentDir = parent;
@@ -61485,7 +61672,7 @@ function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
61485
61672
  }
61486
61673
  function ensureOutputDir(outputDir) {
61487
61674
  try {
61488
- fs36.mkdirSync(outputDir, { recursive: true });
61675
+ fs37.mkdirSync(outputDir, { recursive: true });
61489
61676
  } catch (error93) {
61490
61677
  if (!error93 || error93.code !== "EEXIST") {
61491
61678
  throw error93;
@@ -61555,7 +61742,7 @@ var sbom_generate = createSwarmTool({
61555
61742
  const changedFiles = obj.changed_files;
61556
61743
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
61557
61744
  const workingDir = directory;
61558
- const outputDir = path49.isAbsolute(relativeOutputDir) ? relativeOutputDir : path49.join(workingDir, relativeOutputDir);
61745
+ const outputDir = path50.isAbsolute(relativeOutputDir) ? relativeOutputDir : path50.join(workingDir, relativeOutputDir);
61559
61746
  let manifestFiles = [];
61560
61747
  if (scope === "all") {
61561
61748
  manifestFiles = findManifestFiles(workingDir);
@@ -61578,11 +61765,11 @@ var sbom_generate = createSwarmTool({
61578
61765
  const processedFiles = [];
61579
61766
  for (const manifestFile of manifestFiles) {
61580
61767
  try {
61581
- const fullPath = path49.isAbsolute(manifestFile) ? manifestFile : path49.join(workingDir, manifestFile);
61582
- if (!fs36.existsSync(fullPath)) {
61768
+ const fullPath = path50.isAbsolute(manifestFile) ? manifestFile : path50.join(workingDir, manifestFile);
61769
+ if (!fs37.existsSync(fullPath)) {
61583
61770
  continue;
61584
61771
  }
61585
- const content = fs36.readFileSync(fullPath, "utf-8");
61772
+ const content = fs37.readFileSync(fullPath, "utf-8");
61586
61773
  const components = detectComponents(manifestFile, content);
61587
61774
  processedFiles.push(manifestFile);
61588
61775
  if (components.length > 0) {
@@ -61595,8 +61782,8 @@ var sbom_generate = createSwarmTool({
61595
61782
  const bom = generateCycloneDX(allComponents);
61596
61783
  const bomJson = serializeCycloneDX(bom);
61597
61784
  const filename = generateSbomFilename();
61598
- const outputPath = path49.join(outputDir, filename);
61599
- fs36.writeFileSync(outputPath, bomJson, "utf-8");
61785
+ const outputPath = path50.join(outputDir, filename);
61786
+ fs37.writeFileSync(outputPath, bomJson, "utf-8");
61600
61787
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
61601
61788
  try {
61602
61789
  const timestamp = new Date().toISOString();
@@ -61638,8 +61825,8 @@ var sbom_generate = createSwarmTool({
61638
61825
  // src/tools/schema-drift.ts
61639
61826
  init_dist();
61640
61827
  init_create_tool();
61641
- import * as fs37 from "fs";
61642
- import * as path50 from "path";
61828
+ import * as fs38 from "fs";
61829
+ import * as path51 from "path";
61643
61830
  var SPEC_CANDIDATES = [
61644
61831
  "openapi.json",
61645
61832
  "openapi.yaml",
@@ -61671,28 +61858,28 @@ function normalizePath2(p) {
61671
61858
  }
61672
61859
  function discoverSpecFile(cwd, specFileArg) {
61673
61860
  if (specFileArg) {
61674
- const resolvedPath = path50.resolve(cwd, specFileArg);
61675
- const normalizedCwd = cwd.endsWith(path50.sep) ? cwd : cwd + path50.sep;
61861
+ const resolvedPath = path51.resolve(cwd, specFileArg);
61862
+ const normalizedCwd = cwd.endsWith(path51.sep) ? cwd : cwd + path51.sep;
61676
61863
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
61677
61864
  throw new Error("Invalid spec_file: path traversal detected");
61678
61865
  }
61679
- const ext = path50.extname(resolvedPath).toLowerCase();
61866
+ const ext = path51.extname(resolvedPath).toLowerCase();
61680
61867
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
61681
61868
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
61682
61869
  }
61683
- const stats = fs37.statSync(resolvedPath);
61870
+ const stats = fs38.statSync(resolvedPath);
61684
61871
  if (stats.size > MAX_SPEC_SIZE) {
61685
61872
  throw new Error(`Invalid spec_file: file exceeds ${MAX_SPEC_SIZE / 1024 / 1024}MB limit`);
61686
61873
  }
61687
- if (!fs37.existsSync(resolvedPath)) {
61874
+ if (!fs38.existsSync(resolvedPath)) {
61688
61875
  throw new Error(`Spec file not found: ${resolvedPath}`);
61689
61876
  }
61690
61877
  return resolvedPath;
61691
61878
  }
61692
61879
  for (const candidate of SPEC_CANDIDATES) {
61693
- const candidatePath = path50.resolve(cwd, candidate);
61694
- if (fs37.existsSync(candidatePath)) {
61695
- const stats = fs37.statSync(candidatePath);
61880
+ const candidatePath = path51.resolve(cwd, candidate);
61881
+ if (fs38.existsSync(candidatePath)) {
61882
+ const stats = fs38.statSync(candidatePath);
61696
61883
  if (stats.size <= MAX_SPEC_SIZE) {
61697
61884
  return candidatePath;
61698
61885
  }
@@ -61701,8 +61888,8 @@ function discoverSpecFile(cwd, specFileArg) {
61701
61888
  return null;
61702
61889
  }
61703
61890
  function parseSpec(specFile) {
61704
- const content = fs37.readFileSync(specFile, "utf-8");
61705
- const ext = path50.extname(specFile).toLowerCase();
61891
+ const content = fs38.readFileSync(specFile, "utf-8");
61892
+ const ext = path51.extname(specFile).toLowerCase();
61706
61893
  if (ext === ".json") {
61707
61894
  return parseJsonSpec(content);
61708
61895
  }
@@ -61773,12 +61960,12 @@ function extractRoutes(cwd) {
61773
61960
  function walkDir(dir) {
61774
61961
  let entries;
61775
61962
  try {
61776
- entries = fs37.readdirSync(dir, { withFileTypes: true });
61963
+ entries = fs38.readdirSync(dir, { withFileTypes: true });
61777
61964
  } catch {
61778
61965
  return;
61779
61966
  }
61780
61967
  for (const entry of entries) {
61781
- const fullPath = path50.join(dir, entry.name);
61968
+ const fullPath = path51.join(dir, entry.name);
61782
61969
  if (entry.isSymbolicLink()) {
61783
61970
  continue;
61784
61971
  }
@@ -61788,7 +61975,7 @@ function extractRoutes(cwd) {
61788
61975
  }
61789
61976
  walkDir(fullPath);
61790
61977
  } else if (entry.isFile()) {
61791
- const ext = path50.extname(entry.name).toLowerCase();
61978
+ const ext = path51.extname(entry.name).toLowerCase();
61792
61979
  const baseName = entry.name.toLowerCase();
61793
61980
  if (![".ts", ".js", ".mjs"].includes(ext)) {
61794
61981
  continue;
@@ -61806,7 +61993,7 @@ function extractRoutes(cwd) {
61806
61993
  }
61807
61994
  function extractRoutesFromFile(filePath) {
61808
61995
  const routes = [];
61809
- const content = fs37.readFileSync(filePath, "utf-8");
61996
+ const content = fs38.readFileSync(filePath, "utf-8");
61810
61997
  const lines = content.split(/\r?\n/);
61811
61998
  const expressRegex = /(?:app|router|server|express)\.(get|post|put|patch|delete|options|head)\s*\(\s*['"`]([^'"`]+)['"`]/g;
61812
61999
  const flaskRegex = /@(?:app|blueprint|bp)\.route\s*\(\s*['"]([^'"]+)['"]/g;
@@ -61957,8 +62144,8 @@ init_secretscan();
61957
62144
  // src/tools/symbols.ts
61958
62145
  init_tool();
61959
62146
  init_create_tool();
61960
- import * as fs38 from "fs";
61961
- import * as path51 from "path";
62147
+ import * as fs39 from "fs";
62148
+ import * as path52 from "path";
61962
62149
  var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
61963
62150
  var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
61964
62151
  function containsControlCharacters(str) {
@@ -61987,11 +62174,11 @@ function containsWindowsAttacks(str) {
61987
62174
  }
61988
62175
  function isPathInWorkspace(filePath, workspace) {
61989
62176
  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)) {
62177
+ const resolvedPath = path52.resolve(workspace, filePath);
62178
+ const realWorkspace = fs39.realpathSync(workspace);
62179
+ const realResolvedPath = fs39.realpathSync(resolvedPath);
62180
+ const relativePath = path52.relative(realWorkspace, realResolvedPath);
62181
+ if (relativePath.startsWith("..") || path52.isAbsolute(relativePath)) {
61995
62182
  return false;
61996
62183
  }
61997
62184
  return true;
@@ -62003,17 +62190,17 @@ function validatePathForRead(filePath, workspace) {
62003
62190
  return isPathInWorkspace(filePath, workspace);
62004
62191
  }
62005
62192
  function extractTSSymbols(filePath, cwd) {
62006
- const fullPath = path51.join(cwd, filePath);
62193
+ const fullPath = path52.join(cwd, filePath);
62007
62194
  if (!validatePathForRead(fullPath, cwd)) {
62008
62195
  return [];
62009
62196
  }
62010
62197
  let content;
62011
62198
  try {
62012
- const stats = fs38.statSync(fullPath);
62199
+ const stats = fs39.statSync(fullPath);
62013
62200
  if (stats.size > MAX_FILE_SIZE_BYTES7) {
62014
62201
  throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
62015
62202
  }
62016
- content = fs38.readFileSync(fullPath, "utf-8");
62203
+ content = fs39.readFileSync(fullPath, "utf-8");
62017
62204
  } catch {
62018
62205
  return [];
62019
62206
  }
@@ -62155,17 +62342,17 @@ function extractTSSymbols(filePath, cwd) {
62155
62342
  });
62156
62343
  }
62157
62344
  function extractPythonSymbols(filePath, cwd) {
62158
- const fullPath = path51.join(cwd, filePath);
62345
+ const fullPath = path52.join(cwd, filePath);
62159
62346
  if (!validatePathForRead(fullPath, cwd)) {
62160
62347
  return [];
62161
62348
  }
62162
62349
  let content;
62163
62350
  try {
62164
- const stats = fs38.statSync(fullPath);
62351
+ const stats = fs39.statSync(fullPath);
62165
62352
  if (stats.size > MAX_FILE_SIZE_BYTES7) {
62166
62353
  throw new Error(`File too large: ${stats.size} bytes (max: ${MAX_FILE_SIZE_BYTES7})`);
62167
62354
  }
62168
- content = fs38.readFileSync(fullPath, "utf-8");
62355
+ content = fs39.readFileSync(fullPath, "utf-8");
62169
62356
  } catch {
62170
62357
  return [];
62171
62358
  }
@@ -62238,7 +62425,7 @@ var symbols = createSwarmTool({
62238
62425
  }, null, 2);
62239
62426
  }
62240
62427
  const cwd = directory;
62241
- const ext = path51.extname(file3);
62428
+ const ext = path52.extname(file3);
62242
62429
  if (containsControlCharacters(file3)) {
62243
62430
  return JSON.stringify({
62244
62431
  file: file3,
@@ -62309,8 +62496,8 @@ init_test_runner();
62309
62496
  init_dist();
62310
62497
  init_utils();
62311
62498
  init_create_tool();
62312
- import * as fs39 from "fs";
62313
- import * as path52 from "path";
62499
+ import * as fs40 from "fs";
62500
+ import * as path53 from "path";
62314
62501
  var MAX_TEXT_LENGTH = 200;
62315
62502
  var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
62316
62503
  var SUPPORTED_EXTENSIONS2 = new Set([
@@ -62381,9 +62568,9 @@ function validatePathsInput(paths, cwd) {
62381
62568
  return { error: "paths contains path traversal", resolvedPath: null };
62382
62569
  }
62383
62570
  try {
62384
- const resolvedPath = path52.resolve(paths);
62385
- const normalizedCwd = path52.resolve(cwd);
62386
- const normalizedResolved = path52.resolve(resolvedPath);
62571
+ const resolvedPath = path53.resolve(paths);
62572
+ const normalizedCwd = path53.resolve(cwd);
62573
+ const normalizedResolved = path53.resolve(resolvedPath);
62387
62574
  if (!normalizedResolved.startsWith(normalizedCwd)) {
62388
62575
  return {
62389
62576
  error: "paths must be within the current working directory",
@@ -62399,13 +62586,13 @@ function validatePathsInput(paths, cwd) {
62399
62586
  }
62400
62587
  }
62401
62588
  function isSupportedExtension(filePath) {
62402
- const ext = path52.extname(filePath).toLowerCase();
62589
+ const ext = path53.extname(filePath).toLowerCase();
62403
62590
  return SUPPORTED_EXTENSIONS2.has(ext);
62404
62591
  }
62405
62592
  function findSourceFiles2(dir, files = []) {
62406
62593
  let entries;
62407
62594
  try {
62408
- entries = fs39.readdirSync(dir);
62595
+ entries = fs40.readdirSync(dir);
62409
62596
  } catch {
62410
62597
  return files;
62411
62598
  }
@@ -62414,10 +62601,10 @@ function findSourceFiles2(dir, files = []) {
62414
62601
  if (SKIP_DIRECTORIES3.has(entry)) {
62415
62602
  continue;
62416
62603
  }
62417
- const fullPath = path52.join(dir, entry);
62604
+ const fullPath = path53.join(dir, entry);
62418
62605
  let stat2;
62419
62606
  try {
62420
- stat2 = fs39.statSync(fullPath);
62607
+ stat2 = fs40.statSync(fullPath);
62421
62608
  } catch {
62422
62609
  continue;
62423
62610
  }
@@ -62510,7 +62697,7 @@ var todo_extract = createSwarmTool({
62510
62697
  return JSON.stringify(errorResult, null, 2);
62511
62698
  }
62512
62699
  const scanPath = resolvedPath;
62513
- if (!fs39.existsSync(scanPath)) {
62700
+ if (!fs40.existsSync(scanPath)) {
62514
62701
  const errorResult = {
62515
62702
  error: `path not found: ${pathsInput}`,
62516
62703
  total: 0,
@@ -62520,13 +62707,13 @@ var todo_extract = createSwarmTool({
62520
62707
  return JSON.stringify(errorResult, null, 2);
62521
62708
  }
62522
62709
  const filesToScan = [];
62523
- const stat2 = fs39.statSync(scanPath);
62710
+ const stat2 = fs40.statSync(scanPath);
62524
62711
  if (stat2.isFile()) {
62525
62712
  if (isSupportedExtension(scanPath)) {
62526
62713
  filesToScan.push(scanPath);
62527
62714
  } else {
62528
62715
  const errorResult = {
62529
- error: `unsupported file extension: ${path52.extname(scanPath)}`,
62716
+ error: `unsupported file extension: ${path53.extname(scanPath)}`,
62530
62717
  total: 0,
62531
62718
  byPriority: { high: 0, medium: 0, low: 0 },
62532
62719
  entries: []
@@ -62539,11 +62726,11 @@ var todo_extract = createSwarmTool({
62539
62726
  const allEntries = [];
62540
62727
  for (const filePath of filesToScan) {
62541
62728
  try {
62542
- const fileStat = fs39.statSync(filePath);
62729
+ const fileStat = fs40.statSync(filePath);
62543
62730
  if (fileStat.size > MAX_FILE_SIZE_BYTES8) {
62544
62731
  continue;
62545
62732
  }
62546
- const content = fs39.readFileSync(filePath, "utf-8");
62733
+ const content = fs40.readFileSync(filePath, "utf-8");
62547
62734
  const entries = parseTodoComments(content, filePath, tagsSet);
62548
62735
  allEntries.push(...entries);
62549
62736
  } catch {}
@@ -62571,18 +62758,18 @@ var todo_extract = createSwarmTool({
62571
62758
  // src/tools/update-task-status.ts
62572
62759
  init_tool();
62573
62760
  init_schema();
62574
- import * as fs41 from "fs";
62575
- import * as path54 from "path";
62761
+ import * as fs42 from "fs";
62762
+ import * as path55 from "path";
62576
62763
 
62577
62764
  // src/hooks/diff-scope.ts
62578
- import * as fs40 from "fs";
62579
- import * as path53 from "path";
62765
+ import * as fs41 from "fs";
62766
+ import * as path54 from "path";
62580
62767
  function getDeclaredScope(taskId, directory) {
62581
62768
  try {
62582
- const planPath = path53.join(directory, ".swarm", "plan.json");
62583
- if (!fs40.existsSync(planPath))
62769
+ const planPath = path54.join(directory, ".swarm", "plan.json");
62770
+ if (!fs41.existsSync(planPath))
62584
62771
  return null;
62585
- const raw = fs40.readFileSync(planPath, "utf-8");
62772
+ const raw = fs41.readFileSync(planPath, "utf-8");
62586
62773
  const plan = JSON.parse(raw);
62587
62774
  for (const phase of plan.phases ?? []) {
62588
62775
  for (const task of phase.tasks ?? []) {
@@ -62694,7 +62881,7 @@ var TIER_3_PATTERNS = [
62694
62881
  ];
62695
62882
  function matchesTier3Pattern(files) {
62696
62883
  for (const file3 of files) {
62697
- const fileName = path54.basename(file3);
62884
+ const fileName = path55.basename(file3);
62698
62885
  for (const pattern of TIER_3_PATTERNS) {
62699
62886
  if (pattern.test(fileName)) {
62700
62887
  return true;
@@ -62716,8 +62903,8 @@ function checkReviewerGate(taskId, workingDirectory) {
62716
62903
  if (hasActiveTurboMode2()) {
62717
62904
  const resolvedDir2 = workingDirectory ?? process.cwd();
62718
62905
  try {
62719
- const planPath = path54.join(resolvedDir2, ".swarm", "plan.json");
62720
- const planRaw = fs41.readFileSync(planPath, "utf-8");
62906
+ const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
62907
+ const planRaw = fs42.readFileSync(planPath, "utf-8");
62721
62908
  const plan = JSON.parse(planRaw);
62722
62909
  for (const planPhase of plan.phases ?? []) {
62723
62910
  for (const task of planPhase.tasks ?? []) {
@@ -62736,8 +62923,8 @@ function checkReviewerGate(taskId, workingDirectory) {
62736
62923
  }
62737
62924
  const resolvedDir = workingDirectory ?? process.cwd();
62738
62925
  try {
62739
- const evidencePath = path54.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
62740
- const raw = fs41.readFileSync(evidencePath, "utf-8");
62926
+ const evidencePath = path55.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
62927
+ const raw = fs42.readFileSync(evidencePath, "utf-8");
62741
62928
  const evidence = JSON.parse(raw);
62742
62929
  if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
62743
62930
  const allGatesMet = evidence.required_gates.every((gate) => evidence.gates[gate] != null);
@@ -62777,8 +62964,8 @@ function checkReviewerGate(taskId, workingDirectory) {
62777
62964
  }
62778
62965
  try {
62779
62966
  const resolvedDir2 = workingDirectory ?? process.cwd();
62780
- const planPath = path54.join(resolvedDir2, ".swarm", "plan.json");
62781
- const planRaw = fs41.readFileSync(planPath, "utf-8");
62967
+ const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
62968
+ const planRaw = fs42.readFileSync(planPath, "utf-8");
62782
62969
  const plan = JSON.parse(planRaw);
62783
62970
  for (const planPhase of plan.phases ?? []) {
62784
62971
  for (const task of planPhase.tasks ?? []) {
@@ -62959,8 +63146,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
62959
63146
  };
62960
63147
  }
62961
63148
  }
62962
- normalizedDir = path54.normalize(args2.working_directory);
62963
- const pathParts = normalizedDir.split(path54.sep);
63149
+ normalizedDir = path55.normalize(args2.working_directory);
63150
+ const pathParts = normalizedDir.split(path55.sep);
62964
63151
  if (pathParts.includes("..")) {
62965
63152
  return {
62966
63153
  success: false,
@@ -62970,11 +63157,11 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
62970
63157
  ]
62971
63158
  };
62972
63159
  }
62973
- const resolvedDir = path54.resolve(normalizedDir);
63160
+ const resolvedDir = path55.resolve(normalizedDir);
62974
63161
  try {
62975
- const realPath = fs41.realpathSync(resolvedDir);
62976
- const planPath = path54.join(realPath, ".swarm", "plan.json");
62977
- if (!fs41.existsSync(planPath)) {
63162
+ const realPath = fs42.realpathSync(resolvedDir);
63163
+ const planPath = path55.join(realPath, ".swarm", "plan.json");
63164
+ if (!fs42.existsSync(planPath)) {
62978
63165
  return {
62979
63166
  success: false,
62980
63167
  message: `Invalid working_directory: plan not found in "${realPath}"`,
@@ -63168,7 +63355,7 @@ var OpenCodeSwarm = async (ctx) => {
63168
63355
  const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
63169
63356
  preflightTriggerManager = new PTM(automationConfig);
63170
63357
  const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
63171
- const swarmDir = path55.resolve(ctx.directory, ".swarm");
63358
+ const swarmDir = path56.resolve(ctx.directory, ".swarm");
63172
63359
  statusArtifact = new ASA(swarmDir);
63173
63360
  statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
63174
63361
  if (automationConfig.capabilities?.evidence_auto_summaries === true) {