opencode-swarm 7.0.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -33,7 +33,7 @@ var package_default;
33
33
  var init_package = __esm(() => {
34
34
  package_default = {
35
35
  name: "opencode-swarm",
36
- version: "7.0.0",
36
+ version: "7.0.1",
37
37
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
38
38
  main: "dist/index.js",
39
39
  types: "dist/index.d.ts",
@@ -16750,7 +16750,7 @@ async function loadPlan(directory) {
16750
16750
  const rebuilt = await replayFromLedger(directory);
16751
16751
  if (rebuilt) {
16752
16752
  await rebuildPlan(directory, rebuilt);
16753
- warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at SWARM_PLAN.md if it exists.");
16753
+ warn("[loadPlan] Rebuilt plan from ledger. Checkpoint available at .swarm/SWARM_PLAN.md if it exists.");
16754
16754
  return rebuilt;
16755
16755
  }
16756
16756
  } catch (replayError) {
@@ -16771,7 +16771,7 @@ async function loadPlan(directory) {
16771
16771
  return approved.plan;
16772
16772
  }
16773
16773
  } catch {}
16774
- warn(`[loadPlan] Ledger replay failed during hash-mismatch rebuild: ${replayError instanceof Error ? replayError.message : String(replayError)}. Returning stale plan.json. To recover: check SWARM_PLAN.md for a checkpoint, or run /swarm reset-session.`);
16774
+ warn(`[loadPlan] Ledger replay failed during hash-mismatch rebuild: ${replayError instanceof Error ? replayError.message : String(replayError)}. Returning stale plan.json. To recover: check .swarm/SWARM_PLAN.md for a checkpoint, or run /swarm reset-session.`);
16775
16775
  }
16776
16776
  }
16777
16777
  }
@@ -16817,7 +16817,7 @@ async function loadPlan(directory) {
16817
16817
  }
16818
16818
  return validated;
16819
16819
  } catch (error49) {
16820
- warn(`[loadPlan] plan.json validation failed: ${error49 instanceof Error ? error49.message : String(error49)}. Attempting rebuild from ledger. If rebuild fails, check SWARM_PLAN.md for a checkpoint.`);
16820
+ warn(`[loadPlan] plan.json validation failed: ${error49 instanceof Error ? error49.message : String(error49)}. Attempting rebuild from ledger. If rebuild fails, check .swarm/SWARM_PLAN.md for a checkpoint.`);
16821
16821
  let rawPlanId = null;
16822
16822
  try {
16823
16823
  const rawParsed = JSON.parse(planJsonContent);
@@ -39463,6 +39463,7 @@ var init_create_tool = __esm(() => {
39463
39463
  // src/tools/checkpoint.ts
39464
39464
  var exports_checkpoint = {};
39465
39465
  __export(exports_checkpoint, {
39466
+ saveCheckpointRecord: () => saveCheckpointRecord,
39466
39467
  checkpoint: () => checkpoint
39467
39468
  });
39468
39469
  import * as child_process from "node:child_process";
@@ -39617,6 +39618,38 @@ function handleSave(label, directory) {
39617
39618
  }, null, 2);
39618
39619
  }
39619
39620
  }
39621
+ function saveCheckpointRecord(label, directory) {
39622
+ const labelError = validateLabel(label);
39623
+ if (labelError) {
39624
+ return { success: false, error: labelError };
39625
+ }
39626
+ try {
39627
+ const log2 = readCheckpointLog(directory);
39628
+ if (log2.checkpoints.find((c) => c.label === label)) {
39629
+ return { success: false, error: `duplicate label: "${label}"` };
39630
+ }
39631
+ let sha = "";
39632
+ if (isGitRepo()) {
39633
+ try {
39634
+ sha = getCurrentSha();
39635
+ } catch {
39636
+ sha = "";
39637
+ }
39638
+ }
39639
+ log2.checkpoints.push({
39640
+ label,
39641
+ sha,
39642
+ timestamp: new Date().toISOString()
39643
+ });
39644
+ writeCheckpointLog(log2, directory);
39645
+ return { success: true, sha };
39646
+ } catch (e) {
39647
+ return {
39648
+ success: false,
39649
+ error: e instanceof Error ? e.message : "unknown error"
39650
+ };
39651
+ }
39652
+ }
39620
39653
  function handleRestore(label, directory) {
39621
39654
  try {
39622
39655
  const log2 = readCheckpointLog(directory);
@@ -42084,22 +42117,20 @@ async function handleCloseCommand(directory, args2) {
42084
42117
  }
42085
42118
  } catch {}
42086
42119
  let swarmPlanFilesRemoved = 0;
42087
- const swarmPlanJsonPath = path18.join(directory, "SWARM_PLAN.json");
42088
- const swarmPlanMdPath = path18.join(directory, "SWARM_PLAN.md");
42089
- try {
42090
- await fs12.unlink(swarmPlanJsonPath);
42091
- swarmPlanFilesRemoved++;
42092
- } catch (err2) {
42093
- if (err2?.code !== "ENOENT") {
42094
- warnings.push(`Failed to remove SWARM_PLAN.json: ${err2 instanceof Error ? err2.message : String(err2)}`);
42095
- }
42096
- }
42097
- try {
42098
- await fs12.unlink(swarmPlanMdPath);
42099
- swarmPlanFilesRemoved++;
42100
- } catch (err2) {
42101
- if (err2?.code !== "ENOENT") {
42102
- warnings.push(`Failed to remove SWARM_PLAN.md: ${err2 instanceof Error ? err2.message : String(err2)}`);
42120
+ const candidates = [
42121
+ path18.join(directory, ".swarm", "SWARM_PLAN.json"),
42122
+ path18.join(directory, ".swarm", "SWARM_PLAN.md"),
42123
+ path18.join(directory, "SWARM_PLAN.json"),
42124
+ path18.join(directory, "SWARM_PLAN.md")
42125
+ ];
42126
+ for (const candidate of candidates) {
42127
+ try {
42128
+ await fs12.unlink(candidate);
42129
+ swarmPlanFilesRemoved++;
42130
+ } catch (err2) {
42131
+ if (err2?.code !== "ENOENT") {
42132
+ warnings.push(`Failed to remove ${path18.basename(candidate)}: ${err2 instanceof Error ? err2.message : String(err2)}`);
42133
+ }
42103
42134
  }
42104
42135
  }
42105
42136
  clearAllScopes(directory);
@@ -42174,9 +42205,7 @@ async function handleCloseCommand(directory, args2) {
42174
42205
  "- Reset context.md for next session",
42175
42206
  "- Cleared agent sessions and delegation chains",
42176
42207
  ...configBackupsRemoved > 0 ? [`- Removed ${configBackupsRemoved} stale config backup file(s)`] : [],
42177
- ...swarmPlanFilesRemoved > 0 ? [
42178
- `- Removed ${swarmPlanFilesRemoved} root-level SWARM_PLAN checkpoint artifact(s)`
42179
- ] : [],
42208
+ ...swarmPlanFilesRemoved > 0 ? [`- Removed ${swarmPlanFilesRemoved} SWARM_PLAN checkpoint artifact(s)`] : [],
42180
42209
  ...planExists && !planAlreadyDone ? ["- Set non-completed phases/tasks to closed status"] : [],
42181
42210
  ...curationSucceeded && allLessons.length > 0 ? [`- Committed ${allLessons.length} lesson(s) to knowledge store`] : [],
42182
42211
  "",
@@ -44094,11 +44123,21 @@ function getPluginConfigDir() {
44094
44123
  function getPluginCachePaths() {
44095
44124
  const cacheBase = process.env.XDG_CACHE_HOME || path24.join(os5.homedir(), ".cache");
44096
44125
  const configDir = getPluginConfigDir();
44097
- return [
44126
+ const paths = [
44127
+ path24.join(cacheBase, "opencode", "node_modules", "opencode-swarm"),
44098
44128
  path24.join(cacheBase, "opencode", "packages", "opencode-swarm@latest"),
44099
- path24.join(configDir, "node_modules", "opencode-swarm"),
44100
- path24.join(cacheBase, "opencode", "node_modules", "opencode-swarm")
44129
+ path24.join(configDir, "node_modules", "opencode-swarm")
44101
44130
  ];
44131
+ if (process.platform === "darwin") {
44132
+ const libCaches = path24.join(os5.homedir(), "Library", "Caches");
44133
+ paths.push(path24.join(libCaches, "opencode", "node_modules", "opencode-swarm"), path24.join(libCaches, "opencode", "packages", "opencode-swarm@latest"));
44134
+ }
44135
+ if (process.platform === "win32") {
44136
+ const localAppData = process.env.LOCALAPPDATA || path24.join(os5.homedir(), "AppData", "Local");
44137
+ const appData = process.env.APPDATA || path24.join(os5.homedir(), "AppData", "Roaming");
44138
+ paths.push(path24.join(localAppData, "opencode", "node_modules", "opencode-swarm"), path24.join(localAppData, "opencode", "packages", "opencode-swarm@latest"), path24.join(appData, "opencode", "node_modules", "opencode-swarm"));
44139
+ }
44140
+ return paths;
44102
44141
  }
44103
44142
  var init_cache_paths = () => {};
44104
44143
 
@@ -53940,13 +53979,14 @@ var init_manager3 = __esm(() => {
53940
53979
 
53941
53980
  // src/commands/reset.ts
53942
53981
  import * as fs25 from "node:fs";
53982
+ import * as path38 from "node:path";
53943
53983
  async function handleResetCommand(directory, args2) {
53944
53984
  const hasConfirm = args2.includes("--confirm");
53945
53985
  if (!hasConfirm) {
53946
53986
  return [
53947
53987
  "## Swarm Reset",
53948
53988
  "",
53949
- "⚠️ This will delete plan.md and context.md from .swarm/",
53989
+ "⚠️ This will delete all swarm state from .swarm/ (plan, context, checkpoints, SWARM_PLAN artifacts)",
53950
53990
  "",
53951
53991
  "**Tip**: Run `/swarm export` first to backup your state.",
53952
53992
  "",
@@ -53954,7 +53994,15 @@ async function handleResetCommand(directory, args2) {
53954
53994
  ].join(`
53955
53995
  `);
53956
53996
  }
53957
- const filesToReset = ["plan.md", "context.md"];
53997
+ const filesToReset = [
53998
+ "plan.md",
53999
+ "plan.json",
54000
+ "context.md",
54001
+ "SWARM_PLAN.md",
54002
+ "SWARM_PLAN.json",
54003
+ "checkpoints.json",
54004
+ "events.jsonl"
54005
+ ];
53958
54006
  const results = [];
53959
54007
  for (const filename of filesToReset) {
53960
54008
  try {
@@ -53969,6 +54017,15 @@ async function handleResetCommand(directory, args2) {
53969
54017
  results.push(`- ❌ Failed to delete ${filename}`);
53970
54018
  }
53971
54019
  }
54020
+ for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
54021
+ try {
54022
+ const rootPath = path38.join(directory, filename);
54023
+ if (fs25.existsSync(rootPath)) {
54024
+ fs25.unlinkSync(rootPath);
54025
+ results.push(`- ✅ Deleted ${filename} (root)`);
54026
+ }
54027
+ } catch {}
54028
+ }
53972
54029
  try {
53973
54030
  resetAutomationManager();
53974
54031
  results.push("- ✅ Stopped background automation (in-memory queues cleared)");
@@ -54002,7 +54059,7 @@ var init_reset = __esm(() => {
54002
54059
 
54003
54060
  // src/commands/reset-session.ts
54004
54061
  import * as fs26 from "node:fs";
54005
- import * as path38 from "node:path";
54062
+ import * as path39 from "node:path";
54006
54063
  async function handleResetSessionCommand(directory, _args) {
54007
54064
  const results = [];
54008
54065
  try {
@@ -54017,13 +54074,13 @@ async function handleResetSessionCommand(directory, _args) {
54017
54074
  results.push("❌ Failed to delete state.json");
54018
54075
  }
54019
54076
  try {
54020
- const sessionDir = path38.dirname(validateSwarmPath(directory, "session/state.json"));
54077
+ const sessionDir = path39.dirname(validateSwarmPath(directory, "session/state.json"));
54021
54078
  if (fs26.existsSync(sessionDir)) {
54022
54079
  const files = fs26.readdirSync(sessionDir);
54023
54080
  const otherFiles = files.filter((f) => f !== "state.json");
54024
54081
  let deletedCount = 0;
54025
54082
  for (const file3 of otherFiles) {
54026
- const filePath = path38.join(sessionDir, file3);
54083
+ const filePath = path39.join(sessionDir, file3);
54027
54084
  if (fs26.lstatSync(filePath).isFile()) {
54028
54085
  fs26.unlinkSync(filePath);
54029
54086
  deletedCount++;
@@ -54056,7 +54113,7 @@ var init_reset_session = __esm(() => {
54056
54113
 
54057
54114
  // src/summaries/manager.ts
54058
54115
  import { mkdirSync as mkdirSync13, readdirSync as readdirSync10, renameSync as renameSync10, rmSync as rmSync4, statSync as statSync10 } from "node:fs";
54059
- import * as path39 from "node:path";
54116
+ import * as path40 from "node:path";
54060
54117
  function sanitizeSummaryId(id) {
54061
54118
  if (!id || id.length === 0) {
54062
54119
  throw new Error("Invalid summary ID: empty string");
@@ -54090,9 +54147,9 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
54090
54147
  if (serializedSize > maxStoredBytes) {
54091
54148
  throw new Error(`Summary entry size (${serializedSize} bytes) exceeds maximum (${maxStoredBytes} bytes)`);
54092
54149
  }
54093
- const relativePath = path39.join("summaries", `${sanitizedId}.json`);
54150
+ const relativePath = path40.join("summaries", `${sanitizedId}.json`);
54094
54151
  const summaryPath = validateSwarmPath(directory, relativePath);
54095
- const summaryDir = path39.dirname(summaryPath);
54152
+ const summaryDir = path40.dirname(summaryPath);
54096
54153
  const entry = {
54097
54154
  id: sanitizedId,
54098
54155
  summaryText,
@@ -54102,7 +54159,7 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
54102
54159
  };
54103
54160
  const entryJson = JSON.stringify(entry);
54104
54161
  mkdirSync13(summaryDir, { recursive: true });
54105
- const tempPath = path39.join(summaryDir, `${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);
54162
+ const tempPath = path40.join(summaryDir, `${sanitizedId}.json.tmp.${Date.now()}.${process.pid}`);
54106
54163
  try {
54107
54164
  await Bun.write(tempPath, entryJson);
54108
54165
  renameSync10(tempPath, summaryPath);
@@ -54115,7 +54172,7 @@ async function storeSummary(directory, id, fullOutput, summaryText, maxStoredByt
54115
54172
  }
54116
54173
  async function loadFullOutput(directory, id) {
54117
54174
  const sanitizedId = sanitizeSummaryId(id);
54118
- const relativePath = path39.join("summaries", `${sanitizedId}.json`);
54175
+ const relativePath = path40.join("summaries", `${sanitizedId}.json`);
54119
54176
  validateSwarmPath(directory, relativePath);
54120
54177
  const content = await readSwarmFileAsync(directory, relativePath);
54121
54178
  if (content === null) {
@@ -54177,7 +54234,7 @@ var init_retrieve = __esm(() => {
54177
54234
 
54178
54235
  // src/commands/rollback.ts
54179
54236
  import * as fs27 from "node:fs";
54180
- import * as path40 from "node:path";
54237
+ import * as path41 from "node:path";
54181
54238
  async function handleRollbackCommand(directory, args2) {
54182
54239
  const phaseArg = args2[0];
54183
54240
  if (!phaseArg) {
@@ -54242,8 +54299,8 @@ async function handleRollbackCommand(directory, args2) {
54242
54299
  if (EXCLUDE_FILES.has(file3) || file3.startsWith("plan-ledger.archived-")) {
54243
54300
  continue;
54244
54301
  }
54245
- const src = path40.join(checkpointDir, file3);
54246
- const dest = path40.join(swarmDir, file3);
54302
+ const src = path41.join(checkpointDir, file3);
54303
+ const dest = path41.join(swarmDir, file3);
54247
54304
  try {
54248
54305
  fs27.cpSync(src, dest, { recursive: true, force: true });
54249
54306
  successes.push(file3);
@@ -54262,12 +54319,12 @@ async function handleRollbackCommand(directory, args2) {
54262
54319
  ].join(`
54263
54320
  `);
54264
54321
  }
54265
- const existingLedgerPath = path40.join(swarmDir, "plan-ledger.jsonl");
54322
+ const existingLedgerPath = path41.join(swarmDir, "plan-ledger.jsonl");
54266
54323
  if (fs27.existsSync(existingLedgerPath)) {
54267
54324
  fs27.unlinkSync(existingLedgerPath);
54268
54325
  }
54269
54326
  try {
54270
- const planJsonPath = path40.join(swarmDir, "plan.json");
54327
+ const planJsonPath = path41.join(swarmDir, "plan.json");
54271
54328
  if (fs27.existsSync(planJsonPath)) {
54272
54329
  const planRaw = fs27.readFileSync(planJsonPath, "utf-8");
54273
54330
  const plan = PlanSchema.parse(JSON.parse(planRaw));
@@ -54345,9 +54402,9 @@ async function handleSimulateCommand(directory, args2) {
54345
54402
  const report = reportLines.filter(Boolean).join(`
54346
54403
  `);
54347
54404
  const fs28 = await import("node:fs/promises");
54348
- const path41 = await import("node:path");
54349
- const reportPath = path41.join(directory, ".swarm", "simulate-report.md");
54350
- await fs28.mkdir(path41.dirname(reportPath), { recursive: true });
54405
+ const path42 = await import("node:path");
54406
+ const reportPath = path42.join(directory, ".swarm", "simulate-report.md");
54407
+ await fs28.mkdir(path42.dirname(reportPath), { recursive: true });
54351
54408
  await fs28.writeFile(reportPath, report, "utf-8");
54352
54409
  return `${darkMatterPairs.length} hidden coupling pairs detected`;
54353
54410
  }
@@ -54366,7 +54423,7 @@ async function handleSpecifyCommand(_directory, args2) {
54366
54423
 
54367
54424
  // src/services/compaction-service.ts
54368
54425
  import * as fs28 from "node:fs";
54369
- import * as path41 from "node:path";
54426
+ import * as path42 from "node:path";
54370
54427
  function makeInitialState() {
54371
54428
  return {
54372
54429
  lastObservationAt: 0,
@@ -54388,7 +54445,7 @@ function getSessionState(sessionId) {
54388
54445
  }
54389
54446
  function appendSnapshot(directory, tier, budgetPct, message) {
54390
54447
  try {
54391
- const snapshotPath = path41.join(directory, ".swarm", "context-snapshot.md");
54448
+ const snapshotPath = path42.join(directory, ".swarm", "context-snapshot.md");
54392
54449
  const timestamp = new Date().toISOString();
54393
54450
  const entry = `
54394
54451
  ## [${tier.toUpperCase()}] ${timestamp} — ${budgetPct.toFixed(1)}% used
@@ -58769,7 +58826,7 @@ COVERAGE REPORTING:
58769
58826
 
58770
58827
  // src/agents/index.ts
58771
58828
  import { mkdir as mkdir6, writeFile as writeFile6 } from "node:fs/promises";
58772
- import * as path42 from "node:path";
58829
+ import * as path43 from "node:path";
58773
58830
  function stripSwarmPrefix(agentName, swarmPrefix) {
58774
58831
  if (!swarmPrefix || !agentName)
58775
58832
  return agentName;
@@ -59080,14 +59137,14 @@ function getAgentConfigs(config3, directory, sessionId) {
59080
59137
  }));
59081
59138
  if (directory) {
59082
59139
  const sid = sessionId ?? `init-${Date.now()}`;
59083
- const evidenceDir = path42.join(directory, ".swarm", "evidence");
59140
+ const evidenceDir = path43.join(directory, ".swarm", "evidence");
59084
59141
  const filename = `agent-tools-${sid}.json`;
59085
59142
  const snapshotData = JSON.stringify({
59086
59143
  sessionId: sid,
59087
59144
  generatedAt: new Date().toISOString(),
59088
59145
  agents: agentToolSnapshot
59089
59146
  }, null, 2);
59090
- mkdir6(evidenceDir, { recursive: true }).then(() => writeFile6(path42.join(evidenceDir, filename), snapshotData)).catch(() => {});
59147
+ mkdir6(evidenceDir, { recursive: true }).then(() => writeFile6(path43.join(evidenceDir, filename), snapshotData)).catch(() => {});
59091
59148
  }
59092
59149
  return result;
59093
59150
  }
@@ -59113,13 +59170,13 @@ __export(exports_evidence_summary_integration, {
59113
59170
  EvidenceSummaryIntegration: () => EvidenceSummaryIntegration
59114
59171
  });
59115
59172
  import { existsSync as existsSync24, mkdirSync as mkdirSync14, writeFileSync as writeFileSync6 } from "node:fs";
59116
- import * as path43 from "node:path";
59173
+ import * as path44 from "node:path";
59117
59174
  function persistSummary(projectDir, artifact, filename) {
59118
- const swarmPath = path43.join(projectDir, ".swarm");
59175
+ const swarmPath = path44.join(projectDir, ".swarm");
59119
59176
  if (!existsSync24(swarmPath)) {
59120
59177
  mkdirSync14(swarmPath, { recursive: true });
59121
59178
  }
59122
- const artifactPath = path43.join(swarmPath, filename);
59179
+ const artifactPath = path44.join(swarmPath, filename);
59123
59180
  const content = JSON.stringify(artifact, null, 2);
59124
59181
  writeFileSync6(artifactPath, content, "utf-8");
59125
59182
  log("[EvidenceSummaryIntegration] Summary persisted", {
@@ -59238,7 +59295,7 @@ __export(exports_status_artifact, {
59238
59295
  AutomationStatusArtifact: () => AutomationStatusArtifact
59239
59296
  });
59240
59297
  import * as fs30 from "node:fs";
59241
- import * as path45 from "node:path";
59298
+ import * as path46 from "node:path";
59242
59299
  function createEmptySnapshot(mode, capabilities) {
59243
59300
  return {
59244
59301
  timestamp: Date.now(),
@@ -59297,7 +59354,7 @@ class AutomationStatusArtifact {
59297
59354
  });
59298
59355
  }
59299
59356
  getFilePath() {
59300
- return path45.join(this.swarmDir, this.filename);
59357
+ return path46.join(this.swarmDir, this.filename);
59301
59358
  }
59302
59359
  load() {
59303
59360
  const filePath = this.getFilePath();
@@ -59710,12 +59767,12 @@ __export(exports_review_receipt, {
59710
59767
  });
59711
59768
  import * as crypto5 from "node:crypto";
59712
59769
  import * as fs34 from "node:fs";
59713
- import * as path46 from "node:path";
59770
+ import * as path47 from "node:path";
59714
59771
  function resolveReceiptsDir(directory) {
59715
- return path46.join(directory, ".swarm", "review-receipts");
59772
+ return path47.join(directory, ".swarm", "review-receipts");
59716
59773
  }
59717
59774
  function resolveReceiptIndexPath(directory) {
59718
- return path46.join(resolveReceiptsDir(directory), "index.json");
59775
+ return path47.join(resolveReceiptsDir(directory), "index.json");
59719
59776
  }
59720
59777
  function buildReceiptFilename(id, date9) {
59721
59778
  const dateStr = date9.toISOString().slice(0, 10);
@@ -59754,7 +59811,7 @@ async function readReceiptIndex(directory) {
59754
59811
  }
59755
59812
  async function writeReceiptIndex(directory, index) {
59756
59813
  const indexPath = resolveReceiptIndexPath(directory);
59757
- const dir = path46.dirname(indexPath);
59814
+ const dir = path47.dirname(indexPath);
59758
59815
  await fs34.promises.mkdir(dir, { recursive: true });
59759
59816
  const tmpPath = `${indexPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
59760
59817
  await fs34.promises.writeFile(tmpPath, JSON.stringify(index, null, 2), "utf-8");
@@ -59765,7 +59822,7 @@ async function persistReviewReceipt(directory, receipt) {
59765
59822
  await fs34.promises.mkdir(receiptsDir, { recursive: true });
59766
59823
  const now = new Date(receipt.reviewed_at);
59767
59824
  const filename = buildReceiptFilename(receipt.id, now);
59768
- const receiptPath = path46.join(receiptsDir, filename);
59825
+ const receiptPath = path47.join(receiptsDir, filename);
59769
59826
  const tmpPath = `${receiptPath}.tmp.${Date.now()}.${Math.random().toString(36).slice(2)}`;
59770
59827
  await fs34.promises.writeFile(tmpPath, JSON.stringify(receipt, null, 2), "utf-8");
59771
59828
  fs34.renameSync(tmpPath, receiptPath);
@@ -59787,7 +59844,7 @@ async function readReceiptById(directory, receiptId) {
59787
59844
  const entry = index.entries.find((e) => e.id === receiptId);
59788
59845
  if (!entry)
59789
59846
  return null;
59790
- const receiptPath = path46.join(resolveReceiptsDir(directory), entry.filename);
59847
+ const receiptPath = path47.join(resolveReceiptsDir(directory), entry.filename);
59791
59848
  try {
59792
59849
  const content = await fs34.promises.readFile(receiptPath, "utf-8");
59793
59850
  return JSON.parse(content);
@@ -59800,7 +59857,7 @@ async function readReceiptsByScopeHash(directory, scopeHash) {
59800
59857
  const matching = index.entries.filter((e) => e.scope_hash === scopeHash).sort((a, b) => b.reviewed_at.localeCompare(a.reviewed_at));
59801
59858
  const receipts = [];
59802
59859
  for (const entry of matching) {
59803
- const receiptPath = path46.join(resolveReceiptsDir(directory), entry.filename);
59860
+ const receiptPath = path47.join(resolveReceiptsDir(directory), entry.filename);
59804
59861
  try {
59805
59862
  const content = await fs34.promises.readFile(receiptPath, "utf-8");
59806
59863
  receipts.push(JSON.parse(content));
@@ -59813,7 +59870,7 @@ async function readAllReceipts(directory) {
59813
59870
  const sorted = [...index.entries].sort((a, b) => b.reviewed_at.localeCompare(a.reviewed_at));
59814
59871
  const receipts = [];
59815
59872
  for (const entry of sorted) {
59816
- const receiptPath = path46.join(resolveReceiptsDir(directory), entry.filename);
59873
+ const receiptPath = path47.join(resolveReceiptsDir(directory), entry.filename);
59817
59874
  try {
59818
59875
  const content = await fs34.promises.readFile(receiptPath, "utf-8");
59819
59876
  receipts.push(JSON.parse(content));
@@ -61401,11 +61458,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
61401
61458
  throw toThrow;
61402
61459
  }, "quit_");
61403
61460
  var scriptDirectory = "";
61404
- function locateFile(path57) {
61461
+ function locateFile(path58) {
61405
61462
  if (Module["locateFile"]) {
61406
- return Module["locateFile"](path57, scriptDirectory);
61463
+ return Module["locateFile"](path58, scriptDirectory);
61407
61464
  }
61408
- return scriptDirectory + path57;
61465
+ return scriptDirectory + path58;
61409
61466
  }
61410
61467
  __name(locateFile, "locateFile");
61411
61468
  var readAsync, readBinary;
@@ -63154,13 +63211,13 @@ __export(exports_runtime, {
63154
63211
  getInitializedLanguages: () => getInitializedLanguages,
63155
63212
  clearParserCache: () => clearParserCache
63156
63213
  });
63157
- import * as path57 from "node:path";
63214
+ import * as path58 from "node:path";
63158
63215
  import { fileURLToPath as fileURLToPath2 } from "node:url";
63159
63216
  async function initTreeSitter() {
63160
63217
  if (treeSitterInitialized) {
63161
63218
  return;
63162
63219
  }
63163
- const thisDir = path57.dirname(fileURLToPath2(import.meta.url));
63220
+ const thisDir = path58.dirname(fileURLToPath2(import.meta.url));
63164
63221
  const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
63165
63222
  if (isSource) {
63166
63223
  await Parser.init();
@@ -63168,7 +63225,7 @@ async function initTreeSitter() {
63168
63225
  const grammarsDir = getGrammarsDirAbsolute();
63169
63226
  await Parser.init({
63170
63227
  locateFile(scriptName) {
63171
- return path57.join(grammarsDir, scriptName);
63228
+ return path58.join(grammarsDir, scriptName);
63172
63229
  }
63173
63230
  });
63174
63231
  }
@@ -63189,11 +63246,11 @@ function getWasmFileName(languageId) {
63189
63246
  return `tree-sitter-${sanitized}.wasm`;
63190
63247
  }
63191
63248
  function getGrammarsDirAbsolute() {
63192
- const thisDir = path57.dirname(fileURLToPath2(import.meta.url));
63249
+ const thisDir = path58.dirname(fileURLToPath2(import.meta.url));
63193
63250
  const normalized = thisDir.replace(/\\/g, "/");
63194
63251
  const isSource = normalized.endsWith("/src/lang");
63195
63252
  const isCliBundle = normalized.endsWith("/cli");
63196
- return isSource ? path57.join(thisDir, "grammars") : isCliBundle ? path57.join(thisDir, "..", "lang", "grammars") : path57.join(thisDir, "lang", "grammars");
63253
+ return isSource ? path58.join(thisDir, "grammars") : isCliBundle ? path58.join(thisDir, "..", "lang", "grammars") : path58.join(thisDir, "lang", "grammars");
63197
63254
  }
63198
63255
  async function loadGrammar(languageId) {
63199
63256
  if (typeof languageId !== "string" || languageId.length > 100) {
@@ -63209,7 +63266,7 @@ async function loadGrammar(languageId) {
63209
63266
  await initTreeSitter();
63210
63267
  const parser = new Parser;
63211
63268
  const wasmFileName = getWasmFileName(normalizedId);
63212
- const wasmPath = path57.join(getGrammarsDirAbsolute(), wasmFileName);
63269
+ const wasmPath = path58.join(getGrammarsDirAbsolute(), wasmFileName);
63213
63270
  const { existsSync: existsSync30 } = await import("node:fs");
63214
63271
  if (!existsSync30(wasmPath)) {
63215
63272
  throw new Error(`Grammar file not found for ${languageId}: ${wasmPath}
@@ -63244,7 +63301,7 @@ async function isGrammarAvailable(languageId) {
63244
63301
  }
63245
63302
  try {
63246
63303
  const wasmFileName = getWasmFileName(normalizedId);
63247
- const wasmPath = path57.join(getGrammarsDirAbsolute(), wasmFileName);
63304
+ const wasmPath = path58.join(getGrammarsDirAbsolute(), wasmFileName);
63248
63305
  const { statSync: statSync18 } = await import("node:fs");
63249
63306
  statSync18(wasmPath);
63250
63307
  return true;
@@ -63303,13 +63360,13 @@ __export(exports_doc_scan, {
63303
63360
  import * as crypto7 from "node:crypto";
63304
63361
  import * as fs43 from "node:fs";
63305
63362
  import { mkdir as mkdir9, readFile as readFile8, writeFile as writeFile8 } from "node:fs/promises";
63306
- import * as path59 from "node:path";
63363
+ import * as path60 from "node:path";
63307
63364
  function normalizeSeparators(filePath) {
63308
63365
  return filePath.replace(/\\/g, "/");
63309
63366
  }
63310
63367
  function matchesDocPattern(filePath, patterns) {
63311
63368
  const normalizedPath = normalizeSeparators(filePath);
63312
- const basename8 = path59.basename(filePath);
63369
+ const basename8 = path60.basename(filePath);
63313
63370
  for (const pattern of patterns) {
63314
63371
  if (!pattern.includes("/") && !pattern.includes("\\")) {
63315
63372
  if (basename8 === pattern) {
@@ -63365,7 +63422,7 @@ function stripMarkdown(text) {
63365
63422
  return text.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1").replace(/\*\*([^*]+)\*\*/g, "$1").replace(/`([^`]+)`/g, "$1").replace(/^\s*[-*•]\s+/gm, "").replace(/^\s*\d+\.\s+/gm, "").trim();
63366
63423
  }
63367
63424
  async function scanDocIndex(directory) {
63368
- const manifestPath = path59.join(directory, ".swarm", "doc-manifest.json");
63425
+ const manifestPath = path60.join(directory, ".swarm", "doc-manifest.json");
63369
63426
  const defaultPatterns = DocsConfigSchema.parse({}).doc_patterns;
63370
63427
  const extraPatterns = [
63371
63428
  "ARCHITECTURE.md",
@@ -63382,7 +63439,7 @@ async function scanDocIndex(directory) {
63382
63439
  let cacheValid = true;
63383
63440
  for (const file3 of existingManifest.files) {
63384
63441
  try {
63385
- const fullPath = path59.join(directory, file3.path);
63442
+ const fullPath = path60.join(directory, file3.path);
63386
63443
  const stat3 = fs43.statSync(fullPath);
63387
63444
  if (stat3.mtimeMs > file3.mtime) {
63388
63445
  cacheValid = false;
@@ -63412,7 +63469,7 @@ async function scanDocIndex(directory) {
63412
63469
  }
63413
63470
  const entries = rawEntries.filter((e) => typeof e === "string");
63414
63471
  for (const entry of entries) {
63415
- const fullPath = path59.join(directory, entry);
63472
+ const fullPath = path60.join(directory, entry);
63416
63473
  let stat3;
63417
63474
  try {
63418
63475
  stat3 = fs43.statSync(fullPath);
@@ -63448,7 +63505,7 @@ async function scanDocIndex(directory) {
63448
63505
  } catch {
63449
63506
  continue;
63450
63507
  }
63451
- const { title, summary } = extractTitleAndSummary(content, path59.basename(entry));
63508
+ const { title, summary } = extractTitleAndSummary(content, path60.basename(entry));
63452
63509
  const lineCount = content.split(`
63453
63510
  `).length;
63454
63511
  discoveredFiles.push({
@@ -63474,7 +63531,7 @@ async function scanDocIndex(directory) {
63474
63531
  files: discoveredFiles
63475
63532
  };
63476
63533
  try {
63477
- await mkdir9(path59.dirname(manifestPath), { recursive: true });
63534
+ await mkdir9(path60.dirname(manifestPath), { recursive: true });
63478
63535
  await writeFile8(manifestPath, JSON.stringify(manifest, null, 2), "utf-8");
63479
63536
  } catch {}
63480
63537
  return { manifest, cached: false };
@@ -63513,7 +63570,7 @@ function extractConstraintsFromContent(content) {
63513
63570
  return constraints;
63514
63571
  }
63515
63572
  async function extractDocConstraints(directory, taskFiles, taskDescription) {
63516
- const manifestPath = path59.join(directory, ".swarm", "doc-manifest.json");
63573
+ const manifestPath = path60.join(directory, ".swarm", "doc-manifest.json");
63517
63574
  let manifest;
63518
63575
  try {
63519
63576
  const content = await readFile8(manifestPath, "utf-8");
@@ -63539,7 +63596,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
63539
63596
  }
63540
63597
  let fullContent;
63541
63598
  try {
63542
- fullContent = await readFile8(path59.join(directory, docFile.path), "utf-8");
63599
+ fullContent = await readFile8(path60.join(directory, docFile.path), "utf-8");
63543
63600
  } catch {
63544
63601
  skippedCount++;
63545
63602
  continue;
@@ -63562,7 +63619,7 @@ async function extractDocConstraints(directory, taskFiles, taskDescription) {
63562
63619
  tier: "swarm",
63563
63620
  lesson: constraint,
63564
63621
  category: "architecture",
63565
- tags: ["doc-scan", path59.basename(docFile.path)],
63622
+ tags: ["doc-scan", path60.basename(docFile.path)],
63566
63623
  scope: "global",
63567
63624
  confidence: 0.5,
63568
63625
  status: "candidate",
@@ -63635,7 +63692,7 @@ var init_doc_scan = __esm(() => {
63635
63692
  }
63636
63693
  } catch {}
63637
63694
  if (force) {
63638
- const manifestPath = path59.join(directory, ".swarm", "doc-manifest.json");
63695
+ const manifestPath = path60.join(directory, ".swarm", "doc-manifest.json");
63639
63696
  try {
63640
63697
  fs43.unlinkSync(manifestPath);
63641
63698
  } catch {}
@@ -63826,9 +63883,9 @@ __export(exports_curator_drift, {
63826
63883
  buildDriftInjectionText: () => buildDriftInjectionText
63827
63884
  });
63828
63885
  import * as fs46 from "node:fs";
63829
- import * as path62 from "node:path";
63886
+ import * as path63 from "node:path";
63830
63887
  async function readPriorDriftReports(directory) {
63831
- const swarmDir = path62.join(directory, ".swarm");
63888
+ const swarmDir = path63.join(directory, ".swarm");
63832
63889
  const entries = await fs46.promises.readdir(swarmDir).catch(() => null);
63833
63890
  if (entries === null)
63834
63891
  return [];
@@ -63855,7 +63912,7 @@ async function readPriorDriftReports(directory) {
63855
63912
  async function writeDriftReport(directory, report) {
63856
63913
  const filename = `${DRIFT_REPORT_PREFIX}${report.phase}.json`;
63857
63914
  const filePath = validateSwarmPath(directory, filename);
63858
- const swarmDir = path62.dirname(filePath);
63915
+ const swarmDir = path63.dirname(filePath);
63859
63916
  await fs46.promises.mkdir(swarmDir, { recursive: true });
63860
63917
  try {
63861
63918
  await fs46.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
@@ -63991,7 +64048,7 @@ var init_curator_drift = __esm(() => {
63991
64048
  init_package();
63992
64049
  init_agents2();
63993
64050
  import * as fs87 from "node:fs";
63994
- import * as path105 from "node:path";
64051
+ import * as path106 from "node:path";
63995
64052
 
63996
64053
  // src/background/index.ts
63997
64054
  init_event_bus();
@@ -64002,7 +64059,7 @@ init_manager3();
64002
64059
  init_manager();
64003
64060
  init_utils();
64004
64061
  import * as fs29 from "node:fs";
64005
- import * as path44 from "node:path";
64062
+ import * as path45 from "node:path";
64006
64063
 
64007
64064
  class PlanSyncWorker {
64008
64065
  directory;
@@ -64026,10 +64083,10 @@ class PlanSyncWorker {
64026
64083
  this.onSyncComplete = options.onSyncComplete;
64027
64084
  }
64028
64085
  getSwarmDir() {
64029
- return path44.resolve(this.directory, ".swarm");
64086
+ return path45.resolve(this.directory, ".swarm");
64030
64087
  }
64031
64088
  getPlanJsonPath() {
64032
- return path44.join(this.getSwarmDir(), "plan.json");
64089
+ return path45.join(this.getSwarmDir(), "plan.json");
64033
64090
  }
64034
64091
  start() {
64035
64092
  if (this.disposed) {
@@ -64248,8 +64305,8 @@ class PlanSyncWorker {
64248
64305
  checkForUnauthorizedWrite() {
64249
64306
  try {
64250
64307
  const swarmDir = this.getSwarmDir();
64251
- const planJsonPath = path44.join(swarmDir, "plan.json");
64252
- const markerPath = path44.join(swarmDir, ".plan-write-marker");
64308
+ const planJsonPath = path45.join(swarmDir, "plan.json");
64309
+ const markerPath = path45.join(swarmDir, ".plan-write-marker");
64253
64310
  const planStats = fs29.statSync(planJsonPath);
64254
64311
  const planMtimeMs = Math.floor(planStats.mtimeMs);
64255
64312
  const markerContent = fs29.readFileSync(markerPath, "utf8");
@@ -64486,11 +64543,11 @@ async function doFlush(directory) {
64486
64543
  const activitySection = renderActivitySection();
64487
64544
  const updated = replaceOrAppendSection(existing, "## Agent Activity", activitySection);
64488
64545
  const flushedCount = swarmState.pendingEvents;
64489
- const path46 = nodePath2.join(directory, ".swarm", "context.md");
64490
- const tempPath = `${path46}.tmp`;
64546
+ const path47 = nodePath2.join(directory, ".swarm", "context.md");
64547
+ const tempPath = `${path47}.tmp`;
64491
64548
  try {
64492
64549
  await Bun.write(tempPath, updated);
64493
- renameSync11(tempPath, path46);
64550
+ renameSync11(tempPath, path47);
64494
64551
  } catch (writeError) {
64495
64552
  try {
64496
64553
  unlinkSync8(tempPath);
@@ -64541,7 +64598,7 @@ ${content.substring(endIndex + 1)}`;
64541
64598
  init_manager();
64542
64599
  init_utils2();
64543
64600
  import * as fs31 from "node:fs";
64544
- import { join as join42 } from "node:path";
64601
+ import { join as join43 } from "node:path";
64545
64602
  function createCompactionCustomizerHook(config3, directory) {
64546
64603
  const enabled = config3.hooks?.compaction !== false;
64547
64604
  if (!enabled) {
@@ -64586,7 +64643,7 @@ function createCompactionCustomizerHook(config3, directory) {
64586
64643
  }
64587
64644
  }
64588
64645
  try {
64589
- const summariesDir = join42(directory, ".swarm", "summaries");
64646
+ const summariesDir = join43(directory, ".swarm", "summaries");
64590
64647
  const files = await fs31.promises.readdir(summariesDir);
64591
64648
  if (files.length > 0) {
64592
64649
  const count = files.length;
@@ -65851,7 +65908,7 @@ init_schema();
65851
65908
  init_manager();
65852
65909
  init_curator();
65853
65910
  init_utils2();
65854
- import * as path47 from "node:path";
65911
+ import * as path48 from "node:path";
65855
65912
  function createPhaseMonitorHook(directory, preflightManager, curatorRunner, delegateFactory) {
65856
65913
  let lastKnownPhase = null;
65857
65914
  const handler = async (input, _output) => {
@@ -65871,9 +65928,9 @@ function createPhaseMonitorHook(directory, preflightManager, curatorRunner, dele
65871
65928
  const llmDelegate = delegateFactory?.(sessionId);
65872
65929
  const initResult = await runner(directory, curatorConfig, llmDelegate);
65873
65930
  if (initResult.briefing) {
65874
- const briefingPath = path47.join(directory, ".swarm", "curator-briefing.md");
65931
+ const briefingPath = path48.join(directory, ".swarm", "curator-briefing.md");
65875
65932
  const { mkdir: mkdir7, writeFile: writeFile7 } = await import("node:fs/promises");
65876
- await mkdir7(path47.dirname(briefingPath), { recursive: true });
65933
+ await mkdir7(path48.dirname(briefingPath), { recursive: true });
65877
65934
  await writeFile7(briefingPath, initResult.briefing, "utf-8");
65878
65935
  const { buildApprovedReceipt: buildApprovedReceipt2, persistReviewReceipt: persistReviewReceipt2 } = await Promise.resolve().then(() => (init_review_receipt(), exports_review_receipt));
65879
65936
  const initReceipt = buildApprovedReceipt2({
@@ -65998,7 +66055,7 @@ ${originalText}`;
65998
66055
  }
65999
66056
  // src/hooks/repo-graph-builder.ts
66000
66057
  init_constants();
66001
- import * as path50 from "node:path";
66058
+ import * as path51 from "node:path";
66002
66059
 
66003
66060
  // src/tools/repo-graph.ts
66004
66061
  init_utils2();
@@ -66007,14 +66064,14 @@ init_path_security();
66007
66064
  import * as fsSync2 from "node:fs";
66008
66065
  import { constants as constants3, existsSync as existsSync28, realpathSync as realpathSync6 } from "node:fs";
66009
66066
  import * as fsPromises3 from "node:fs/promises";
66010
- import * as path49 from "node:path";
66067
+ import * as path50 from "node:path";
66011
66068
 
66012
66069
  // src/tools/symbols.ts
66013
66070
  init_zod();
66014
66071
  init_create_tool();
66015
66072
  init_path_security();
66016
66073
  import * as fs35 from "node:fs";
66017
- import * as path48 from "node:path";
66074
+ import * as path49 from "node:path";
66018
66075
  var MAX_FILE_SIZE_BYTES2 = 1024 * 1024;
66019
66076
  var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
66020
66077
  function containsWindowsAttacks(str) {
@@ -66031,11 +66088,11 @@ function containsWindowsAttacks(str) {
66031
66088
  }
66032
66089
  function isPathInWorkspace(filePath, workspace) {
66033
66090
  try {
66034
- const resolvedPath = path48.resolve(workspace, filePath);
66091
+ const resolvedPath = path49.resolve(workspace, filePath);
66035
66092
  const realWorkspace = fs35.realpathSync(workspace);
66036
66093
  const realResolvedPath = fs35.realpathSync(resolvedPath);
66037
- const relativePath = path48.relative(realWorkspace, realResolvedPath);
66038
- if (relativePath.startsWith("..") || path48.isAbsolute(relativePath)) {
66094
+ const relativePath = path49.relative(realWorkspace, realResolvedPath);
66095
+ if (relativePath.startsWith("..") || path49.isAbsolute(relativePath)) {
66039
66096
  return false;
66040
66097
  }
66041
66098
  return true;
@@ -66047,7 +66104,7 @@ function validatePathForRead(filePath, workspace) {
66047
66104
  return isPathInWorkspace(filePath, workspace);
66048
66105
  }
66049
66106
  function extractTSSymbols(filePath, cwd) {
66050
- const fullPath = path48.join(cwd, filePath);
66107
+ const fullPath = path49.join(cwd, filePath);
66051
66108
  if (!validatePathForRead(fullPath, cwd)) {
66052
66109
  return [];
66053
66110
  }
@@ -66199,7 +66256,7 @@ function extractTSSymbols(filePath, cwd) {
66199
66256
  });
66200
66257
  }
66201
66258
  function extractPythonSymbols(filePath, cwd) {
66202
- const fullPath = path48.join(cwd, filePath);
66259
+ const fullPath = path49.join(cwd, filePath);
66203
66260
  if (!validatePathForRead(fullPath, cwd)) {
66204
66261
  return [];
66205
66262
  }
@@ -66282,7 +66339,7 @@ var symbols = createSwarmTool({
66282
66339
  }, null, 2);
66283
66340
  }
66284
66341
  const cwd = directory;
66285
- const ext = path48.extname(file3);
66342
+ const ext = path49.extname(file3);
66286
66343
  if (containsControlChars(file3)) {
66287
66344
  return JSON.stringify({
66288
66345
  file: file3,
@@ -66346,7 +66403,7 @@ var symbols = createSwarmTool({
66346
66403
  var WINDOWS_RENAME_MAX_RETRIES = 3;
66347
66404
  var WINDOWS_RENAME_RETRY_DELAY_MS = 50;
66348
66405
  function normalizeGraphPath(filePath) {
66349
- return path49.normalize(filePath).replace(/\\/g, "/");
66406
+ return path50.normalize(filePath).replace(/\\/g, "/");
66350
66407
  }
66351
66408
  var REPO_GRAPH_FILENAME = "repo-graph.json";
66352
66409
  var GRAPH_SCHEMA_VERSION = "1.0.0";
@@ -66455,8 +66512,8 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
66455
66512
  }
66456
66513
  try {
66457
66514
  if (specifier.startsWith(".")) {
66458
- const sourceDir = path49.dirname(sourceFile);
66459
- let resolved = path49.resolve(sourceDir, specifier);
66515
+ const sourceDir = path50.dirname(sourceFile);
66516
+ let resolved = path50.resolve(sourceDir, specifier);
66460
66517
  let realResolved;
66461
66518
  try {
66462
66519
  realResolved = realpathSync6(resolved);
@@ -66467,7 +66524,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
66467
66524
  try {
66468
66525
  realRoot = realpathSync6(workspaceRoot);
66469
66526
  } catch {
66470
- realRoot = path49.normalize(workspaceRoot);
66527
+ realRoot = path50.normalize(workspaceRoot);
66471
66528
  }
66472
66529
  if (!existsSync28(resolved)) {
66473
66530
  const EXTENSIONS = [
@@ -66499,9 +66556,9 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
66499
66556
  return null;
66500
66557
  }
66501
66558
  }
66502
- const normalizedResolved = path49.normalize(realResolved);
66503
- const normalizedRoot = path49.normalize(realRoot);
66504
- if (!normalizedResolved.startsWith(normalizedRoot + path49.sep) && normalizedResolved !== normalizedRoot) {
66559
+ const normalizedResolved = path50.normalize(realResolved);
66560
+ const normalizedRoot = path50.normalize(realRoot);
66561
+ if (!normalizedResolved.startsWith(normalizedRoot + path50.sep) && normalizedResolved !== normalizedRoot) {
66505
66562
  return null;
66506
66563
  }
66507
66564
  return resolved;
@@ -66514,7 +66571,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
66514
66571
  function createEmptyGraph(workspaceRoot) {
66515
66572
  return {
66516
66573
  schema_version: GRAPH_SCHEMA_VERSION,
66517
- workspaceRoot: path49.normalize(workspaceRoot),
66574
+ workspaceRoot: path50.normalize(workspaceRoot),
66518
66575
  nodes: {},
66519
66576
  edges: [],
66520
66577
  metadata: {
@@ -66548,10 +66605,10 @@ function addEdge(graph, edge) {
66548
66605
  }
66549
66606
  }
66550
66607
  function getCachedGraph(workspace) {
66551
- return graphCache.get(path49.normalize(workspace));
66608
+ return graphCache.get(path50.normalize(workspace));
66552
66609
  }
66553
66610
  function setCachedGraph(workspace, graph, mtime) {
66554
- const normalized = path49.normalize(workspace);
66611
+ const normalized = path50.normalize(workspace);
66555
66612
  graphCache.set(normalized, graph);
66556
66613
  dirtyFlags.set(normalized, false);
66557
66614
  if (mtime !== undefined) {
@@ -66559,10 +66616,10 @@ function setCachedGraph(workspace, graph, mtime) {
66559
66616
  }
66560
66617
  }
66561
66618
  function isDirty(workspace) {
66562
- return dirtyFlags.get(path49.normalize(workspace)) ?? false;
66619
+ return dirtyFlags.get(path50.normalize(workspace)) ?? false;
66563
66620
  }
66564
66621
  function clearCache(workspace) {
66565
- const normalized = path49.normalize(workspace);
66622
+ const normalized = path50.normalize(workspace);
66566
66623
  graphCache.delete(normalized);
66567
66624
  dirtyFlags.delete(normalized);
66568
66625
  mtimeCache.delete(normalized);
@@ -66575,7 +66632,7 @@ function getGraphPath(workspace) {
66575
66632
  }
66576
66633
  async function loadGraph(workspace) {
66577
66634
  validateWorkspace(workspace);
66578
- const normalized = path49.normalize(workspace);
66635
+ const normalized = path50.normalize(workspace);
66579
66636
  const cached3 = getCachedGraph(normalized);
66580
66637
  if (cached3 && !isDirty(normalized)) {
66581
66638
  try {
@@ -66669,28 +66726,28 @@ async function saveGraph(workspace, graph, options) {
66669
66726
  if (!Array.isArray(graph.edges)) {
66670
66727
  throw new Error("Graph must have edges array");
66671
66728
  }
66672
- const normalizedWorkspace = path49.normalize(workspace);
66729
+ const normalizedWorkspace = path50.normalize(workspace);
66673
66730
  let realWorkspace;
66674
66731
  try {
66675
66732
  realWorkspace = realpathSync6(workspace);
66676
66733
  } catch {
66677
66734
  realWorkspace = normalizedWorkspace;
66678
66735
  }
66679
- const normalizedGraphRoot = path49.normalize(graph.workspaceRoot);
66736
+ const normalizedGraphRoot = path50.normalize(graph.workspaceRoot);
66680
66737
  let realGraphRoot;
66681
66738
  try {
66682
66739
  realGraphRoot = realpathSync6(graph.workspaceRoot);
66683
66740
  } catch {
66684
66741
  realGraphRoot = normalizedGraphRoot;
66685
66742
  }
66686
- if (path49.normalize(realWorkspace) !== path49.normalize(realGraphRoot)) {
66743
+ if (path50.normalize(realWorkspace) !== path50.normalize(realGraphRoot)) {
66687
66744
  throw new Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);
66688
66745
  }
66689
66746
  const normalized = normalizedWorkspace;
66690
66747
  const graphPath = getGraphPath(workspace);
66691
66748
  updateGraphMetadata(graph);
66692
66749
  const tempPath = `${graphPath}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`;
66693
- await fsPromises3.mkdir(path49.dirname(tempPath), { recursive: true });
66750
+ await fsPromises3.mkdir(path50.dirname(tempPath), { recursive: true });
66694
66751
  let lastError = null;
66695
66752
  try {
66696
66753
  if (options?.createAtomic) {
@@ -66821,7 +66878,7 @@ function findSourceFiles(dir, stats) {
66821
66878
  stats.skippedDirs++;
66822
66879
  continue;
66823
66880
  }
66824
- const fullPath = path49.join(dir, entry);
66881
+ const fullPath = path50.join(dir, entry);
66825
66882
  let stat3;
66826
66883
  try {
66827
66884
  stat3 = fsSync2.statSync(fullPath);
@@ -66832,7 +66889,7 @@ function findSourceFiles(dir, stats) {
66832
66889
  const subFiles = findSourceFiles(fullPath, stats);
66833
66890
  files.push(...subFiles);
66834
66891
  } else if (stat3.isFile()) {
66835
- const ext = path49.extname(fullPath).toLowerCase();
66892
+ const ext = path50.extname(fullPath).toLowerCase();
66836
66893
  if (SUPPORTED_EXTENSIONS.includes(ext)) {
66837
66894
  files.push(fullPath);
66838
66895
  }
@@ -66841,11 +66898,11 @@ function findSourceFiles(dir, stats) {
66841
66898
  return files;
66842
66899
  }
66843
66900
  function toModuleName(filePath, workspaceRoot) {
66844
- const relative9 = path49.relative(workspaceRoot, filePath);
66845
- return relative9.split(path49.sep).join("/");
66901
+ const relative9 = path50.relative(workspaceRoot, filePath);
66902
+ return relative9.split(path50.sep).join("/");
66846
66903
  }
66847
66904
  function getLanguage(filePath) {
66848
- const ext = path49.extname(filePath).toLowerCase();
66905
+ const ext = path50.extname(filePath).toLowerCase();
66849
66906
  return EXTENSION_TO_LANGUAGE[ext] ?? "unknown";
66850
66907
  }
66851
66908
  function isBinaryContent(content) {
@@ -66858,7 +66915,7 @@ function buildWorkspaceGraph(workspaceRoot, options) {
66858
66915
  validateWorkspace(workspaceRoot);
66859
66916
  const maxFileSize = options?.maxFileSizeBytes ?? 1024 * 1024;
66860
66917
  const maxFiles = options?.maxFiles ?? 1e4;
66861
- const absoluteRoot = path49.resolve(workspaceRoot);
66918
+ const absoluteRoot = path50.resolve(workspaceRoot);
66862
66919
  if (!existsSync28(absoluteRoot)) {
66863
66920
  throw new Error(`Workspace directory does not exist: ${workspaceRoot}`);
66864
66921
  }
@@ -66899,16 +66956,16 @@ function buildWorkspaceGraph(workspaceRoot, options) {
66899
66956
  continue;
66900
66957
  }
66901
66958
  stats.filesScanned++;
66902
- const ext = path49.extname(filePath).toLowerCase();
66959
+ const ext = path50.extname(filePath).toLowerCase();
66903
66960
  let exports = [];
66904
66961
  let parsedImports = [];
66905
66962
  try {
66906
66963
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
66907
- const relativePath = path49.relative(absoluteRoot, filePath);
66964
+ const relativePath = path50.relative(absoluteRoot, filePath);
66908
66965
  const symbols2 = extractTSSymbols(relativePath, absoluteRoot);
66909
66966
  exports = symbols2.filter((s) => s.exported).map((s) => s.name);
66910
66967
  } else if (ext === ".py") {
66911
- const relativePath = path49.relative(absoluteRoot, filePath);
66968
+ const relativePath = path50.relative(absoluteRoot, filePath);
66912
66969
  const symbols2 = extractPythonSymbols(relativePath, absoluteRoot);
66913
66970
  exports = symbols2.filter((s) => s.exported).map((s) => s.name);
66914
66971
  }
@@ -66965,15 +67022,15 @@ function scanFile(filePath, absoluteRoot, maxFileSize) {
66965
67022
  if (isBinaryContent(content)) {
66966
67023
  return { node: null, edges: [] };
66967
67024
  }
66968
- const ext = path49.extname(filePath).toLowerCase();
67025
+ const ext = path50.extname(filePath).toLowerCase();
66969
67026
  let exports = [];
66970
67027
  try {
66971
67028
  if ([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
66972
- const relativePath = path49.relative(absoluteRoot, filePath);
67029
+ const relativePath = path50.relative(absoluteRoot, filePath);
66973
67030
  const symbols2 = extractTSSymbols(relativePath, absoluteRoot);
66974
67031
  exports = symbols2.filter((s) => s.exported).map((s) => s.name);
66975
67032
  } else if (ext === ".py") {
66976
- const relativePath = path49.relative(absoluteRoot, filePath);
67033
+ const relativePath = path50.relative(absoluteRoot, filePath);
66977
67034
  const symbols2 = extractPythonSymbols(relativePath, absoluteRoot);
66978
67035
  exports = symbols2.filter((s) => s.exported).map((s) => s.name);
66979
67036
  }
@@ -67017,7 +67074,7 @@ async function updateGraphForFiles(workspaceRoot, filePaths, options) {
67017
67074
  return graph2;
67018
67075
  }
67019
67076
  const graph = existingGraph;
67020
- const absoluteRoot = path49.resolve(workspaceRoot);
67077
+ const absoluteRoot = path50.resolve(workspaceRoot);
67021
67078
  const maxFileSize = 1024 * 1024;
67022
67079
  const updatedPaths = new Set;
67023
67080
  for (const rawFilePath of filePaths) {
@@ -67130,7 +67187,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
67130
67187
  if (!isSupportedSourceFile(filePath)) {
67131
67188
  return;
67132
67189
  }
67133
- const absoluteFilePath = path50.isAbsolute(filePath) ? filePath : path50.resolve(workspaceRoot, filePath);
67190
+ const absoluteFilePath = path51.isAbsolute(filePath) ? filePath : path51.resolve(workspaceRoot, filePath);
67134
67191
  const normalizedAbsolute = absoluteFilePath.replace(/\\/g, "/");
67135
67192
  const normalizedWorkspace = workspaceRoot.replace(/\\/g, "/");
67136
67193
  if (!normalizedAbsolute.startsWith(`${normalizedWorkspace}/`) && normalizedAbsolute !== normalizedWorkspace) {
@@ -67138,7 +67195,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
67138
67195
  }
67139
67196
  try {
67140
67197
  await _updateGraphForFiles(workspaceRoot, [absoluteFilePath]);
67141
- log(`[repo-graph] Incremental update for ${path50.basename(filePath)}`);
67198
+ log(`[repo-graph] Incremental update for ${path51.basename(filePath)}`);
67142
67199
  } catch (error93) {
67143
67200
  const message = error93 instanceof Error ? error93.message : String(error93);
67144
67201
  error48(`[repo-graph] Incremental update failed: ${message}`);
@@ -67157,14 +67214,14 @@ init_manager2();
67157
67214
  init_detector();
67158
67215
  init_manager();
67159
67216
  import * as fs44 from "node:fs";
67160
- import * as path60 from "node:path";
67217
+ import * as path61 from "node:path";
67161
67218
 
67162
67219
  // src/services/decision-drift-analyzer.ts
67163
67220
  init_utils2();
67164
67221
  init_manager();
67165
67222
  init_utils();
67166
67223
  import * as fs36 from "node:fs";
67167
- import * as path51 from "node:path";
67224
+ import * as path52 from "node:path";
67168
67225
  var DEFAULT_DRIFT_CONFIG = {
67169
67226
  staleThresholdPhases: 1,
67170
67227
  detectContradictions: true,
@@ -67318,7 +67375,7 @@ async function analyzeDecisionDrift(directory, config3 = {}) {
67318
67375
  currentPhase = legacyPhase;
67319
67376
  }
67320
67377
  }
67321
- const contextPath = path51.join(directory, ".swarm", "context.md");
67378
+ const contextPath = path52.join(directory, ".swarm", "context.md");
67322
67379
  let contextContent = "";
67323
67380
  try {
67324
67381
  if (fs36.existsSync(contextPath)) {
@@ -67457,7 +67514,7 @@ init_utils();
67457
67514
  init_constants();
67458
67515
  init_schema();
67459
67516
  import * as fs37 from "node:fs/promises";
67460
- import * as path52 from "node:path";
67517
+ import * as path53 from "node:path";
67461
67518
  function safeGet(obj, key) {
67462
67519
  if (!obj || !Object.hasOwn(obj, key))
67463
67520
  return;
@@ -67689,23 +67746,18 @@ async function handleDebuggingSpiral(match, taskId, directory) {
67689
67746
  let eventLogged = false;
67690
67747
  let checkpointCreated = false;
67691
67748
  try {
67692
- const swarmDir = path52.join(directory, ".swarm");
67749
+ const swarmDir = path53.join(directory, ".swarm");
67693
67750
  await fs37.mkdir(swarmDir, { recursive: true });
67694
- const eventsPath = path52.join(swarmDir, "events.jsonl");
67751
+ const eventsPath = path53.join(swarmDir, "events.jsonl");
67695
67752
  await fs37.appendFile(eventsPath, `${formatDebuggingSpiralEvent(match, taskId)}
67696
67753
  `);
67697
67754
  eventLogged = true;
67698
67755
  } catch {}
67699
67756
  const checkpointLabel = `spiral-${taskId}-${Date.now()}`;
67700
67757
  try {
67701
- const { checkpoint: checkpoint2 } = await Promise.resolve().then(() => (init_checkpoint(), exports_checkpoint));
67702
- const result = await checkpoint2.execute({ action: "save", label: checkpointLabel }, { directory });
67703
- try {
67704
- const parsed = JSON.parse(result);
67705
- checkpointCreated = parsed.success === true;
67706
- } catch {
67707
- checkpointCreated = false;
67708
- }
67758
+ const { saveCheckpointRecord: saveCheckpointRecord2 } = await Promise.resolve().then(() => (init_checkpoint(), exports_checkpoint));
67759
+ const result = saveCheckpointRecord2(checkpointLabel, directory);
67760
+ checkpointCreated = result.success === true;
67709
67761
  } catch {
67710
67762
  checkpointCreated = false;
67711
67763
  }
@@ -67831,7 +67883,7 @@ import * as fs41 from "node:fs";
67831
67883
 
67832
67884
  // src/graph/graph-builder.ts
67833
67885
  import * as fs39 from "node:fs";
67834
- import * as path55 from "node:path";
67886
+ import * as path56 from "node:path";
67835
67887
 
67836
67888
  // node_modules/yocto-queue/index.js
67837
67889
  class Node {
@@ -67992,7 +68044,7 @@ function validateConcurrency(concurrency) {
67992
68044
  // src/graph/import-extractor.ts
67993
68045
  init_path_security();
67994
68046
  import * as fs38 from "node:fs";
67995
- import * as path53 from "node:path";
68047
+ import * as path54 from "node:path";
67996
68048
  var SOURCE_EXTENSIONS2 = [
67997
68049
  ".ts",
67998
68050
  ".tsx",
@@ -68037,14 +68089,14 @@ function getLanguageFromExtension(ext) {
68037
68089
  return null;
68038
68090
  }
68039
68091
  function toRelForwardSlash(absPath, root) {
68040
- return path53.relative(root, absPath).replace(/\\/g, "/");
68092
+ return path54.relative(root, absPath).replace(/\\/g, "/");
68041
68093
  }
68042
68094
  function tryResolveTSJS(rawModule, sourceFileAbs) {
68043
68095
  if (!rawModule.startsWith(".") && !rawModule.startsWith("/")) {
68044
68096
  return null;
68045
68097
  }
68046
- const sourceDir = path53.dirname(sourceFileAbs);
68047
- const baseAbs = path53.resolve(sourceDir, rawModule);
68098
+ const sourceDir = path54.dirname(sourceFileAbs);
68099
+ const baseAbs = path54.resolve(sourceDir, rawModule);
68048
68100
  const probe = (basePath) => {
68049
68101
  for (const ext of RESOLVE_EXTENSION_CANDIDATES) {
68050
68102
  const test = basePath + ext;
@@ -68055,7 +68107,7 @@ function tryResolveTSJS(rawModule, sourceFileAbs) {
68055
68107
  } catch {}
68056
68108
  }
68057
68109
  for (const indexFile of RESOLVE_INDEX_CANDIDATES) {
68058
- const test = path53.join(basePath, indexFile);
68110
+ const test = path54.join(basePath, indexFile);
68059
68111
  try {
68060
68112
  const stat3 = fs38.statSync(test);
68061
68113
  if (stat3.isFile())
@@ -68085,13 +68137,13 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
68085
68137
  }
68086
68138
  const remainder = rawModule.slice(leadingDots).replace(/\./g, "/");
68087
68139
  const upDirs = "../".repeat(Math.max(0, leadingDots - 1));
68088
- const sourceDir = path53.dirname(sourceFileAbs);
68089
- const baseAbs = path53.resolve(sourceDir, upDirs + remainder);
68140
+ const sourceDir = path54.dirname(sourceFileAbs);
68141
+ const baseAbs = path54.resolve(sourceDir, upDirs + remainder);
68090
68142
  const accept = (test) => {
68091
68143
  try {
68092
68144
  const stat3 = fs38.statSync(test);
68093
68145
  if (stat3.isFile()) {
68094
- const rel = path53.relative(workspaceRoot, test).replace(/\\/g, "/");
68146
+ const rel = path54.relative(workspaceRoot, test).replace(/\\/g, "/");
68095
68147
  if (rel.startsWith(".."))
68096
68148
  return null;
68097
68149
  return test;
@@ -68105,7 +68157,7 @@ function tryResolvePython(rawModule, sourceFileAbs, workspaceRoot) {
68105
68157
  return hit;
68106
68158
  }
68107
68159
  for (const indexFile of PY_INDEX_CANDIDATES) {
68108
- const hit = accept(path53.join(baseAbs, indexFile));
68160
+ const hit = accept(path54.join(baseAbs, indexFile));
68109
68161
  if (hit)
68110
68162
  return hit;
68111
68163
  }
@@ -68476,7 +68528,7 @@ function parseRustUses(content) {
68476
68528
  }
68477
68529
  function extractImports2(opts) {
68478
68530
  const { absoluteFilePath, workspaceRoot } = opts;
68479
- const ext = path53.extname(absoluteFilePath).toLowerCase();
68531
+ const ext = path54.extname(absoluteFilePath).toLowerCase();
68480
68532
  const language = getLanguageFromExtension(ext);
68481
68533
  if (!language)
68482
68534
  return [];
@@ -68527,9 +68579,9 @@ function extractImports2(opts) {
68527
68579
  }
68528
68580
 
68529
68581
  // src/graph/symbol-extractor.ts
68530
- import * as path54 from "node:path";
68582
+ import * as path55 from "node:path";
68531
68583
  function extractExportedSymbols(relativeFilePath, workspaceRoot) {
68532
- const ext = path54.extname(relativeFilePath).toLowerCase();
68584
+ const ext = path55.extname(relativeFilePath).toLowerCase();
68533
68585
  const language = getLanguageFromExtension(ext);
68534
68586
  if (!language)
68535
68587
  return [];
@@ -68618,15 +68670,15 @@ function findSourceFiles2(workspaceRoot, skipDirs = DEFAULT_SKIP_DIRS) {
68618
68670
  if (entry.isDirectory()) {
68619
68671
  if (skipDirs.has(entry.name))
68620
68672
  continue;
68621
- stack.push(path55.join(dir, entry.name));
68673
+ stack.push(path56.join(dir, entry.name));
68622
68674
  continue;
68623
68675
  }
68624
68676
  if (!entry.isFile())
68625
68677
  continue;
68626
- const ext = path55.extname(entry.name).toLowerCase();
68678
+ const ext = path56.extname(entry.name).toLowerCase();
68627
68679
  if (!SOURCE_EXT_SET.has(ext))
68628
68680
  continue;
68629
- out2.push(path55.join(dir, entry.name));
68681
+ out2.push(path56.join(dir, entry.name));
68630
68682
  }
68631
68683
  }
68632
68684
  return out2;
@@ -68654,7 +68706,7 @@ async function buildRepoGraph(workspaceRoot, options = {}) {
68654
68706
  };
68655
68707
  }
68656
68708
  async function processFile(absoluteFilePath, workspaceRoot) {
68657
- const ext = path55.extname(absoluteFilePath).toLowerCase();
68709
+ const ext = path56.extname(absoluteFilePath).toLowerCase();
68658
68710
  const language = getLanguageFromExtension(ext);
68659
68711
  if (!language)
68660
68712
  return null;
@@ -68674,7 +68726,7 @@ async function processFile(absoluteFilePath, workspaceRoot) {
68674
68726
  } catch {
68675
68727
  return null;
68676
68728
  }
68677
- const relPath = path55.relative(workspaceRoot, absoluteFilePath).replace(/\\/g, "/");
68729
+ const relPath = path56.relative(workspaceRoot, absoluteFilePath).replace(/\\/g, "/");
68678
68730
  const imports = extractImports2({
68679
68731
  absoluteFilePath,
68680
68732
  workspaceRoot,
@@ -68916,10 +68968,10 @@ function formatSummary(opts) {
68916
68968
  // src/graph/graph-store.ts
68917
68969
  import * as crypto6 from "node:crypto";
68918
68970
  import * as fs40 from "node:fs";
68919
- import * as path56 from "node:path";
68971
+ import * as path57 from "node:path";
68920
68972
  var SWARM_DIR = ".swarm";
68921
68973
  function getGraphPath2(workspaceRoot) {
68922
- return path56.join(workspaceRoot, SWARM_DIR, REPO_GRAPH_FILENAME2);
68974
+ return path57.join(workspaceRoot, SWARM_DIR, REPO_GRAPH_FILENAME2);
68923
68975
  }
68924
68976
  function loadGraph2(workspaceRoot) {
68925
68977
  const file3 = getGraphPath2(workspaceRoot);
@@ -68941,7 +68993,7 @@ function loadGraph2(workspaceRoot) {
68941
68993
  }
68942
68994
  function saveGraph2(workspaceRoot, graph) {
68943
68995
  const file3 = getGraphPath2(workspaceRoot);
68944
- const dir = path56.dirname(file3);
68996
+ const dir = path57.dirname(file3);
68945
68997
  try {
68946
68998
  const stat3 = fs40.lstatSync(dir);
68947
68999
  if (stat3.isSymbolicLink()) {
@@ -69047,7 +69099,7 @@ function buildReviewerBlastRadiusBlock(directory, changedFiles) {
69047
69099
  // src/hooks/semantic-diff-injection.ts
69048
69100
  import * as child_process5 from "node:child_process";
69049
69101
  import * as fs42 from "node:fs";
69050
- import * as path58 from "node:path";
69102
+ import * as path59 from "node:path";
69051
69103
 
69052
69104
  // src/diff/ast-diff.ts
69053
69105
  init_tree_sitter();
@@ -69794,17 +69846,17 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
69794
69846
  const fileConsumers = {};
69795
69847
  if (graph) {
69796
69848
  for (const f of filesToProcess) {
69797
- const relativePath = path58.isAbsolute(f) ? path58.relative(directory, f) : f;
69849
+ const relativePath = path59.isAbsolute(f) ? path59.relative(directory, f) : f;
69798
69850
  const normalized = normalizeGraphPath2(relativePath);
69799
69851
  fileConsumers[normalized] = getImporters(graph, normalized).length;
69800
69852
  fileConsumers[f] = fileConsumers[normalized];
69801
69853
  }
69802
69854
  }
69803
69855
  for (const filePath of filesToProcess) {
69804
- const normalizedPath = path58.normalize(filePath);
69805
- const resolvedPath = path58.resolve(directory, normalizedPath);
69806
- const relativeToDir = path58.relative(directory, resolvedPath);
69807
- if (relativeToDir.startsWith("..") || path58.isAbsolute(relativeToDir)) {
69856
+ const normalizedPath = path59.normalize(filePath);
69857
+ const resolvedPath = path59.resolve(directory, normalizedPath);
69858
+ const relativeToDir = path59.relative(directory, resolvedPath);
69859
+ if (relativeToDir.startsWith("..") || path59.isAbsolute(relativeToDir)) {
69808
69860
  continue;
69809
69861
  }
69810
69862
  try {
@@ -69831,7 +69883,7 @@ async function buildSemanticDiffBlock(directory, changedFiles, maxFiles = 10) {
69831
69883
  stdio: "pipe",
69832
69884
  maxBuffer: 5 * 1024 * 1024
69833
69885
  }) : "";
69834
- const newContent = fs42.readFileSync(path58.join(directory, filePath), "utf-8");
69886
+ const newContent = fs42.readFileSync(path59.join(directory, filePath), "utf-8");
69835
69887
  const astResult = await computeASTDiff(filePath, oldContent, newContent);
69836
69888
  if (astResult && (astResult.changes.length > 0 || astResult.error !== undefined)) {
69837
69889
  astDiffs.push(astResult);
@@ -70173,7 +70225,7 @@ function createSystemEnhancerHook(config3, directory) {
70173
70225
  await fs44.promises.writeFile(darkMatterPath, darkMatterReport, "utf-8");
70174
70226
  warn(`[system-enhancer] Dark matter scan complete: ${darkMatter.length} co-change patterns found`);
70175
70227
  try {
70176
- const projectName = path60.basename(path60.resolve(directory));
70228
+ const projectName = path61.basename(path61.resolve(directory));
70177
70229
  const knowledgeEntries = darkMatterToKnowledgeEntries2(darkMatter, projectName);
70178
70230
  const knowledgePath = resolveSwarmKnowledgePath(directory);
70179
70231
  const existingEntries = await readKnowledge(knowledgePath);
@@ -70372,7 +70424,7 @@ ${lines.join(`
70372
70424
  try {
70373
70425
  const taskId_ccp = ccpSession?.currentTaskId;
70374
70426
  if (taskId_ccp && !taskId_ccp.includes("..") && !taskId_ccp.includes("/") && !taskId_ccp.includes("\\") && !taskId_ccp.includes("\x00")) {
70375
- const evidencePath = path60.join(directory, ".swarm", "evidence", `${taskId_ccp}.json`);
70427
+ const evidencePath = path61.join(directory, ".swarm", "evidence", `${taskId_ccp}.json`);
70376
70428
  if (fs44.existsSync(evidencePath)) {
70377
70429
  const evidenceContent = fs44.readFileSync(evidencePath, "utf-8");
70378
70430
  const evidenceData = JSON.parse(evidenceContent);
@@ -71518,7 +71570,7 @@ init_hive_promoter();
71518
71570
 
71519
71571
  // src/hooks/incremental-verify.ts
71520
71572
  import * as fs45 from "node:fs";
71521
- import * as path61 from "node:path";
71573
+ import * as path62 from "node:path";
71522
71574
 
71523
71575
  // src/hooks/spawn-helper.ts
71524
71576
  import * as child_process6 from "node:child_process";
@@ -71596,18 +71648,18 @@ function spawnAsync(command, cwd, timeoutMs) {
71596
71648
  // src/hooks/incremental-verify.ts
71597
71649
  var emittedSkipAdvisories = new Set;
71598
71650
  function detectPackageManager(projectDir) {
71599
- if (fs45.existsSync(path61.join(projectDir, "bun.lockb")))
71651
+ if (fs45.existsSync(path62.join(projectDir, "bun.lockb")))
71600
71652
  return "bun";
71601
- if (fs45.existsSync(path61.join(projectDir, "pnpm-lock.yaml")))
71653
+ if (fs45.existsSync(path62.join(projectDir, "pnpm-lock.yaml")))
71602
71654
  return "pnpm";
71603
- if (fs45.existsSync(path61.join(projectDir, "yarn.lock")))
71655
+ if (fs45.existsSync(path62.join(projectDir, "yarn.lock")))
71604
71656
  return "yarn";
71605
- if (fs45.existsSync(path61.join(projectDir, "package-lock.json")))
71657
+ if (fs45.existsSync(path62.join(projectDir, "package-lock.json")))
71606
71658
  return "npm";
71607
71659
  return "bun";
71608
71660
  }
71609
71661
  function detectTypecheckCommand(projectDir) {
71610
- const pkgPath = path61.join(projectDir, "package.json");
71662
+ const pkgPath = path62.join(projectDir, "package.json");
71611
71663
  if (fs45.existsSync(pkgPath)) {
71612
71664
  try {
71613
71665
  const pkg = JSON.parse(fs45.readFileSync(pkgPath, "utf8"));
@@ -71624,8 +71676,8 @@ function detectTypecheckCommand(projectDir) {
71624
71676
  ...pkg.dependencies,
71625
71677
  ...pkg.devDependencies
71626
71678
  };
71627
- if (!deps?.typescript && !fs45.existsSync(path61.join(projectDir, "tsconfig.json"))) {}
71628
- const hasTSMarkers = deps?.typescript || fs45.existsSync(path61.join(projectDir, "tsconfig.json"));
71679
+ if (!deps?.typescript && !fs45.existsSync(path62.join(projectDir, "tsconfig.json"))) {}
71680
+ const hasTSMarkers = deps?.typescript || fs45.existsSync(path62.join(projectDir, "tsconfig.json"));
71629
71681
  if (hasTSMarkers) {
71630
71682
  return { command: ["npx", "tsc", "--noEmit"], language: "typescript" };
71631
71683
  }
@@ -71633,13 +71685,13 @@ function detectTypecheckCommand(projectDir) {
71633
71685
  return null;
71634
71686
  }
71635
71687
  }
71636
- if (fs45.existsSync(path61.join(projectDir, "go.mod"))) {
71688
+ if (fs45.existsSync(path62.join(projectDir, "go.mod"))) {
71637
71689
  return { command: ["go", "vet", "./..."], language: "go" };
71638
71690
  }
71639
- if (fs45.existsSync(path61.join(projectDir, "Cargo.toml"))) {
71691
+ if (fs45.existsSync(path62.join(projectDir, "Cargo.toml"))) {
71640
71692
  return { command: ["cargo", "check"], language: "rust" };
71641
71693
  }
71642
- if (fs45.existsSync(path61.join(projectDir, "pyproject.toml")) || fs45.existsSync(path61.join(projectDir, "requirements.txt")) || fs45.existsSync(path61.join(projectDir, "setup.py"))) {
71694
+ if (fs45.existsSync(path62.join(projectDir, "pyproject.toml")) || fs45.existsSync(path62.join(projectDir, "requirements.txt")) || fs45.existsSync(path62.join(projectDir, "setup.py"))) {
71643
71695
  return { command: null, language: "python" };
71644
71696
  }
71645
71697
  try {
@@ -71989,7 +72041,7 @@ init_scope_persistence();
71989
72041
  init_state();
71990
72042
  init_delegation_gate();
71991
72043
  init_normalize_tool_name();
71992
- import * as path63 from "node:path";
72044
+ import * as path64 from "node:path";
71993
72045
  var WRITE_TOOLS = new Set(WRITE_TOOL_NAMES);
71994
72046
  function createScopeGuardHook(config3, directory, injectAdvisory) {
71995
72047
  const enabled = config3.enabled ?? true;
@@ -72047,13 +72099,13 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
72047
72099
  }
72048
72100
  function isFileInScope(filePath, scopeEntries, directory) {
72049
72101
  const dir = directory ?? process.cwd();
72050
- const resolvedFile = path63.resolve(dir, filePath);
72102
+ const resolvedFile = path64.resolve(dir, filePath);
72051
72103
  return scopeEntries.some((scope) => {
72052
- const resolvedScope = path63.resolve(dir, scope);
72104
+ const resolvedScope = path64.resolve(dir, scope);
72053
72105
  if (resolvedFile === resolvedScope)
72054
72106
  return true;
72055
- const rel = path63.relative(resolvedScope, resolvedFile);
72056
- return rel.length > 0 && !rel.startsWith("..") && !path63.isAbsolute(rel);
72107
+ const rel = path64.relative(resolvedScope, resolvedFile);
72108
+ return rel.length > 0 && !rel.startsWith("..") && !path64.isAbsolute(rel);
72057
72109
  });
72058
72110
  }
72059
72111
 
@@ -72105,7 +72157,7 @@ function createSelfReviewHook(config3, injectAdvisory) {
72105
72157
 
72106
72158
  // src/hooks/slop-detector.ts
72107
72159
  import * as fs47 from "node:fs";
72108
- import * as path64 from "node:path";
72160
+ import * as path65 from "node:path";
72109
72161
  var WRITE_EDIT_TOOLS = new Set([
72110
72162
  "write",
72111
72163
  "edit",
@@ -72155,7 +72207,7 @@ function walkFiles(dir, exts, deadline) {
72155
72207
  break;
72156
72208
  if (entry.isSymbolicLink())
72157
72209
  continue;
72158
- const full = path64.join(dir, entry.name);
72210
+ const full = path65.join(dir, entry.name);
72159
72211
  if (entry.isDirectory()) {
72160
72212
  if (entry.name === "node_modules" || entry.name === ".git")
72161
72213
  continue;
@@ -72170,7 +72222,7 @@ function walkFiles(dir, exts, deadline) {
72170
72222
  return results;
72171
72223
  }
72172
72224
  function checkDeadExports(content, projectDir, startTime) {
72173
- const hasPackageJson = fs47.existsSync(path64.join(projectDir, "package.json"));
72225
+ const hasPackageJson = fs47.existsSync(path65.join(projectDir, "package.json"));
72174
72226
  if (!hasPackageJson)
72175
72227
  return null;
72176
72228
  const exportMatches = content.matchAll(/^\+(?:export)\s+(?:function|class|const|type|interface)\s+(\w{3,})/gm);
@@ -72378,14 +72430,14 @@ function createSteeringConsumedHook(directory) {
72378
72430
  // src/hooks/trajectory-logger.ts
72379
72431
  init_manager2();
72380
72432
  import * as fs50 from "node:fs/promises";
72381
- import * as path66 from "node:path";
72433
+ import * as path67 from "node:path";
72382
72434
 
72383
72435
  // src/prm/trajectory-store.ts
72384
72436
  init_utils2();
72385
72437
  import * as fs49 from "node:fs/promises";
72386
- import * as path65 from "node:path";
72438
+ import * as path66 from "node:path";
72387
72439
  function getTrajectoryPath(sessionId, directory) {
72388
- const relativePath = path65.join("trajectories", `${sessionId}.jsonl`);
72440
+ const relativePath = path66.join("trajectories", `${sessionId}.jsonl`);
72389
72441
  return validateSwarmPath(directory, relativePath);
72390
72442
  }
72391
72443
  var _inMemoryTrajectoryCache = new Map;
@@ -72404,7 +72456,7 @@ async function appendTrajectoryEntry(sessionId, entry, directory, maxLines = 100
72404
72456
  _inMemoryTrajectoryCache.set(sessionId, cached3);
72405
72457
  }
72406
72458
  const trajectoryPath = getTrajectoryPath(sessionId, directory);
72407
- await fs49.mkdir(path65.dirname(trajectoryPath), { recursive: true });
72459
+ await fs49.mkdir(path66.dirname(trajectoryPath), { recursive: true });
72408
72460
  const line = `${JSON.stringify(entry)}
72409
72461
  `;
72410
72462
  await fs49.appendFile(trajectoryPath, line, "utf-8");
@@ -72443,7 +72495,7 @@ async function cleanupOldTrajectoryFiles(directory, maxAgeDays = 7) {
72443
72495
  for (const entry of entries) {
72444
72496
  if (!entry.isFile())
72445
72497
  continue;
72446
- const filePath = path65.join(dirPath, entry.name);
72498
+ const filePath = path66.join(dirPath, entry.name);
72447
72499
  try {
72448
72500
  const stat4 = await fs49.stat(filePath);
72449
72501
  if (now - stat4.mtimeMs > cutoffMs) {
@@ -72635,10 +72687,10 @@ function createTrajectoryLoggerHook(config3, _directory) {
72635
72687
  elapsed_ms
72636
72688
  };
72637
72689
  const sanitized = sanitizeTaskId2(taskId);
72638
- const relativePath = path66.join("evidence", sanitized, "trajectory.jsonl");
72690
+ const relativePath = path67.join("evidence", sanitized, "trajectory.jsonl");
72639
72691
  const trajectoryPath = validateSwarmPath(_directory, relativePath);
72640
72692
  try {
72641
- await fs50.mkdir(path66.dirname(trajectoryPath), { recursive: true });
72693
+ await fs50.mkdir(path67.dirname(trajectoryPath), { recursive: true });
72642
72694
  const line = `${JSON.stringify(entry)}
72643
72695
  `;
72644
72696
  await fs50.appendFile(trajectoryPath, line, "utf-8");
@@ -73189,16 +73241,16 @@ init_telemetry();
73189
73241
 
73190
73242
  // src/prm/replay.ts
73191
73243
  import { promises as fs51 } from "node:fs";
73192
- import path67 from "node:path";
73244
+ import path68 from "node:path";
73193
73245
  function isPathSafe2(targetPath, basePath) {
73194
- const resolvedTarget = path67.resolve(targetPath);
73195
- const resolvedBase = path67.resolve(basePath);
73196
- const rel = path67.relative(resolvedBase, resolvedTarget);
73197
- return !rel.startsWith("..") && !path67.isAbsolute(rel);
73246
+ const resolvedTarget = path68.resolve(targetPath);
73247
+ const resolvedBase = path68.resolve(basePath);
73248
+ const rel = path68.relative(resolvedBase, resolvedTarget);
73249
+ return !rel.startsWith("..") && !path68.isAbsolute(rel);
73198
73250
  }
73199
73251
  function isWithinReplaysDir(targetPath) {
73200
- const resolved = path67.resolve(targetPath);
73201
- const parts2 = resolved.split(path67.sep);
73252
+ const resolved = path68.resolve(targetPath);
73253
+ const parts2 = resolved.split(path68.sep);
73202
73254
  for (let i2 = 0;i2 < parts2.length - 1; i2++) {
73203
73255
  if (parts2[i2] === ".swarm" && parts2[i2 + 1] === "replays") {
73204
73256
  return true;
@@ -73211,10 +73263,10 @@ function sanitizeFilename(input) {
73211
73263
  }
73212
73264
  async function startReplayRecording(sessionID, directory) {
73213
73265
  try {
73214
- const replayDir = path67.join(directory, ".swarm", "replays");
73266
+ const replayDir = path68.join(directory, ".swarm", "replays");
73215
73267
  const safeSessionID = sanitizeFilename(sessionID);
73216
73268
  const filename = `${safeSessionID}-${Date.now()}.jsonl`;
73217
- const filepath = path67.join(replayDir, filename);
73269
+ const filepath = path68.join(replayDir, filename);
73218
73270
  if (!isPathSafe2(filepath, replayDir)) {
73219
73271
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
73220
73272
  return null;
@@ -73587,7 +73639,7 @@ init_telemetry();
73587
73639
  init_dist();
73588
73640
  init_create_tool();
73589
73641
  import * as fs52 from "node:fs";
73590
- import * as path68 from "node:path";
73642
+ import * as path69 from "node:path";
73591
73643
  init_path_security();
73592
73644
  var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
73593
73645
  function containsWindowsAttacks2(str) {
@@ -73604,14 +73656,14 @@ function containsWindowsAttacks2(str) {
73604
73656
  }
73605
73657
  function isPathInWorkspace2(filePath, workspace) {
73606
73658
  try {
73607
- const resolvedPath = path68.resolve(workspace, filePath);
73659
+ const resolvedPath = path69.resolve(workspace, filePath);
73608
73660
  if (!fs52.existsSync(resolvedPath)) {
73609
73661
  return true;
73610
73662
  }
73611
73663
  const realWorkspace = fs52.realpathSync(workspace);
73612
73664
  const realResolvedPath = fs52.realpathSync(resolvedPath);
73613
- const relativePath = path68.relative(realWorkspace, realResolvedPath);
73614
- if (relativePath.startsWith("..") || path68.isAbsolute(relativePath)) {
73665
+ const relativePath = path69.relative(realWorkspace, realResolvedPath);
73666
+ if (relativePath.startsWith("..") || path69.isAbsolute(relativePath)) {
73615
73667
  return false;
73616
73668
  }
73617
73669
  return true;
@@ -73620,7 +73672,7 @@ function isPathInWorkspace2(filePath, workspace) {
73620
73672
  }
73621
73673
  }
73622
73674
  function processFile2(file3, cwd, exportedOnly) {
73623
- const ext = path68.extname(file3);
73675
+ const ext = path69.extname(file3);
73624
73676
  if (containsControlChars(file3)) {
73625
73677
  return {
73626
73678
  file: file3,
@@ -73653,7 +73705,7 @@ function processFile2(file3, cwd, exportedOnly) {
73653
73705
  errorType: "path-outside-workspace"
73654
73706
  };
73655
73707
  }
73656
- const fullPath = path68.join(cwd, file3);
73708
+ const fullPath = path69.join(cwd, file3);
73657
73709
  if (!fs52.existsSync(fullPath)) {
73658
73710
  return {
73659
73711
  file: file3,
@@ -73945,15 +73997,15 @@ init_task_id();
73945
73997
  init_create_tool();
73946
73998
  init_resolve_working_directory();
73947
73999
  import * as fs53 from "node:fs";
73948
- import * as path69 from "node:path";
74000
+ import * as path70 from "node:path";
73949
74001
  var EVIDENCE_DIR = ".swarm/evidence";
73950
74002
  function isValidTaskId3(taskId) {
73951
74003
  return isStrictTaskId(taskId);
73952
74004
  }
73953
74005
  function isPathWithinSwarm(filePath, workspaceRoot) {
73954
- const normalizedWorkspace = path69.resolve(workspaceRoot);
73955
- const swarmPath = path69.join(normalizedWorkspace, ".swarm", "evidence");
73956
- const normalizedPath = path69.resolve(filePath);
74006
+ const normalizedWorkspace = path70.resolve(workspaceRoot);
74007
+ const swarmPath = path70.join(normalizedWorkspace, ".swarm", "evidence");
74008
+ const normalizedPath = path70.resolve(filePath);
73957
74009
  return normalizedPath.startsWith(swarmPath);
73958
74010
  }
73959
74011
  function readEvidenceFile(evidencePath) {
@@ -74034,7 +74086,7 @@ var check_gate_status = createSwarmTool({
74034
74086
  };
74035
74087
  return JSON.stringify(errorResult, null, 2);
74036
74088
  }
74037
- const evidencePath = path69.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
74089
+ const evidencePath = path70.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
74038
74090
  if (!isPathWithinSwarm(evidencePath, directory)) {
74039
74091
  const errorResult = {
74040
74092
  taskId: taskIdInput,
@@ -74131,7 +74183,7 @@ init_state();
74131
74183
  init_create_tool();
74132
74184
  init_resolve_working_directory();
74133
74185
  import * as fs54 from "node:fs";
74134
- import * as path70 from "node:path";
74186
+ import * as path71 from "node:path";
74135
74187
  function extractMatches(regex, text) {
74136
74188
  return Array.from(text.matchAll(regex));
74137
74189
  }
@@ -74283,10 +74335,10 @@ async function executeCompletionVerify(args2, directory) {
74283
74335
  let hasFileReadFailure = false;
74284
74336
  for (const filePath of fileTargets) {
74285
74337
  const normalizedPath = filePath.replace(/\\/g, "/");
74286
- const resolvedPath = path70.resolve(directory, normalizedPath);
74287
- const projectRoot = path70.resolve(directory);
74288
- const relative16 = path70.relative(projectRoot, resolvedPath);
74289
- const withinProject = relative16 === "" || !relative16.startsWith("..") && !path70.isAbsolute(relative16);
74338
+ const resolvedPath = path71.resolve(directory, normalizedPath);
74339
+ const projectRoot = path71.resolve(directory);
74340
+ const relative16 = path71.relative(projectRoot, resolvedPath);
74341
+ const withinProject = relative16 === "" || !relative16.startsWith("..") && !path71.isAbsolute(relative16);
74290
74342
  if (!withinProject) {
74291
74343
  blockedTasks.push({
74292
74344
  task_id: task.id,
@@ -74341,8 +74393,8 @@ async function executeCompletionVerify(args2, directory) {
74341
74393
  blockedTasks
74342
74394
  };
74343
74395
  try {
74344
- const evidenceDir = path70.join(directory, ".swarm", "evidence", `${phase}`);
74345
- const evidencePath = path70.join(evidenceDir, "completion-verify.json");
74396
+ const evidenceDir = path71.join(directory, ".swarm", "evidence", `${phase}`);
74397
+ const evidencePath = path71.join(evidenceDir, "completion-verify.json");
74346
74398
  fs54.mkdirSync(evidenceDir, { recursive: true });
74347
74399
  const evidenceBundle = {
74348
74400
  schema_version: "1.0.0",
@@ -74419,11 +74471,11 @@ var completion_verify = createSwarmTool({
74419
74471
  // src/tools/complexity-hotspots.ts
74420
74472
  init_zod();
74421
74473
  import * as fs56 from "node:fs";
74422
- import * as path72 from "node:path";
74474
+ import * as path73 from "node:path";
74423
74475
 
74424
74476
  // src/quality/metrics.ts
74425
74477
  import * as fs55 from "node:fs";
74426
- import * as path71 from "node:path";
74478
+ import * as path72 from "node:path";
74427
74479
  var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
74428
74480
  var MIN_DUPLICATION_LINES = 10;
74429
74481
  function estimateCyclomaticComplexity(content) {
@@ -74475,7 +74527,7 @@ async function computeComplexityDelta(files, workingDir) {
74475
74527
  let totalComplexity = 0;
74476
74528
  const analyzedFiles = [];
74477
74529
  for (const file3 of files) {
74478
- const fullPath = path71.isAbsolute(file3) ? file3 : path71.join(workingDir, file3);
74530
+ const fullPath = path72.isAbsolute(file3) ? file3 : path72.join(workingDir, file3);
74479
74531
  if (!fs55.existsSync(fullPath)) {
74480
74532
  continue;
74481
74533
  }
@@ -74598,7 +74650,7 @@ function countGoExports(content) {
74598
74650
  function getExportCountForFile(filePath) {
74599
74651
  try {
74600
74652
  const content = fs55.readFileSync(filePath, "utf-8");
74601
- const ext = path71.extname(filePath).toLowerCase();
74653
+ const ext = path72.extname(filePath).toLowerCase();
74602
74654
  switch (ext) {
74603
74655
  case ".ts":
74604
74656
  case ".tsx":
@@ -74624,7 +74676,7 @@ async function computePublicApiDelta(files, workingDir) {
74624
74676
  let totalExports = 0;
74625
74677
  const analyzedFiles = [];
74626
74678
  for (const file3 of files) {
74627
- const fullPath = path71.isAbsolute(file3) ? file3 : path71.join(workingDir, file3);
74679
+ const fullPath = path72.isAbsolute(file3) ? file3 : path72.join(workingDir, file3);
74628
74680
  if (!fs55.existsSync(fullPath)) {
74629
74681
  continue;
74630
74682
  }
@@ -74658,7 +74710,7 @@ async function computeDuplicationRatio(files, workingDir) {
74658
74710
  let duplicateLines = 0;
74659
74711
  const analyzedFiles = [];
74660
74712
  for (const file3 of files) {
74661
- const fullPath = path71.isAbsolute(file3) ? file3 : path71.join(workingDir, file3);
74713
+ const fullPath = path72.isAbsolute(file3) ? file3 : path72.join(workingDir, file3);
74662
74714
  if (!fs55.existsSync(fullPath)) {
74663
74715
  continue;
74664
74716
  }
@@ -74691,8 +74743,8 @@ function countCodeLines(content) {
74691
74743
  return lines.length;
74692
74744
  }
74693
74745
  function isTestFile(filePath) {
74694
- const basename10 = path71.basename(filePath);
74695
- const _ext = path71.extname(filePath).toLowerCase();
74746
+ const basename10 = path72.basename(filePath);
74747
+ const _ext = path72.extname(filePath).toLowerCase();
74696
74748
  const testPatterns = [
74697
74749
  ".test.",
74698
74750
  ".spec.",
@@ -74773,8 +74825,8 @@ function matchGlobSegment(globSegments, pathSegments) {
74773
74825
  }
74774
74826
  return gIndex === globSegments.length && pIndex === pathSegments.length;
74775
74827
  }
74776
- function matchesGlobSegment(path72, glob) {
74777
- const normalizedPath = path72.replace(/\\/g, "/");
74828
+ function matchesGlobSegment(path73, glob) {
74829
+ const normalizedPath = path73.replace(/\\/g, "/");
74778
74830
  const normalizedGlob = glob.replace(/\\/g, "/");
74779
74831
  if (normalizedPath.includes("//")) {
74780
74832
  return false;
@@ -74805,8 +74857,8 @@ function simpleGlobToRegex2(glob) {
74805
74857
  function hasGlobstar(glob) {
74806
74858
  return glob.includes("**");
74807
74859
  }
74808
- function globMatches(path72, glob) {
74809
- const normalizedPath = path72.replace(/\\/g, "/");
74860
+ function globMatches(path73, glob) {
74861
+ const normalizedPath = path73.replace(/\\/g, "/");
74810
74862
  if (!glob || glob === "") {
74811
74863
  if (normalizedPath.includes("//")) {
74812
74864
  return false;
@@ -74842,7 +74894,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
74842
74894
  async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
74843
74895
  let testLines = 0;
74844
74896
  let codeLines = 0;
74845
- const srcDir = path71.join(workingDir, "src");
74897
+ const srcDir = path72.join(workingDir, "src");
74846
74898
  if (fs55.existsSync(srcDir)) {
74847
74899
  await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
74848
74900
  codeLines += lines;
@@ -74850,14 +74902,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
74850
74902
  }
74851
74903
  const possibleSrcDirs = ["lib", "app", "source", "core"];
74852
74904
  for (const dir of possibleSrcDirs) {
74853
- const dirPath = path71.join(workingDir, dir);
74905
+ const dirPath = path72.join(workingDir, dir);
74854
74906
  if (fs55.existsSync(dirPath)) {
74855
74907
  await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
74856
74908
  codeLines += lines;
74857
74909
  });
74858
74910
  }
74859
74911
  }
74860
- const testsDir = path71.join(workingDir, "tests");
74912
+ const testsDir = path72.join(workingDir, "tests");
74861
74913
  if (fs55.existsSync(testsDir)) {
74862
74914
  await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
74863
74915
  testLines += lines;
@@ -74865,7 +74917,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
74865
74917
  }
74866
74918
  const possibleTestDirs = ["test", "__tests__", "specs"];
74867
74919
  for (const dir of possibleTestDirs) {
74868
- const dirPath = path71.join(workingDir, dir);
74920
+ const dirPath = path72.join(workingDir, dir);
74869
74921
  if (fs55.existsSync(dirPath) && dirPath !== testsDir) {
74870
74922
  await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
74871
74923
  testLines += lines;
@@ -74880,7 +74932,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
74880
74932
  try {
74881
74933
  const entries = fs55.readdirSync(dirPath, { withFileTypes: true });
74882
74934
  for (const entry of entries) {
74883
- const fullPath = path71.join(dirPath, entry.name);
74935
+ const fullPath = path72.join(dirPath, entry.name);
74884
74936
  if (entry.isDirectory()) {
74885
74937
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
74886
74938
  continue;
@@ -74888,7 +74940,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
74888
74940
  await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
74889
74941
  } else if (entry.isFile()) {
74890
74942
  const relativePath = fullPath.replace(`${dirPath}/`, "");
74891
- const ext = path71.extname(entry.name).toLowerCase();
74943
+ const ext = path72.extname(entry.name).toLowerCase();
74892
74944
  const validExts = [
74893
74945
  ".ts",
74894
74946
  ".tsx",
@@ -75141,7 +75193,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
75141
75193
  const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
75142
75194
  const filteredChurn = new Map;
75143
75195
  for (const [file3, count] of churnMap) {
75144
- const ext = path72.extname(file3).toLowerCase();
75196
+ const ext = path73.extname(file3).toLowerCase();
75145
75197
  if (extSet.has(ext)) {
75146
75198
  filteredChurn.set(file3, count);
75147
75199
  }
@@ -75152,7 +75204,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
75152
75204
  for (const [file3, churnCount] of filteredChurn) {
75153
75205
  let fullPath = file3;
75154
75206
  if (!fs56.existsSync(fullPath)) {
75155
- fullPath = path72.join(cwd, file3);
75207
+ fullPath = path73.join(cwd, file3);
75156
75208
  }
75157
75209
  const complexity = getComplexityForFile2(fullPath);
75158
75210
  if (complexity !== null) {
@@ -75326,7 +75378,7 @@ import {
75326
75378
  readFileSync as readFileSync36,
75327
75379
  writeFileSync as writeFileSync11
75328
75380
  } from "node:fs";
75329
- import { join as join66 } from "node:path";
75381
+ import { join as join67 } from "node:path";
75330
75382
  var EVIDENCE_DIR2 = ".swarm/evidence";
75331
75383
  var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
75332
75384
  var COUNCIL_GATE_NAME = "council";
@@ -75360,9 +75412,9 @@ function writeCouncilEvidence(workingDir, synthesis) {
75360
75412
  if (!VALID_TASK_ID.test(synthesis.taskId)) {
75361
75413
  throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
75362
75414
  }
75363
- const dir = join66(workingDir, EVIDENCE_DIR2);
75415
+ const dir = join67(workingDir, EVIDENCE_DIR2);
75364
75416
  mkdirSync18(dir, { recursive: true });
75365
- const filePath = join66(dir, `${synthesis.taskId}.json`);
75417
+ const filePath = join67(dir, `${synthesis.taskId}.json`);
75366
75418
  const existingRoot = Object.create(null);
75367
75419
  if (existsSync37(filePath)) {
75368
75420
  try {
@@ -75396,7 +75448,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
75396
75448
  updated.required_gates = [];
75397
75449
  writeFileSync11(filePath, JSON.stringify(updated, null, 2));
75398
75450
  try {
75399
- const councilDir = join66(workingDir, ".swarm", "council");
75451
+ const councilDir = join67(workingDir, ".swarm", "council");
75400
75452
  mkdirSync18(councilDir, { recursive: true });
75401
75453
  const auditLine = JSON.stringify({
75402
75454
  round: synthesis.roundNumber,
@@ -75404,7 +75456,7 @@ function writeCouncilEvidence(workingDir, synthesis) {
75404
75456
  timestamp: synthesis.timestamp,
75405
75457
  vetoedBy: synthesis.vetoedBy
75406
75458
  });
75407
- appendFileSync6(join66(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
75459
+ appendFileSync6(join67(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
75408
75460
  `);
75409
75461
  } catch (auditError) {
75410
75462
  console.warn(`writeCouncilEvidence: failed to append round-history audit log: ${auditError instanceof Error ? auditError.message : String(auditError)}`);
@@ -75538,20 +75590,20 @@ function buildUnifiedFeedback(taskId, verdict, vetoedBy, requiredFixes, advisory
75538
75590
 
75539
75591
  // src/council/criteria-store.ts
75540
75592
  import { existsSync as existsSync38, mkdirSync as mkdirSync19, readFileSync as readFileSync37, writeFileSync as writeFileSync12 } from "node:fs";
75541
- import { join as join67 } from "node:path";
75593
+ import { join as join68 } from "node:path";
75542
75594
  var COUNCIL_DIR = ".swarm/council";
75543
75595
  function writeCriteria(workingDir, taskId, criteria) {
75544
- const dir = join67(workingDir, COUNCIL_DIR);
75596
+ const dir = join68(workingDir, COUNCIL_DIR);
75545
75597
  mkdirSync19(dir, { recursive: true });
75546
75598
  const payload = {
75547
75599
  taskId,
75548
75600
  criteria,
75549
75601
  declaredAt: new Date().toISOString()
75550
75602
  };
75551
- writeFileSync12(join67(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
75603
+ writeFileSync12(join68(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
75552
75604
  }
75553
75605
  function readCriteria(workingDir, taskId) {
75554
- const filePath = join67(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
75606
+ const filePath = join68(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
75555
75607
  if (!existsSync38(filePath))
75556
75608
  return null;
75557
75609
  try {
@@ -75704,7 +75756,7 @@ var submit_council_verdicts = createSwarmTool({
75704
75756
  init_zod();
75705
75757
  init_loader();
75706
75758
  import * as fs57 from "node:fs";
75707
- import * as path73 from "node:path";
75759
+ import * as path74 from "node:path";
75708
75760
 
75709
75761
  // src/council/general-council-advisory.ts
75710
75762
  var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
@@ -76152,10 +76204,10 @@ var convene_general_council = createSwarmTool({
76152
76204
  const round1 = input.round1Responses;
76153
76205
  const round2 = input.round2Responses ?? [];
76154
76206
  const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
76155
- const evidenceDir = path73.join(workingDir, ".swarm", "council", "general");
76207
+ const evidenceDir = path74.join(workingDir, ".swarm", "council", "general");
76156
76208
  const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
76157
76209
  const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
76158
- const evidencePath = path73.join(evidenceDir, evidenceFile);
76210
+ const evidencePath = path74.join(evidenceDir, evidenceFile);
76159
76211
  try {
76160
76212
  await fs57.promises.mkdir(evidenceDir, { recursive: true });
76161
76213
  await fs57.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
@@ -76392,7 +76444,7 @@ init_state();
76392
76444
  init_task_id();
76393
76445
  init_create_tool();
76394
76446
  import * as fs58 from "node:fs";
76395
- import * as path74 from "node:path";
76447
+ import * as path75 from "node:path";
76396
76448
  function validateTaskIdFormat2(taskId) {
76397
76449
  return validateTaskIdFormat(taskId);
76398
76450
  }
@@ -76466,8 +76518,8 @@ async function executeDeclareScope(args2, fallbackDir) {
76466
76518
  };
76467
76519
  }
76468
76520
  }
76469
- normalizedDir = path74.normalize(args2.working_directory);
76470
- const pathParts = normalizedDir.split(path74.sep);
76521
+ normalizedDir = path75.normalize(args2.working_directory);
76522
+ const pathParts = normalizedDir.split(path75.sep);
76471
76523
  if (pathParts.includes("..")) {
76472
76524
  return {
76473
76525
  success: false,
@@ -76477,10 +76529,10 @@ async function executeDeclareScope(args2, fallbackDir) {
76477
76529
  ]
76478
76530
  };
76479
76531
  }
76480
- const resolvedDir = path74.resolve(normalizedDir);
76532
+ const resolvedDir = path75.resolve(normalizedDir);
76481
76533
  try {
76482
76534
  const realPath = fs58.realpathSync(resolvedDir);
76483
- const planPath2 = path74.join(realPath, ".swarm", "plan.json");
76535
+ const planPath2 = path75.join(realPath, ".swarm", "plan.json");
76484
76536
  if (!fs58.existsSync(planPath2)) {
76485
76537
  return {
76486
76538
  success: false,
@@ -76504,7 +76556,7 @@ async function executeDeclareScope(args2, fallbackDir) {
76504
76556
  console.warn("[declare-scope] fallbackDir is undefined, falling back to process.cwd()");
76505
76557
  }
76506
76558
  const directory = normalizedDir || fallbackDir;
76507
- const planPath = path74.resolve(directory, ".swarm", "plan.json");
76559
+ const planPath = path75.resolve(directory, ".swarm", "plan.json");
76508
76560
  if (!fs58.existsSync(planPath)) {
76509
76561
  return {
76510
76562
  success: false,
@@ -76544,8 +76596,8 @@ async function executeDeclareScope(args2, fallbackDir) {
76544
76596
  const normalizeErrors = [];
76545
76597
  const dir = normalizedDir || fallbackDir || process.cwd();
76546
76598
  const mergedFiles = rawMergedFiles.map((file3) => {
76547
- if (path74.isAbsolute(file3)) {
76548
- const relativePath = path74.relative(dir, file3).replace(/\\/g, "/");
76599
+ if (path75.isAbsolute(file3)) {
76600
+ const relativePath = path75.relative(dir, file3).replace(/\\/g, "/");
76549
76601
  if (relativePath.startsWith("..")) {
76550
76602
  normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
76551
76603
  return file3;
@@ -76606,7 +76658,7 @@ var declare_scope = createSwarmTool({
76606
76658
  init_zod();
76607
76659
  import * as child_process7 from "node:child_process";
76608
76660
  import * as fs59 from "node:fs";
76609
- import * as path75 from "node:path";
76661
+ import * as path76 from "node:path";
76610
76662
  init_create_tool();
76611
76663
  var MAX_DIFF_LINES = 500;
76612
76664
  var DIFF_TIMEOUT_MS = 30000;
@@ -76635,20 +76687,20 @@ function validateBase(base) {
76635
76687
  function validatePaths(paths) {
76636
76688
  if (!paths)
76637
76689
  return null;
76638
- for (const path76 of paths) {
76639
- if (!path76 || path76.length === 0) {
76690
+ for (const path77 of paths) {
76691
+ if (!path77 || path77.length === 0) {
76640
76692
  return "empty path not allowed";
76641
76693
  }
76642
- if (path76.length > MAX_PATH_LENGTH) {
76694
+ if (path77.length > MAX_PATH_LENGTH) {
76643
76695
  return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
76644
76696
  }
76645
- if (SHELL_METACHARACTERS2.test(path76)) {
76697
+ if (SHELL_METACHARACTERS2.test(path77)) {
76646
76698
  return "path contains shell metacharacters";
76647
76699
  }
76648
- if (path76.startsWith("-")) {
76700
+ if (path77.startsWith("-")) {
76649
76701
  return 'path cannot start with "-" (option-like arguments not allowed)';
76650
76702
  }
76651
- if (CONTROL_CHAR_PATTERN2.test(path76)) {
76703
+ if (CONTROL_CHAR_PATTERN2.test(path77)) {
76652
76704
  return "path contains control characters";
76653
76705
  }
76654
76706
  }
@@ -76754,8 +76806,8 @@ var diff = createSwarmTool({
76754
76806
  if (parts2.length >= 3) {
76755
76807
  const additions = parseInt(parts2[0], 10) || 0;
76756
76808
  const deletions = parseInt(parts2[1], 10) || 0;
76757
- const path76 = parts2[2];
76758
- files.push({ path: path76, additions, deletions });
76809
+ const path77 = parts2[2];
76810
+ files.push({ path: path77, additions, deletions });
76759
76811
  }
76760
76812
  }
76761
76813
  const contractChanges = [];
@@ -76795,7 +76847,7 @@ var diff = createSwarmTool({
76795
76847
  } else if (base === "unstaged") {
76796
76848
  const oldRef = `:${file3.path}`;
76797
76849
  oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
76798
- newContent = fs59.readFileSync(path75.join(directory, file3.path), "utf-8");
76850
+ newContent = fs59.readFileSync(path76.join(directory, file3.path), "utf-8");
76799
76851
  } else {
76800
76852
  const oldRef = `${base}:${file3.path}`;
76801
76853
  oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
@@ -76870,7 +76922,7 @@ var diff = createSwarmTool({
76870
76922
  init_zod();
76871
76923
  import * as child_process8 from "node:child_process";
76872
76924
  import * as fs60 from "node:fs";
76873
- import * as path76 from "node:path";
76925
+ import * as path77 from "node:path";
76874
76926
  init_create_tool();
76875
76927
  var diff_summary = createSwarmTool({
76876
76928
  description: "Generate a filtered semantic diff summary from AST analysis. Returns SemanticDiffSummary with optional filtering by classification or riskLevel.",
@@ -76918,7 +76970,7 @@ var diff_summary = createSwarmTool({
76918
76970
  }
76919
76971
  try {
76920
76972
  let oldContent;
76921
- const newContent = fs60.readFileSync(path76.join(workingDir, filePath), "utf-8");
76973
+ const newContent = fs60.readFileSync(path77.join(workingDir, filePath), "utf-8");
76922
76974
  if (fileExistsInHead) {
76923
76975
  oldContent = child_process8.execFileSync("git", ["show", `HEAD:${filePath}`], {
76924
76976
  encoding: "utf-8",
@@ -77147,7 +77199,7 @@ init_zod();
77147
77199
  init_create_tool();
77148
77200
  init_path_security();
77149
77201
  import * as fs61 from "node:fs";
77150
- import * as path77 from "node:path";
77202
+ import * as path78 from "node:path";
77151
77203
  var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
77152
77204
  var MAX_EVIDENCE_FILES = 1000;
77153
77205
  var EVIDENCE_DIR3 = ".swarm/evidence";
@@ -77174,9 +77226,9 @@ function validateRequiredTypes(input) {
77174
77226
  return null;
77175
77227
  }
77176
77228
  function isPathWithinSwarm2(filePath, cwd) {
77177
- const normalizedCwd = path77.resolve(cwd);
77178
- const swarmPath = path77.join(normalizedCwd, ".swarm");
77179
- const normalizedPath = path77.resolve(filePath);
77229
+ const normalizedCwd = path78.resolve(cwd);
77230
+ const swarmPath = path78.join(normalizedCwd, ".swarm");
77231
+ const normalizedPath = path78.resolve(filePath);
77180
77232
  return normalizedPath.startsWith(swarmPath);
77181
77233
  }
77182
77234
  function parseCompletedTasks(planContent) {
@@ -77206,10 +77258,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
77206
77258
  if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
77207
77259
  continue;
77208
77260
  }
77209
- const filePath = path77.join(evidenceDir, filename);
77261
+ const filePath = path78.join(evidenceDir, filename);
77210
77262
  try {
77211
- const resolvedPath = path77.resolve(filePath);
77212
- const evidenceDirResolved = path77.resolve(evidenceDir);
77263
+ const resolvedPath = path78.resolve(filePath);
77264
+ const evidenceDirResolved = path78.resolve(evidenceDir);
77213
77265
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
77214
77266
  continue;
77215
77267
  }
@@ -77327,7 +77379,7 @@ var evidence_check = createSwarmTool({
77327
77379
  return JSON.stringify(errorResult, null, 2);
77328
77380
  }
77329
77381
  const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
77330
- const planPath = path77.join(cwd, PLAN_FILE);
77382
+ const planPath = path78.join(cwd, PLAN_FILE);
77331
77383
  if (!isPathWithinSwarm2(planPath, cwd)) {
77332
77384
  const errorResult = {
77333
77385
  error: "plan file path validation failed",
@@ -77359,7 +77411,7 @@ var evidence_check = createSwarmTool({
77359
77411
  };
77360
77412
  return JSON.stringify(result2, null, 2);
77361
77413
  }
77362
- const evidenceDir = path77.join(cwd, EVIDENCE_DIR3);
77414
+ const evidenceDir = path78.join(cwd, EVIDENCE_DIR3);
77363
77415
  const evidence = readEvidenceFiles(evidenceDir, cwd);
77364
77416
  const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
77365
77417
  const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
@@ -77377,7 +77429,7 @@ var evidence_check = createSwarmTool({
77377
77429
  init_zod();
77378
77430
  init_create_tool();
77379
77431
  import * as fs62 from "node:fs";
77380
- import * as path78 from "node:path";
77432
+ import * as path79 from "node:path";
77381
77433
  var EXT_MAP = {
77382
77434
  python: ".py",
77383
77435
  py: ".py",
@@ -77458,12 +77510,12 @@ var extract_code_blocks = createSwarmTool({
77458
77510
  if (prefix) {
77459
77511
  filename = `${prefix}_${filename}`;
77460
77512
  }
77461
- let filepath = path78.join(targetDir, filename);
77462
- const base = path78.basename(filepath, path78.extname(filepath));
77463
- const ext = path78.extname(filepath);
77513
+ let filepath = path79.join(targetDir, filename);
77514
+ const base = path79.basename(filepath, path79.extname(filepath));
77515
+ const ext = path79.extname(filepath);
77464
77516
  let counter = 1;
77465
77517
  while (fs62.existsSync(filepath)) {
77466
- filepath = path78.join(targetDir, `${base}_${counter}${ext}`);
77518
+ filepath = path79.join(targetDir, `${base}_${counter}${ext}`);
77467
77519
  counter++;
77468
77520
  }
77469
77521
  try {
@@ -77727,7 +77779,7 @@ init_zod();
77727
77779
  init_create_tool();
77728
77780
  init_path_security();
77729
77781
  import * as fs63 from "node:fs";
77730
- import * as path79 from "node:path";
77782
+ import * as path80 from "node:path";
77731
77783
  var MAX_FILE_PATH_LENGTH2 = 500;
77732
77784
  var MAX_SYMBOL_LENGTH = 256;
77733
77785
  var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
@@ -77775,7 +77827,7 @@ function validateSymbolInput(symbol3) {
77775
77827
  return null;
77776
77828
  }
77777
77829
  function isBinaryFile2(filePath, buffer) {
77778
- const ext = path79.extname(filePath).toLowerCase();
77830
+ const ext = path80.extname(filePath).toLowerCase();
77779
77831
  if (ext === ".json" || ext === ".md" || ext === ".txt") {
77780
77832
  return false;
77781
77833
  }
@@ -77799,15 +77851,15 @@ function parseImports(content, targetFile, targetSymbol) {
77799
77851
  const imports = [];
77800
77852
  let _resolvedTarget;
77801
77853
  try {
77802
- _resolvedTarget = path79.resolve(targetFile);
77854
+ _resolvedTarget = path80.resolve(targetFile);
77803
77855
  } catch {
77804
77856
  _resolvedTarget = targetFile;
77805
77857
  }
77806
- const targetBasename = path79.basename(targetFile, path79.extname(targetFile));
77858
+ const targetBasename = path80.basename(targetFile, path80.extname(targetFile));
77807
77859
  const targetWithExt = targetFile;
77808
77860
  const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
77809
- const normalizedTargetWithExt = path79.normalize(targetWithExt).replace(/\\/g, "/");
77810
- const normalizedTargetWithoutExt = path79.normalize(targetWithoutExt).replace(/\\/g, "/");
77861
+ const normalizedTargetWithExt = path80.normalize(targetWithExt).replace(/\\/g, "/");
77862
+ const normalizedTargetWithoutExt = path80.normalize(targetWithoutExt).replace(/\\/g, "/");
77811
77863
  const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
77812
77864
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
77813
77865
  const modulePath = match[1] || match[2] || match[3];
@@ -77830,9 +77882,9 @@ function parseImports(content, targetFile, targetSymbol) {
77830
77882
  }
77831
77883
  const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
77832
77884
  let isMatch = false;
77833
- const _targetDir = path79.dirname(targetFile);
77834
- const targetExt = path79.extname(targetFile);
77835
- const targetBasenameNoExt = path79.basename(targetFile, targetExt);
77885
+ const _targetDir = path80.dirname(targetFile);
77886
+ const targetExt = path80.extname(targetFile);
77887
+ const targetBasenameNoExt = path80.basename(targetFile, targetExt);
77836
77888
  const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
77837
77889
  const moduleName = modulePath.split(/[/\\]/).pop() || "";
77838
77890
  const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
@@ -77900,10 +77952,10 @@ function findSourceFiles3(dir, files = [], stats = { skippedDirs: [], skippedFil
77900
77952
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
77901
77953
  for (const entry of entries) {
77902
77954
  if (SKIP_DIRECTORIES4.has(entry)) {
77903
- stats.skippedDirs.push(path79.join(dir, entry));
77955
+ stats.skippedDirs.push(path80.join(dir, entry));
77904
77956
  continue;
77905
77957
  }
77906
- const fullPath = path79.join(dir, entry);
77958
+ const fullPath = path80.join(dir, entry);
77907
77959
  let stat4;
77908
77960
  try {
77909
77961
  stat4 = fs63.statSync(fullPath);
@@ -77917,7 +77969,7 @@ function findSourceFiles3(dir, files = [], stats = { skippedDirs: [], skippedFil
77917
77969
  if (stat4.isDirectory()) {
77918
77970
  findSourceFiles3(fullPath, files, stats);
77919
77971
  } else if (stat4.isFile()) {
77920
- const ext = path79.extname(fullPath).toLowerCase();
77972
+ const ext = path80.extname(fullPath).toLowerCase();
77921
77973
  if (SUPPORTED_EXTENSIONS3.includes(ext)) {
77922
77974
  files.push(fullPath);
77923
77975
  }
@@ -77974,7 +78026,7 @@ var imports = createSwarmTool({
77974
78026
  return JSON.stringify(errorResult, null, 2);
77975
78027
  }
77976
78028
  try {
77977
- const targetFile = path79.resolve(file3);
78029
+ const targetFile = path80.resolve(file3);
77978
78030
  if (!fs63.existsSync(targetFile)) {
77979
78031
  const errorResult = {
77980
78032
  error: `target file not found: ${file3}`,
@@ -77996,7 +78048,7 @@ var imports = createSwarmTool({
77996
78048
  };
77997
78049
  return JSON.stringify(errorResult, null, 2);
77998
78050
  }
77999
- const baseDir = path79.dirname(targetFile);
78051
+ const baseDir = path80.dirname(targetFile);
78000
78052
  const scanStats = {
78001
78053
  skippedDirs: [],
78002
78054
  skippedFiles: 0,
@@ -78542,7 +78594,7 @@ init_qa_gate_profile();
78542
78594
  init_manager2();
78543
78595
  init_curator();
78544
78596
  import * as fs65 from "node:fs";
78545
- import * as path81 from "node:path";
78597
+ import * as path82 from "node:path";
78546
78598
  init_knowledge_curator();
78547
78599
  init_knowledge_reader();
78548
78600
  init_knowledge_store();
@@ -78555,14 +78607,16 @@ init_plan_schema();
78555
78607
  init_ledger();
78556
78608
  init_manager();
78557
78609
  import * as fs64 from "node:fs";
78558
- import * as path80 from "node:path";
78610
+ import * as path81 from "node:path";
78559
78611
  async function writeCheckpoint(directory) {
78560
78612
  try {
78561
78613
  const plan = await loadPlan(directory);
78562
78614
  if (!plan)
78563
78615
  return;
78564
- const jsonPath = path80.join(directory, "SWARM_PLAN.json");
78565
- const mdPath = path80.join(directory, "SWARM_PLAN.md");
78616
+ const swarmDir = path81.join(directory, ".swarm");
78617
+ fs64.mkdirSync(swarmDir, { recursive: true });
78618
+ const jsonPath = path81.join(swarmDir, "SWARM_PLAN.json");
78619
+ const mdPath = path81.join(swarmDir, "SWARM_PLAN.md");
78566
78620
  fs64.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
78567
78621
  const md = derivePlanMarkdown(plan);
78568
78622
  fs64.writeFileSync(mdPath, md, "utf8");
@@ -78797,7 +78851,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
78797
78851
  let driftCheckEnabled = true;
78798
78852
  let driftHasSpecMd = false;
78799
78853
  try {
78800
- const specMdPath = path81.join(dir, ".swarm", "spec.md");
78854
+ const specMdPath = path82.join(dir, ".swarm", "spec.md");
78801
78855
  driftHasSpecMd = fs65.existsSync(specMdPath);
78802
78856
  const gatePlan = await loadPlan(dir);
78803
78857
  if (gatePlan) {
@@ -78819,7 +78873,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
78819
78873
  } else {
78820
78874
  let phaseType;
78821
78875
  try {
78822
- const planPath = path81.join(dir, ".swarm", "plan.json");
78876
+ const planPath = path82.join(dir, ".swarm", "plan.json");
78823
78877
  if (fs65.existsSync(planPath)) {
78824
78878
  const planRaw = fs65.readFileSync(planPath, "utf-8");
78825
78879
  const plan = JSON.parse(planRaw);
@@ -78832,7 +78886,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
78832
78886
  warnings.push(`Phase ${phase} is annotated as 'non-code'. Drift verification was skipped per phase type annotation.`);
78833
78887
  } else {
78834
78888
  try {
78835
- const driftEvidencePath = path81.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
78889
+ const driftEvidencePath = path82.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
78836
78890
  let driftVerdictFound = false;
78837
78891
  let driftVerdictApproved = false;
78838
78892
  try {
@@ -78870,7 +78924,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
78870
78924
  let incompleteTaskCount = 0;
78871
78925
  let planParseable = false;
78872
78926
  try {
78873
- const planPath = path81.join(dir, ".swarm", "plan.json");
78927
+ const planPath = path82.join(dir, ".swarm", "plan.json");
78874
78928
  if (fs65.existsSync(planPath)) {
78875
78929
  const planRaw = fs65.readFileSync(planPath, "utf-8");
78876
78930
  const plan = JSON.parse(planRaw);
@@ -78937,7 +78991,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
78937
78991
  const overrides = session2?.qaGateSessionOverrides ?? {};
78938
78992
  const effective = getEffectiveGates(profile, overrides);
78939
78993
  if (effective.hallucination_guard === true) {
78940
- const hgPath = path81.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
78994
+ const hgPath = path82.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
78941
78995
  let hgVerdictFound = false;
78942
78996
  let hgVerdictApproved = false;
78943
78997
  try {
@@ -79009,7 +79063,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
79009
79063
  const overrides = session2?.qaGateSessionOverrides ?? {};
79010
79064
  const effective = getEffectiveGates(profile, overrides);
79011
79065
  if (effective.mutation_test === true) {
79012
- const mgPath = path81.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
79066
+ const mgPath = path82.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
79013
79067
  let mgVerdictFound = false;
79014
79068
  let mgVerdict;
79015
79069
  try {
@@ -79083,7 +79137,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
79083
79137
  const effective = getEffectiveGates(profile, overrides);
79084
79138
  if (effective.council_mode === true) {
79085
79139
  councilModeEnabled = true;
79086
- const pcPath = path81.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
79140
+ const pcPath = path82.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
79087
79141
  let pcVerdictFound = false;
79088
79142
  let _pcVerdict;
79089
79143
  let pcQuorumSize;
@@ -79285,7 +79339,7 @@ Advisory notes: ${advisoryNotes.join("; ")}` : "";
79285
79339
  }
79286
79340
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
79287
79341
  try {
79288
- const projectName = path81.basename(dir);
79342
+ const projectName = path82.basename(dir);
79289
79343
  const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
79290
79344
  if (curationResult) {
79291
79345
  const sessionState = swarmState.agentSessions.get(sessionID);
@@ -79654,7 +79708,7 @@ init_discovery();
79654
79708
  init_utils();
79655
79709
  init_create_tool();
79656
79710
  import * as fs66 from "node:fs";
79657
- import * as path82 from "node:path";
79711
+ import * as path83 from "node:path";
79658
79712
  var MAX_OUTPUT_BYTES5 = 52428800;
79659
79713
  var AUDIT_TIMEOUT_MS = 120000;
79660
79714
  function isValidEcosystem(value) {
@@ -79682,16 +79736,16 @@ function validateArgs3(args2) {
79682
79736
  function detectEcosystems(directory) {
79683
79737
  const ecosystems = [];
79684
79738
  const cwd = directory;
79685
- if (fs66.existsSync(path82.join(cwd, "package.json"))) {
79739
+ if (fs66.existsSync(path83.join(cwd, "package.json"))) {
79686
79740
  ecosystems.push("npm");
79687
79741
  }
79688
- if (fs66.existsSync(path82.join(cwd, "pyproject.toml")) || fs66.existsSync(path82.join(cwd, "requirements.txt"))) {
79742
+ if (fs66.existsSync(path83.join(cwd, "pyproject.toml")) || fs66.existsSync(path83.join(cwd, "requirements.txt"))) {
79689
79743
  ecosystems.push("pip");
79690
79744
  }
79691
- if (fs66.existsSync(path82.join(cwd, "Cargo.toml"))) {
79745
+ if (fs66.existsSync(path83.join(cwd, "Cargo.toml"))) {
79692
79746
  ecosystems.push("cargo");
79693
79747
  }
79694
- if (fs66.existsSync(path82.join(cwd, "go.mod"))) {
79748
+ if (fs66.existsSync(path83.join(cwd, "go.mod"))) {
79695
79749
  ecosystems.push("go");
79696
79750
  }
79697
79751
  try {
@@ -79700,13 +79754,13 @@ function detectEcosystems(directory) {
79700
79754
  ecosystems.push("dotnet");
79701
79755
  }
79702
79756
  } catch {}
79703
- if (fs66.existsSync(path82.join(cwd, "Gemfile")) || fs66.existsSync(path82.join(cwd, "Gemfile.lock"))) {
79757
+ if (fs66.existsSync(path83.join(cwd, "Gemfile")) || fs66.existsSync(path83.join(cwd, "Gemfile.lock"))) {
79704
79758
  ecosystems.push("ruby");
79705
79759
  }
79706
- if (fs66.existsSync(path82.join(cwd, "pubspec.yaml"))) {
79760
+ if (fs66.existsSync(path83.join(cwd, "pubspec.yaml"))) {
79707
79761
  ecosystems.push("dart");
79708
79762
  }
79709
- if (fs66.existsSync(path82.join(cwd, "composer.lock"))) {
79763
+ if (fs66.existsSync(path83.join(cwd, "composer.lock"))) {
79710
79764
  ecosystems.push("composer");
79711
79765
  }
79712
79766
  return ecosystems;
@@ -80866,7 +80920,7 @@ var pkg_audit = createSwarmTool({
80866
80920
  init_zod();
80867
80921
  init_manager2();
80868
80922
  import * as fs67 from "node:fs";
80869
- import * as path83 from "node:path";
80923
+ import * as path84 from "node:path";
80870
80924
  init_utils();
80871
80925
  init_create_tool();
80872
80926
  var MAX_FILE_SIZE = 1024 * 1024;
@@ -80989,7 +81043,7 @@ function isScaffoldFile(filePath) {
80989
81043
  if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
80990
81044
  return true;
80991
81045
  }
80992
- const filename = path83.basename(filePath);
81046
+ const filename = path84.basename(filePath);
80993
81047
  if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
80994
81048
  return true;
80995
81049
  }
@@ -81006,7 +81060,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
81006
81060
  if (regex.test(normalizedPath)) {
81007
81061
  return true;
81008
81062
  }
81009
- const filename = path83.basename(filePath);
81063
+ const filename = path84.basename(filePath);
81010
81064
  const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
81011
81065
  if (filenameRegex.test(filename)) {
81012
81066
  return true;
@@ -81015,7 +81069,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
81015
81069
  return false;
81016
81070
  }
81017
81071
  function isParserSupported(filePath) {
81018
- const ext = path83.extname(filePath).toLowerCase();
81072
+ const ext = path84.extname(filePath).toLowerCase();
81019
81073
  return SUPPORTED_PARSER_EXTENSIONS.has(ext);
81020
81074
  }
81021
81075
  function isPlanFile(filePath) {
@@ -81262,9 +81316,9 @@ async function placeholderScan(input, directory) {
81262
81316
  let filesScanned = 0;
81263
81317
  const filesWithFindings = new Set;
81264
81318
  for (const filePath of changed_files) {
81265
- const fullPath = path83.isAbsolute(filePath) ? filePath : path83.resolve(directory, filePath);
81266
- const resolvedDirectory = path83.resolve(directory);
81267
- if (!fullPath.startsWith(resolvedDirectory + path83.sep) && fullPath !== resolvedDirectory) {
81319
+ const fullPath = path84.isAbsolute(filePath) ? filePath : path84.resolve(directory, filePath);
81320
+ const resolvedDirectory = path84.resolve(directory);
81321
+ if (!fullPath.startsWith(resolvedDirectory + path84.sep) && fullPath !== resolvedDirectory) {
81268
81322
  continue;
81269
81323
  }
81270
81324
  if (!fs67.existsSync(fullPath)) {
@@ -81273,7 +81327,7 @@ async function placeholderScan(input, directory) {
81273
81327
  if (isAllowedByGlobs(filePath, allow_globs)) {
81274
81328
  continue;
81275
81329
  }
81276
- const relativeFilePath = path83.relative(directory, fullPath).replace(/\\/g, "/");
81330
+ const relativeFilePath = path84.relative(directory, fullPath).replace(/\\/g, "/");
81277
81331
  if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
81278
81332
  continue;
81279
81333
  }
@@ -81345,7 +81399,7 @@ var placeholder_scan = createSwarmTool({
81345
81399
  });
81346
81400
  // src/tools/pre-check-batch.ts
81347
81401
  import * as fs70 from "node:fs";
81348
- import * as path86 from "node:path";
81402
+ import * as path87 from "node:path";
81349
81403
  init_zod();
81350
81404
  init_manager2();
81351
81405
  init_utils();
@@ -81482,7 +81536,7 @@ init_zod();
81482
81536
  init_manager2();
81483
81537
  init_detector();
81484
81538
  import * as fs69 from "node:fs";
81485
- import * as path85 from "node:path";
81539
+ import * as path86 from "node:path";
81486
81540
  import { extname as extname18 } from "node:path";
81487
81541
 
81488
81542
  // src/sast/rules/c.ts
@@ -82376,24 +82430,24 @@ init_create_tool();
82376
82430
  init_utils2();
82377
82431
  import * as crypto8 from "node:crypto";
82378
82432
  import * as fs68 from "node:fs";
82379
- import * as path84 from "node:path";
82433
+ import * as path85 from "node:path";
82380
82434
  var BASELINE_SCHEMA_VERSION = "1.0.0";
82381
82435
  var MAX_BASELINE_FINDINGS = 2000;
82382
82436
  var MAX_BASELINE_BYTES = 2 * 1048576;
82383
82437
  var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
82384
82438
  function normalizeFindingPath(directory, file3) {
82385
- const resolved = path84.isAbsolute(file3) ? file3 : path84.resolve(directory, file3);
82386
- const rel = path84.relative(path84.resolve(directory), resolved);
82439
+ const resolved = path85.isAbsolute(file3) ? file3 : path85.resolve(directory, file3);
82440
+ const rel = path85.relative(path85.resolve(directory), resolved);
82387
82441
  return rel.replace(/\\/g, "/");
82388
82442
  }
82389
82443
  function baselineRelPath(phase) {
82390
- return path84.join("evidence", String(phase), "sast-baseline.json");
82444
+ return path85.join("evidence", String(phase), "sast-baseline.json");
82391
82445
  }
82392
82446
  function tempRelPath(phase) {
82393
- return path84.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
82447
+ return path85.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
82394
82448
  }
82395
82449
  function lockRelPath(phase) {
82396
- return path84.join("evidence", String(phase), "sast-baseline.json.lock");
82450
+ return path85.join("evidence", String(phase), "sast-baseline.json.lock");
82397
82451
  }
82398
82452
  function getLine(lines, idx) {
82399
82453
  if (idx < 0 || idx >= lines.length)
@@ -82514,8 +82568,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
82514
82568
  message: e instanceof Error ? e.message : "Path validation failed"
82515
82569
  };
82516
82570
  }
82517
- fs68.mkdirSync(path84.dirname(baselinePath), { recursive: true });
82518
- fs68.mkdirSync(path84.dirname(tempPath), { recursive: true });
82571
+ fs68.mkdirSync(path85.dirname(baselinePath), { recursive: true });
82572
+ fs68.mkdirSync(path85.dirname(tempPath), { recursive: true });
82519
82573
  const releaseLock = await acquireLock(lockPath);
82520
82574
  try {
82521
82575
  let existing = null;
@@ -82782,9 +82836,9 @@ async function sastScan(input, directory, config3) {
82782
82836
  _filesSkipped++;
82783
82837
  continue;
82784
82838
  }
82785
- const resolvedPath = path85.isAbsolute(filePath) ? filePath : path85.resolve(directory, filePath);
82786
- const resolvedDirectory = path85.resolve(directory);
82787
- if (!resolvedPath.startsWith(resolvedDirectory + path85.sep) && resolvedPath !== resolvedDirectory) {
82839
+ const resolvedPath = path86.isAbsolute(filePath) ? filePath : path86.resolve(directory, filePath);
82840
+ const resolvedDirectory = path86.resolve(directory);
82841
+ if (!resolvedPath.startsWith(resolvedDirectory + path86.sep) && resolvedPath !== resolvedDirectory) {
82788
82842
  _filesSkipped++;
82789
82843
  continue;
82790
82844
  }
@@ -83095,18 +83149,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
83095
83149
  let resolved;
83096
83150
  const isWinAbs = isWindowsAbsolutePath(inputPath);
83097
83151
  if (isWinAbs) {
83098
- resolved = path86.win32.resolve(inputPath);
83099
- } else if (path86.isAbsolute(inputPath)) {
83100
- resolved = path86.resolve(inputPath);
83152
+ resolved = path87.win32.resolve(inputPath);
83153
+ } else if (path87.isAbsolute(inputPath)) {
83154
+ resolved = path87.resolve(inputPath);
83101
83155
  } else {
83102
- resolved = path86.resolve(baseDir, inputPath);
83156
+ resolved = path87.resolve(baseDir, inputPath);
83103
83157
  }
83104
- const workspaceResolved = path86.resolve(workspaceDir);
83158
+ const workspaceResolved = path87.resolve(workspaceDir);
83105
83159
  let relative20;
83106
83160
  if (isWinAbs) {
83107
- relative20 = path86.win32.relative(workspaceResolved, resolved);
83161
+ relative20 = path87.win32.relative(workspaceResolved, resolved);
83108
83162
  } else {
83109
- relative20 = path86.relative(workspaceResolved, resolved);
83163
+ relative20 = path87.relative(workspaceResolved, resolved);
83110
83164
  }
83111
83165
  if (relative20.startsWith("..")) {
83112
83166
  return "path traversal detected";
@@ -83171,7 +83225,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
83171
83225
  if (typeof file3 !== "string") {
83172
83226
  continue;
83173
83227
  }
83174
- const resolvedPath = path86.resolve(file3);
83228
+ const resolvedPath = path87.resolve(file3);
83175
83229
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
83176
83230
  if (validationError) {
83177
83231
  continue;
@@ -83328,7 +83382,7 @@ async function runSecretscanWithFiles(files, directory) {
83328
83382
  skippedFiles++;
83329
83383
  continue;
83330
83384
  }
83331
- const resolvedPath = path86.resolve(file3);
83385
+ const resolvedPath = path87.resolve(file3);
83332
83386
  const validationError = validatePath(resolvedPath, directory, directory);
83333
83387
  if (validationError) {
83334
83388
  skippedFiles++;
@@ -83346,7 +83400,7 @@ async function runSecretscanWithFiles(files, directory) {
83346
83400
  };
83347
83401
  }
83348
83402
  for (const file3 of validatedFiles) {
83349
- const ext = path86.extname(file3).toLowerCase();
83403
+ const ext = path87.extname(file3).toLowerCase();
83350
83404
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
83351
83405
  skippedFiles++;
83352
83406
  continue;
@@ -83565,7 +83619,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
83565
83619
  const preexistingFindings = [];
83566
83620
  for (const finding of findings) {
83567
83621
  const filePath = finding.location.file;
83568
- const normalised = path86.relative(directory, filePath).replace(/\\/g, "/");
83622
+ const normalised = path87.relative(directory, filePath).replace(/\\/g, "/");
83569
83623
  const changedLines = changedLineRanges.get(normalised);
83570
83624
  if (changedLines?.has(finding.location.line)) {
83571
83625
  newFindings.push(finding);
@@ -83616,7 +83670,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
83616
83670
  warn(`pre_check_batch: Invalid file path: ${file3}`);
83617
83671
  continue;
83618
83672
  }
83619
- changedFiles.push(path86.resolve(directory, file3));
83673
+ changedFiles.push(path87.resolve(directory, file3));
83620
83674
  }
83621
83675
  if (changedFiles.length === 0) {
83622
83676
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -83817,7 +83871,7 @@ var pre_check_batch = createSwarmTool({
83817
83871
  };
83818
83872
  return JSON.stringify(errorResult, null, 2);
83819
83873
  }
83820
- const resolvedDirectory = path86.resolve(typedArgs.directory);
83874
+ const resolvedDirectory = path87.resolve(typedArgs.directory);
83821
83875
  const workspaceAnchor = resolvedDirectory;
83822
83876
  const dirError = validateDirectory2(resolvedDirectory, workspaceAnchor);
83823
83877
  if (dirError) {
@@ -83858,7 +83912,7 @@ var pre_check_batch = createSwarmTool({
83858
83912
  });
83859
83913
  // src/tools/repo-map.ts
83860
83914
  init_zod();
83861
- import * as path87 from "node:path";
83915
+ import * as path88 from "node:path";
83862
83916
  init_path_security();
83863
83917
  init_create_tool();
83864
83918
  var VALID_ACTIONS = [
@@ -83883,7 +83937,7 @@ function validateFile(p) {
83883
83937
  return "file contains control characters";
83884
83938
  if (containsPathTraversal(p))
83885
83939
  return "file contains path traversal";
83886
- if (path87.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
83940
+ if (path88.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
83887
83941
  return "file must be a workspace-relative path, not absolute";
83888
83942
  }
83889
83943
  return null;
@@ -83906,8 +83960,8 @@ function ok(action, payload) {
83906
83960
  }
83907
83961
  function toRelativeGraphPath(input, workspaceRoot) {
83908
83962
  const normalized = input.replace(/\\/g, "/");
83909
- if (path87.isAbsolute(normalized)) {
83910
- const rel = path87.relative(workspaceRoot, normalized).replace(/\\/g, "/");
83963
+ if (path88.isAbsolute(normalized)) {
83964
+ const rel = path88.relative(workspaceRoot, normalized).replace(/\\/g, "/");
83911
83965
  return normalizeGraphPath2(rel);
83912
83966
  }
83913
83967
  return normalizeGraphPath2(normalized);
@@ -84052,7 +84106,7 @@ var repo_map = createSwarmTool({
84052
84106
  init_zod();
84053
84107
  init_create_tool();
84054
84108
  import * as fs71 from "node:fs";
84055
- import * as path88 from "node:path";
84109
+ import * as path89 from "node:path";
84056
84110
  var SPEC_FILE = ".swarm/spec.md";
84057
84111
  var EVIDENCE_DIR4 = ".swarm/evidence";
84058
84112
  var OBLIGATION_KEYWORDS = ["MUST", "SHOULD", "SHALL"];
@@ -84121,7 +84175,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
84121
84175
  return [];
84122
84176
  }
84123
84177
  for (const entry of entries) {
84124
- const entryPath = path88.join(evidenceDir, entry);
84178
+ const entryPath = path89.join(evidenceDir, entry);
84125
84179
  try {
84126
84180
  const stat4 = fs71.statSync(entryPath);
84127
84181
  if (!stat4.isDirectory()) {
@@ -84137,11 +84191,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
84137
84191
  if (entryPhase !== String(phase)) {
84138
84192
  continue;
84139
84193
  }
84140
- const evidenceFilePath = path88.join(entryPath, "evidence.json");
84194
+ const evidenceFilePath = path89.join(entryPath, "evidence.json");
84141
84195
  try {
84142
- const resolvedPath = path88.resolve(evidenceFilePath);
84143
- const evidenceDirResolved = path88.resolve(evidenceDir);
84144
- if (!resolvedPath.startsWith(evidenceDirResolved + path88.sep)) {
84196
+ const resolvedPath = path89.resolve(evidenceFilePath);
84197
+ const evidenceDirResolved = path89.resolve(evidenceDir);
84198
+ if (!resolvedPath.startsWith(evidenceDirResolved + path89.sep)) {
84145
84199
  continue;
84146
84200
  }
84147
84201
  const stat4 = fs71.lstatSync(evidenceFilePath);
@@ -84175,7 +84229,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
84175
84229
  if (Array.isArray(diffEntry.files_changed)) {
84176
84230
  for (const file3 of diffEntry.files_changed) {
84177
84231
  if (typeof file3 === "string") {
84178
- touchedFiles.add(path88.resolve(cwd, file3));
84232
+ touchedFiles.add(path89.resolve(cwd, file3));
84179
84233
  }
84180
84234
  }
84181
84235
  }
@@ -84188,8 +84242,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
84188
84242
  }
84189
84243
  function searchFileForKeywords(filePath, keywords, cwd) {
84190
84244
  try {
84191
- const resolvedPath = path88.resolve(filePath);
84192
- const cwdResolved = path88.resolve(cwd);
84245
+ const resolvedPath = path89.resolve(filePath);
84246
+ const cwdResolved = path89.resolve(cwd);
84193
84247
  if (!resolvedPath.startsWith(cwdResolved)) {
84194
84248
  return false;
84195
84249
  }
@@ -84323,7 +84377,7 @@ var req_coverage = createSwarmTool({
84323
84377
  }, null, 2);
84324
84378
  }
84325
84379
  const cwd = inputDirectory || directory;
84326
- const specPath = path88.join(cwd, SPEC_FILE);
84380
+ const specPath = path89.join(cwd, SPEC_FILE);
84327
84381
  let specContent;
84328
84382
  try {
84329
84383
  specContent = fs71.readFileSync(specPath, "utf-8");
@@ -84350,7 +84404,7 @@ var req_coverage = createSwarmTool({
84350
84404
  message: "No FR requirements found in spec.md"
84351
84405
  }, null, 2);
84352
84406
  }
84353
- const evidenceDir = path88.join(cwd, EVIDENCE_DIR4);
84407
+ const evidenceDir = path89.join(cwd, EVIDENCE_DIR4);
84354
84408
  const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
84355
84409
  const analyzedRequirements = [];
84356
84410
  let coveredCount = 0;
@@ -84376,7 +84430,7 @@ var req_coverage = createSwarmTool({
84376
84430
  requirements: analyzedRequirements
84377
84431
  };
84378
84432
  const reportFilename = `req-coverage-phase-${phase}.json`;
84379
- const reportPath = path88.join(evidenceDir, reportFilename);
84433
+ const reportPath = path89.join(evidenceDir, reportFilename);
84380
84434
  try {
84381
84435
  if (!fs71.existsSync(evidenceDir)) {
84382
84436
  fs71.mkdirSync(evidenceDir, { recursive: true });
@@ -84464,7 +84518,7 @@ init_qa_gate_profile();
84464
84518
  init_file_locks();
84465
84519
  import * as crypto9 from "node:crypto";
84466
84520
  import * as fs72 from "node:fs";
84467
- import * as path89 from "node:path";
84521
+ import * as path90 from "node:path";
84468
84522
  init_ledger();
84469
84523
  init_manager();
84470
84524
  init_state();
@@ -84542,8 +84596,8 @@ async function executeSavePlan(args2, fallbackDir) {
84542
84596
  };
84543
84597
  }
84544
84598
  if (args2.working_directory && fallbackDir) {
84545
- const resolvedTarget = path89.resolve(args2.working_directory);
84546
- const resolvedRoot = path89.resolve(fallbackDir);
84599
+ const resolvedTarget = path90.resolve(args2.working_directory);
84600
+ const resolvedRoot = path90.resolve(fallbackDir);
84547
84601
  let fallbackExists = false;
84548
84602
  try {
84549
84603
  fs72.accessSync(resolvedRoot, fs72.constants.F_OK);
@@ -84552,7 +84606,7 @@ async function executeSavePlan(args2, fallbackDir) {
84552
84606
  fallbackExists = false;
84553
84607
  }
84554
84608
  if (fallbackExists) {
84555
- const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path89.sep);
84609
+ const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path90.sep);
84556
84610
  if (isSubdirectory) {
84557
84611
  return {
84558
84612
  success: false,
@@ -84568,7 +84622,7 @@ async function executeSavePlan(args2, fallbackDir) {
84568
84622
  let specMtime;
84569
84623
  let specHash;
84570
84624
  if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
84571
- const specPath = path89.join(targetWorkspace, ".swarm", "spec.md");
84625
+ const specPath = path90.join(targetWorkspace, ".swarm", "spec.md");
84572
84626
  try {
84573
84627
  const stat4 = await fs72.promises.stat(specPath);
84574
84628
  specMtime = stat4.mtime.toISOString();
@@ -84584,7 +84638,7 @@ async function executeSavePlan(args2, fallbackDir) {
84584
84638
  }
84585
84639
  }
84586
84640
  if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
84587
- const contextPath = path89.join(targetWorkspace, ".swarm", "context.md");
84641
+ const contextPath = path90.join(targetWorkspace, ".swarm", "context.md");
84588
84642
  let contextContent = "";
84589
84643
  try {
84590
84644
  contextContent = await fs72.promises.readFile(contextPath, "utf8");
@@ -84734,7 +84788,7 @@ async function executeSavePlan(args2, fallbackDir) {
84734
84788
  }
84735
84789
  await writeCheckpoint(dir).catch(() => {});
84736
84790
  try {
84737
- const markerPath = path89.join(dir, ".swarm", ".plan-write-marker");
84791
+ const markerPath = path90.join(dir, ".swarm", ".plan-write-marker");
84738
84792
  const marker = JSON.stringify({
84739
84793
  source: "save_plan",
84740
84794
  timestamp: new Date().toISOString(),
@@ -84757,7 +84811,7 @@ async function executeSavePlan(args2, fallbackDir) {
84757
84811
  return {
84758
84812
  success: true,
84759
84813
  message: "Plan saved successfully",
84760
- plan_path: path89.join(dir, ".swarm", "plan.json"),
84814
+ plan_path: path90.join(dir, ".swarm", "plan.json"),
84761
84815
  phases_count: plan.phases.length,
84762
84816
  tasks_count: tasksCount,
84763
84817
  ...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
@@ -84810,7 +84864,7 @@ var save_plan = createSwarmTool({
84810
84864
  init_zod();
84811
84865
  init_manager2();
84812
84866
  import * as fs73 from "node:fs";
84813
- import * as path90 from "node:path";
84867
+ import * as path91 from "node:path";
84814
84868
 
84815
84869
  // src/sbom/detectors/index.ts
84816
84870
  init_utils();
@@ -85660,7 +85714,7 @@ function findManifestFiles(rootDir) {
85660
85714
  try {
85661
85715
  const entries = fs73.readdirSync(dir, { withFileTypes: true });
85662
85716
  for (const entry of entries) {
85663
- const fullPath = path90.join(dir, entry.name);
85717
+ const fullPath = path91.join(dir, entry.name);
85664
85718
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
85665
85719
  continue;
85666
85720
  }
@@ -85669,7 +85723,7 @@ function findManifestFiles(rootDir) {
85669
85723
  } else if (entry.isFile()) {
85670
85724
  for (const pattern of patterns) {
85671
85725
  if (simpleGlobToRegex(pattern).test(entry.name)) {
85672
- manifestFiles.push(path90.relative(rootDir, fullPath));
85726
+ manifestFiles.push(path91.relative(rootDir, fullPath));
85673
85727
  break;
85674
85728
  }
85675
85729
  }
@@ -85687,11 +85741,11 @@ function findManifestFilesInDirs(directories, workingDir) {
85687
85741
  try {
85688
85742
  const entries = fs73.readdirSync(dir, { withFileTypes: true });
85689
85743
  for (const entry of entries) {
85690
- const fullPath = path90.join(dir, entry.name);
85744
+ const fullPath = path91.join(dir, entry.name);
85691
85745
  if (entry.isFile()) {
85692
85746
  for (const pattern of patterns) {
85693
85747
  if (simpleGlobToRegex(pattern).test(entry.name)) {
85694
- found.push(path90.relative(workingDir, fullPath));
85748
+ found.push(path91.relative(workingDir, fullPath));
85695
85749
  break;
85696
85750
  }
85697
85751
  }
@@ -85704,11 +85758,11 @@ function findManifestFilesInDirs(directories, workingDir) {
85704
85758
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
85705
85759
  const dirs = new Set;
85706
85760
  for (const file3 of changedFiles) {
85707
- let currentDir = path90.dirname(file3);
85761
+ let currentDir = path91.dirname(file3);
85708
85762
  while (true) {
85709
- if (currentDir && currentDir !== "." && currentDir !== path90.sep) {
85710
- dirs.add(path90.join(workingDir, currentDir));
85711
- const parent = path90.dirname(currentDir);
85763
+ if (currentDir && currentDir !== "." && currentDir !== path91.sep) {
85764
+ dirs.add(path91.join(workingDir, currentDir));
85765
+ const parent = path91.dirname(currentDir);
85712
85766
  if (parent === currentDir)
85713
85767
  break;
85714
85768
  currentDir = parent;
@@ -85792,7 +85846,7 @@ var sbom_generate = createSwarmTool({
85792
85846
  const changedFiles = obj.changed_files;
85793
85847
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
85794
85848
  const workingDir = directory;
85795
- const outputDir = path90.isAbsolute(relativeOutputDir) ? relativeOutputDir : path90.join(workingDir, relativeOutputDir);
85849
+ const outputDir = path91.isAbsolute(relativeOutputDir) ? relativeOutputDir : path91.join(workingDir, relativeOutputDir);
85796
85850
  let manifestFiles = [];
85797
85851
  if (scope === "all") {
85798
85852
  manifestFiles = findManifestFiles(workingDir);
@@ -85815,7 +85869,7 @@ var sbom_generate = createSwarmTool({
85815
85869
  const processedFiles = [];
85816
85870
  for (const manifestFile of manifestFiles) {
85817
85871
  try {
85818
- const fullPath = path90.isAbsolute(manifestFile) ? manifestFile : path90.join(workingDir, manifestFile);
85872
+ const fullPath = path91.isAbsolute(manifestFile) ? manifestFile : path91.join(workingDir, manifestFile);
85819
85873
  if (!fs73.existsSync(fullPath)) {
85820
85874
  continue;
85821
85875
  }
@@ -85832,7 +85886,7 @@ var sbom_generate = createSwarmTool({
85832
85886
  const bom = generateCycloneDX(allComponents);
85833
85887
  const bomJson = serializeCycloneDX(bom);
85834
85888
  const filename = generateSbomFilename();
85835
- const outputPath = path90.join(outputDir, filename);
85889
+ const outputPath = path91.join(outputDir, filename);
85836
85890
  fs73.writeFileSync(outputPath, bomJson, "utf-8");
85837
85891
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
85838
85892
  try {
@@ -85876,7 +85930,7 @@ var sbom_generate = createSwarmTool({
85876
85930
  init_zod();
85877
85931
  init_create_tool();
85878
85932
  import * as fs74 from "node:fs";
85879
- import * as path91 from "node:path";
85933
+ import * as path92 from "node:path";
85880
85934
  var SPEC_CANDIDATES = [
85881
85935
  "openapi.json",
85882
85936
  "openapi.yaml",
@@ -85908,12 +85962,12 @@ function normalizePath3(p) {
85908
85962
  }
85909
85963
  function discoverSpecFile(cwd, specFileArg) {
85910
85964
  if (specFileArg) {
85911
- const resolvedPath = path91.resolve(cwd, specFileArg);
85912
- const normalizedCwd = cwd.endsWith(path91.sep) ? cwd : cwd + path91.sep;
85965
+ const resolvedPath = path92.resolve(cwd, specFileArg);
85966
+ const normalizedCwd = cwd.endsWith(path92.sep) ? cwd : cwd + path92.sep;
85913
85967
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
85914
85968
  throw new Error("Invalid spec_file: path traversal detected");
85915
85969
  }
85916
- const ext = path91.extname(resolvedPath).toLowerCase();
85970
+ const ext = path92.extname(resolvedPath).toLowerCase();
85917
85971
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
85918
85972
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
85919
85973
  }
@@ -85927,7 +85981,7 @@ function discoverSpecFile(cwd, specFileArg) {
85927
85981
  return resolvedPath;
85928
85982
  }
85929
85983
  for (const candidate of SPEC_CANDIDATES) {
85930
- const candidatePath = path91.resolve(cwd, candidate);
85984
+ const candidatePath = path92.resolve(cwd, candidate);
85931
85985
  if (fs74.existsSync(candidatePath)) {
85932
85986
  const stats = fs74.statSync(candidatePath);
85933
85987
  if (stats.size <= MAX_SPEC_SIZE) {
@@ -85939,7 +85993,7 @@ function discoverSpecFile(cwd, specFileArg) {
85939
85993
  }
85940
85994
  function parseSpec(specFile) {
85941
85995
  const content = fs74.readFileSync(specFile, "utf-8");
85942
- const ext = path91.extname(specFile).toLowerCase();
85996
+ const ext = path92.extname(specFile).toLowerCase();
85943
85997
  if (ext === ".json") {
85944
85998
  return parseJsonSpec(content);
85945
85999
  }
@@ -86015,7 +86069,7 @@ function extractRoutes(cwd) {
86015
86069
  return;
86016
86070
  }
86017
86071
  for (const entry of entries) {
86018
- const fullPath = path91.join(dir, entry.name);
86072
+ const fullPath = path92.join(dir, entry.name);
86019
86073
  if (entry.isSymbolicLink()) {
86020
86074
  continue;
86021
86075
  }
@@ -86025,7 +86079,7 @@ function extractRoutes(cwd) {
86025
86079
  }
86026
86080
  walkDir(fullPath);
86027
86081
  } else if (entry.isFile()) {
86028
- const ext = path91.extname(entry.name).toLowerCase();
86082
+ const ext = path92.extname(entry.name).toLowerCase();
86029
86083
  const baseName = entry.name.toLowerCase();
86030
86084
  if (![".ts", ".js", ".mjs"].includes(ext)) {
86031
86085
  continue;
@@ -86192,7 +86246,7 @@ init_zod();
86192
86246
  init_path_security();
86193
86247
  init_create_tool();
86194
86248
  import * as fs75 from "node:fs";
86195
- import * as path92 from "node:path";
86249
+ import * as path93 from "node:path";
86196
86250
  var DEFAULT_MAX_RESULTS = 100;
86197
86251
  var DEFAULT_MAX_LINES = 200;
86198
86252
  var REGEX_TIMEOUT_MS = 5000;
@@ -86228,11 +86282,11 @@ function containsWindowsAttacks3(str) {
86228
86282
  }
86229
86283
  function isPathInWorkspace3(filePath, workspace) {
86230
86284
  try {
86231
- const resolvedPath = path92.resolve(workspace, filePath);
86285
+ const resolvedPath = path93.resolve(workspace, filePath);
86232
86286
  const realWorkspace = fs75.realpathSync(workspace);
86233
86287
  const realResolvedPath = fs75.realpathSync(resolvedPath);
86234
- const relativePath = path92.relative(realWorkspace, realResolvedPath);
86235
- if (relativePath.startsWith("..") || path92.isAbsolute(relativePath)) {
86288
+ const relativePath = path93.relative(realWorkspace, realResolvedPath);
86289
+ if (relativePath.startsWith("..") || path93.isAbsolute(relativePath)) {
86236
86290
  return false;
86237
86291
  }
86238
86292
  return true;
@@ -86245,11 +86299,11 @@ function validatePathForRead2(filePath, workspace) {
86245
86299
  }
86246
86300
  function findRgInEnvPath() {
86247
86301
  const searchPath = process.env.PATH ?? "";
86248
- for (const dir of searchPath.split(path92.delimiter)) {
86302
+ for (const dir of searchPath.split(path93.delimiter)) {
86249
86303
  if (!dir)
86250
86304
  continue;
86251
86305
  const isWindows = process.platform === "win32";
86252
- const candidate = path92.join(dir, isWindows ? "rg.exe" : "rg");
86306
+ const candidate = path93.join(dir, isWindows ? "rg.exe" : "rg");
86253
86307
  if (fs75.existsSync(candidate))
86254
86308
  return candidate;
86255
86309
  }
@@ -86379,8 +86433,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
86379
86433
  try {
86380
86434
  const entries = fs75.readdirSync(dir, { withFileTypes: true });
86381
86435
  for (const entry of entries) {
86382
- const fullPath = path92.join(dir, entry.name);
86383
- const relativePath = path92.relative(workspace, fullPath);
86436
+ const fullPath = path93.join(dir, entry.name);
86437
+ const relativePath = path93.relative(workspace, fullPath);
86384
86438
  if (!validatePathForRead2(fullPath, workspace)) {
86385
86439
  continue;
86386
86440
  }
@@ -86421,7 +86475,7 @@ async function fallbackSearch(opts) {
86421
86475
  const matches = [];
86422
86476
  let total = 0;
86423
86477
  for (const file3 of files) {
86424
- const fullPath = path92.join(opts.workspace, file3);
86478
+ const fullPath = path93.join(opts.workspace, file3);
86425
86479
  if (!validatePathForRead2(fullPath, opts.workspace)) {
86426
86480
  continue;
86427
86481
  }
@@ -86678,7 +86732,7 @@ init_zod();
86678
86732
  init_path_security();
86679
86733
  init_create_tool();
86680
86734
  import * as fs76 from "node:fs";
86681
- import * as path93 from "node:path";
86735
+ import * as path94 from "node:path";
86682
86736
  var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
86683
86737
  function containsWindowsAttacks4(str) {
86684
86738
  if (/:[^\\/]/.test(str))
@@ -86692,14 +86746,14 @@ function containsWindowsAttacks4(str) {
86692
86746
  }
86693
86747
  function isPathInWorkspace4(filePath, workspace) {
86694
86748
  try {
86695
- const resolvedPath = path93.resolve(workspace, filePath);
86749
+ const resolvedPath = path94.resolve(workspace, filePath);
86696
86750
  if (!fs76.existsSync(resolvedPath)) {
86697
86751
  return true;
86698
86752
  }
86699
86753
  const realWorkspace = fs76.realpathSync(workspace);
86700
86754
  const realResolvedPath = fs76.realpathSync(resolvedPath);
86701
- const relativePath = path93.relative(realWorkspace, realResolvedPath);
86702
- if (relativePath.startsWith("..") || path93.isAbsolute(relativePath)) {
86755
+ const relativePath = path94.relative(realWorkspace, realResolvedPath);
86756
+ if (relativePath.startsWith("..") || path94.isAbsolute(relativePath)) {
86703
86757
  return false;
86704
86758
  }
86705
86759
  return true;
@@ -86907,7 +86961,7 @@ var suggestPatch = createSwarmTool({
86907
86961
  });
86908
86962
  continue;
86909
86963
  }
86910
- const fullPath = path93.resolve(directory, change.file);
86964
+ const fullPath = path94.resolve(directory, change.file);
86911
86965
  if (!fs76.existsSync(fullPath)) {
86912
86966
  errors5.push({
86913
86967
  success: false,
@@ -87170,7 +87224,7 @@ var generate_mutants = createSwarmTool({
87170
87224
  init_spec_schema();
87171
87225
  init_create_tool();
87172
87226
  import * as fs77 from "node:fs";
87173
- import * as path94 from "node:path";
87227
+ import * as path95 from "node:path";
87174
87228
  var SPEC_FILE_NAME = "spec.md";
87175
87229
  var SWARM_DIR2 = ".swarm";
87176
87230
  var OBLIGATION_KEYWORDS2 = ["MUST", "SHALL", "SHOULD", "MAY"];
@@ -87223,7 +87277,7 @@ var lint_spec = createSwarmTool({
87223
87277
  async execute(_args, directory) {
87224
87278
  const errors5 = [];
87225
87279
  const warnings = [];
87226
- const specPath = path94.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
87280
+ const specPath = path95.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
87227
87281
  if (!fs77.existsSync(specPath)) {
87228
87282
  const result2 = {
87229
87283
  valid: false,
@@ -87294,12 +87348,12 @@ var lint_spec = createSwarmTool({
87294
87348
  // src/tools/mutation-test.ts
87295
87349
  init_zod();
87296
87350
  import * as fs78 from "node:fs";
87297
- import * as path96 from "node:path";
87351
+ import * as path97 from "node:path";
87298
87352
 
87299
87353
  // src/mutation/engine.ts
87300
87354
  import { spawnSync as spawnSync3 } from "node:child_process";
87301
87355
  import { unlinkSync as unlinkSync13, writeFileSync as writeFileSync19 } from "node:fs";
87302
- import * as path95 from "node:path";
87356
+ import * as path96 from "node:path";
87303
87357
 
87304
87358
  // src/mutation/equivalence.ts
87305
87359
  function isStaticallyEquivalent(originalCode, mutatedCode) {
@@ -87434,7 +87488,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
87434
87488
  let patchFile;
87435
87489
  try {
87436
87490
  const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
87437
- patchFile = path95.join(workingDir, `.mutation_patch_${safeId2}.diff`);
87491
+ patchFile = path96.join(workingDir, `.mutation_patch_${safeId2}.diff`);
87438
87492
  try {
87439
87493
  writeFileSync19(patchFile, patch.patch);
87440
87494
  } catch (writeErr) {
@@ -87828,7 +87882,7 @@ var mutation_test = createSwarmTool({
87828
87882
  ];
87829
87883
  for (const filePath of uniquePaths) {
87830
87884
  try {
87831
- const resolvedPath = path96.resolve(cwd, filePath);
87885
+ const resolvedPath = path97.resolve(cwd, filePath);
87832
87886
  sourceFiles.set(filePath, fs78.readFileSync(resolvedPath, "utf-8"));
87833
87887
  } catch {}
87834
87888
  }
@@ -87848,7 +87902,7 @@ init_zod();
87848
87902
  init_manager2();
87849
87903
  init_detector();
87850
87904
  import * as fs79 from "node:fs";
87851
- import * as path97 from "node:path";
87905
+ import * as path98 from "node:path";
87852
87906
  init_create_tool();
87853
87907
  var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
87854
87908
  var BINARY_CHECK_BYTES = 8192;
@@ -87914,7 +87968,7 @@ async function syntaxCheck(input, directory, config3) {
87914
87968
  if (languages?.length) {
87915
87969
  const lowerLangs = languages.map((l) => l.toLowerCase());
87916
87970
  filesToCheck = filesToCheck.filter((file3) => {
87917
- const ext = path97.extname(file3.path).toLowerCase();
87971
+ const ext = path98.extname(file3.path).toLowerCase();
87918
87972
  const langDef = getLanguageForExtension(ext);
87919
87973
  const fileProfile = getProfileForFile(file3.path);
87920
87974
  const langId = fileProfile?.id || langDef?.id;
@@ -87927,7 +87981,7 @@ async function syntaxCheck(input, directory, config3) {
87927
87981
  let skippedCount = 0;
87928
87982
  for (const fileInfo of filesToCheck) {
87929
87983
  const { path: filePath } = fileInfo;
87930
- const fullPath = path97.isAbsolute(filePath) ? filePath : path97.join(directory, filePath);
87984
+ const fullPath = path98.isAbsolute(filePath) ? filePath : path98.join(directory, filePath);
87931
87985
  const result = {
87932
87986
  path: filePath,
87933
87987
  language: "",
@@ -87976,7 +88030,7 @@ async function syntaxCheck(input, directory, config3) {
87976
88030
  results.push(result);
87977
88031
  continue;
87978
88032
  }
87979
- const ext = path97.extname(filePath).toLowerCase();
88033
+ const ext = path98.extname(filePath).toLowerCase();
87980
88034
  const langDef = getLanguageForExtension(ext);
87981
88035
  result.language = profile?.id || langDef?.id || "unknown";
87982
88036
  const errors5 = extractSyntaxErrors(parser, content);
@@ -88069,7 +88123,7 @@ init_utils();
88069
88123
  init_create_tool();
88070
88124
  init_path_security();
88071
88125
  import * as fs80 from "node:fs";
88072
- import * as path98 from "node:path";
88126
+ import * as path99 from "node:path";
88073
88127
  var MAX_TEXT_LENGTH = 200;
88074
88128
  var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
88075
88129
  var SUPPORTED_EXTENSIONS4 = new Set([
@@ -88135,9 +88189,9 @@ function validatePathsInput(paths, cwd) {
88135
88189
  return { error: "paths contains path traversal", resolvedPath: null };
88136
88190
  }
88137
88191
  try {
88138
- const resolvedPath = path98.resolve(paths);
88139
- const normalizedCwd = path98.resolve(cwd);
88140
- const normalizedResolved = path98.resolve(resolvedPath);
88192
+ const resolvedPath = path99.resolve(paths);
88193
+ const normalizedCwd = path99.resolve(cwd);
88194
+ const normalizedResolved = path99.resolve(resolvedPath);
88141
88195
  if (!normalizedResolved.startsWith(normalizedCwd)) {
88142
88196
  return {
88143
88197
  error: "paths must be within the current working directory",
@@ -88153,7 +88207,7 @@ function validatePathsInput(paths, cwd) {
88153
88207
  }
88154
88208
  }
88155
88209
  function isSupportedExtension(filePath) {
88156
- const ext = path98.extname(filePath).toLowerCase();
88210
+ const ext = path99.extname(filePath).toLowerCase();
88157
88211
  return SUPPORTED_EXTENSIONS4.has(ext);
88158
88212
  }
88159
88213
  function findSourceFiles4(dir, files = []) {
@@ -88168,7 +88222,7 @@ function findSourceFiles4(dir, files = []) {
88168
88222
  if (SKIP_DIRECTORIES5.has(entry)) {
88169
88223
  continue;
88170
88224
  }
88171
- const fullPath = path98.join(dir, entry);
88225
+ const fullPath = path99.join(dir, entry);
88172
88226
  let stat4;
88173
88227
  try {
88174
88228
  stat4 = fs80.statSync(fullPath);
@@ -88280,7 +88334,7 @@ var todo_extract = createSwarmTool({
88280
88334
  filesToScan.push(scanPath);
88281
88335
  } else {
88282
88336
  const errorResult = {
88283
- error: `unsupported file extension: ${path98.extname(scanPath)}`,
88337
+ error: `unsupported file extension: ${path99.extname(scanPath)}`,
88284
88338
  total: 0,
88285
88339
  byPriority: { high: 0, medium: 0, low: 0 },
88286
88340
  entries: []
@@ -88329,14 +88383,14 @@ init_schema();
88329
88383
  init_qa_gate_profile();
88330
88384
  init_gate_evidence();
88331
88385
  import * as fs82 from "node:fs";
88332
- import * as path100 from "node:path";
88386
+ import * as path101 from "node:path";
88333
88387
 
88334
88388
  // src/hooks/diff-scope.ts
88335
88389
  import * as fs81 from "node:fs";
88336
- import * as path99 from "node:path";
88390
+ import * as path100 from "node:path";
88337
88391
  function getDeclaredScope(taskId, directory) {
88338
88392
  try {
88339
- const planPath = path99.join(directory, ".swarm", "plan.json");
88393
+ const planPath = path100.join(directory, ".swarm", "plan.json");
88340
88394
  if (!fs81.existsSync(planPath))
88341
88395
  return null;
88342
88396
  const raw = fs81.readFileSync(planPath, "utf-8");
@@ -88455,7 +88509,7 @@ var TIER_3_PATTERNS = [
88455
88509
  ];
88456
88510
  function matchesTier3Pattern(files) {
88457
88511
  for (const file3 of files) {
88458
- const fileName = path100.basename(file3);
88512
+ const fileName = path101.basename(file3);
88459
88513
  for (const pattern of TIER_3_PATTERNS) {
88460
88514
  if (pattern.test(fileName)) {
88461
88515
  return true;
@@ -88469,7 +88523,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
88469
88523
  if (hasActiveTurboMode()) {
88470
88524
  const resolvedDir2 = workingDirectory;
88471
88525
  try {
88472
- const planPath = path100.join(resolvedDir2, ".swarm", "plan.json");
88526
+ const planPath = path101.join(resolvedDir2, ".swarm", "plan.json");
88473
88527
  const planRaw = fs82.readFileSync(planPath, "utf-8");
88474
88528
  const plan = JSON.parse(planRaw);
88475
88529
  for (const planPhase of plan.phases ?? []) {
@@ -88539,7 +88593,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
88539
88593
  }
88540
88594
  try {
88541
88595
  const resolvedDir2 = workingDirectory;
88542
- const planPath = path100.join(resolvedDir2, ".swarm", "plan.json");
88596
+ const planPath = path101.join(resolvedDir2, ".swarm", "plan.json");
88543
88597
  const planRaw = fs82.readFileSync(planPath, "utf-8");
88544
88598
  const plan = JSON.parse(planRaw);
88545
88599
  for (const planPhase of plan.phases ?? []) {
@@ -88697,7 +88751,7 @@ function checkCouncilGate(workingDirectory, taskId) {
88697
88751
  return { blocked: false, reason: "" };
88698
88752
  }
88699
88753
  try {
88700
- const planPath = path100.join(workingDirectory, ".swarm", "plan.json");
88754
+ const planPath = path101.join(workingDirectory, ".swarm", "plan.json");
88701
88755
  const planRaw = fs82.readFileSync(planPath, "utf-8");
88702
88756
  const planObj = JSON.parse(planRaw);
88703
88757
  if (planObj.swarm && planObj.title) {
@@ -88788,8 +88842,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
88788
88842
  };
88789
88843
  }
88790
88844
  }
88791
- normalizedDir = path100.normalize(args2.working_directory);
88792
- const pathParts = normalizedDir.split(path100.sep);
88845
+ normalizedDir = path101.normalize(args2.working_directory);
88846
+ const pathParts = normalizedDir.split(path101.sep);
88793
88847
  if (pathParts.includes("..")) {
88794
88848
  return {
88795
88849
  success: false,
@@ -88799,10 +88853,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
88799
88853
  ]
88800
88854
  };
88801
88855
  }
88802
- const resolvedDir = path100.resolve(normalizedDir);
88856
+ const resolvedDir = path101.resolve(normalizedDir);
88803
88857
  try {
88804
88858
  const realPath = fs82.realpathSync(resolvedDir);
88805
- const planPath = path100.join(realPath, ".swarm", "plan.json");
88859
+ const planPath = path101.join(realPath, ".swarm", "plan.json");
88806
88860
  if (!fs82.existsSync(planPath)) {
88807
88861
  return {
88808
88862
  success: false,
@@ -88834,8 +88888,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
88834
88888
  }
88835
88889
  if (args2.status === "in_progress") {
88836
88890
  try {
88837
- const evidencePath = path100.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
88838
- fs82.mkdirSync(path100.dirname(evidencePath), { recursive: true });
88891
+ const evidencePath = path101.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
88892
+ fs82.mkdirSync(path101.dirname(evidencePath), { recursive: true });
88839
88893
  const fd = fs82.openSync(evidencePath, "wx");
88840
88894
  let writeOk = false;
88841
88895
  try {
@@ -88859,7 +88913,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
88859
88913
  recoverTaskStateFromDelegations(args2.task_id);
88860
88914
  let phaseRequiresReviewer = true;
88861
88915
  try {
88862
- const planPath = path100.join(directory, ".swarm", "plan.json");
88916
+ const planPath = path101.join(directory, ".swarm", "plan.json");
88863
88917
  const planRaw = fs82.readFileSync(planPath, "utf-8");
88864
88918
  const plan = JSON.parse(planRaw);
88865
88919
  const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
@@ -89179,7 +89233,7 @@ init_ledger();
89179
89233
  init_manager();
89180
89234
  init_create_tool();
89181
89235
  import fs83 from "node:fs";
89182
- import path101 from "node:path";
89236
+ import path102 from "node:path";
89183
89237
  function derivePlanId5(plan) {
89184
89238
  return `${plan.swarm}-${plan.title}`.replace(/[^a-zA-Z0-9-_]/g, "_");
89185
89239
  }
@@ -89230,7 +89284,7 @@ async function executeWriteDriftEvidence(args2, directory) {
89230
89284
  entries: [evidenceEntry]
89231
89285
  };
89232
89286
  const filename = "drift-verifier.json";
89233
- const relativePath = path101.join("evidence", String(phase), filename);
89287
+ const relativePath = path102.join("evidence", String(phase), filename);
89234
89288
  let validatedPath;
89235
89289
  try {
89236
89290
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -89241,10 +89295,10 @@ async function executeWriteDriftEvidence(args2, directory) {
89241
89295
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
89242
89296
  }, null, 2);
89243
89297
  }
89244
- const evidenceDir = path101.dirname(validatedPath);
89298
+ const evidenceDir = path102.dirname(validatedPath);
89245
89299
  try {
89246
89300
  await fs83.promises.mkdir(evidenceDir, { recursive: true });
89247
- const tempPath = path101.join(evidenceDir, `.${filename}.tmp`);
89301
+ const tempPath = path102.join(evidenceDir, `.${filename}.tmp`);
89248
89302
  await fs83.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
89249
89303
  await fs83.promises.rename(tempPath, validatedPath);
89250
89304
  let snapshotInfo;
@@ -89341,7 +89395,7 @@ init_zod();
89341
89395
  init_utils2();
89342
89396
  init_create_tool();
89343
89397
  import fs84 from "node:fs";
89344
- import path102 from "node:path";
89398
+ import path103 from "node:path";
89345
89399
  function normalizeVerdict2(verdict) {
89346
89400
  switch (verdict) {
89347
89401
  case "APPROVED":
@@ -89389,7 +89443,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
89389
89443
  entries: [evidenceEntry]
89390
89444
  };
89391
89445
  const filename = "hallucination-guard.json";
89392
- const relativePath = path102.join("evidence", String(phase), filename);
89446
+ const relativePath = path103.join("evidence", String(phase), filename);
89393
89447
  let validatedPath;
89394
89448
  try {
89395
89449
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -89400,10 +89454,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
89400
89454
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
89401
89455
  }, null, 2);
89402
89456
  }
89403
- const evidenceDir = path102.dirname(validatedPath);
89457
+ const evidenceDir = path103.dirname(validatedPath);
89404
89458
  try {
89405
89459
  await fs84.promises.mkdir(evidenceDir, { recursive: true });
89406
- const tempPath = path102.join(evidenceDir, `.${filename}.tmp`);
89460
+ const tempPath = path103.join(evidenceDir, `.${filename}.tmp`);
89407
89461
  await fs84.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
89408
89462
  await fs84.promises.rename(tempPath, validatedPath);
89409
89463
  return JSON.stringify({
@@ -89452,7 +89506,7 @@ init_zod();
89452
89506
  init_utils2();
89453
89507
  init_create_tool();
89454
89508
  import fs85 from "node:fs";
89455
- import path103 from "node:path";
89509
+ import path104 from "node:path";
89456
89510
  function normalizeVerdict3(verdict) {
89457
89511
  switch (verdict) {
89458
89512
  case "PASS":
@@ -89526,7 +89580,7 @@ async function executeWriteMutationEvidence(args2, directory) {
89526
89580
  entries: [evidenceEntry]
89527
89581
  };
89528
89582
  const filename = "mutation-gate.json";
89529
- const relativePath = path103.join("evidence", String(phase), filename);
89583
+ const relativePath = path104.join("evidence", String(phase), filename);
89530
89584
  let validatedPath;
89531
89585
  try {
89532
89586
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -89537,10 +89591,10 @@ async function executeWriteMutationEvidence(args2, directory) {
89537
89591
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
89538
89592
  }, null, 2);
89539
89593
  }
89540
- const evidenceDir = path103.dirname(validatedPath);
89594
+ const evidenceDir = path104.dirname(validatedPath);
89541
89595
  try {
89542
89596
  await fs85.promises.mkdir(evidenceDir, { recursive: true });
89543
- const tempPath = path103.join(evidenceDir, `.${filename}.tmp`);
89597
+ const tempPath = path104.join(evidenceDir, `.${filename}.tmp`);
89544
89598
  await fs85.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
89545
89599
  await fs85.promises.rename(tempPath, validatedPath);
89546
89600
  return JSON.stringify({
@@ -89597,19 +89651,19 @@ init_utils();
89597
89651
 
89598
89652
  // src/utils/gitignore-warning.ts
89599
89653
  import * as fs86 from "node:fs";
89600
- import * as path104 from "node:path";
89654
+ import * as path105 from "node:path";
89601
89655
  var _gitignoreWarningEmitted = false;
89602
89656
  function findGitRoot(startDir) {
89603
89657
  let current = startDir;
89604
89658
  while (true) {
89605
89659
  try {
89606
- const gitPath = path104.join(current, ".git");
89660
+ const gitPath = path105.join(current, ".git");
89607
89661
  const stat4 = fs86.statSync(gitPath);
89608
89662
  if (stat4.isDirectory()) {
89609
89663
  return current;
89610
89664
  }
89611
89665
  } catch {}
89612
- const parent = path104.dirname(current);
89666
+ const parent = path105.dirname(current);
89613
89667
  if (parent === current) {
89614
89668
  return null;
89615
89669
  }
@@ -89641,12 +89695,12 @@ function warnIfSwarmNotGitignored(directory, quiet = false) {
89641
89695
  const gitRoot = findGitRoot(directory);
89642
89696
  if (!gitRoot)
89643
89697
  return;
89644
- const gitignoreContent = readFileSafe(path104.join(gitRoot, ".gitignore"));
89698
+ const gitignoreContent = readFileSafe(path105.join(gitRoot, ".gitignore"));
89645
89699
  if (gitignoreContent !== null && fileCoversSwarm(gitignoreContent)) {
89646
89700
  _gitignoreWarningEmitted = true;
89647
89701
  return;
89648
89702
  }
89649
- const excludeContent = readFileSafe(path104.join(gitRoot, ".git", "info", "exclude"));
89703
+ const excludeContent = readFileSafe(path105.join(gitRoot, ".git", "info", "exclude"));
89650
89704
  if (excludeContent !== null && fileCoversSwarm(excludeContent)) {
89651
89705
  _gitignoreWarningEmitted = true;
89652
89706
  return;
@@ -89694,8 +89748,8 @@ init_warning_buffer();
89694
89748
  var _heartbeatTimers = new Map;
89695
89749
  function writeSwarmConfigExampleIfNew(projectDirectory) {
89696
89750
  try {
89697
- const swarmDir = path105.join(projectDirectory, ".swarm");
89698
- const dest = path105.join(swarmDir, "config.example.json");
89751
+ const swarmDir = path106.join(projectDirectory, ".swarm");
89752
+ const dest = path106.join(swarmDir, "config.example.json");
89699
89753
  if (fs87.existsSync(dest))
89700
89754
  return;
89701
89755
  const example = {
@@ -89899,7 +89953,7 @@ async function initializeOpenCodeSwarm(ctx) {
89899
89953
  const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
89900
89954
  preflightTriggerManager = new PTM(automationConfig);
89901
89955
  const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
89902
- const swarmDir = path105.resolve(ctx.directory, ".swarm");
89956
+ const swarmDir = path106.resolve(ctx.directory, ".swarm");
89903
89957
  statusArtifact = new ASA(swarmDir);
89904
89958
  statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
89905
89959
  if (automationConfig.capabilities?.evidence_auto_summaries === true) {