opencode-swarm 7.49.1 → 7.50.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.49.1",
72
+ version: "7.50.0",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -679,6 +679,10 @@ var init_tool_metadata = __esm(() => {
679
679
  lean_turbo_status: {
680
680
  description: "returns Lean Turbo configuration and active status for the current session",
681
681
  agents: ["architect"]
682
+ },
683
+ apply_patch: {
684
+ description: "Apply a unified diff patch to workspace files with exact context matching, atomic writes, and path validation",
685
+ agents: ["coder"]
682
686
  }
683
687
  };
684
688
  TOOL_NAMES = Object.keys(TOOL_METADATA);
@@ -92314,7 +92318,7 @@ __export(exports_design_doc_drift, {
92314
92318
  _internals: () => _internals60
92315
92319
  });
92316
92320
  import * as fs98 from "node:fs";
92317
- import * as path136 from "node:path";
92321
+ import * as path137 from "node:path";
92318
92322
  function mtimeMsOrNull(absPath) {
92319
92323
  try {
92320
92324
  return fs98.statSync(absPath).mtimeMs;
@@ -92325,35 +92329,35 @@ function mtimeMsOrNull(absPath) {
92325
92329
  function resolveAnchorWithin(directory, anchor) {
92326
92330
  if (!anchor || typeof anchor !== "string")
92327
92331
  return null;
92328
- const root = path136.resolve(directory);
92329
- const resolved = path136.resolve(root, anchor);
92330
- const rel = path136.relative(root, resolved);
92331
- if (rel.startsWith("..") || path136.isAbsolute(rel))
92332
+ const root = path137.resolve(directory);
92333
+ const resolved = path137.resolve(root, anchor);
92334
+ const rel = path137.relative(root, resolved);
92335
+ if (rel.startsWith("..") || path137.isAbsolute(rel))
92332
92336
  return null;
92333
92337
  return resolved;
92334
92338
  }
92335
92339
  async function runDesignDocDriftCheck(directory, phase, outDir) {
92336
92340
  try {
92337
- const root = path136.resolve(directory);
92338
- const outAbs = path136.resolve(root, outDir);
92339
- const outRel = path136.relative(root, outAbs);
92340
- if (outRel.startsWith("..") || path136.isAbsolute(outRel)) {
92341
+ const root = path137.resolve(directory);
92342
+ const outAbs = path137.resolve(root, outDir);
92343
+ const outRel = path137.relative(root, outAbs);
92344
+ if (outRel.startsWith("..") || path137.isAbsolute(outRel)) {
92341
92345
  return null;
92342
92346
  }
92343
92347
  const docMtimes = new Map;
92344
92348
  const checkedDocs = [];
92345
92349
  const missingDocs = [];
92346
92350
  for (const [docName, relFile] of Object.entries(DESIGN_DOC_FILES)) {
92347
- const abs = path136.join(outAbs, relFile);
92351
+ const abs = path137.join(outAbs, relFile);
92348
92352
  const mtime = mtimeMsOrNull(abs);
92349
92353
  docMtimes.set(docName, mtime);
92350
92354
  if (mtime === null) {
92351
- missingDocs.push(path136.join(outDir, relFile));
92355
+ missingDocs.push(path137.join(outDir, relFile));
92352
92356
  } else {
92353
- checkedDocs.push(path136.join(outDir, relFile));
92357
+ checkedDocs.push(path137.join(outDir, relFile));
92354
92358
  }
92355
92359
  }
92356
- const traceabilityAbs = path136.join(outAbs, TRACEABILITY_REL);
92360
+ const traceabilityAbs = path137.join(outAbs, TRACEABILITY_REL);
92357
92361
  let registry3 = null;
92358
92362
  try {
92359
92363
  const stat9 = await fs98.promises.stat(traceabilityAbs);
@@ -92366,7 +92370,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
92366
92370
  registry3 = null;
92367
92371
  }
92368
92372
  const noDocs = checkedDocs.length === 0 || registry3 === null;
92369
- const specMtime = mtimeMsOrNull(path136.join(root, ".swarm", "spec.md"));
92373
+ const specMtime = mtimeMsOrNull(path137.join(root, ".swarm", "spec.md"));
92370
92374
  const staleSections = [];
92371
92375
  if (!noDocs && Array.isArray(registry3?.sections)) {
92372
92376
  for (const section of registry3.sections) {
@@ -92422,7 +92426,7 @@ async function runDesignDocDriftCheck(directory, phase, outDir) {
92422
92426
  };
92423
92427
  const filename = `${DOC_DRIFT_REPORT_PREFIX}${phase}.json`;
92424
92428
  const filePath = validateSwarmPath(directory, filename);
92425
- await fs98.promises.mkdir(path136.dirname(filePath), { recursive: true });
92429
+ await fs98.promises.mkdir(path137.dirname(filePath), { recursive: true });
92426
92430
  await fs98.promises.writeFile(filePath, JSON.stringify(report, null, 2), "utf-8");
92427
92431
  getGlobalEventBus().publish("curator.docdrift.completed", {
92428
92432
  phase,
@@ -92453,10 +92457,10 @@ var init_design_doc_drift = __esm(() => {
92453
92457
  domain: "domain.md",
92454
92458
  "technical-spec": "technical-spec.md",
92455
92459
  "behavior-spec": "behavior-spec.md",
92456
- "reference-impl": path136.join("reference", "reference-impl.md"),
92457
- "idiom-notes": path136.join("reference", "idiom-notes.md")
92460
+ "reference-impl": path137.join("reference", "reference-impl.md"),
92461
+ "idiom-notes": path137.join("reference", "idiom-notes.md")
92458
92462
  };
92459
- TRACEABILITY_REL = path136.join("reference", "traceability.json");
92463
+ TRACEABILITY_REL = path137.join("reference", "traceability.json");
92460
92464
  _internals60 = {
92461
92465
  mtimeMsOrNull,
92462
92466
  resolveAnchorWithin,
@@ -92472,7 +92476,7 @@ __export(exports_project_context, {
92472
92476
  LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
92473
92477
  });
92474
92478
  import * as fs122 from "node:fs";
92475
- import * as path165 from "node:path";
92479
+ import * as path166 from "node:path";
92476
92480
  function detectFileExists2(directory, pattern) {
92477
92481
  if (pattern.includes("*") || pattern.includes("?")) {
92478
92482
  try {
@@ -92484,7 +92488,7 @@ function detectFileExists2(directory, pattern) {
92484
92488
  }
92485
92489
  }
92486
92490
  try {
92487
- fs122.accessSync(path165.join(directory, pattern));
92491
+ fs122.accessSync(path166.join(directory, pattern));
92488
92492
  return true;
92489
92493
  } catch {
92490
92494
  return false;
@@ -92493,7 +92497,7 @@ function detectFileExists2(directory, pattern) {
92493
92497
  function selectTestCommandFromScriptsTest(backend, directory) {
92494
92498
  let pkgRaw;
92495
92499
  try {
92496
- pkgRaw = fs122.readFileSync(path165.join(directory, "package.json"), "utf-8");
92500
+ pkgRaw = fs122.readFileSync(path166.join(directory, "package.json"), "utf-8");
92497
92501
  } catch {
92498
92502
  return null;
92499
92503
  }
@@ -92602,7 +92606,7 @@ var init_project_context = __esm(() => {
92602
92606
  init_package();
92603
92607
  init_agents2();
92604
92608
  init_critic();
92605
- import * as path166 from "node:path";
92609
+ import * as path167 from "node:path";
92606
92610
 
92607
92611
  // src/background/index.ts
92608
92612
  init_event_bus();
@@ -103467,29 +103471,34 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
103467
103471
  if (!declaredScope || declaredScope.length === 0)
103468
103472
  return;
103469
103473
  const argsObj = output.args;
103470
- const rawFilePath = argsObj?.path ?? argsObj?.filePath ?? argsObj?.file;
103471
- if (typeof rawFilePath !== "string" || !rawFilePath)
103472
- return;
103473
- const filePath = rawFilePath.replace(/[\r\n\t]/g, "_").split(String.fromCharCode(27)).join("_").replace(/\[[\d;]*m/g, "");
103474
- if (!isFileInScope(filePath, declaredScope, directory)) {
103475
- const taskId2 = session?.currentTaskId ?? "unknown";
103476
- const violationMessage = `SCOPE VIOLATION: ${agentName} attempted to modify '${filePath}' which is not in declared scope for task ${taskId2}. Declared scope: [${declaredScope.slice(0, 3).join(", ")}${declaredScope.length > 3 ? "..." : ""}]`;
103477
- if (session) {
103478
- session.lastScopeViolation = violationMessage;
103479
- session.scopeViolationDetected = true;
103480
- }
103481
- if (injectAdvisory) {
103482
- for (const [archSessionId, archSession] of swarmState.agentSessions) {
103483
- const archAgent = swarmState.activeAgent.get(archSessionId) ?? archSession.agentName;
103484
- if (stripKnownSwarmPrefix(archAgent) === ORCHESTRATOR_NAME) {
103485
- try {
103486
- injectAdvisory(archSessionId, `[SCOPE GUARD] ${violationMessage}`);
103487
- } catch {}
103488
- break;
103474
+ const candidatePaths = [];
103475
+ const singlePathKeys = ["path", "filePath", "file"];
103476
+ for (const key of singlePathKeys) {
103477
+ const val = argsObj?.[key];
103478
+ if (typeof val === "string" && val) {
103479
+ candidatePaths.push(val);
103480
+ }
103481
+ }
103482
+ let hasArrayKeys = false;
103483
+ const arrayPathKeys = ["files", "paths", "targetFiles"];
103484
+ for (const key of arrayPathKeys) {
103485
+ const val = argsObj?.[key];
103486
+ if (Array.isArray(val)) {
103487
+ hasArrayKeys = true;
103488
+ for (const item of val) {
103489
+ if (typeof item === "string" && item) {
103490
+ candidatePaths.push(item);
103489
103491
  }
103490
103492
  }
103491
103493
  }
103492
- throw new Error(violationMessage);
103494
+ }
103495
+ if (candidatePaths.length === 0 && !hasArrayKeys)
103496
+ return;
103497
+ for (const rawPath of candidatePaths) {
103498
+ const filePath = sanitizePath(rawPath);
103499
+ if (!isFileInScope(filePath, declaredScope, directory)) {
103500
+ reportScopeViolation(agentName, filePath, taskId, session, injectAdvisory, swarmState, declaredScope);
103501
+ }
103493
103502
  }
103494
103503
  }
103495
103504
  };
@@ -103497,7 +103506,7 @@ function createScopeGuardHook(config3, directory, injectAdvisory) {
103497
103506
  function isFileInScope(filePath, scopeEntries, directory) {
103498
103507
  const dir = directory ?? process.cwd();
103499
103508
  const resolvedFile = path102.resolve(dir, filePath);
103500
- return scopeEntries.some((scope) => {
103509
+ return scopeEntries.filter((scope) => scope.length > 0).some((scope) => {
103501
103510
  const resolvedScope = path102.resolve(dir, scope);
103502
103511
  if (resolvedFile === resolvedScope)
103503
103512
  return true;
@@ -103505,6 +103514,38 @@ function isFileInScope(filePath, scopeEntries, directory) {
103505
103514
  return rel.length > 0 && !rel.startsWith("..") && !path102.isAbsolute(rel);
103506
103515
  });
103507
103516
  }
103517
+ function sanitizePath(raw) {
103518
+ let result = "";
103519
+ for (let i2 = 0;i2 < raw.length; i2++) {
103520
+ const c = raw.charCodeAt(i2);
103521
+ if (c <= 31 || c === 127 || c >= 128 && c <= 159) {
103522
+ result += "_";
103523
+ continue;
103524
+ }
103525
+ result += raw[i2];
103526
+ }
103527
+ return result.replace(/\[[\d;]*m/g, "");
103528
+ }
103529
+ function reportScopeViolation(agentName, filePath, taskId, session, injectAdvisory, state, scopeEntries) {
103530
+ const taskLabel = taskId ?? "unknown";
103531
+ const violationMessage = `SCOPE VIOLATION: ${agentName} attempted to modify '${filePath}' which is not in declared scope for task ${taskLabel}. Declared scope: [${scopeEntries.slice(0, 3).join(", ")}${scopeEntries.length > 3 ? "..." : ""}]`;
103532
+ if (session) {
103533
+ session.lastScopeViolation = violationMessage;
103534
+ session.scopeViolationDetected = true;
103535
+ }
103536
+ if (injectAdvisory) {
103537
+ for (const [archSessionId, archSession] of state.agentSessions) {
103538
+ const archAgent = state.activeAgent.get(archSessionId) ?? archSession.agentName;
103539
+ if (stripKnownSwarmPrefix(archAgent) === ORCHESTRATOR_NAME) {
103540
+ try {
103541
+ injectAdvisory(archSessionId, `[SCOPE GUARD] ${violationMessage}`);
103542
+ } catch {}
103543
+ break;
103544
+ }
103545
+ }
103546
+ }
103547
+ throw new Error(violationMessage);
103548
+ }
103508
103549
 
103509
103550
  // src/hooks/self-review.ts
103510
103551
  init_constants();
@@ -105997,20 +106038,836 @@ init_snapshot_writer();
105997
106038
  init_state();
105998
106039
  init_telemetry();
105999
106040
 
106041
+ // src/tools/apply-patch.ts
106042
+ init_zod();
106043
+ init_path_security();
106044
+ init_create_tool();
106045
+ import {
106046
+ existsSync as existsSync58,
106047
+ mkdirSync as mkdirSync27,
106048
+ mkdtempSync as mkdtempSync2,
106049
+ readFileSync as readFileSync39,
106050
+ realpathSync as realpathSync13,
106051
+ renameSync as renameSync20,
106052
+ rmdirSync,
106053
+ unlinkSync as unlinkSync17,
106054
+ writeFileSync as writeFileSync20
106055
+ } from "node:fs";
106056
+ import * as path109 from "node:path";
106057
+ var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
106058
+ var MAX_PATCH_SIZE = 500000;
106059
+ function containsWindowsAttacks2(filePath) {
106060
+ if (/:[^\\/]/.test(filePath))
106061
+ return true;
106062
+ const parts2 = filePath.split(/[/\\]/);
106063
+ for (const part of parts2) {
106064
+ if (WINDOWS_RESERVED_NAMES2.test(part))
106065
+ return true;
106066
+ }
106067
+ return false;
106068
+ }
106069
+ function isProtectedPath2(filePath) {
106070
+ const normalized = filePath.replace(/\\/g, "/");
106071
+ const segments = normalized.split("/");
106072
+ return segments.some((seg) => seg === ".git" || seg === ".swarm");
106073
+ }
106074
+ function containsStrictControlChars(str) {
106075
+ for (let i2 = 0;i2 < str.length; i2++) {
106076
+ const c = str.charCodeAt(i2);
106077
+ if (c <= 31 && c !== 9 && c !== 10 && c !== 13)
106078
+ return true;
106079
+ }
106080
+ return false;
106081
+ }
106082
+ function isCanonicalProtectedPath(targetPath, workspace) {
106083
+ try {
106084
+ const canonicalTarget = realpathSync13(targetPath);
106085
+ const canonicalWorkspace = realpathSync13(workspace);
106086
+ const relative21 = path109.relative(canonicalWorkspace, canonicalTarget).replace(/\\/g, "/");
106087
+ const segments = relative21.split("/").filter(Boolean);
106088
+ return segments.some((seg) => seg === ".git" || seg === ".swarm");
106089
+ } catch {
106090
+ const parentDir = path109.dirname(targetPath);
106091
+ if (parentDir === targetPath)
106092
+ return false;
106093
+ try {
106094
+ const canonicalParent = realpathSync13(parentDir);
106095
+ const canonicalWorkspace = realpathSync13(workspace);
106096
+ const relative21 = path109.relative(canonicalWorkspace, canonicalParent).replace(/\\/g, "/");
106097
+ const segments = relative21.split("/").filter(Boolean);
106098
+ return segments.some((seg) => seg === ".git" || seg === ".swarm");
106099
+ } catch {
106100
+ return false;
106101
+ }
106102
+ }
106103
+ }
106104
+ function isCanonicalPathWithinWorkspace(targetPath, workspaceRoot) {
106105
+ try {
106106
+ const canonicalTarget = realpathSync13(targetPath);
106107
+ const canonicalWorkspace = realpathSync13(workspaceRoot);
106108
+ const relative21 = path109.relative(canonicalWorkspace, canonicalTarget);
106109
+ if (relative21.startsWith("..") || path109.isAbsolute(relative21))
106110
+ return false;
106111
+ const segments = relative21.replace(/\\/g, "/").split("/").filter(Boolean);
106112
+ if (segments.some((seg) => seg === ".git" || seg === ".swarm"))
106113
+ return false;
106114
+ return true;
106115
+ } catch {
106116
+ const parentDir = path109.dirname(targetPath);
106117
+ if (parentDir === targetPath) {
106118
+ return false;
106119
+ }
106120
+ try {
106121
+ const canonicalParent = realpathSync13(parentDir);
106122
+ const canonicalWorkspace = realpathSync13(workspaceRoot);
106123
+ const relative21 = path109.relative(canonicalWorkspace, canonicalParent);
106124
+ if (relative21.startsWith("..") || path109.isAbsolute(relative21))
106125
+ return false;
106126
+ const segments = relative21.replace(/\\/g, "/").split("/").filter(Boolean);
106127
+ if (segments.some((seg) => seg === ".git" || seg === ".swarm"))
106128
+ return false;
106129
+ return true;
106130
+ } catch {
106131
+ return false;
106132
+ }
106133
+ }
106134
+ }
106135
+ function validatePatchTargetPath(filePath, workspace) {
106136
+ if (!filePath || filePath.trim() === "") {
106137
+ return "Empty file path";
106138
+ }
106139
+ if (path109.isAbsolute(filePath) || /^[A-Za-z]:[/\\]/.test(filePath)) {
106140
+ return `Absolute path rejected: ${filePath}`;
106141
+ }
106142
+ if (containsPathTraversal(filePath)) {
106143
+ return `Path traversal detected: ${filePath}`;
106144
+ }
106145
+ if (containsStrictControlChars(filePath)) {
106146
+ return `Control characters detected in path: ${filePath}`;
106147
+ }
106148
+ if (containsControlChars(filePath)) {
106149
+ return `Control characters detected in path: ${filePath}`;
106150
+ }
106151
+ if (containsWindowsAttacks2(filePath)) {
106152
+ return `Windows reserved name or invalid path: ${filePath}`;
106153
+ }
106154
+ if (isProtectedPath2(filePath)) {
106155
+ return `Protected directory target rejected: ${filePath}`;
106156
+ }
106157
+ const resolved = path109.resolve(workspace, filePath);
106158
+ const relative21 = path109.relative(workspace, resolved);
106159
+ if (relative21.startsWith("..") || path109.isAbsolute(relative21)) {
106160
+ return `Path escapes workspace: ${filePath}`;
106161
+ }
106162
+ if (!isCanonicalPathWithinWorkspace(resolved, workspace)) {
106163
+ return `Path escapes workspace via symlink/junction: ${filePath}`;
106164
+ }
106165
+ return null;
106166
+ }
106167
+ function extractHeaderPath(header, prefix) {
106168
+ const trimmed = header.trim();
106169
+ if (!trimmed.startsWith(prefix))
106170
+ return null;
106171
+ const rest = trimmed.slice(prefix.length).trim();
106172
+ if (rest === "/dev/null")
106173
+ return "/dev/null";
106174
+ if (rest.startsWith("a/") || rest.startsWith("b/")) {
106175
+ const stripped = rest.slice(2);
106176
+ if (stripped.length === 0)
106177
+ return null;
106178
+ return stripped;
106179
+ }
106180
+ return rest.length > 0 ? rest : null;
106181
+ }
106182
+ function parseHunkHeader(line) {
106183
+ const match = line.match(/^@@\s*-(\d+)(?:,(\d+))?\s*\+(\d+)(?:,(\d+))?\s*@@/);
106184
+ if (!match)
106185
+ return null;
106186
+ return {
106187
+ oldStart: parseInt(match[1], 10),
106188
+ oldCount: match[2] !== undefined ? parseInt(match[2], 10) : 1,
106189
+ newStart: parseInt(match[3], 10),
106190
+ newCount: match[4] !== undefined ? parseInt(match[4], 10) : 1
106191
+ };
106192
+ }
106193
+ function parseUnifiedDiff(patchText) {
106194
+ if (patchText.length > MAX_PATCH_SIZE) {
106195
+ return {
106196
+ files: [],
106197
+ error: `Patch exceeds maximum size of ${MAX_PATCH_SIZE} characters`
106198
+ };
106199
+ }
106200
+ if (patchText.includes("\x00")) {
106201
+ return {
106202
+ files: [],
106203
+ error: "Binary content detected (null byte) — binary patches are not supported (FR-013)"
106204
+ };
106205
+ }
106206
+ const normalized = patchText.replace(/\r\n/g, `
106207
+ `).replace(/\r/g, `
106208
+ `);
106209
+ let lines = normalized.split(`
106210
+ `);
106211
+ if (lines.length > 0 && lines[lines.length - 1] === "") {
106212
+ lines = lines.slice(0, -1);
106213
+ }
106214
+ for (const line of lines) {
106215
+ if (line === "GIT binary patch" || line.startsWith("Binary files ")) {
106216
+ return { files: [], error: "Binary patches are not supported (FR-013)" };
106217
+ }
106218
+ if (line.startsWith("rename from") || line.startsWith("rename to") || line.startsWith("copy from") || line.startsWith("copy to")) {
106219
+ return {
106220
+ files: [],
106221
+ error: "Rename/copy patches are not supported (FR-013)"
106222
+ };
106223
+ }
106224
+ }
106225
+ const fileDiffs = [];
106226
+ let i2 = 0;
106227
+ while (i2 < lines.length) {
106228
+ let oldHeaderPath = null;
106229
+ let newHeaderPath = null;
106230
+ if (lines[i2].startsWith("diff --git ")) {
106231
+ i2++;
106232
+ while (i2 < lines.length && (lines[i2].startsWith("index ") || lines[i2].startsWith("old mode ") || lines[i2].startsWith("new mode ") || lines[i2].startsWith("deleted file ") || lines[i2].startsWith("new file ") || lines[i2].startsWith("similarity index ") || lines[i2].startsWith("dissimilarity index "))) {
106233
+ i2++;
106234
+ }
106235
+ }
106236
+ if (i2 < lines.length && lines[i2].startsWith("--- ")) {
106237
+ oldHeaderPath = extractHeaderPath(lines[i2], "--- ");
106238
+ i2++;
106239
+ } else if (oldHeaderPath === null) {
106240
+ i2++;
106241
+ continue;
106242
+ }
106243
+ if (i2 < lines.length && lines[i2].startsWith("+++ ")) {
106244
+ newHeaderPath = extractHeaderPath(lines[i2], "+++ ");
106245
+ i2++;
106246
+ } else {
106247
+ continue;
106248
+ }
106249
+ if (oldHeaderPath === null || newHeaderPath === null) {
106250
+ continue;
106251
+ }
106252
+ const isNewFile = oldHeaderPath === "/dev/null";
106253
+ const isDelete = newHeaderPath === "/dev/null";
106254
+ const targetPath = isDelete ? oldHeaderPath : newHeaderPath;
106255
+ if (targetPath === "/dev/null") {
106256
+ continue;
106257
+ }
106258
+ const hunks = [];
106259
+ while (i2 < lines.length && lines[i2].startsWith("@@")) {
106260
+ const header = parseHunkHeader(lines[i2]);
106261
+ if (!header) {
106262
+ i2++;
106263
+ continue;
106264
+ }
106265
+ i2++;
106266
+ const hunkLines = [];
106267
+ while (i2 < lines.length) {
106268
+ const line = lines[i2];
106269
+ if (line.startsWith("@@") || line.startsWith("diff --git ") || line.startsWith("--- ") || line.startsWith("+++ ")) {
106270
+ break;
106271
+ }
106272
+ if (line.startsWith("\\")) {
106273
+ i2++;
106274
+ continue;
106275
+ }
106276
+ if (line.length === 0) {
106277
+ break;
106278
+ }
106279
+ const firstChar = line[0];
106280
+ if (firstChar !== " " && firstChar !== "+" && firstChar !== "-") {
106281
+ break;
106282
+ }
106283
+ if (firstChar === "+") {
106284
+ hunkLines.push({ type: "addition", content: line.slice(1) });
106285
+ } else if (firstChar === "-") {
106286
+ hunkLines.push({ type: "removal", content: line.slice(1) });
106287
+ } else {
106288
+ hunkLines.push({ type: "context", content: line.slice(1) });
106289
+ }
106290
+ i2++;
106291
+ }
106292
+ hunks.push({
106293
+ oldStart: header.oldStart,
106294
+ oldCount: header.oldCount,
106295
+ newStart: header.newStart,
106296
+ newCount: header.newCount,
106297
+ lines: hunkLines
106298
+ });
106299
+ }
106300
+ if (hunks.length > 0) {
106301
+ fileDiffs.push({
106302
+ oldPath: oldHeaderPath,
106303
+ newPath: newHeaderPath,
106304
+ isNewFile,
106305
+ isDelete,
106306
+ hunks
106307
+ });
106308
+ } else {
106309
+ fileDiffs.push({
106310
+ oldPath: oldHeaderPath,
106311
+ newPath: newHeaderPath,
106312
+ isNewFile,
106313
+ isDelete,
106314
+ hunks: []
106315
+ });
106316
+ }
106317
+ }
106318
+ return { files: fileDiffs, error: null };
106319
+ }
106320
+ function arraysEqual(a, b) {
106321
+ if (a.length !== b.length)
106322
+ return false;
106323
+ for (let idx = 0;idx < a.length; idx++) {
106324
+ if (a[idx] !== b[idx])
106325
+ return false;
106326
+ }
106327
+ return true;
106328
+ }
106329
+ function applyHunks(content, fileDiff) {
106330
+ const normalizedContent = content.replace(/\r\n/g, `
106331
+ `);
106332
+ const fileLines = normalizedContent.split(`
106333
+ `);
106334
+ if (fileDiff.isNewFile) {
106335
+ const newLines = [];
106336
+ for (const hunk of fileDiff.hunks) {
106337
+ for (const line of hunk.lines) {
106338
+ if (line.type === "addition" || line.type === "context") {
106339
+ newLines.push(line.content);
106340
+ }
106341
+ }
106342
+ }
106343
+ return { success: true, appliedLines: newLines };
106344
+ }
106345
+ if (fileDiff.isDelete) {
106346
+ return { success: true, appliedLines: [] };
106347
+ }
106348
+ let accumulatedDelta = 0;
106349
+ for (let hunkIdx = 0;hunkIdx < fileDiff.hunks.length; hunkIdx++) {
106350
+ const hunk = fileDiff.hunks[hunkIdx];
106351
+ const searchStart = Math.max(0, hunk.oldStart - 1 + accumulatedDelta);
106352
+ const expectedOldLines = [];
106353
+ const newLinesForHunk = [];
106354
+ for (const line of hunk.lines) {
106355
+ if (line.type === "context") {
106356
+ expectedOldLines.push(line.content);
106357
+ newLinesForHunk.push(line.content);
106358
+ } else if (line.type === "removal") {
106359
+ expectedOldLines.push(line.content);
106360
+ } else if (line.type === "addition") {
106361
+ newLinesForHunk.push(line.content);
106362
+ }
106363
+ }
106364
+ const exactOffset = searchStart;
106365
+ const matchFound = exactOffset <= fileLines.length - expectedOldLines.length && arraysEqual(fileLines.slice(exactOffset, exactOffset + expectedOldLines.length), expectedOldLines);
106366
+ if (matchFound) {
106367
+ fileLines.splice(exactOffset, expectedOldLines.length, ...newLinesForHunk);
106368
+ const delta = newLinesForHunk.length - expectedOldLines.length;
106369
+ accumulatedDelta += delta;
106370
+ }
106371
+ if (!matchFound) {
106372
+ const diagStart = Math.min(searchStart, fileLines.length);
106373
+ const diagEnd = Math.min(diagStart + expectedOldLines.length, fileLines.length);
106374
+ const actualContent = fileLines.slice(diagStart, diagEnd).join(`
106375
+ `);
106376
+ const expectedContent = expectedOldLines.join(`
106377
+ `);
106378
+ return {
106379
+ success: false,
106380
+ failedHunkIndex: hunkIdx,
106381
+ error: {
106382
+ hunkIndex: hunkIdx,
106383
+ type: "context-mismatch",
106384
+ message: `Context mismatch in hunk ${hunkIdx + 1} at line ${searchStart + 1}: expected context does not match file content`,
106385
+ expected: expectedContent.length > 200 ? `${expectedContent.slice(0, 200)}... (truncated)` : expectedContent,
106386
+ actual: actualContent.length > 200 ? `${actualContent.slice(0, 200)}... (truncated)` : actualContent,
106387
+ line: searchStart + 1
106388
+ }
106389
+ };
106390
+ }
106391
+ }
106392
+ return { success: true, appliedLines: fileLines };
106393
+ }
106394
+ function atomicWriteFileSync(targetPath, content) {
106395
+ const dir = path109.dirname(targetPath);
106396
+ mkdirSync27(dir, { recursive: true });
106397
+ const tempPrefix = `.apply-patch-${Date.now()}-${process.pid}`;
106398
+ let tempPath;
106399
+ try {
106400
+ const tempDir = realpathSync13(mkdtempSync2(path109.join(dir, tempPrefix)));
106401
+ tempPath = path109.join(tempDir, "content");
106402
+ } catch {
106403
+ tempPath = path109.join(dir, `${tempPrefix}.tmp`);
106404
+ }
106405
+ try {
106406
+ writeFileSync20(tempPath, content, "utf-8");
106407
+ renameSync20(tempPath, targetPath);
106408
+ } finally {
106409
+ if (existsSync58(tempPath)) {
106410
+ try {
106411
+ unlinkSync17(tempPath);
106412
+ } catch {}
106413
+ }
106414
+ const tempDir = path109.dirname(tempPath);
106415
+ if (tempDir !== dir && existsSync58(tempDir)) {
106416
+ try {
106417
+ rmdirSync(tempDir);
106418
+ } catch {}
106419
+ }
106420
+ }
106421
+ }
106422
+ function detectLineEnding(content) {
106423
+ return content.includes(`\r
106424
+ `) ? `\r
106425
+ ` : `
106426
+ `;
106427
+ }
106428
+ function ensureFinalNewline(content, originalEndsWithNewline) {
106429
+ if (originalEndsWithNewline && !content.endsWith(`
106430
+ `)) {
106431
+ return `${content}
106432
+ `;
106433
+ }
106434
+ if (!originalEndsWithNewline && content.endsWith(`
106435
+ `)) {
106436
+ return content.slice(0, -1);
106437
+ }
106438
+ return content;
106439
+ }
106440
+ function processFileDiff(fileDiff, targetPath, fullPath, workspace, dryRun, allowCreates, allowDeletes) {
106441
+ const hunksTotal = fileDiff.hunks.length;
106442
+ if (!isCanonicalPathWithinWorkspace(fullPath, workspace)) {
106443
+ return {
106444
+ file: targetPath,
106445
+ status: "error",
106446
+ hunks: hunksTotal,
106447
+ hunksApplied: 0,
106448
+ hunksFailed: hunksTotal,
106449
+ errors: [
106450
+ {
106451
+ hunkIndex: 0,
106452
+ type: "context-mismatch",
106453
+ message: `Path escapes workspace via symlink/junction: ${targetPath}`
106454
+ }
106455
+ ]
106456
+ };
106457
+ }
106458
+ if (isCanonicalProtectedPath(fullPath, workspace)) {
106459
+ return {
106460
+ file: targetPath,
106461
+ status: "error",
106462
+ hunks: hunksTotal,
106463
+ hunksApplied: 0,
106464
+ hunksFailed: hunksTotal,
106465
+ errors: [
106466
+ {
106467
+ hunkIndex: 0,
106468
+ type: "context-mismatch",
106469
+ message: `Protected directory target rejected via symlink: ${targetPath}`
106470
+ }
106471
+ ]
106472
+ };
106473
+ }
106474
+ if (fileDiff.isNewFile) {
106475
+ if (!allowCreates) {
106476
+ return {
106477
+ file: targetPath,
106478
+ status: "error",
106479
+ hunks: hunksTotal,
106480
+ hunksApplied: 0,
106481
+ hunksFailed: hunksTotal,
106482
+ errors: [
106483
+ {
106484
+ hunkIndex: 0,
106485
+ type: "create-not-allowed",
106486
+ message: `New file creation not allowed: ${targetPath} (set allowCreates to true)`
106487
+ }
106488
+ ]
106489
+ };
106490
+ }
106491
+ const parentDir = path109.dirname(fullPath);
106492
+ if (!existsSync58(parentDir)) {
106493
+ return {
106494
+ file: targetPath,
106495
+ status: "error",
106496
+ hunks: hunksTotal,
106497
+ hunksApplied: 0,
106498
+ hunksFailed: hunksTotal,
106499
+ errors: [
106500
+ {
106501
+ hunkIndex: 0,
106502
+ type: "file-not-found",
106503
+ message: `Parent directory does not exist: ${parentDir}`
106504
+ }
106505
+ ]
106506
+ };
106507
+ }
106508
+ if (existsSync58(fullPath)) {
106509
+ return {
106510
+ file: targetPath,
106511
+ status: "error",
106512
+ hunks: hunksTotal,
106513
+ hunksApplied: 0,
106514
+ hunksFailed: hunksTotal,
106515
+ errors: [
106516
+ {
106517
+ hunkIndex: 0,
106518
+ type: "file-not-found",
106519
+ message: `File already exists: ${targetPath} (cannot create — patch may be stale)`
106520
+ }
106521
+ ]
106522
+ };
106523
+ }
106524
+ if (hunksTotal === 0) {
106525
+ return {
106526
+ file: targetPath,
106527
+ status: "no-changes",
106528
+ hunks: 0,
106529
+ hunksApplied: 0,
106530
+ hunksFailed: 0
106531
+ };
106532
+ }
106533
+ const hunkResult2 = applyHunks("", fileDiff);
106534
+ if (!hunkResult2.success || !hunkResult2.appliedLines) {
106535
+ return {
106536
+ file: targetPath,
106537
+ status: "error",
106538
+ hunks: hunksTotal,
106539
+ hunksApplied: 0,
106540
+ hunksFailed: hunksTotal,
106541
+ errors: hunkResult2.error ? [hunkResult2.error] : []
106542
+ };
106543
+ }
106544
+ if (!dryRun) {
106545
+ const content2 = ensureFinalNewline(hunkResult2.appliedLines.join(`
106546
+ `), true);
106547
+ atomicWriteFileSync(fullPath, content2);
106548
+ }
106549
+ return {
106550
+ file: targetPath,
106551
+ status: "created",
106552
+ hunks: hunksTotal,
106553
+ hunksApplied: hunksTotal,
106554
+ hunksFailed: 0
106555
+ };
106556
+ }
106557
+ if (fileDiff.isDelete) {
106558
+ if (hunksTotal === 0) {
106559
+ return {
106560
+ file: targetPath,
106561
+ status: "no-changes",
106562
+ hunks: 0,
106563
+ hunksApplied: 0,
106564
+ hunksFailed: 0
106565
+ };
106566
+ }
106567
+ if (!allowDeletes) {
106568
+ return {
106569
+ file: targetPath,
106570
+ status: "error",
106571
+ hunks: hunksTotal,
106572
+ hunksApplied: 0,
106573
+ hunksFailed: hunksTotal,
106574
+ errors: [
106575
+ {
106576
+ hunkIndex: 0,
106577
+ type: "delete-not-allowed",
106578
+ message: `File deletion not allowed: ${targetPath} (set allowDeletes to true)`
106579
+ }
106580
+ ]
106581
+ };
106582
+ }
106583
+ if (!existsSync58(fullPath)) {
106584
+ return {
106585
+ file: targetPath,
106586
+ status: "error",
106587
+ hunks: hunksTotal,
106588
+ hunksApplied: 0,
106589
+ hunksFailed: hunksTotal,
106590
+ errors: [
106591
+ {
106592
+ hunkIndex: 0,
106593
+ type: "file-not-found",
106594
+ message: `File not found for deletion: ${targetPath}`
106595
+ }
106596
+ ]
106597
+ };
106598
+ }
106599
+ if (!dryRun) {
106600
+ try {
106601
+ unlinkSync17(fullPath);
106602
+ } catch (err2) {
106603
+ return {
106604
+ file: targetPath,
106605
+ status: "error",
106606
+ hunks: hunksTotal,
106607
+ hunksApplied: 0,
106608
+ hunksFailed: hunksTotal,
106609
+ errors: [
106610
+ {
106611
+ hunkIndex: 0,
106612
+ type: "file-not-found",
106613
+ message: `Failed to delete file: ${err2 instanceof Error ? err2.message : String(err2)}`
106614
+ }
106615
+ ]
106616
+ };
106617
+ }
106618
+ }
106619
+ return {
106620
+ file: targetPath,
106621
+ status: "applied",
106622
+ hunks: hunksTotal,
106623
+ hunksApplied: hunksTotal,
106624
+ hunksFailed: 0
106625
+ };
106626
+ }
106627
+ if (!existsSync58(fullPath)) {
106628
+ return {
106629
+ file: targetPath,
106630
+ status: "error",
106631
+ hunks: hunksTotal,
106632
+ hunksApplied: 0,
106633
+ hunksFailed: hunksTotal,
106634
+ errors: [
106635
+ {
106636
+ hunkIndex: 0,
106637
+ type: "file-not-found",
106638
+ message: `File not found: ${targetPath}`
106639
+ }
106640
+ ]
106641
+ };
106642
+ }
106643
+ let content;
106644
+ try {
106645
+ content = readFileSync39(fullPath, "utf-8");
106646
+ } catch (err2) {
106647
+ return {
106648
+ file: targetPath,
106649
+ status: "error",
106650
+ hunks: hunksTotal,
106651
+ hunksApplied: 0,
106652
+ hunksFailed: hunksTotal,
106653
+ errors: [
106654
+ {
106655
+ hunkIndex: 0,
106656
+ type: "file-not-found",
106657
+ message: `Could not read file: ${err2 instanceof Error ? err2.message : String(err2)}`
106658
+ }
106659
+ ]
106660
+ };
106661
+ }
106662
+ if (hunksTotal === 0) {
106663
+ return {
106664
+ file: targetPath,
106665
+ status: "no-changes",
106666
+ hunks: 0,
106667
+ hunksApplied: 0,
106668
+ hunksFailed: 0
106669
+ };
106670
+ }
106671
+ const originalEndsWithNewline = content.endsWith(`
106672
+ `);
106673
+ const originalLineEnding = detectLineEnding(content);
106674
+ const hunkResult = applyHunks(content, fileDiff);
106675
+ if (!hunkResult.success) {
106676
+ return {
106677
+ file: targetPath,
106678
+ status: "error",
106679
+ hunks: hunksTotal,
106680
+ hunksApplied: 0,
106681
+ hunksFailed: hunksTotal,
106682
+ errors: hunkResult.error ? [hunkResult.error] : []
106683
+ };
106684
+ }
106685
+ const resultContent = hunkResult.appliedLines.join(`
106686
+ `);
106687
+ if (resultContent === "" && !dryRun && !allowDeletes && content.length > 0) {
106688
+ return {
106689
+ file: targetPath,
106690
+ status: "error",
106691
+ hunks: hunksTotal,
106692
+ hunksApplied: hunksTotal,
106693
+ hunksFailed: 0,
106694
+ errors: [
106695
+ {
106696
+ hunkIndex: 0,
106697
+ type: "delete-not-allowed",
106698
+ message: `Patch would delete all content from ${targetPath}. Set allowDeletes to true to permit file deletion.`
106699
+ }
106700
+ ]
106701
+ };
106702
+ }
106703
+ let finalContent;
106704
+ if (resultContent === "") {
106705
+ finalContent = "";
106706
+ } else {
106707
+ const withLineEnding = originalLineEnding === `\r
106708
+ ` ? resultContent.replace(/\n/g, `\r
106709
+ `) : resultContent;
106710
+ finalContent = ensureFinalNewline(withLineEnding, originalEndsWithNewline);
106711
+ }
106712
+ if (finalContent === content) {
106713
+ return {
106714
+ file: targetPath,
106715
+ status: "no-changes",
106716
+ hunks: hunksTotal,
106717
+ hunksApplied: hunksTotal,
106718
+ hunksFailed: 0
106719
+ };
106720
+ }
106721
+ if (!dryRun) {
106722
+ atomicWriteFileSync(fullPath, finalContent);
106723
+ }
106724
+ return {
106725
+ file: targetPath,
106726
+ status: "applied",
106727
+ hunks: hunksTotal,
106728
+ hunksApplied: hunksTotal,
106729
+ hunksFailed: 0
106730
+ };
106731
+ }
106732
+ function buildErrorResult(message) {
106733
+ return {
106734
+ success: false,
106735
+ files: [
106736
+ {
106737
+ file: "",
106738
+ status: "error",
106739
+ hunks: 0,
106740
+ hunksApplied: 0,
106741
+ hunksFailed: 0,
106742
+ errors: [
106743
+ {
106744
+ hunkIndex: 0,
106745
+ type: "context-mismatch",
106746
+ message
106747
+ }
106748
+ ]
106749
+ }
106750
+ ],
106751
+ summary: {
106752
+ totalFiles: 0,
106753
+ applied: 0,
106754
+ failed: 1,
106755
+ totalHunks: 0
106756
+ }
106757
+ };
106758
+ }
106759
+ var applyPatch = createSwarmTool({
106760
+ description: "Apply a unified diff patch to workspace files. Validates paths, matches context exactly, and writes atomically. Coder-scoped write tool.",
106761
+ args: {
106762
+ patch: exports_external.string().min(1).describe("Unified diff text to parse and apply"),
106763
+ files: exports_external.array(exports_external.string()).min(1).describe("Array of target file paths the patch is expected to touch. Every parsed target must appear in this list."),
106764
+ dryRun: exports_external.boolean().optional().default(false).describe("Validate without writing files (default: false)"),
106765
+ allowCreates: exports_external.boolean().optional().default(false).describe("Allow creating new files from patches with --- /dev/null (default: false)"),
106766
+ allowDeletes: exports_external.boolean().optional().default(false).describe("Allow deleting files from patches with +++ /dev/null (default: false)")
106767
+ },
106768
+ execute: async (args2, directory) => {
106769
+ if (!args2 || typeof args2 !== "object") {
106770
+ return JSON.stringify(buildErrorResult("Could not parse apply_patch arguments"), null, 2);
106771
+ }
106772
+ const obj = args2;
106773
+ const patchText = obj.patch ?? "";
106774
+ const files = obj.files ?? [];
106775
+ const dryRun = obj.dryRun ?? false;
106776
+ const allowCreates = obj.allowCreates ?? false;
106777
+ const allowDeletes = obj.allowDeletes ?? false;
106778
+ if (!existsSync58(directory)) {
106779
+ return JSON.stringify(buildErrorResult("Workspace directory does not exist"), null, 2);
106780
+ }
106781
+ if (files.length === 0) {
106782
+ return JSON.stringify(buildErrorResult("files array cannot be empty"), null, 2);
106783
+ }
106784
+ if (!patchText || patchText.trim() === "") {
106785
+ return JSON.stringify(buildErrorResult("patch text cannot be empty"), null, 2);
106786
+ }
106787
+ for (const filePath of files) {
106788
+ const validationError = validatePatchTargetPath(filePath, directory);
106789
+ if (validationError) {
106790
+ return JSON.stringify(buildErrorResult(validationError), null, 2);
106791
+ }
106792
+ }
106793
+ const { files: parsedFiles, error: parseError } = parseUnifiedDiff(patchText);
106794
+ if (parseError) {
106795
+ return JSON.stringify(buildErrorResult(parseError), null, 2);
106796
+ }
106797
+ if (parsedFiles.length === 0) {
106798
+ return JSON.stringify({
106799
+ success: true,
106800
+ dryRun,
106801
+ files: [],
106802
+ summary: { totalFiles: 0, applied: 0, failed: 0, totalHunks: 0 }
106803
+ }, null, 2);
106804
+ }
106805
+ const declaredFileSet = new Set(files);
106806
+ const undeclaredTargets = [];
106807
+ for (const fileDiff of parsedFiles) {
106808
+ const targetPath = fileDiff.isDelete ? fileDiff.oldPath : fileDiff.newPath;
106809
+ if (targetPath && targetPath !== "/dev/null" && !declaredFileSet.has(targetPath)) {
106810
+ undeclaredTargets.push(targetPath);
106811
+ }
106812
+ }
106813
+ if (undeclaredTargets.length > 0) {
106814
+ return JSON.stringify(buildErrorResult(`Patch targets files not in the declared files array: ${undeclaredTargets.join(", ")}`), null, 2);
106815
+ }
106816
+ const parsedTargetSet = new Set(parsedFiles.map((fd) => fd.isDelete ? fd.oldPath : fd.newPath).filter(Boolean));
106817
+ const extraFiles = files.filter((f) => !parsedTargetSet.has(f));
106818
+ const fileResults = [];
106819
+ let totalApplied = 0;
106820
+ let totalFailed = 0;
106821
+ let totalHunks = 0;
106822
+ for (const fileDiff of parsedFiles) {
106823
+ const targetPath = fileDiff.isDelete ? fileDiff.oldPath : fileDiff.newPath;
106824
+ const fullPath = path109.resolve(directory, targetPath);
106825
+ totalHunks += fileDiff.hunks.length;
106826
+ const result = processFileDiff(fileDiff, targetPath, fullPath, directory, dryRun, allowCreates, allowDeletes);
106827
+ fileResults.push(result);
106828
+ if (result.status === "applied" || result.status === "created") {
106829
+ totalApplied++;
106830
+ } else if (result.status === "error") {
106831
+ totalFailed++;
106832
+ }
106833
+ }
106834
+ const output = {
106835
+ success: totalFailed === 0,
106836
+ dryRun,
106837
+ files: fileResults,
106838
+ summary: {
106839
+ totalFiles: fileResults.length,
106840
+ applied: totalApplied,
106841
+ failed: totalFailed,
106842
+ totalHunks
106843
+ }
106844
+ };
106845
+ if (extraFiles.length > 0) {
106846
+ return JSON.stringify({
106847
+ ...output,
106848
+ warnings: [
106849
+ `files[] contains entries not targeted by the patch: ${extraFiles.join(", ")}`
106850
+ ]
106851
+ }, null, 2);
106852
+ }
106853
+ return JSON.stringify(output, null, 2);
106854
+ }
106855
+ });
106856
+
106000
106857
  // src/tools/batch-symbols.ts
106001
106858
  init_dist();
106002
106859
  init_create_tool();
106003
106860
  import * as fs72 from "node:fs";
106004
- import * as path109 from "node:path";
106861
+ import * as path110 from "node:path";
106005
106862
  init_path_security();
106006
- var WINDOWS_RESERVED_NAMES2 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
106007
- function containsWindowsAttacks2(str) {
106863
+ var WINDOWS_RESERVED_NAMES3 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
106864
+ function containsWindowsAttacks3(str) {
106008
106865
  if (/:[^\\/]/.test(str)) {
106009
106866
  return true;
106010
106867
  }
106011
106868
  const parts2 = str.split(/[/\\]/);
106012
106869
  for (const part of parts2) {
106013
- if (WINDOWS_RESERVED_NAMES2.test(part)) {
106870
+ if (WINDOWS_RESERVED_NAMES3.test(part)) {
106014
106871
  return true;
106015
106872
  }
106016
106873
  }
@@ -106018,14 +106875,14 @@ function containsWindowsAttacks2(str) {
106018
106875
  }
106019
106876
  function isPathInWorkspace2(filePath, workspace) {
106020
106877
  try {
106021
- const resolvedPath = path109.resolve(workspace, filePath);
106878
+ const resolvedPath = path110.resolve(workspace, filePath);
106022
106879
  if (!fs72.existsSync(resolvedPath)) {
106023
106880
  return true;
106024
106881
  }
106025
106882
  const realWorkspace = fs72.realpathSync(workspace);
106026
106883
  const realResolvedPath = fs72.realpathSync(resolvedPath);
106027
- const relativePath = path109.relative(realWorkspace, realResolvedPath);
106028
- if (relativePath.startsWith("..") || path109.isAbsolute(relativePath)) {
106884
+ const relativePath = path110.relative(realWorkspace, realResolvedPath);
106885
+ if (relativePath.startsWith("..") || path110.isAbsolute(relativePath)) {
106029
106886
  return false;
106030
106887
  }
106031
106888
  return true;
@@ -106034,7 +106891,7 @@ function isPathInWorkspace2(filePath, workspace) {
106034
106891
  }
106035
106892
  }
106036
106893
  function processFile2(file3, cwd, exportedOnly) {
106037
- const ext = path109.extname(file3);
106894
+ const ext = path110.extname(file3);
106038
106895
  if (containsControlChars(file3)) {
106039
106896
  return {
106040
106897
  file: file3,
@@ -106051,7 +106908,7 @@ function processFile2(file3, cwd, exportedOnly) {
106051
106908
  errorType: "path-traversal"
106052
106909
  };
106053
106910
  }
106054
- if (containsWindowsAttacks2(file3)) {
106911
+ if (containsWindowsAttacks3(file3)) {
106055
106912
  return {
106056
106913
  file: file3,
106057
106914
  success: false,
@@ -106067,7 +106924,7 @@ function processFile2(file3, cwd, exportedOnly) {
106067
106924
  errorType: "path-outside-workspace"
106068
106925
  };
106069
106926
  }
106070
- const fullPath = path109.join(cwd, file3);
106927
+ const fullPath = path110.join(cwd, file3);
106071
106928
  if (!fs72.existsSync(fullPath)) {
106072
106929
  return {
106073
106930
  file: file3,
@@ -106361,15 +107218,15 @@ init_task_id();
106361
107218
  init_create_tool();
106362
107219
  init_resolve_working_directory();
106363
107220
  import * as fs73 from "node:fs";
106364
- import * as path110 from "node:path";
107221
+ import * as path111 from "node:path";
106365
107222
  var EVIDENCE_DIR = ".swarm/evidence";
106366
107223
  function isValidTaskId3(taskId) {
106367
107224
  return isStrictTaskId(taskId);
106368
107225
  }
106369
107226
  function isPathWithinSwarm(filePath, workspaceRoot) {
106370
- const normalizedWorkspace = path110.resolve(workspaceRoot);
106371
- const swarmPath = path110.join(normalizedWorkspace, ".swarm", "evidence");
106372
- const normalizedPath = path110.resolve(filePath);
107227
+ const normalizedWorkspace = path111.resolve(workspaceRoot);
107228
+ const swarmPath = path111.join(normalizedWorkspace, ".swarm", "evidence");
107229
+ const normalizedPath = path111.resolve(filePath);
106373
107230
  return normalizedPath.startsWith(swarmPath);
106374
107231
  }
106375
107232
  function readEvidenceFile(evidencePath) {
@@ -106450,7 +107307,7 @@ var check_gate_status = createSwarmTool({
106450
107307
  };
106451
107308
  return JSON.stringify(errorResult, null, 2);
106452
107309
  }
106453
- const evidencePath = path110.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
107310
+ const evidencePath = path111.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
106454
107311
  if (!isPathWithinSwarm(evidencePath, directory)) {
106455
107312
  const errorResult = {
106456
107313
  taskId: taskIdInput,
@@ -106547,7 +107404,7 @@ init_state();
106547
107404
  init_create_tool();
106548
107405
  init_resolve_working_directory();
106549
107406
  import * as fs74 from "node:fs";
106550
- import * as path111 from "node:path";
107407
+ import * as path112 from "node:path";
106551
107408
  function extractMatches(regex, text) {
106552
107409
  return Array.from(text.matchAll(regex));
106553
107410
  }
@@ -106699,10 +107556,10 @@ async function executeCompletionVerify(args2, directory) {
106699
107556
  let hasFileReadFailure = false;
106700
107557
  for (const filePath of fileTargets) {
106701
107558
  const normalizedPath = filePath.replace(/\\/g, "/");
106702
- const resolvedPath = path111.resolve(directory, normalizedPath);
106703
- const projectRoot = path111.resolve(directory);
106704
- const relative22 = path111.relative(projectRoot, resolvedPath);
106705
- const withinProject = relative22 === "" || !relative22.startsWith("..") && !path111.isAbsolute(relative22);
107559
+ const resolvedPath = path112.resolve(directory, normalizedPath);
107560
+ const projectRoot = path112.resolve(directory);
107561
+ const relative23 = path112.relative(projectRoot, resolvedPath);
107562
+ const withinProject = relative23 === "" || !relative23.startsWith("..") && !path112.isAbsolute(relative23);
106706
107563
  if (!withinProject) {
106707
107564
  blockedTasks.push({
106708
107565
  task_id: task.id,
@@ -106757,8 +107614,8 @@ async function executeCompletionVerify(args2, directory) {
106757
107614
  blockedTasks
106758
107615
  };
106759
107616
  try {
106760
- const evidenceDir = path111.join(directory, ".swarm", "evidence", `${phase}`);
106761
- const evidencePath = path111.join(evidenceDir, "completion-verify.json");
107617
+ const evidenceDir = path112.join(directory, ".swarm", "evidence", `${phase}`);
107618
+ const evidencePath = path112.join(evidenceDir, "completion-verify.json");
106762
107619
  fs74.mkdirSync(evidenceDir, { recursive: true });
106763
107620
  const evidenceBundle = {
106764
107621
  schema_version: "1.0.0",
@@ -106836,11 +107693,11 @@ var completion_verify = createSwarmTool({
106836
107693
  // src/tools/complexity-hotspots.ts
106837
107694
  init_zod();
106838
107695
  import * as fs76 from "node:fs";
106839
- import * as path113 from "node:path";
107696
+ import * as path114 from "node:path";
106840
107697
 
106841
107698
  // src/quality/metrics.ts
106842
107699
  import * as fs75 from "node:fs";
106843
- import * as path112 from "node:path";
107700
+ import * as path113 from "node:path";
106844
107701
  var MAX_FILE_SIZE_BYTES4 = 256 * 1024;
106845
107702
  var MIN_DUPLICATION_LINES = 10;
106846
107703
  function estimateCyclomaticComplexity(content) {
@@ -106892,7 +107749,7 @@ async function computeComplexityDelta(files, workingDir) {
106892
107749
  let totalComplexity = 0;
106893
107750
  const analyzedFiles = [];
106894
107751
  for (const file3 of files) {
106895
- const fullPath = path112.isAbsolute(file3) ? file3 : path112.join(workingDir, file3);
107752
+ const fullPath = path113.isAbsolute(file3) ? file3 : path113.join(workingDir, file3);
106896
107753
  if (!fs75.existsSync(fullPath)) {
106897
107754
  continue;
106898
107755
  }
@@ -107015,7 +107872,7 @@ function countGoExports(content) {
107015
107872
  function getExportCountForFile(filePath) {
107016
107873
  try {
107017
107874
  const content = fs75.readFileSync(filePath, "utf-8");
107018
- const ext = path112.extname(filePath).toLowerCase();
107875
+ const ext = path113.extname(filePath).toLowerCase();
107019
107876
  switch (ext) {
107020
107877
  case ".ts":
107021
107878
  case ".tsx":
@@ -107041,7 +107898,7 @@ async function computePublicApiDelta(files, workingDir) {
107041
107898
  let totalExports = 0;
107042
107899
  const analyzedFiles = [];
107043
107900
  for (const file3 of files) {
107044
- const fullPath = path112.isAbsolute(file3) ? file3 : path112.join(workingDir, file3);
107901
+ const fullPath = path113.isAbsolute(file3) ? file3 : path113.join(workingDir, file3);
107045
107902
  if (!fs75.existsSync(fullPath)) {
107046
107903
  continue;
107047
107904
  }
@@ -107075,7 +107932,7 @@ async function computeDuplicationRatio(files, workingDir) {
107075
107932
  let duplicateLines = 0;
107076
107933
  const analyzedFiles = [];
107077
107934
  for (const file3 of files) {
107078
- const fullPath = path112.isAbsolute(file3) ? file3 : path112.join(workingDir, file3);
107935
+ const fullPath = path113.isAbsolute(file3) ? file3 : path113.join(workingDir, file3);
107079
107936
  if (!fs75.existsSync(fullPath)) {
107080
107937
  continue;
107081
107938
  }
@@ -107108,8 +107965,8 @@ function countCodeLines(content) {
107108
107965
  return lines.length;
107109
107966
  }
107110
107967
  function isTestFile(filePath) {
107111
- const basename16 = path112.basename(filePath);
107112
- const _ext = path112.extname(filePath).toLowerCase();
107968
+ const basename16 = path113.basename(filePath);
107969
+ const _ext = path113.extname(filePath).toLowerCase();
107113
107970
  const testPatterns = [
107114
107971
  ".test.",
107115
107972
  ".spec.",
@@ -107190,8 +108047,8 @@ function matchGlobSegment(globSegments, pathSegments) {
107190
108047
  }
107191
108048
  return gIndex === globSegments.length && pIndex === pathSegments.length;
107192
108049
  }
107193
- function matchesGlobSegment(path113, glob) {
107194
- const normalizedPath = path113.replace(/\\/g, "/");
108050
+ function matchesGlobSegment(path114, glob) {
108051
+ const normalizedPath = path114.replace(/\\/g, "/");
107195
108052
  const normalizedGlob = glob.replace(/\\/g, "/");
107196
108053
  if (normalizedPath.includes("//")) {
107197
108054
  return false;
@@ -107222,8 +108079,8 @@ function simpleGlobToRegex2(glob) {
107222
108079
  function hasGlobstar(glob) {
107223
108080
  return glob.includes("**");
107224
108081
  }
107225
- function globMatches(path113, glob) {
107226
- const normalizedPath = path113.replace(/\\/g, "/");
108082
+ function globMatches(path114, glob) {
108083
+ const normalizedPath = path114.replace(/\\/g, "/");
107227
108084
  if (!glob || glob === "") {
107228
108085
  if (normalizedPath.includes("//")) {
107229
108086
  return false;
@@ -107259,7 +108116,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
107259
108116
  async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
107260
108117
  let testLines = 0;
107261
108118
  let codeLines = 0;
107262
- const srcDir = path112.join(workingDir, "src");
108119
+ const srcDir = path113.join(workingDir, "src");
107263
108120
  if (fs75.existsSync(srcDir)) {
107264
108121
  await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
107265
108122
  codeLines += lines;
@@ -107267,14 +108124,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
107267
108124
  }
107268
108125
  const possibleSrcDirs = ["lib", "app", "source", "core"];
107269
108126
  for (const dir of possibleSrcDirs) {
107270
- const dirPath = path112.join(workingDir, dir);
108127
+ const dirPath = path113.join(workingDir, dir);
107271
108128
  if (fs75.existsSync(dirPath)) {
107272
108129
  await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
107273
108130
  codeLines += lines;
107274
108131
  });
107275
108132
  }
107276
108133
  }
107277
- const testsDir = path112.join(workingDir, "tests");
108134
+ const testsDir = path113.join(workingDir, "tests");
107278
108135
  if (fs75.existsSync(testsDir)) {
107279
108136
  await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
107280
108137
  testLines += lines;
@@ -107282,7 +108139,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
107282
108139
  }
107283
108140
  const possibleTestDirs = ["test", "__tests__", "specs"];
107284
108141
  for (const dir of possibleTestDirs) {
107285
- const dirPath = path112.join(workingDir, dir);
108142
+ const dirPath = path113.join(workingDir, dir);
107286
108143
  if (fs75.existsSync(dirPath) && dirPath !== testsDir) {
107287
108144
  await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
107288
108145
  testLines += lines;
@@ -107297,7 +108154,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
107297
108154
  try {
107298
108155
  const entries = fs75.readdirSync(dirPath, { withFileTypes: true });
107299
108156
  for (const entry of entries) {
107300
- const fullPath = path112.join(dirPath, entry.name);
108157
+ const fullPath = path113.join(dirPath, entry.name);
107301
108158
  if (entry.isDirectory()) {
107302
108159
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
107303
108160
  continue;
@@ -107305,7 +108162,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
107305
108162
  await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
107306
108163
  } else if (entry.isFile()) {
107307
108164
  const relativePath = fullPath.replace(`${dirPath}/`, "");
107308
- const ext = path112.extname(entry.name).toLowerCase();
108165
+ const ext = path113.extname(entry.name).toLowerCase();
107309
108166
  const validExts = [
107310
108167
  ".ts",
107311
108168
  ".tsx",
@@ -107556,7 +108413,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
107556
108413
  const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
107557
108414
  const filteredChurn = new Map;
107558
108415
  for (const [file3, count] of churnMap) {
107559
- const ext = path113.extname(file3).toLowerCase();
108416
+ const ext = path114.extname(file3).toLowerCase();
107560
108417
  if (extSet.has(ext)) {
107561
108418
  filteredChurn.set(file3, count);
107562
108419
  }
@@ -107567,7 +108424,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
107567
108424
  for (const [file3, churnCount] of filteredChurn) {
107568
108425
  let fullPath = file3;
107569
108426
  if (!fs76.existsSync(fullPath)) {
107570
- fullPath = path113.join(cwd, file3);
108427
+ fullPath = path114.join(cwd, file3);
107571
108428
  }
107572
108429
  const complexity = getComplexityForFile2(fullPath);
107573
108430
  if (complexity !== null) {
@@ -107736,8 +108593,8 @@ ${body2}`);
107736
108593
 
107737
108594
  // src/council/council-evidence-writer.ts
107738
108595
  init_task_file();
107739
- import { appendFileSync as appendFileSync12, existsSync as existsSync62, mkdirSync as mkdirSync28, readFileSync as readFileSync44 } from "node:fs";
107740
- import { join as join94 } from "node:path";
108596
+ import { appendFileSync as appendFileSync12, existsSync as existsSync63, mkdirSync as mkdirSync29, readFileSync as readFileSync45 } from "node:fs";
108597
+ import { join as join95 } from "node:path";
107741
108598
  var EVIDENCE_DIR2 = ".swarm/evidence";
107742
108599
  var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
107743
108600
  var COUNCIL_GATE_NAME = "council";
@@ -107774,14 +108631,14 @@ async function writeCouncilEvidence(workingDir, synthesis) {
107774
108631
  if (!VALID_TASK_ID.test(synthesis.taskId)) {
107775
108632
  throw new Error(`writeCouncilEvidence: invalid taskId "${synthesis.taskId}" — must match N.M or N.M.P format`);
107776
108633
  }
107777
- const dir = join94(workingDir, EVIDENCE_DIR2);
107778
- mkdirSync28(dir, { recursive: true });
108634
+ const dir = join95(workingDir, EVIDENCE_DIR2);
108635
+ mkdirSync29(dir, { recursive: true });
107779
108636
  const filePath = taskEvidencePath(workingDir, synthesis.taskId);
107780
108637
  await _internals53.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
107781
108638
  const existingRoot = Object.create(null);
107782
- if (existsSync62(filePath)) {
108639
+ if (existsSync63(filePath)) {
107783
108640
  try {
107784
- const parsed = JSON.parse(readFileSync44(filePath, "utf-8"));
108641
+ const parsed = JSON.parse(readFileSync45(filePath, "utf-8"));
107785
108642
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
107786
108643
  safeAssignOwnProps(existingRoot, parsed);
107787
108644
  }
@@ -107812,15 +108669,15 @@ async function writeCouncilEvidence(workingDir, synthesis) {
107812
108669
  await atomicWriteFile(filePath, JSON.stringify(updated, null, 2));
107813
108670
  });
107814
108671
  try {
107815
- const councilDir = join94(workingDir, ".swarm", "council");
107816
- mkdirSync28(councilDir, { recursive: true });
108672
+ const councilDir = join95(workingDir, ".swarm", "council");
108673
+ mkdirSync29(councilDir, { recursive: true });
107817
108674
  const auditLine = JSON.stringify({
107818
108675
  round: synthesis.roundNumber,
107819
108676
  verdict: synthesis.overallVerdict,
107820
108677
  timestamp: synthesis.timestamp,
107821
108678
  vetoedBy: synthesis.vetoedBy
107822
108679
  });
107823
- appendFileSync12(join94(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
108680
+ appendFileSync12(join95(councilDir, `${synthesis.taskId}.rounds.jsonl`), `${auditLine}
107824
108681
  `);
107825
108682
  } catch (auditError) {
107826
108683
  console.warn(`writeCouncilEvidence: failed to append round-history audit log: ${auditError instanceof Error ? auditError.message : String(auditError)}`);
@@ -108142,25 +108999,25 @@ function buildFinalCouncilFeedback(projectSummary, verdict, vetoedBy, requiredFi
108142
108999
  }
108143
109000
 
108144
109001
  // src/council/criteria-store.ts
108145
- import { existsSync as existsSync63, mkdirSync as mkdirSync29, readFileSync as readFileSync45, writeFileSync as writeFileSync21 } from "node:fs";
108146
- import { join as join95 } from "node:path";
109002
+ import { existsSync as existsSync64, mkdirSync as mkdirSync30, readFileSync as readFileSync46, writeFileSync as writeFileSync22 } from "node:fs";
109003
+ import { join as join96 } from "node:path";
108147
109004
  var COUNCIL_DIR = ".swarm/council";
108148
109005
  function writeCriteria(workingDir, taskId, criteria) {
108149
- const dir = join95(workingDir, COUNCIL_DIR);
108150
- mkdirSync29(dir, { recursive: true });
109006
+ const dir = join96(workingDir, COUNCIL_DIR);
109007
+ mkdirSync30(dir, { recursive: true });
108151
109008
  const payload = {
108152
109009
  taskId,
108153
109010
  criteria,
108154
109011
  declaredAt: new Date().toISOString()
108155
109012
  };
108156
- writeFileSync21(join95(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
109013
+ writeFileSync22(join96(dir, `${safeId(taskId)}.json`), JSON.stringify(payload, null, 2));
108157
109014
  }
108158
109015
  function readCriteria(workingDir, taskId) {
108159
- const filePath = join95(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
108160
- if (!existsSync63(filePath))
109016
+ const filePath = join96(workingDir, COUNCIL_DIR, `${safeId(taskId)}.json`);
109017
+ if (!existsSync64(filePath))
108161
109018
  return null;
108162
109019
  try {
108163
- const parsed = JSON.parse(readFileSync45(filePath, "utf-8"));
109020
+ const parsed = JSON.parse(readFileSync46(filePath, "utf-8"));
108164
109021
  if (parsed && typeof parsed === "object" && typeof parsed.taskId === "string" && Array.isArray(parsed.criteria)) {
108165
109022
  return parsed;
108166
109023
  }
@@ -108310,7 +109167,7 @@ var submit_council_verdicts = createSwarmTool({
108310
109167
  init_zod();
108311
109168
  init_loader();
108312
109169
  import * as fs77 from "node:fs";
108313
- import * as path114 from "node:path";
109170
+ import * as path115 from "node:path";
108314
109171
 
108315
109172
  // src/council/general-council-advisory.ts
108316
109173
  var ADVISORY_HEADER = "[general_council] (advisory; not blocking)";
@@ -108738,10 +109595,10 @@ var convene_general_council = createSwarmTool({
108738
109595
  const round1 = input.round1Responses;
108739
109596
  const round2 = input.round2Responses ?? [];
108740
109597
  const result = synthesizeGeneralCouncil(input.question, input.mode, round1, round2);
108741
- const evidenceDir = path114.join(workingDir, ".swarm", "council", "general");
109598
+ const evidenceDir = path115.join(workingDir, ".swarm", "council", "general");
108742
109599
  const safeTimestamp = result.timestamp.replace(/[:.]/g, "-");
108743
109600
  const evidenceFile = `${safeTimestamp}-${input.mode}.json`;
108744
- const evidencePath = path114.join(evidenceDir, evidenceFile);
109601
+ const evidencePath = path115.join(evidenceDir, evidenceFile);
108745
109602
  try {
108746
109603
  await fs77.promises.mkdir(evidenceDir, { recursive: true });
108747
109604
  await fs77.promises.writeFile(evidencePath, JSON.stringify(result, null, 2));
@@ -109012,7 +109869,7 @@ init_state();
109012
109869
  init_task_id();
109013
109870
  init_create_tool();
109014
109871
  import * as fs78 from "node:fs";
109015
- import * as path115 from "node:path";
109872
+ import * as path116 from "node:path";
109016
109873
  function validateTaskIdFormat2(taskId) {
109017
109874
  return validateTaskIdFormat(taskId);
109018
109875
  }
@@ -109086,8 +109943,8 @@ async function executeDeclareScope(args2, fallbackDir) {
109086
109943
  };
109087
109944
  }
109088
109945
  }
109089
- normalizedDir = path115.normalize(args2.working_directory);
109090
- const pathParts = normalizedDir.split(path115.sep);
109946
+ normalizedDir = path116.normalize(args2.working_directory);
109947
+ const pathParts = normalizedDir.split(path116.sep);
109091
109948
  if (pathParts.includes("..")) {
109092
109949
  return {
109093
109950
  success: false,
@@ -109097,10 +109954,10 @@ async function executeDeclareScope(args2, fallbackDir) {
109097
109954
  ]
109098
109955
  };
109099
109956
  }
109100
- const resolvedDir = path115.resolve(normalizedDir);
109957
+ const resolvedDir = path116.resolve(normalizedDir);
109101
109958
  try {
109102
109959
  const realPath = fs78.realpathSync(resolvedDir);
109103
- const planPath2 = path115.join(realPath, ".swarm", "plan.json");
109960
+ const planPath2 = path116.join(realPath, ".swarm", "plan.json");
109104
109961
  if (!fs78.existsSync(planPath2)) {
109105
109962
  return {
109106
109963
  success: false,
@@ -109121,9 +109978,9 @@ async function executeDeclareScope(args2, fallbackDir) {
109121
109978
  }
109122
109979
  if (normalizedDir && fallbackDir) {
109123
109980
  try {
109124
- const canonicalWorkingDir = fs78.realpathSync(path115.resolve(normalizedDir));
109125
- const canonicalProjectRoot = fs78.realpathSync(path115.resolve(fallbackDir));
109126
- if (canonicalWorkingDir.startsWith(canonicalProjectRoot + path115.sep)) {
109981
+ const canonicalWorkingDir = fs78.realpathSync(path116.resolve(normalizedDir));
109982
+ const canonicalProjectRoot = fs78.realpathSync(path116.resolve(fallbackDir));
109983
+ if (canonicalWorkingDir.startsWith(canonicalProjectRoot + path116.sep)) {
109127
109984
  return {
109128
109985
  success: false,
109129
109986
  message: `working_directory "${normalizedDir}" is a subdirectory of the project root. Use the project root "${fallbackDir}" instead.`,
@@ -109145,7 +110002,7 @@ async function executeDeclareScope(args2, fallbackDir) {
109145
110002
  };
109146
110003
  }
109147
110004
  const directory = normalizedDir || fallbackDir;
109148
- const planPath = path115.resolve(directory, ".swarm", "plan.json");
110005
+ const planPath = path116.resolve(directory, ".swarm", "plan.json");
109149
110006
  if (!fs78.existsSync(planPath)) {
109150
110007
  return {
109151
110008
  success: false,
@@ -109185,8 +110042,8 @@ async function executeDeclareScope(args2, fallbackDir) {
109185
110042
  const normalizeErrors = [];
109186
110043
  const dir = directory;
109187
110044
  const mergedFiles = rawMergedFiles.map((file3) => {
109188
- if (path115.isAbsolute(file3)) {
109189
- const relativePath = path115.relative(dir, file3).replace(/\\/g, "/");
110045
+ if (path116.isAbsolute(file3)) {
110046
+ const relativePath = path116.relative(dir, file3).replace(/\\/g, "/");
109190
110047
  if (relativePath.startsWith("..")) {
109191
110048
  normalizeErrors.push(`Path '${file3}' resolves outside the project directory`);
109192
110049
  return file3;
@@ -109248,7 +110105,7 @@ var declare_scope = createSwarmTool({
109248
110105
  init_zod();
109249
110106
  import * as child_process7 from "node:child_process";
109250
110107
  import * as fs79 from "node:fs";
109251
- import * as path116 from "node:path";
110108
+ import * as path117 from "node:path";
109252
110109
  init_create_tool();
109253
110110
  var MAX_DIFF_LINES = 500;
109254
110111
  var DIFF_TIMEOUT_MS = 30000;
@@ -109277,20 +110134,20 @@ function validateBase(base) {
109277
110134
  function validatePaths(paths) {
109278
110135
  if (!paths)
109279
110136
  return null;
109280
- for (const path117 of paths) {
109281
- if (!path117 || path117.length === 0) {
110137
+ for (const path118 of paths) {
110138
+ if (!path118 || path118.length === 0) {
109282
110139
  return "empty path not allowed";
109283
110140
  }
109284
- if (path117.length > MAX_PATH_LENGTH) {
110141
+ if (path118.length > MAX_PATH_LENGTH) {
109285
110142
  return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
109286
110143
  }
109287
- if (SHELL_METACHARACTERS2.test(path117)) {
110144
+ if (SHELL_METACHARACTERS2.test(path118)) {
109288
110145
  return "path contains shell metacharacters";
109289
110146
  }
109290
- if (path117.startsWith("-")) {
110147
+ if (path118.startsWith("-")) {
109291
110148
  return 'path cannot start with "-" (option-like arguments not allowed)';
109292
110149
  }
109293
- if (CONTROL_CHAR_PATTERN2.test(path117)) {
110150
+ if (CONTROL_CHAR_PATTERN2.test(path118)) {
109294
110151
  return "path contains control characters";
109295
110152
  }
109296
110153
  }
@@ -109398,8 +110255,8 @@ var diff = createSwarmTool({
109398
110255
  if (parts2.length >= 3) {
109399
110256
  const additions = parseInt(parts2[0], 10) || 0;
109400
110257
  const deletions = parseInt(parts2[1], 10) || 0;
109401
- const path117 = parts2[2];
109402
- files.push({ path: path117, additions, deletions });
110258
+ const path118 = parts2[2];
110259
+ files.push({ path: path118, additions, deletions });
109403
110260
  }
109404
110261
  }
109405
110262
  const contractChanges = [];
@@ -109438,7 +110295,7 @@ var diff = createSwarmTool({
109438
110295
  } else if (base === "unstaged") {
109439
110296
  const oldRef = `:${file3.path}`;
109440
110297
  oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
109441
- newContent = fs79.readFileSync(path116.join(directory, file3.path), "utf-8");
110298
+ newContent = fs79.readFileSync(path117.join(directory, file3.path), "utf-8");
109442
110299
  } else {
109443
110300
  const oldRef = `${base}:${file3.path}`;
109444
110301
  oldContent = fileExistsInRef(oldRef) ? getContentFromRef(oldRef) : "";
@@ -109515,12 +110372,12 @@ var diff = createSwarmTool({
109515
110372
  init_zod();
109516
110373
  import * as child_process8 from "node:child_process";
109517
110374
  import * as fs80 from "node:fs";
109518
- import * as path117 from "node:path";
110375
+ import * as path118 from "node:path";
109519
110376
  init_create_tool();
109520
110377
  init_resolve_working_directory();
109521
110378
  async function execGit2(workingDir, args2, options) {
109522
110379
  try {
109523
- const stdout = await new Promise((resolve40, reject) => {
110380
+ const stdout = await new Promise((resolve41, reject) => {
109524
110381
  const execOpts = {
109525
110382
  encoding: "utf-8",
109526
110383
  cwd: workingDir,
@@ -109533,7 +110390,7 @@ async function execGit2(workingDir, args2, options) {
109533
110390
  reject(error93);
109534
110391
  return;
109535
110392
  }
109536
- resolve40(output ?? "");
110393
+ resolve41(output ?? "");
109537
110394
  });
109538
110395
  });
109539
110396
  return stdout;
@@ -109584,7 +110441,7 @@ var diff_summary = createSwarmTool({
109584
110441
  }
109585
110442
  try {
109586
110443
  let oldContent;
109587
- const newContent = await fs80.promises.readFile(path117.join(workingDir, filePath), "utf-8");
110444
+ const newContent = await fs80.promises.readFile(path118.join(workingDir, filePath), "utf-8");
109588
110445
  if (fileExistsInHead) {
109589
110446
  oldContent = await execGit2(workingDir, ["show", `HEAD:${filePath}`], {
109590
110447
  timeout: 5000,
@@ -109814,7 +110671,7 @@ init_zod();
109814
110671
  init_create_tool();
109815
110672
  init_path_security();
109816
110673
  import * as fs81 from "node:fs";
109817
- import * as path118 from "node:path";
110674
+ import * as path119 from "node:path";
109818
110675
  var MAX_FILE_SIZE_BYTES6 = 1024 * 1024;
109819
110676
  var MAX_EVIDENCE_FILES = 1000;
109820
110677
  var EVIDENCE_DIR3 = ".swarm/evidence";
@@ -109841,9 +110698,9 @@ function validateRequiredTypes(input) {
109841
110698
  return null;
109842
110699
  }
109843
110700
  function isPathWithinSwarm2(filePath, cwd) {
109844
- const normalizedCwd = path118.resolve(cwd);
109845
- const swarmPath = path118.join(normalizedCwd, ".swarm");
109846
- const normalizedPath = path118.resolve(filePath);
110701
+ const normalizedCwd = path119.resolve(cwd);
110702
+ const swarmPath = path119.join(normalizedCwd, ".swarm");
110703
+ const normalizedPath = path119.resolve(filePath);
109847
110704
  return normalizedPath.startsWith(swarmPath);
109848
110705
  }
109849
110706
  function parseCompletedTasks(planContent) {
@@ -109873,10 +110730,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
109873
110730
  if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
109874
110731
  continue;
109875
110732
  }
109876
- const filePath = path118.join(evidenceDir, filename);
110733
+ const filePath = path119.join(evidenceDir, filename);
109877
110734
  try {
109878
- const resolvedPath = path118.resolve(filePath);
109879
- const evidenceDirResolved = path118.resolve(evidenceDir);
110735
+ const resolvedPath = path119.resolve(filePath);
110736
+ const evidenceDirResolved = path119.resolve(evidenceDir);
109880
110737
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
109881
110738
  continue;
109882
110739
  }
@@ -109994,7 +110851,7 @@ var evidence_check = createSwarmTool({
109994
110851
  return JSON.stringify(errorResult, null, 2);
109995
110852
  }
109996
110853
  const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
109997
- const planPath = path118.join(cwd, PLAN_FILE);
110854
+ const planPath = path119.join(cwd, PLAN_FILE);
109998
110855
  if (!isPathWithinSwarm2(planPath, cwd)) {
109999
110856
  const errorResult = {
110000
110857
  error: "plan file path validation failed",
@@ -110026,7 +110883,7 @@ var evidence_check = createSwarmTool({
110026
110883
  };
110027
110884
  return JSON.stringify(result2, null, 2);
110028
110885
  }
110029
- const evidenceDir = path118.join(cwd, EVIDENCE_DIR3);
110886
+ const evidenceDir = path119.join(cwd, EVIDENCE_DIR3);
110030
110887
  const evidence = readEvidenceFiles(evidenceDir, cwd);
110031
110888
  const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
110032
110889
  const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
@@ -110045,7 +110902,7 @@ var evidence_check = createSwarmTool({
110045
110902
  init_zod();
110046
110903
  init_create_tool();
110047
110904
  import * as fs82 from "node:fs";
110048
- import * as path119 from "node:path";
110905
+ import * as path120 from "node:path";
110049
110906
  var EXT_MAP = {
110050
110907
  python: ".py",
110051
110908
  py: ".py",
@@ -110126,12 +110983,12 @@ var extract_code_blocks = createSwarmTool({
110126
110983
  if (prefix) {
110127
110984
  filename = `${prefix}_${filename}`;
110128
110985
  }
110129
- let filepath = path119.join(targetDir, filename);
110130
- const base = path119.basename(filepath, path119.extname(filepath));
110131
- const ext = path119.extname(filepath);
110986
+ let filepath = path120.join(targetDir, filename);
110987
+ const base = path120.basename(filepath, path120.extname(filepath));
110988
+ const ext = path120.extname(filepath);
110132
110989
  let counter = 1;
110133
110990
  while (fs82.existsSync(filepath)) {
110134
- filepath = path119.join(targetDir, `${base}_${counter}${ext}`);
110991
+ filepath = path120.join(targetDir, `${base}_${counter}${ext}`);
110135
110992
  counter++;
110136
110993
  }
110137
110994
  try {
@@ -110473,7 +111330,7 @@ init_create_tool();
110473
111330
  var GITINGEST_TIMEOUT_MS = 1e4;
110474
111331
  var GITINGEST_MAX_RESPONSE_BYTES = 5242880;
110475
111332
  var GITINGEST_MAX_RETRIES = 2;
110476
- var delay = (ms) => new Promise((resolve41) => setTimeout(resolve41, ms));
111333
+ var delay = (ms) => new Promise((resolve42) => setTimeout(resolve42, ms));
110477
111334
  async function fetchGitingest(args2) {
110478
111335
  for (let attempt = 0;attempt <= GITINGEST_MAX_RETRIES; attempt++) {
110479
111336
  try {
@@ -110562,7 +111419,7 @@ init_zod();
110562
111419
  init_create_tool();
110563
111420
  init_path_security();
110564
111421
  import * as fs83 from "node:fs";
110565
- import * as path120 from "node:path";
111422
+ import * as path121 from "node:path";
110566
111423
  var MAX_FILE_PATH_LENGTH2 = 500;
110567
111424
  var MAX_SYMBOL_LENGTH = 256;
110568
111425
  var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
@@ -110610,7 +111467,7 @@ function validateSymbolInput(symbol3) {
110610
111467
  return null;
110611
111468
  }
110612
111469
  function isBinaryFile2(filePath, buffer) {
110613
- const ext = path120.extname(filePath).toLowerCase();
111470
+ const ext = path121.extname(filePath).toLowerCase();
110614
111471
  if (ext === ".json" || ext === ".md" || ext === ".txt") {
110615
111472
  return false;
110616
111473
  }
@@ -110634,15 +111491,15 @@ function parseImports(content, targetFile, targetSymbol) {
110634
111491
  const imports = [];
110635
111492
  let _resolvedTarget;
110636
111493
  try {
110637
- _resolvedTarget = path120.resolve(targetFile);
111494
+ _resolvedTarget = path121.resolve(targetFile);
110638
111495
  } catch {
110639
111496
  _resolvedTarget = targetFile;
110640
111497
  }
110641
- const targetBasename = path120.basename(targetFile, path120.extname(targetFile));
111498
+ const targetBasename = path121.basename(targetFile, path121.extname(targetFile));
110642
111499
  const targetWithExt = targetFile;
110643
111500
  const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
110644
- const normalizedTargetWithExt = path120.normalize(targetWithExt).replace(/\\/g, "/");
110645
- const normalizedTargetWithoutExt = path120.normalize(targetWithoutExt).replace(/\\/g, "/");
111501
+ const normalizedTargetWithExt = path121.normalize(targetWithExt).replace(/\\/g, "/");
111502
+ const normalizedTargetWithoutExt = path121.normalize(targetWithoutExt).replace(/\\/g, "/");
110646
111503
  const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
110647
111504
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
110648
111505
  const modulePath = match[1] || match[2] || match[3];
@@ -110665,9 +111522,9 @@ function parseImports(content, targetFile, targetSymbol) {
110665
111522
  }
110666
111523
  const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
110667
111524
  let isMatch = false;
110668
- const _targetDir = path120.dirname(targetFile);
110669
- const targetExt = path120.extname(targetFile);
110670
- const targetBasenameNoExt = path120.basename(targetFile, targetExt);
111525
+ const _targetDir = path121.dirname(targetFile);
111526
+ const targetExt = path121.extname(targetFile);
111527
+ const targetBasenameNoExt = path121.basename(targetFile, targetExt);
110671
111528
  const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
110672
111529
  const moduleName = modulePath.split(/[/\\]/).pop() || "";
110673
111530
  const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
@@ -110735,10 +111592,10 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
110735
111592
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
110736
111593
  for (const entry of entries) {
110737
111594
  if (SKIP_DIRECTORIES4.has(entry)) {
110738
- stats.skippedDirs.push(path120.join(dir, entry));
111595
+ stats.skippedDirs.push(path121.join(dir, entry));
110739
111596
  continue;
110740
111597
  }
110741
- const fullPath = path120.join(dir, entry);
111598
+ const fullPath = path121.join(dir, entry);
110742
111599
  let stat9;
110743
111600
  try {
110744
111601
  stat9 = fs83.statSync(fullPath);
@@ -110752,7 +111609,7 @@ function findSourceFiles2(dir, files = [], stats = { skippedDirs: [], skippedFil
110752
111609
  if (stat9.isDirectory()) {
110753
111610
  findSourceFiles2(fullPath, files, stats);
110754
111611
  } else if (stat9.isFile()) {
110755
- const ext = path120.extname(fullPath).toLowerCase();
111612
+ const ext = path121.extname(fullPath).toLowerCase();
110756
111613
  if (SUPPORTED_EXTENSIONS3.includes(ext)) {
110757
111614
  files.push(fullPath);
110758
111615
  }
@@ -110809,7 +111666,7 @@ var imports = createSwarmTool({
110809
111666
  return JSON.stringify(errorResult, null, 2);
110810
111667
  }
110811
111668
  try {
110812
- const targetFile = path120.resolve(file3);
111669
+ const targetFile = path121.resolve(file3);
110813
111670
  if (!fs83.existsSync(targetFile)) {
110814
111671
  const errorResult = {
110815
111672
  error: `target file not found: ${file3}`,
@@ -110831,7 +111688,7 @@ var imports = createSwarmTool({
110831
111688
  };
110832
111689
  return JSON.stringify(errorResult, null, 2);
110833
111690
  }
110834
- const baseDir = path120.dirname(targetFile);
111691
+ const baseDir = path121.dirname(targetFile);
110835
111692
  const scanStats = {
110836
111693
  skippedDirs: [],
110837
111694
  skippedFiles: 0,
@@ -111219,7 +112076,7 @@ init_zod();
111219
112076
  init_config();
111220
112077
  init_knowledge_store();
111221
112078
  init_create_tool();
111222
- import { existsSync as existsSync68 } from "node:fs";
112079
+ import { existsSync as existsSync69 } from "node:fs";
111223
112080
  var DEFAULT_LIMIT = 10;
111224
112081
  var MAX_LESSON_LENGTH = 200;
111225
112082
  var VALID_CATEGORIES3 = [
@@ -111295,14 +112152,14 @@ function validateLimit(limit) {
111295
112152
  }
111296
112153
  async function readSwarmKnowledge(directory) {
111297
112154
  const swarmPath = resolveSwarmKnowledgePath(directory);
111298
- if (!existsSync68(swarmPath)) {
112155
+ if (!existsSync69(swarmPath)) {
111299
112156
  return [];
111300
112157
  }
111301
112158
  return readKnowledge(swarmPath);
111302
112159
  }
111303
112160
  async function readHiveKnowledge() {
111304
112161
  const hivePath = resolveHiveKnowledgePath();
111305
- if (!existsSync68(hivePath)) {
112162
+ if (!existsSync69(hivePath)) {
111306
112163
  return [];
111307
112164
  }
111308
112165
  return readKnowledge(hivePath);
@@ -111728,11 +112585,11 @@ var lean_turbo_acquire_locks = createSwarmTool({
111728
112585
  init_zod();
111729
112586
  init_constants();
111730
112587
  import * as fs85 from "node:fs";
111731
- import * as path122 from "node:path";
112588
+ import * as path123 from "node:path";
111732
112589
 
111733
112590
  // src/turbo/lean/conflicts.ts
111734
112591
  import * as fs84 from "node:fs";
111735
- import * as path121 from "node:path";
112592
+ import * as path122 from "node:path";
111736
112593
  var DEFAULT_GLOBAL_FILES = [
111737
112594
  "package.json",
111738
112595
  "package-lock.json",
@@ -111835,7 +112692,7 @@ function isGlobalFile(normalizedPath) {
111835
112692
  }
111836
112693
  return false;
111837
112694
  }
111838
- function isProtectedPath2(normalizedPath) {
112695
+ function isProtectedPath3(normalizedPath) {
111839
112696
  const lowerPath = normalizedPath.toLowerCase();
111840
112697
  for (const pattern of DEFAULT_PROTECTED_PATTERNS) {
111841
112698
  if (lowerPath.includes(pattern.toLowerCase())) {
@@ -111859,7 +112716,7 @@ function isProtectedPath2(normalizedPath) {
111859
112716
  return false;
111860
112717
  }
111861
112718
  function readTaskScopes(directory, taskId) {
111862
- const scopePath = path121.join(directory, ".swarm", "scopes", `scope-${taskId}.json`);
112719
+ const scopePath = path122.join(directory, ".swarm", "scopes", `scope-${taskId}.json`);
111863
112720
  try {
111864
112721
  if (!fs84.existsSync(scopePath)) {
111865
112722
  return null;
@@ -111885,7 +112742,7 @@ function assessTaskRisk(files, hasDeclaredScope, hasInvalidScope, config3) {
111885
112742
  files: globalFiles
111886
112743
  };
111887
112744
  }
111888
- const protectedFiles = files.filter(isProtectedPath2);
112745
+ const protectedFiles = files.filter(isProtectedPath3);
111889
112746
  if (protectedFiles.length > 0) {
111890
112747
  return {
111891
112748
  category: "protected",
@@ -112247,7 +113104,7 @@ function createEmptyPlan(phaseNumber, planId) {
112247
113104
  // src/tools/lean-turbo-plan-lanes.ts
112248
113105
  init_create_tool();
112249
113106
  function readPlanJson(directory) {
112250
- const planPath = path122.join(directory, ".swarm", "plan.json");
113107
+ const planPath = path123.join(directory, ".swarm", "plan.json");
112251
113108
  if (!fs85.existsSync(planPath)) {
112252
113109
  return null;
112253
113110
  }
@@ -112303,15 +113160,15 @@ init_config();
112303
113160
  // src/turbo/lean/reviewer.ts
112304
113161
  init_state();
112305
113162
  import * as fs87 from "node:fs/promises";
112306
- import * as path124 from "node:path";
113163
+ import * as path125 from "node:path";
112307
113164
 
112308
113165
  // src/turbo/lean/evidence.ts
112309
113166
  init_bun_compat();
112310
113167
  import { rmSync as rmSync6 } from "node:fs";
112311
113168
  import * as fs86 from "node:fs/promises";
112312
- import * as path123 from "node:path";
113169
+ import * as path124 from "node:path";
112313
113170
  function leanTurboEvidenceDir(directory, phase) {
112314
- return path123.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
113171
+ return path124.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
112315
113172
  }
112316
113173
  function validateLaneId(laneId) {
112317
113174
  if (laneId.length === 0) {
@@ -112333,16 +113190,16 @@ function validateLaneId(laneId) {
112333
113190
  function laneEvidencePath(directory, phase, laneId) {
112334
113191
  validateLaneId(laneId);
112335
113192
  const expectedDir = leanTurboEvidenceDir(directory, phase);
112336
- const resolvedPath = path123.resolve(path123.join(expectedDir, `${laneId}.json`));
112337
- const resolvedDir = path123.resolve(expectedDir);
112338
- if (!resolvedPath.startsWith(resolvedDir + path123.sep) && resolvedPath !== resolvedDir) {
113193
+ const resolvedPath = path124.resolve(path124.join(expectedDir, `${laneId}.json`));
113194
+ const resolvedDir = path124.resolve(expectedDir);
113195
+ if (!resolvedPath.startsWith(resolvedDir + path124.sep) && resolvedPath !== resolvedDir) {
112339
113196
  throw new Error(`Invalid laneId: path traversal detected (got "${laneId}")`);
112340
113197
  }
112341
113198
  return resolvedPath;
112342
113199
  }
112343
113200
  async function atomicWriteJson(filePath, data) {
112344
113201
  const content = JSON.stringify(data, null, 2);
112345
- const dir = path123.dirname(filePath);
113202
+ const dir = path124.dirname(filePath);
112346
113203
  await fs86.mkdir(dir, { recursive: true });
112347
113204
  const tempPath = `${filePath}.tmp.${process.pid}.${Date.now()}.${Math.random().toString(36).slice(2)}`;
112348
113205
  try {
@@ -112356,7 +113213,7 @@ async function atomicWriteJson(filePath, data) {
112356
113213
  }
112357
113214
  }
112358
113215
  function phaseEvidencePath(directory, phase) {
112359
- return path123.join(leanTurboEvidenceDir(directory, phase), "lean-turbo-phase.json");
113216
+ return path124.join(leanTurboEvidenceDir(directory, phase), "lean-turbo-phase.json");
112360
113217
  }
112361
113218
  async function writeLaneEvidence(directory, phase, evidence) {
112362
113219
  const targetPath = laneEvidencePath(directory, phase, evidence.laneId);
@@ -112400,7 +113257,7 @@ async function listLaneEvidence(directory, phase) {
112400
113257
  if (entry === "lean-turbo-phase.json") {
112401
113258
  continue;
112402
113259
  }
112403
- const filePath = path123.join(evidenceDir, entry);
113260
+ const filePath = path124.join(evidenceDir, entry);
112404
113261
  let content;
112405
113262
  try {
112406
113263
  content = await fs86.readFile(filePath, "utf-8");
@@ -112531,9 +113388,9 @@ function parseReviewerVerdict(responseText) {
112531
113388
  return { verdict, reason };
112532
113389
  }
112533
113390
  async function writeReviewerEvidence(directory, phase, verdict, reason) {
112534
- const evidenceDir = path124.join(directory, ".swarm", "evidence", String(phase));
113391
+ const evidenceDir = path125.join(directory, ".swarm", "evidence", String(phase));
112535
113392
  await fs87.mkdir(evidenceDir, { recursive: true });
112536
- const evidencePath = path124.join(evidenceDir, "lean-turbo-reviewer.json");
113393
+ const evidencePath = path125.join(evidenceDir, "lean-turbo-reviewer.json");
112537
113394
  const content = JSON.stringify({
112538
113395
  phase,
112539
113396
  verdict,
@@ -113345,7 +114202,7 @@ init_lint();
113345
114202
  init_spec_schema();
113346
114203
  init_create_tool();
113347
114204
  import * as fs88 from "node:fs";
113348
- import * as path125 from "node:path";
114205
+ import * as path126 from "node:path";
113349
114206
  var SPEC_FILE_NAME = "spec.md";
113350
114207
  var SWARM_DIR2 = ".swarm";
113351
114208
  var OBLIGATION_KEYWORDS = ["MUST", "SHALL", "SHOULD", "MAY"];
@@ -113398,7 +114255,7 @@ var lint_spec = createSwarmTool({
113398
114255
  async execute(_args, directory) {
113399
114256
  const errors5 = [];
113400
114257
  const warnings = [];
113401
- const specPath = path125.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
114258
+ const specPath = path126.join(directory, SWARM_DIR2, SPEC_FILE_NAME);
113402
114259
  if (!fs88.existsSync(specPath)) {
113403
114260
  const result2 = {
113404
114261
  valid: false,
@@ -113470,12 +114327,12 @@ var lint_spec = createSwarmTool({
113470
114327
  // src/tools/mutation-test.ts
113471
114328
  init_zod();
113472
114329
  import * as fs89 from "node:fs";
113473
- import * as path127 from "node:path";
114330
+ import * as path128 from "node:path";
113474
114331
 
113475
114332
  // src/mutation/engine.ts
113476
114333
  import { spawnSync as spawnSync8 } from "node:child_process";
113477
- import { unlinkSync as unlinkSync17, writeFileSync as writeFileSync23 } from "node:fs";
113478
- import * as path126 from "node:path";
114334
+ import { unlinkSync as unlinkSync18, writeFileSync as writeFileSync24 } from "node:fs";
114335
+ import * as path127 from "node:path";
113479
114336
 
113480
114337
  // src/mutation/equivalence.ts
113481
114338
  function isStaticallyEquivalent(originalCode, mutatedCode) {
@@ -113621,9 +114478,9 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
113621
114478
  let patchFile;
113622
114479
  try {
113623
114480
  const safeId2 = patch.id.replace(/[^a-zA-Z0-9_-]/g, "_");
113624
- patchFile = path126.join(workingDir, `.mutation_patch_${safeId2}.diff`);
114481
+ patchFile = path127.join(workingDir, `.mutation_patch_${safeId2}.diff`);
113625
114482
  try {
113626
- writeFileSync23(patchFile, patch.patch);
114483
+ writeFileSync24(patchFile, patch.patch);
113627
114484
  } catch (writeErr) {
113628
114485
  error93 = `Failed to write patch file: ${writeErr}`;
113629
114486
  outcome = "error";
@@ -113719,7 +114576,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
113719
114576
  revertError = new Error(`Failed to revert mutation ${patch.id}: ${revertErr}. Working tree may be dirty.`);
113720
114577
  }
113721
114578
  try {
113722
- unlinkSync17(patchFile);
114579
+ unlinkSync18(patchFile);
113723
114580
  } catch (_unlinkErr) {}
113724
114581
  }
113725
114582
  }
@@ -114025,7 +114882,7 @@ var mutation_test = createSwarmTool({
114025
114882
  ];
114026
114883
  for (const filePath of uniquePaths) {
114027
114884
  try {
114028
- const resolvedPath = path127.resolve(cwd, filePath);
114885
+ const resolvedPath = path128.resolve(cwd, filePath);
114029
114886
  sourceFiles.set(filePath, fs89.readFileSync(resolvedPath, "utf-8"));
114030
114887
  } catch {}
114031
114888
  }
@@ -114047,22 +114904,22 @@ init_config();
114047
114904
  init_schema();
114048
114905
  init_manager2();
114049
114906
  import * as fs99 from "node:fs";
114050
- import * as path137 from "node:path";
114907
+ import * as path138 from "node:path";
114051
114908
 
114052
114909
  // src/full-auto/phase-approval.ts
114053
114910
  init_utils2();
114054
114911
  init_logger();
114055
114912
  init_state2();
114056
114913
  import * as fs90 from "node:fs";
114057
- import * as path128 from "node:path";
114914
+ import * as path129 from "node:path";
114058
114915
  var APPROVAL_TTL_MS = 24 * 60 * 60 * 1000;
114059
114916
  function readEvidenceDir(directory, phase) {
114060
114917
  try {
114061
- const dirPath = validateSwarmPath(directory, path128.posix.join("evidence", String(phase)));
114918
+ const dirPath = validateSwarmPath(directory, path129.posix.join("evidence", String(phase)));
114062
114919
  if (!fs90.existsSync(dirPath))
114063
114920
  return [];
114064
114921
  const entries = fs90.readdirSync(dirPath);
114065
- return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path128.join(dirPath, e));
114922
+ return entries.filter((e) => e.startsWith("full-auto-") && e.endsWith(".json")).map((e) => path129.join(dirPath, e));
114066
114923
  } catch {
114067
114924
  return [];
114068
114925
  }
@@ -114203,16 +115060,16 @@ init_plan_schema();
114203
115060
  init_ledger();
114204
115061
  init_manager();
114205
115062
  import * as fs91 from "node:fs";
114206
- import * as path129 from "node:path";
115063
+ import * as path130 from "node:path";
114207
115064
  async function writeCheckpoint(directory) {
114208
115065
  try {
114209
115066
  const plan = await loadPlan(directory);
114210
115067
  if (!plan)
114211
115068
  return;
114212
- const swarmDir = path129.join(directory, ".swarm");
115069
+ const swarmDir = path130.join(directory, ".swarm");
114213
115070
  fs91.mkdirSync(swarmDir, { recursive: true });
114214
- const jsonPath = path129.join(swarmDir, "SWARM_PLAN.json");
114215
- const mdPath = path129.join(swarmDir, "SWARM_PLAN.md");
115071
+ const jsonPath = path130.join(swarmDir, "SWARM_PLAN.json");
115072
+ const mdPath = path130.join(swarmDir, "SWARM_PLAN.md");
114216
115073
  fs91.writeFileSync(jsonPath, JSON.stringify(plan, null, 2), "utf8");
114217
115074
  const md = derivePlanMarkdown(plan);
114218
115075
  fs91.writeFileSync(mdPath, md, "utf8");
@@ -114231,7 +115088,7 @@ init_telemetry();
114231
115088
  // src/turbo/lean/phase-ready.ts
114232
115089
  init_file_locks();
114233
115090
  import * as fs92 from "node:fs";
114234
- import * as path130 from "node:path";
115091
+ import * as path131 from "node:path";
114235
115092
  init_state3();
114236
115093
  var DEFAULT_CONFIG3 = {
114237
115094
  phase_reviewer: true,
@@ -114240,7 +115097,7 @@ var DEFAULT_CONFIG3 = {
114240
115097
  };
114241
115098
  function defaultReadPlanJson(dir) {
114242
115099
  try {
114243
- const planPath = path130.join(dir, ".swarm", "plan.json");
115100
+ const planPath = path131.join(dir, ".swarm", "plan.json");
114244
115101
  if (!fs92.existsSync(planPath))
114245
115102
  return null;
114246
115103
  const raw = fs92.readFileSync(planPath, "utf-8");
@@ -114255,7 +115112,7 @@ function defaultReadPlanJson(dir) {
114255
115112
  }
114256
115113
  function readReviewerEvidenceFromFile(directory, phase) {
114257
115114
  try {
114258
- const evidencePath = path130.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
115115
+ const evidencePath = path131.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-reviewer.json");
114259
115116
  if (!fs92.existsSync(evidencePath)) {
114260
115117
  return null;
114261
115118
  }
@@ -114275,7 +115132,7 @@ function readReviewerEvidenceFromFile(directory, phase) {
114275
115132
  }
114276
115133
  function readCriticEvidenceFromFile(directory, phase) {
114277
115134
  try {
114278
- const evidencePath = path130.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
115135
+ const evidencePath = path131.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-critic.json");
114279
115136
  if (!fs92.existsSync(evidencePath)) {
114280
115137
  return null;
114281
115138
  }
@@ -114294,7 +115151,7 @@ function readCriticEvidenceFromFile(directory, phase) {
114294
115151
  }
114295
115152
  }
114296
115153
  function listLaneEvidenceSync(directory, phase) {
114297
- const evidenceDir = path130.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
115154
+ const evidenceDir = path131.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
114298
115155
  let entries;
114299
115156
  try {
114300
115157
  entries = fs92.readdirSync(evidenceDir);
@@ -114364,7 +115221,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
114364
115221
  ...DEFAULT_CONFIG3,
114365
115222
  ...actualConfig
114366
115223
  };
114367
- const statePath = path130.join(directory, ".swarm", "turbo-state.json");
115224
+ const statePath = path131.join(directory, ".swarm", "turbo-state.json");
114368
115225
  if (!fs92.existsSync(statePath)) {
114369
115226
  return {
114370
115227
  ok: false,
@@ -114552,7 +115409,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
114552
115409
  }
114553
115410
  }
114554
115411
  if (mergedConfig.integrated_diff_required) {
114555
- const evidencePath = path130.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
115412
+ const evidencePath = path131.join(directory, ".swarm", "evidence", String(phase), "lean-turbo-phase.json");
114556
115413
  let hasDiff = false;
114557
115414
  try {
114558
115415
  const content = fs92.readFileSync(evidencePath, "utf-8");
@@ -114704,13 +115561,13 @@ init_qa_gate_profile();
114704
115561
  init_manager();
114705
115562
  init_state();
114706
115563
  import * as fs93 from "node:fs";
114707
- import * as path131 from "node:path";
115564
+ import * as path132 from "node:path";
114708
115565
  async function runDriftGate(ctx) {
114709
115566
  const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
114710
115567
  let driftCheckEnabled = true;
114711
115568
  let driftHasSpecMd = false;
114712
115569
  try {
114713
- const specMdPath = path131.join(dir, ".swarm", "spec.md");
115570
+ const specMdPath = path132.join(dir, ".swarm", "spec.md");
114714
115571
  driftHasSpecMd = fs93.existsSync(specMdPath);
114715
115572
  const gatePlan = await loadPlan(dir);
114716
115573
  if (gatePlan) {
@@ -114738,7 +115595,7 @@ async function runDriftGate(ctx) {
114738
115595
  }
114739
115596
  let phaseType;
114740
115597
  try {
114741
- const planPath = path131.join(dir, ".swarm", "plan.json");
115598
+ const planPath = path132.join(dir, ".swarm", "plan.json");
114742
115599
  if (fs93.existsSync(planPath)) {
114743
115600
  const planRaw = fs93.readFileSync(planPath, "utf-8");
114744
115601
  const plan = JSON.parse(planRaw);
@@ -114757,7 +115614,7 @@ async function runDriftGate(ctx) {
114757
115614
  };
114758
115615
  }
114759
115616
  try {
114760
- const driftEvidencePath = path131.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
115617
+ const driftEvidencePath = path132.join(dir, ".swarm", "evidence", String(phase), "drift-verifier.json");
114761
115618
  let driftVerdictFound = false;
114762
115619
  let driftVerdictApproved = false;
114763
115620
  try {
@@ -114793,7 +115650,7 @@ async function runDriftGate(ctx) {
114793
115650
  let incompleteTaskCount = 0;
114794
115651
  let planParseable = false;
114795
115652
  try {
114796
- const planPath = path131.join(dir, ".swarm", "plan.json");
115653
+ const planPath = path132.join(dir, ".swarm", "plan.json");
114797
115654
  if (fs93.existsSync(planPath)) {
114798
115655
  const planRaw = fs93.readFileSync(planPath, "utf-8");
114799
115656
  const plan = JSON.parse(planRaw);
@@ -114875,7 +115732,7 @@ init_qa_gate_profile();
114875
115732
  init_manager();
114876
115733
  init_state();
114877
115734
  import * as fs94 from "node:fs";
114878
- import * as path132 from "node:path";
115735
+ import * as path133 from "node:path";
114879
115736
  async function runFinalCouncilGate(ctx) {
114880
115737
  const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
114881
115738
  let finalCouncilEnabled = false;
@@ -114892,7 +115749,7 @@ async function runFinalCouncilGate(ctx) {
114892
115749
  const effective = getEffectiveGates(profile, overrides);
114893
115750
  if (effective.final_council === true) {
114894
115751
  finalCouncilEnabled = true;
114895
- const fcPath = path132.join(dir, ".swarm", "evidence", "final-council.json");
115752
+ const fcPath = path133.join(dir, ".swarm", "evidence", "final-council.json");
114896
115753
  let fcVerdictFound = false;
114897
115754
  let _fcVerdict;
114898
115755
  try {
@@ -115022,7 +115879,7 @@ init_qa_gate_profile();
115022
115879
  init_manager();
115023
115880
  init_state();
115024
115881
  import * as fs95 from "node:fs";
115025
- import * as path133 from "node:path";
115882
+ import * as path134 from "node:path";
115026
115883
  async function runHallucinationGate(ctx) {
115027
115884
  const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
115028
115885
  try {
@@ -115035,7 +115892,7 @@ async function runHallucinationGate(ctx) {
115035
115892
  const overrides = session?.qaGateSessionOverrides ?? {};
115036
115893
  const effective = getEffectiveGates(profile, overrides);
115037
115894
  if (effective.hallucination_guard === true) {
115038
- const hgPath = path133.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
115895
+ const hgPath = path134.join(dir, ".swarm", "evidence", String(phase), "hallucination-guard.json");
115039
115896
  let hgVerdictFound = false;
115040
115897
  let hgVerdictApproved = false;
115041
115898
  try {
@@ -115098,7 +115955,7 @@ init_qa_gate_profile();
115098
115955
  init_manager();
115099
115956
  init_state();
115100
115957
  import * as fs96 from "node:fs";
115101
- import * as path134 from "node:path";
115958
+ import * as path135 from "node:path";
115102
115959
  async function runMutationGate(ctx) {
115103
115960
  const { phase, dir, sessionID, agentsDispatched, safeWarn } = ctx;
115104
115961
  try {
@@ -115111,7 +115968,7 @@ async function runMutationGate(ctx) {
115111
115968
  const overrides = session?.qaGateSessionOverrides ?? {};
115112
115969
  const effective = getEffectiveGates(profile, overrides);
115113
115970
  if (effective.mutation_test === true) {
115114
- const mgPath = path134.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
115971
+ const mgPath = path135.join(dir, ".swarm", "evidence", String(phase), "mutation-gate.json");
115115
115972
  let mgVerdictFound = false;
115116
115973
  let mgVerdict;
115117
115974
  try {
@@ -115174,7 +116031,7 @@ init_qa_gate_profile();
115174
116031
  init_manager();
115175
116032
  init_state();
115176
116033
  import * as fs97 from "node:fs";
115177
- import * as path135 from "node:path";
116034
+ import * as path136 from "node:path";
115178
116035
  async function runPhaseCouncilGate(ctx) {
115179
116036
  const { phase, dir, sessionID, pluginConfig, agentsDispatched, safeWarn } = ctx;
115180
116037
  let councilModeEnabled = false;
@@ -115189,7 +116046,7 @@ async function runPhaseCouncilGate(ctx) {
115189
116046
  const effective = getEffectiveGates(profile, overrides);
115190
116047
  if (effective.council_mode === true) {
115191
116048
  councilModeEnabled = true;
115192
- const pcPath = path135.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
116049
+ const pcPath = path136.join(dir, ".swarm", "evidence", String(phase), "phase-council.json");
115193
116050
  let pcVerdictFound = false;
115194
116051
  let _pcVerdict;
115195
116052
  let pcQuorumSize;
@@ -115704,7 +116561,7 @@ async function executePhaseComplete(args2, workingDirectory, directory) {
115704
116561
  }
115705
116562
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
115706
116563
  try {
115707
- const projectName = path137.basename(dir);
116564
+ const projectName = path138.basename(dir);
115708
116565
  const curationResult = await curateAndStoreSwarm(retroEntry.lessons_learned, projectName, { phase_number: phase }, dir, knowledgeConfig);
115709
116566
  if (curationResult) {
115710
116567
  const sessionState = swarmState.agentSessions.get(sessionID);
@@ -116147,7 +117004,7 @@ init_utils();
116147
117004
  init_bun_compat();
116148
117005
  init_create_tool();
116149
117006
  import * as fs100 from "node:fs";
116150
- import * as path138 from "node:path";
117007
+ import * as path139 from "node:path";
116151
117008
  var MAX_OUTPUT_BYTES6 = 52428800;
116152
117009
  var AUDIT_TIMEOUT_MS = 120000;
116153
117010
  function isValidEcosystem(value) {
@@ -116175,16 +117032,16 @@ function validateArgs3(args2) {
116175
117032
  function detectEcosystems(directory) {
116176
117033
  const ecosystems = [];
116177
117034
  const cwd = directory;
116178
- if (fs100.existsSync(path138.join(cwd, "package.json"))) {
117035
+ if (fs100.existsSync(path139.join(cwd, "package.json"))) {
116179
117036
  ecosystems.push("npm");
116180
117037
  }
116181
- if (fs100.existsSync(path138.join(cwd, "pyproject.toml")) || fs100.existsSync(path138.join(cwd, "requirements.txt"))) {
117038
+ if (fs100.existsSync(path139.join(cwd, "pyproject.toml")) || fs100.existsSync(path139.join(cwd, "requirements.txt"))) {
116182
117039
  ecosystems.push("pip");
116183
117040
  }
116184
- if (fs100.existsSync(path138.join(cwd, "Cargo.toml"))) {
117041
+ if (fs100.existsSync(path139.join(cwd, "Cargo.toml"))) {
116185
117042
  ecosystems.push("cargo");
116186
117043
  }
116187
- if (fs100.existsSync(path138.join(cwd, "go.mod"))) {
117044
+ if (fs100.existsSync(path139.join(cwd, "go.mod"))) {
116188
117045
  ecosystems.push("go");
116189
117046
  }
116190
117047
  try {
@@ -116193,13 +117050,13 @@ function detectEcosystems(directory) {
116193
117050
  ecosystems.push("dotnet");
116194
117051
  }
116195
117052
  } catch {}
116196
- if (fs100.existsSync(path138.join(cwd, "Gemfile")) || fs100.existsSync(path138.join(cwd, "Gemfile.lock"))) {
117053
+ if (fs100.existsSync(path139.join(cwd, "Gemfile")) || fs100.existsSync(path139.join(cwd, "Gemfile.lock"))) {
116197
117054
  ecosystems.push("ruby");
116198
117055
  }
116199
- if (fs100.existsSync(path138.join(cwd, "pubspec.yaml"))) {
117056
+ if (fs100.existsSync(path139.join(cwd, "pubspec.yaml"))) {
116200
117057
  ecosystems.push("dart");
116201
117058
  }
116202
- if (fs100.existsSync(path138.join(cwd, "composer.lock"))) {
117059
+ if (fs100.existsSync(path139.join(cwd, "composer.lock"))) {
116203
117060
  ecosystems.push("composer");
116204
117061
  }
116205
117062
  return ecosystems;
@@ -116212,7 +117069,7 @@ async function runNpmAudit(directory) {
116212
117069
  stderr: "pipe",
116213
117070
  cwd: directory
116214
117071
  });
116215
- const timeoutPromise = new Promise((resolve45) => setTimeout(() => resolve45("timeout"), AUDIT_TIMEOUT_MS));
117072
+ const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
116216
117073
  const result = await Promise.race([
116217
117074
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
116218
117075
  timeoutPromise
@@ -116332,7 +117189,7 @@ async function runPipAudit(directory) {
116332
117189
  stderr: "pipe",
116333
117190
  cwd: directory
116334
117191
  });
116335
- const timeoutPromise = new Promise((resolve45) => setTimeout(() => resolve45("timeout"), AUDIT_TIMEOUT_MS));
117192
+ const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
116336
117193
  const result = await Promise.race([
116337
117194
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr2]) => ({ stdout: stdout2, stderr: stderr2 })),
116338
117195
  timeoutPromise
@@ -116460,7 +117317,7 @@ async function runCargoAudit(directory) {
116460
117317
  stderr: "pipe",
116461
117318
  cwd: directory
116462
117319
  });
116463
- const timeoutPromise = new Promise((resolve45) => setTimeout(() => resolve45("timeout"), AUDIT_TIMEOUT_MS));
117320
+ const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
116464
117321
  const result = await Promise.race([
116465
117322
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
116466
117323
  timeoutPromise
@@ -116584,7 +117441,7 @@ async function runGoAudit(directory) {
116584
117441
  stderr: "pipe",
116585
117442
  cwd: directory
116586
117443
  });
116587
- const timeoutPromise = new Promise((resolve45) => setTimeout(() => resolve45("timeout"), AUDIT_TIMEOUT_MS));
117444
+ const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
116588
117445
  const result = await Promise.race([
116589
117446
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
116590
117447
  timeoutPromise
@@ -116717,7 +117574,7 @@ async function runDotnetAudit(directory) {
116717
117574
  stderr: "pipe",
116718
117575
  cwd: directory
116719
117576
  });
116720
- const timeoutPromise = new Promise((resolve45) => setTimeout(() => resolve45("timeout"), AUDIT_TIMEOUT_MS));
117577
+ const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
116721
117578
  const result = await Promise.race([
116722
117579
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
116723
117580
  timeoutPromise
@@ -116833,7 +117690,7 @@ async function runBundleAudit(directory) {
116833
117690
  stderr: "pipe",
116834
117691
  cwd: directory
116835
117692
  });
116836
- const timeoutPromise = new Promise((resolve45) => setTimeout(() => resolve45("timeout"), AUDIT_TIMEOUT_MS));
117693
+ const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
116837
117694
  const result = await Promise.race([
116838
117695
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
116839
117696
  timeoutPromise
@@ -116978,7 +117835,7 @@ async function runDartAudit(directory) {
116978
117835
  stderr: "pipe",
116979
117836
  cwd: directory
116980
117837
  });
116981
- const timeoutPromise = new Promise((resolve45) => setTimeout(() => resolve45("timeout"), AUDIT_TIMEOUT_MS));
117838
+ const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
116982
117839
  const result = await Promise.race([
116983
117840
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
116984
117841
  timeoutPromise
@@ -117093,7 +117950,7 @@ async function runComposerAudit(directory) {
117093
117950
  stderr: "pipe",
117094
117951
  cwd: directory
117095
117952
  });
117096
- const timeoutPromise = new Promise((resolve45) => setTimeout(() => resolve45("timeout"), AUDIT_TIMEOUT_MS));
117953
+ const timeoutPromise = new Promise((resolve46) => setTimeout(() => resolve46("timeout"), AUDIT_TIMEOUT_MS));
117097
117954
  const result = await Promise.race([
117098
117955
  Promise.all([proc.stdout.text(), proc.stderr.text()]).then(([stdout2, stderr]) => ({ stdout: stdout2, stderr })),
117099
117956
  timeoutPromise
@@ -117336,7 +118193,7 @@ var pkg_audit = createSwarmTool({
117336
118193
  init_zod();
117337
118194
  init_manager2();
117338
118195
  import * as fs101 from "node:fs";
117339
- import * as path139 from "node:path";
118196
+ import * as path140 from "node:path";
117340
118197
  init_utils();
117341
118198
  init_create_tool();
117342
118199
  var MAX_FILE_SIZE = 1024 * 1024;
@@ -117459,7 +118316,7 @@ function isScaffoldFile(filePath) {
117459
118316
  if (SCAFFOLD_PATH_PATTERNS.some((pattern) => pattern.test(normalizedPath))) {
117460
118317
  return true;
117461
118318
  }
117462
- const filename = path139.basename(filePath);
118319
+ const filename = path140.basename(filePath);
117463
118320
  if (SCAFFOLD_FILENAME_PATTERNS.some((pattern) => pattern.test(filename))) {
117464
118321
  return true;
117465
118322
  }
@@ -117476,7 +118333,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
117476
118333
  if (regex.test(normalizedPath)) {
117477
118334
  return true;
117478
118335
  }
117479
- const filename = path139.basename(filePath);
118336
+ const filename = path140.basename(filePath);
117480
118337
  const filenameRegex = new RegExp(`^${regexPattern}$`, "i");
117481
118338
  if (filenameRegex.test(filename)) {
117482
118339
  return true;
@@ -117485,7 +118342,7 @@ function isAllowedByGlobs(filePath, allowGlobs) {
117485
118342
  return false;
117486
118343
  }
117487
118344
  function isParserSupported(filePath) {
117488
- const ext = path139.extname(filePath).toLowerCase();
118345
+ const ext = path140.extname(filePath).toLowerCase();
117489
118346
  return SUPPORTED_PARSER_EXTENSIONS.has(ext);
117490
118347
  }
117491
118348
  function isPlanFile(filePath) {
@@ -117732,9 +118589,9 @@ async function placeholderScan(input, directory) {
117732
118589
  let filesScanned = 0;
117733
118590
  const filesWithFindings = new Set;
117734
118591
  for (const filePath of changed_files) {
117735
- const fullPath = path139.isAbsolute(filePath) ? filePath : path139.resolve(directory, filePath);
117736
- const resolvedDirectory = path139.resolve(directory);
117737
- if (!fullPath.startsWith(resolvedDirectory + path139.sep) && fullPath !== resolvedDirectory) {
118592
+ const fullPath = path140.isAbsolute(filePath) ? filePath : path140.resolve(directory, filePath);
118593
+ const resolvedDirectory = path140.resolve(directory);
118594
+ if (!fullPath.startsWith(resolvedDirectory + path140.sep) && fullPath !== resolvedDirectory) {
117738
118595
  continue;
117739
118596
  }
117740
118597
  if (!fs101.existsSync(fullPath)) {
@@ -117743,7 +118600,7 @@ async function placeholderScan(input, directory) {
117743
118600
  if (isAllowedByGlobs(filePath, allow_globs)) {
117744
118601
  continue;
117745
118602
  }
117746
- const relativeFilePath = path139.relative(directory, fullPath).replace(/\\/g, "/");
118603
+ const relativeFilePath = path140.relative(directory, fullPath).replace(/\\/g, "/");
117747
118604
  if (FILE_ALLOWLIST.some((allowed) => relativeFilePath.endsWith(allowed))) {
117748
118605
  continue;
117749
118606
  }
@@ -117816,7 +118673,7 @@ var placeholder_scan = createSwarmTool({
117816
118673
 
117817
118674
  // src/tools/pre-check-batch.ts
117818
118675
  import * as fs105 from "node:fs";
117819
- import * as path143 from "node:path";
118676
+ import * as path144 from "node:path";
117820
118677
  init_zod();
117821
118678
  init_manager2();
117822
118679
  init_utils();
@@ -117957,7 +118814,7 @@ init_zod();
117957
118814
  init_manager2();
117958
118815
  init_detector();
117959
118816
  import * as fs104 from "node:fs";
117960
- import * as path142 from "node:path";
118817
+ import * as path143 from "node:path";
117961
118818
  import { extname as extname20 } from "node:path";
117962
118819
 
117963
118820
  // src/sast/rules/c.ts
@@ -118673,7 +119530,7 @@ function executeRulesSync(filePath, content, language) {
118673
119530
  // src/sast/semgrep.ts
118674
119531
  import * as child_process9 from "node:child_process";
118675
119532
  import * as fs102 from "node:fs";
118676
- import * as path140 from "node:path";
119533
+ import * as path141 from "node:path";
118677
119534
  var semgrepAvailableCache = null;
118678
119535
  var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
118679
119536
  var DEFAULT_TIMEOUT_MS3 = 30000;
@@ -118754,7 +119611,7 @@ function mapSemgrepSeverity(severity) {
118754
119611
  }
118755
119612
  }
118756
119613
  async function executeWithTimeout(command, args2, options) {
118757
- return new Promise((resolve47) => {
119614
+ return new Promise((resolve48) => {
118758
119615
  const child = child_process9.spawn(command, args2, {
118759
119616
  shell: false,
118760
119617
  cwd: options.cwd
@@ -118763,7 +119620,7 @@ async function executeWithTimeout(command, args2, options) {
118763
119620
  let stderr = "";
118764
119621
  const timeout = setTimeout(() => {
118765
119622
  child.kill("SIGTERM");
118766
- resolve47({
119623
+ resolve48({
118767
119624
  stdout,
118768
119625
  stderr: "Process timed out",
118769
119626
  exitCode: 124
@@ -118777,7 +119634,7 @@ async function executeWithTimeout(command, args2, options) {
118777
119634
  });
118778
119635
  child.on("close", (code) => {
118779
119636
  clearTimeout(timeout);
118780
- resolve47({
119637
+ resolve48({
118781
119638
  stdout,
118782
119639
  stderr,
118783
119640
  exitCode: code ?? 0
@@ -118785,7 +119642,7 @@ async function executeWithTimeout(command, args2, options) {
118785
119642
  });
118786
119643
  child.on("error", (err2) => {
118787
119644
  clearTimeout(timeout);
118788
- resolve47({
119645
+ resolve48({
118789
119646
  stdout,
118790
119647
  stderr: err2.message,
118791
119648
  exitCode: 1
@@ -118860,7 +119717,7 @@ async function runSemgrep(options) {
118860
119717
  }
118861
119718
  function getRulesDirectory(projectRoot) {
118862
119719
  if (projectRoot) {
118863
- return path140.resolve(projectRoot, DEFAULT_RULES_DIR);
119720
+ return path141.resolve(projectRoot, DEFAULT_RULES_DIR);
118864
119721
  }
118865
119722
  return DEFAULT_RULES_DIR;
118866
119723
  }
@@ -118881,24 +119738,24 @@ init_create_tool();
118881
119738
  init_utils2();
118882
119739
  import * as crypto11 from "node:crypto";
118883
119740
  import * as fs103 from "node:fs";
118884
- import * as path141 from "node:path";
119741
+ import * as path142 from "node:path";
118885
119742
  var BASELINE_SCHEMA_VERSION = "1.0.0";
118886
119743
  var MAX_BASELINE_FINDINGS = 2000;
118887
119744
  var MAX_BASELINE_BYTES = 2 * 1048576;
118888
119745
  var LOCK_RETRY_DELAYS_MS = [50, 100, 200, 400, 800];
118889
119746
  function normalizeFindingPath(directory, file3) {
118890
- const resolved = path141.isAbsolute(file3) ? file3 : path141.resolve(directory, file3);
118891
- const rel = path141.relative(path141.resolve(directory), resolved);
119747
+ const resolved = path142.isAbsolute(file3) ? file3 : path142.resolve(directory, file3);
119748
+ const rel = path142.relative(path142.resolve(directory), resolved);
118892
119749
  return rel.replace(/\\/g, "/");
118893
119750
  }
118894
119751
  function baselineRelPath(phase) {
118895
- return path141.join("evidence", String(phase), "sast-baseline.json");
119752
+ return path142.join("evidence", String(phase), "sast-baseline.json");
118896
119753
  }
118897
119754
  function tempRelPath(phase) {
118898
- return path141.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
119755
+ return path142.join("evidence", String(phase), `sast-baseline.json.tmp.${Date.now()}.${process.pid}`);
118899
119756
  }
118900
119757
  function lockRelPath(phase) {
118901
- return path141.join("evidence", String(phase), "sast-baseline.json.lock");
119758
+ return path142.join("evidence", String(phase), "sast-baseline.json.lock");
118902
119759
  }
118903
119760
  function getLine(lines, idx) {
118904
119761
  if (idx < 0 || idx >= lines.length)
@@ -118984,7 +119841,7 @@ async function acquireLock2(lockPath) {
118984
119841
  };
118985
119842
  } catch {
118986
119843
  if (attempt < LOCK_RETRY_DELAYS_MS.length) {
118987
- await new Promise((resolve48) => setTimeout(resolve48, LOCK_RETRY_DELAYS_MS[attempt]));
119844
+ await new Promise((resolve49) => setTimeout(resolve49, LOCK_RETRY_DELAYS_MS[attempt]));
118988
119845
  }
118989
119846
  }
118990
119847
  }
@@ -119019,8 +119876,8 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
119019
119876
  message: e instanceof Error ? e.message : "Path validation failed"
119020
119877
  };
119021
119878
  }
119022
- fs103.mkdirSync(path141.dirname(baselinePath), { recursive: true });
119023
- fs103.mkdirSync(path141.dirname(tempPath), { recursive: true });
119879
+ fs103.mkdirSync(path142.dirname(baselinePath), { recursive: true });
119880
+ fs103.mkdirSync(path142.dirname(tempPath), { recursive: true });
119024
119881
  const releaseLock = await acquireLock2(lockPath);
119025
119882
  try {
119026
119883
  let existing = null;
@@ -119293,9 +120150,9 @@ async function sastScan(input, directory, config3) {
119293
120150
  _filesSkipped++;
119294
120151
  continue;
119295
120152
  }
119296
- const resolvedPath = path142.isAbsolute(filePath) ? filePath : path142.resolve(directory, filePath);
119297
- const resolvedDirectory = path142.resolve(directory);
119298
- if (!resolvedPath.startsWith(resolvedDirectory + path142.sep) && resolvedPath !== resolvedDirectory) {
120153
+ const resolvedPath = path143.isAbsolute(filePath) ? filePath : path143.resolve(directory, filePath);
120154
+ const resolvedDirectory = path143.resolve(directory);
120155
+ if (!resolvedPath.startsWith(resolvedDirectory + path143.sep) && resolvedPath !== resolvedDirectory) {
119299
120156
  _filesSkipped++;
119300
120157
  continue;
119301
120158
  }
@@ -119610,20 +120467,20 @@ function validatePath(inputPath, baseDir, workspaceDir) {
119610
120467
  let resolved;
119611
120468
  const isWinAbs = isWindowsAbsolutePath(inputPath);
119612
120469
  if (isWinAbs) {
119613
- resolved = path143.win32.resolve(inputPath);
119614
- } else if (path143.isAbsolute(inputPath)) {
119615
- resolved = path143.resolve(inputPath);
120470
+ resolved = path144.win32.resolve(inputPath);
120471
+ } else if (path144.isAbsolute(inputPath)) {
120472
+ resolved = path144.resolve(inputPath);
119616
120473
  } else {
119617
- resolved = path143.resolve(baseDir, inputPath);
120474
+ resolved = path144.resolve(baseDir, inputPath);
119618
120475
  }
119619
- const workspaceResolved = path143.resolve(workspaceDir);
119620
- let relative27;
120476
+ const workspaceResolved = path144.resolve(workspaceDir);
120477
+ let relative28;
119621
120478
  if (isWinAbs) {
119622
- relative27 = path143.win32.relative(workspaceResolved, resolved);
120479
+ relative28 = path144.win32.relative(workspaceResolved, resolved);
119623
120480
  } else {
119624
- relative27 = path143.relative(workspaceResolved, resolved);
120481
+ relative28 = path144.relative(workspaceResolved, resolved);
119625
120482
  }
119626
- if (relative27.startsWith("..")) {
120483
+ if (relative28.startsWith("..")) {
119627
120484
  return "path traversal detected";
119628
120485
  }
119629
120486
  return null;
@@ -119686,7 +120543,7 @@ async function runLintOnFiles(linter, files, workspaceDir) {
119686
120543
  if (typeof file3 !== "string") {
119687
120544
  continue;
119688
120545
  }
119689
- const resolvedPath = path143.resolve(file3);
120546
+ const resolvedPath = path144.resolve(file3);
119690
120547
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
119691
120548
  if (validationError) {
119692
120549
  continue;
@@ -119843,7 +120700,7 @@ async function runSecretscanWithFiles(files, directory) {
119843
120700
  skippedFiles++;
119844
120701
  continue;
119845
120702
  }
119846
- const resolvedPath = path143.resolve(file3);
120703
+ const resolvedPath = path144.resolve(file3);
119847
120704
  const validationError = validatePath(resolvedPath, directory, directory);
119848
120705
  if (validationError) {
119849
120706
  skippedFiles++;
@@ -119861,7 +120718,7 @@ async function runSecretscanWithFiles(files, directory) {
119861
120718
  };
119862
120719
  }
119863
120720
  for (const file3 of validatedFiles) {
119864
- const ext = path143.extname(file3).toLowerCase();
120721
+ const ext = path144.extname(file3).toLowerCase();
119865
120722
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
119866
120723
  skippedFiles++;
119867
120724
  continue;
@@ -120080,7 +120937,7 @@ function classifySastFindings(findings, changedLineRanges, directory) {
120080
120937
  const preexistingFindings = [];
120081
120938
  for (const finding of findings) {
120082
120939
  const filePath = finding.location.file;
120083
- const normalised = path143.relative(directory, filePath).replace(/\\/g, "/");
120940
+ const normalised = path144.relative(directory, filePath).replace(/\\/g, "/");
120084
120941
  const changedLines = changedLineRanges.get(normalised);
120085
120942
  if (changedLines?.has(finding.location.line)) {
120086
120943
  newFindings.push(finding);
@@ -120131,7 +120988,7 @@ async function runPreCheckBatch(input, workspaceDir, contextDir) {
120131
120988
  warn(`pre_check_batch: Invalid file path: ${file3}`);
120132
120989
  continue;
120133
120990
  }
120134
- changedFiles.push(path143.resolve(directory, file3));
120991
+ changedFiles.push(path144.resolve(directory, file3));
120135
120992
  }
120136
120993
  if (changedFiles.length === 0) {
120137
120994
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -120332,9 +121189,9 @@ var pre_check_batch = createSwarmTool({
120332
121189
  };
120333
121190
  return JSON.stringify(errorResult, null, 2);
120334
121191
  }
120335
- const resolvedDirectory = path143.resolve(typedArgs.directory);
120336
- const workspaceAnchor = path143.resolve(directory);
120337
- if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path143.sep)) {
121192
+ const resolvedDirectory = path144.resolve(typedArgs.directory);
121193
+ const workspaceAnchor = path144.resolve(directory);
121194
+ if (resolvedDirectory !== workspaceAnchor && resolvedDirectory.startsWith(workspaceAnchor + path144.sep)) {
120338
121195
  const subDirError = `directory "${typedArgs.directory}" is a subdirectory of the project root — pre_check_batch requires the project root directory "${workspaceAnchor}"`;
120339
121196
  const subDirResult = {
120340
121197
  gates_passed: false,
@@ -120386,7 +121243,7 @@ var pre_check_batch = createSwarmTool({
120386
121243
 
120387
121244
  // src/tools/repo-map.ts
120388
121245
  init_zod();
120389
- import * as path144 from "node:path";
121246
+ import * as path145 from "node:path";
120390
121247
  init_path_security();
120391
121248
  init_create_tool();
120392
121249
  var VALID_ACTIONS = [
@@ -120411,7 +121268,7 @@ function validateFile(p) {
120411
121268
  return "file contains control characters";
120412
121269
  if (containsPathTraversal(p))
120413
121270
  return "file contains path traversal";
120414
- if (path144.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
121271
+ if (path145.isAbsolute(p) || /^[a-zA-Z]:[\\/]/.test(p)) {
120415
121272
  return "file must be a workspace-relative path, not absolute";
120416
121273
  }
120417
121274
  return null;
@@ -120434,8 +121291,8 @@ function ok(action, payload) {
120434
121291
  }
120435
121292
  function toRelativeGraphPath(input, workspaceRoot) {
120436
121293
  const normalized = input.replace(/\\/g, "/");
120437
- if (path144.isAbsolute(normalized)) {
120438
- const rel = path144.relative(workspaceRoot, normalized).replace(/\\/g, "/");
121294
+ if (path145.isAbsolute(normalized)) {
121295
+ const rel = path145.relative(workspaceRoot, normalized).replace(/\\/g, "/");
120439
121296
  return normalizeGraphPath2(rel);
120440
121297
  }
120441
121298
  return normalizeGraphPath2(normalized);
@@ -120581,7 +121438,7 @@ var repo_map = createSwarmTool({
120581
121438
  init_zod();
120582
121439
  init_create_tool();
120583
121440
  import * as fs106 from "node:fs";
120584
- import * as path145 from "node:path";
121441
+ import * as path146 from "node:path";
120585
121442
  var SPEC_FILE = ".swarm/spec.md";
120586
121443
  var EVIDENCE_DIR4 = ".swarm/evidence";
120587
121444
  var OBLIGATION_KEYWORDS2 = ["MUST", "SHOULD", "SHALL"];
@@ -120650,7 +121507,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
120650
121507
  return [];
120651
121508
  }
120652
121509
  for (const entry of entries) {
120653
- const entryPath = path145.join(evidenceDir, entry);
121510
+ const entryPath = path146.join(evidenceDir, entry);
120654
121511
  try {
120655
121512
  const stat9 = fs106.statSync(entryPath);
120656
121513
  if (!stat9.isDirectory()) {
@@ -120666,11 +121523,11 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
120666
121523
  if (entryPhase !== String(phase)) {
120667
121524
  continue;
120668
121525
  }
120669
- const evidenceFilePath = path145.join(entryPath, "evidence.json");
121526
+ const evidenceFilePath = path146.join(entryPath, "evidence.json");
120670
121527
  try {
120671
- const resolvedPath = path145.resolve(evidenceFilePath);
120672
- const evidenceDirResolved = path145.resolve(evidenceDir);
120673
- if (!resolvedPath.startsWith(evidenceDirResolved + path145.sep)) {
121528
+ const resolvedPath = path146.resolve(evidenceFilePath);
121529
+ const evidenceDirResolved = path146.resolve(evidenceDir);
121530
+ if (!resolvedPath.startsWith(evidenceDirResolved + path146.sep)) {
120674
121531
  continue;
120675
121532
  }
120676
121533
  const stat9 = fs106.lstatSync(evidenceFilePath);
@@ -120704,7 +121561,7 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
120704
121561
  if (Array.isArray(diffEntry.files_changed)) {
120705
121562
  for (const file3 of diffEntry.files_changed) {
120706
121563
  if (typeof file3 === "string") {
120707
- touchedFiles.add(path145.resolve(cwd, file3));
121564
+ touchedFiles.add(path146.resolve(cwd, file3));
120708
121565
  }
120709
121566
  }
120710
121567
  }
@@ -120717,8 +121574,8 @@ function readTouchedFiles(evidenceDir, phase, cwd) {
120717
121574
  }
120718
121575
  function searchFileForKeywords(filePath, keywords, cwd) {
120719
121576
  try {
120720
- const resolvedPath = path145.resolve(filePath);
120721
- const cwdResolved = path145.resolve(cwd);
121577
+ const resolvedPath = path146.resolve(filePath);
121578
+ const cwdResolved = path146.resolve(cwd);
120722
121579
  if (!resolvedPath.startsWith(cwdResolved)) {
120723
121580
  return false;
120724
121581
  }
@@ -120852,7 +121709,7 @@ var req_coverage = createSwarmTool({
120852
121709
  }, null, 2);
120853
121710
  }
120854
121711
  const cwd = inputDirectory || directory;
120855
- const specPath = path145.join(cwd, SPEC_FILE);
121712
+ const specPath = path146.join(cwd, SPEC_FILE);
120856
121713
  let specContent;
120857
121714
  try {
120858
121715
  specContent = fs106.readFileSync(specPath, "utf-8");
@@ -120879,7 +121736,7 @@ var req_coverage = createSwarmTool({
120879
121736
  message: "No FR requirements found in spec.md"
120880
121737
  }, null, 2);
120881
121738
  }
120882
- const evidenceDir = path145.join(cwd, EVIDENCE_DIR4);
121739
+ const evidenceDir = path146.join(cwd, EVIDENCE_DIR4);
120883
121740
  const touchedFiles = readTouchedFiles(evidenceDir, phase, cwd);
120884
121741
  const analyzedRequirements = [];
120885
121742
  let coveredCount = 0;
@@ -120905,7 +121762,7 @@ var req_coverage = createSwarmTool({
120905
121762
  requirements: analyzedRequirements
120906
121763
  };
120907
121764
  const reportFilename = `req-coverage-phase-${phase}.json`;
120908
- const reportPath = path145.join(evidenceDir, reportFilename);
121765
+ const reportPath = path146.join(evidenceDir, reportFilename);
120909
121766
  try {
120910
121767
  if (!fs106.existsSync(evidenceDir)) {
120911
121768
  fs106.mkdirSync(evidenceDir, { recursive: true });
@@ -120995,7 +121852,7 @@ init_qa_gate_profile();
120995
121852
  init_file_locks();
120996
121853
  import * as crypto12 from "node:crypto";
120997
121854
  import * as fs107 from "node:fs";
120998
- import * as path146 from "node:path";
121855
+ import * as path147 from "node:path";
120999
121856
  init_ledger();
121000
121857
  init_manager();
121001
121858
  init_state();
@@ -121076,8 +121933,8 @@ async function executeSavePlan(args2, fallbackDir) {
121076
121933
  };
121077
121934
  }
121078
121935
  if (args2.working_directory && fallbackDir) {
121079
- const resolvedTarget = path146.resolve(args2.working_directory);
121080
- const resolvedRoot = path146.resolve(fallbackDir);
121936
+ const resolvedTarget = path147.resolve(args2.working_directory);
121937
+ const resolvedRoot = path147.resolve(fallbackDir);
121081
121938
  let fallbackExists = false;
121082
121939
  try {
121083
121940
  fs107.accessSync(resolvedRoot, fs107.constants.F_OK);
@@ -121086,7 +121943,7 @@ async function executeSavePlan(args2, fallbackDir) {
121086
121943
  fallbackExists = false;
121087
121944
  }
121088
121945
  if (fallbackExists) {
121089
- const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path146.sep);
121946
+ const isSubdirectory = resolvedTarget.startsWith(resolvedRoot + path147.sep);
121090
121947
  if (isSubdirectory) {
121091
121948
  return {
121092
121949
  success: false,
@@ -121102,7 +121959,7 @@ async function executeSavePlan(args2, fallbackDir) {
121102
121959
  let specMtime;
121103
121960
  let specHash;
121104
121961
  if (process.env.SWARM_SKIP_SPEC_GATE !== "1") {
121105
- const specPath = path146.join(targetWorkspace, ".swarm", "spec.md");
121962
+ const specPath = path147.join(targetWorkspace, ".swarm", "spec.md");
121106
121963
  try {
121107
121964
  const stat9 = await fs107.promises.stat(specPath);
121108
121965
  specMtime = stat9.mtime.toISOString();
@@ -121118,7 +121975,7 @@ async function executeSavePlan(args2, fallbackDir) {
121118
121975
  }
121119
121976
  }
121120
121977
  if (process.env.SWARM_SKIP_GATE_SELECTION !== "1") {
121121
- const contextPath = path146.join(targetWorkspace, ".swarm", "context.md");
121978
+ const contextPath = path147.join(targetWorkspace, ".swarm", "context.md");
121122
121979
  let contextContent = "";
121123
121980
  try {
121124
121981
  contextContent = await fs107.promises.readFile(contextPath, "utf8");
@@ -121408,7 +122265,7 @@ async function executeSavePlan(args2, fallbackDir) {
121408
122265
  }
121409
122266
  await writeCheckpoint(dir).catch(() => {});
121410
122267
  try {
121411
- const markerPath = path146.join(dir, ".swarm", ".plan-write-marker");
122268
+ const markerPath = path147.join(dir, ".swarm", ".plan-write-marker");
121412
122269
  const marker = JSON.stringify({
121413
122270
  source: "save_plan",
121414
122271
  timestamp: new Date().toISOString(),
@@ -121431,7 +122288,7 @@ async function executeSavePlan(args2, fallbackDir) {
121431
122288
  return {
121432
122289
  success: true,
121433
122290
  message: "Plan saved successfully",
121434
- plan_path: path146.join(dir, ".swarm", "plan.json"),
122291
+ plan_path: path147.join(dir, ".swarm", "plan.json"),
121435
122292
  phases_count: plan.phases.length,
121436
122293
  tasks_count: tasksCount,
121437
122294
  ...resolvedProfile !== undefined ? { execution_profile: resolvedProfile } : {},
@@ -121498,7 +122355,7 @@ var save_plan = createSwarmTool({
121498
122355
  init_zod();
121499
122356
  init_manager2();
121500
122357
  import * as fs108 from "node:fs";
121501
- import * as path147 from "node:path";
122358
+ import * as path148 from "node:path";
121502
122359
 
121503
122360
  // src/sbom/detectors/index.ts
121504
122361
  init_utils();
@@ -122348,7 +123205,7 @@ function findManifestFiles(rootDir) {
122348
123205
  try {
122349
123206
  const entries = fs108.readdirSync(dir, { withFileTypes: true });
122350
123207
  for (const entry of entries) {
122351
- const fullPath = path147.join(dir, entry.name);
123208
+ const fullPath = path148.join(dir, entry.name);
122352
123209
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
122353
123210
  continue;
122354
123211
  }
@@ -122357,7 +123214,7 @@ function findManifestFiles(rootDir) {
122357
123214
  } else if (entry.isFile()) {
122358
123215
  for (const pattern of patterns) {
122359
123216
  if (simpleGlobToRegex(pattern).test(entry.name)) {
122360
- manifestFiles.push(path147.relative(rootDir, fullPath));
123217
+ manifestFiles.push(path148.relative(rootDir, fullPath));
122361
123218
  break;
122362
123219
  }
122363
123220
  }
@@ -122375,11 +123232,11 @@ function findManifestFilesInDirs(directories, workingDir) {
122375
123232
  try {
122376
123233
  const entries = fs108.readdirSync(dir, { withFileTypes: true });
122377
123234
  for (const entry of entries) {
122378
- const fullPath = path147.join(dir, entry.name);
123235
+ const fullPath = path148.join(dir, entry.name);
122379
123236
  if (entry.isFile()) {
122380
123237
  for (const pattern of patterns) {
122381
123238
  if (simpleGlobToRegex(pattern).test(entry.name)) {
122382
- found.push(path147.relative(workingDir, fullPath));
123239
+ found.push(path148.relative(workingDir, fullPath));
122383
123240
  break;
122384
123241
  }
122385
123242
  }
@@ -122392,11 +123249,11 @@ function findManifestFilesInDirs(directories, workingDir) {
122392
123249
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
122393
123250
  const dirs = new Set;
122394
123251
  for (const file3 of changedFiles) {
122395
- let currentDir = path147.dirname(file3);
123252
+ let currentDir = path148.dirname(file3);
122396
123253
  while (true) {
122397
- if (currentDir && currentDir !== "." && currentDir !== path147.sep) {
122398
- dirs.add(path147.join(workingDir, currentDir));
122399
- const parent = path147.dirname(currentDir);
123254
+ if (currentDir && currentDir !== "." && currentDir !== path148.sep) {
123255
+ dirs.add(path148.join(workingDir, currentDir));
123256
+ const parent = path148.dirname(currentDir);
122400
123257
  if (parent === currentDir)
122401
123258
  break;
122402
123259
  currentDir = parent;
@@ -122480,7 +123337,7 @@ var sbom_generate = createSwarmTool({
122480
123337
  const changedFiles = obj.changed_files;
122481
123338
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
122482
123339
  const workingDir = directory;
122483
- const outputDir = path147.isAbsolute(relativeOutputDir) ? relativeOutputDir : path147.join(workingDir, relativeOutputDir);
123340
+ const outputDir = path148.isAbsolute(relativeOutputDir) ? relativeOutputDir : path148.join(workingDir, relativeOutputDir);
122484
123341
  let manifestFiles = [];
122485
123342
  if (scope === "all") {
122486
123343
  manifestFiles = findManifestFiles(workingDir);
@@ -122503,7 +123360,7 @@ var sbom_generate = createSwarmTool({
122503
123360
  const processedFiles = [];
122504
123361
  for (const manifestFile of manifestFiles) {
122505
123362
  try {
122506
- const fullPath = path147.isAbsolute(manifestFile) ? manifestFile : path147.join(workingDir, manifestFile);
123363
+ const fullPath = path148.isAbsolute(manifestFile) ? manifestFile : path148.join(workingDir, manifestFile);
122507
123364
  if (!fs108.existsSync(fullPath)) {
122508
123365
  continue;
122509
123366
  }
@@ -122520,7 +123377,7 @@ var sbom_generate = createSwarmTool({
122520
123377
  const bom = generateCycloneDX(allComponents);
122521
123378
  const bomJson = serializeCycloneDX(bom);
122522
123379
  const filename = generateSbomFilename();
122523
- const outputPath = path147.join(outputDir, filename);
123380
+ const outputPath = path148.join(outputDir, filename);
122524
123381
  fs108.writeFileSync(outputPath, bomJson, "utf-8");
122525
123382
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
122526
123383
  try {
@@ -122565,7 +123422,7 @@ var sbom_generate = createSwarmTool({
122565
123422
  init_zod();
122566
123423
  init_create_tool();
122567
123424
  import * as fs109 from "node:fs";
122568
- import * as path148 from "node:path";
123425
+ import * as path149 from "node:path";
122569
123426
  var SPEC_CANDIDATES = [
122570
123427
  "openapi.json",
122571
123428
  "openapi.yaml",
@@ -122597,12 +123454,12 @@ function normalizePath5(p) {
122597
123454
  }
122598
123455
  function discoverSpecFile(cwd, specFileArg) {
122599
123456
  if (specFileArg) {
122600
- const resolvedPath = path148.resolve(cwd, specFileArg);
122601
- const normalizedCwd = cwd.endsWith(path148.sep) ? cwd : cwd + path148.sep;
123457
+ const resolvedPath = path149.resolve(cwd, specFileArg);
123458
+ const normalizedCwd = cwd.endsWith(path149.sep) ? cwd : cwd + path149.sep;
122602
123459
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
122603
123460
  throw new Error("Invalid spec_file: path traversal detected");
122604
123461
  }
122605
- const ext = path148.extname(resolvedPath).toLowerCase();
123462
+ const ext = path149.extname(resolvedPath).toLowerCase();
122606
123463
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
122607
123464
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
122608
123465
  }
@@ -122616,7 +123473,7 @@ function discoverSpecFile(cwd, specFileArg) {
122616
123473
  return resolvedPath;
122617
123474
  }
122618
123475
  for (const candidate of SPEC_CANDIDATES) {
122619
- const candidatePath = path148.resolve(cwd, candidate);
123476
+ const candidatePath = path149.resolve(cwd, candidate);
122620
123477
  if (fs109.existsSync(candidatePath)) {
122621
123478
  const stats = fs109.statSync(candidatePath);
122622
123479
  if (stats.size <= MAX_SPEC_SIZE) {
@@ -122628,7 +123485,7 @@ function discoverSpecFile(cwd, specFileArg) {
122628
123485
  }
122629
123486
  function parseSpec(specFile) {
122630
123487
  const content = fs109.readFileSync(specFile, "utf-8");
122631
- const ext = path148.extname(specFile).toLowerCase();
123488
+ const ext = path149.extname(specFile).toLowerCase();
122632
123489
  if (ext === ".json") {
122633
123490
  return parseJsonSpec(content);
122634
123491
  }
@@ -122704,7 +123561,7 @@ function extractRoutes(cwd) {
122704
123561
  return;
122705
123562
  }
122706
123563
  for (const entry of entries) {
122707
- const fullPath = path148.join(dir, entry.name);
123564
+ const fullPath = path149.join(dir, entry.name);
122708
123565
  if (entry.isSymbolicLink()) {
122709
123566
  continue;
122710
123567
  }
@@ -122714,7 +123571,7 @@ function extractRoutes(cwd) {
122714
123571
  }
122715
123572
  walkDir(fullPath);
122716
123573
  } else if (entry.isFile()) {
122717
- const ext = path148.extname(entry.name).toLowerCase();
123574
+ const ext = path149.extname(entry.name).toLowerCase();
122718
123575
  const baseName = entry.name.toLowerCase();
122719
123576
  if (![".ts", ".js", ".mjs"].includes(ext)) {
122720
123577
  continue;
@@ -122883,7 +123740,7 @@ init_bun_compat();
122883
123740
  init_path_security();
122884
123741
  init_create_tool();
122885
123742
  import * as fs110 from "node:fs";
122886
- import * as path149 from "node:path";
123743
+ import * as path150 from "node:path";
122887
123744
  var DEFAULT_MAX_RESULTS = 100;
122888
123745
  var DEFAULT_MAX_LINES = 200;
122889
123746
  var REGEX_TIMEOUT_MS = 5000;
@@ -122906,24 +123763,24 @@ function matchesGlobs(filePath, globs) {
122906
123763
  return true;
122907
123764
  return globs.some((glob) => globMatch(glob, filePath));
122908
123765
  }
122909
- var WINDOWS_RESERVED_NAMES3 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
122910
- function containsWindowsAttacks3(str) {
123766
+ var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
123767
+ function containsWindowsAttacks4(str) {
122911
123768
  if (/:[^\\/]/.test(str))
122912
123769
  return true;
122913
123770
  const parts2 = str.split(/[/\\]/);
122914
123771
  for (const part of parts2) {
122915
- if (WINDOWS_RESERVED_NAMES3.test(part))
123772
+ if (WINDOWS_RESERVED_NAMES4.test(part))
122916
123773
  return true;
122917
123774
  }
122918
123775
  return false;
122919
123776
  }
122920
123777
  function isPathInWorkspace3(filePath, workspace) {
122921
123778
  try {
122922
- const resolvedPath = path149.resolve(workspace, filePath);
123779
+ const resolvedPath = path150.resolve(workspace, filePath);
122923
123780
  const realWorkspace = fs110.realpathSync(workspace);
122924
123781
  const realResolvedPath = fs110.realpathSync(resolvedPath);
122925
- const relativePath = path149.relative(realWorkspace, realResolvedPath);
122926
- if (relativePath.startsWith("..") || path149.isAbsolute(relativePath)) {
123782
+ const relativePath = path150.relative(realWorkspace, realResolvedPath);
123783
+ if (relativePath.startsWith("..") || path150.isAbsolute(relativePath)) {
122927
123784
  return false;
122928
123785
  }
122929
123786
  return true;
@@ -122936,11 +123793,11 @@ function validatePathForRead2(filePath, workspace) {
122936
123793
  }
122937
123794
  function findRgInEnvPath() {
122938
123795
  const searchPath = process.env.PATH ?? "";
122939
- for (const dir of searchPath.split(path149.delimiter)) {
123796
+ for (const dir of searchPath.split(path150.delimiter)) {
122940
123797
  if (!dir)
122941
123798
  continue;
122942
123799
  const isWindows = process.platform === "win32";
122943
- const candidate = path149.join(dir, isWindows ? "rg.exe" : "rg");
123800
+ const candidate = path150.join(dir, isWindows ? "rg.exe" : "rg");
122944
123801
  if (fs110.existsSync(candidate))
122945
123802
  return candidate;
122946
123803
  }
@@ -122995,7 +123852,7 @@ async function ripgrepSearch(opts) {
122995
123852
  stderr: "pipe",
122996
123853
  cwd: opts.workspace
122997
123854
  });
122998
- const timeout = new Promise((resolve54) => setTimeout(() => resolve54("timeout"), REGEX_TIMEOUT_MS));
123855
+ const timeout = new Promise((resolve55) => setTimeout(() => resolve55("timeout"), REGEX_TIMEOUT_MS));
122999
123856
  const exitPromise = proc.exited;
123000
123857
  const result = await Promise.race([exitPromise, timeout]);
123001
123858
  if (result === "timeout") {
@@ -123070,8 +123927,8 @@ function collectFiles(dir, workspace, includeGlobs, excludeGlobs) {
123070
123927
  try {
123071
123928
  const entries = fs110.readdirSync(dir, { withFileTypes: true });
123072
123929
  for (const entry of entries) {
123073
- const fullPath = path149.join(dir, entry.name);
123074
- const relativePath = path149.relative(workspace, fullPath);
123930
+ const fullPath = path150.join(dir, entry.name);
123931
+ const relativePath = path150.relative(workspace, fullPath);
123075
123932
  if (!validatePathForRead2(fullPath, workspace)) {
123076
123933
  continue;
123077
123934
  }
@@ -123112,7 +123969,7 @@ async function fallbackSearch(opts) {
123112
123969
  const matches = [];
123113
123970
  let total = 0;
123114
123971
  for (const file3 of files) {
123115
- const fullPath = path149.join(opts.workspace, file3);
123972
+ const fullPath = path150.join(opts.workspace, file3);
123116
123973
  if (!validatePathForRead2(fullPath, opts.workspace)) {
123117
123974
  continue;
123118
123975
  }
@@ -123225,14 +124082,14 @@ var search = createSwarmTool({
123225
124082
  message: "Exclude pattern contains path traversal sequence"
123226
124083
  }, null, 2);
123227
124084
  }
123228
- if (include && containsWindowsAttacks3(include)) {
124085
+ if (include && containsWindowsAttacks4(include)) {
123229
124086
  return JSON.stringify({
123230
124087
  error: true,
123231
124088
  type: "path-escape",
123232
124089
  message: "Include pattern contains invalid Windows-specific sequence"
123233
124090
  }, null, 2);
123234
124091
  }
123235
- if (exclude && containsWindowsAttacks3(exclude)) {
124092
+ if (exclude && containsWindowsAttacks4(exclude)) {
123236
124093
  return JSON.stringify({
123237
124094
  error: true,
123238
124095
  type: "path-escape",
@@ -123525,7 +124382,7 @@ init_config();
123525
124382
  init_schema();
123526
124383
  init_create_tool();
123527
124384
  import { mkdir as mkdir24, rename as rename10, writeFile as writeFile19 } from "node:fs/promises";
123528
- import * as path150 from "node:path";
124385
+ import * as path151 from "node:path";
123529
124386
  var MAX_SPEC_BYTES = 256 * 1024;
123530
124387
  var spec_write = createSwarmTool({
123531
124388
  description: "Write the canonical project spec to .swarm/spec.md. Atomic write, size-bounded (256 KiB), heading-required. Honors spec_writer.allow_spec_write.",
@@ -123566,8 +124423,8 @@ var spec_write = createSwarmTool({
123566
124423
  reason: 'spec must contain at least one top-level "# Heading"'
123567
124424
  }, null, 2);
123568
124425
  }
123569
- const target = path150.join(directory, ".swarm", "spec.md");
123570
- await mkdir24(path150.dirname(target), { recursive: true });
124426
+ const target = path151.join(directory, ".swarm", "spec.md");
124427
+ await mkdir24(path151.dirname(target), { recursive: true });
123571
124428
  const tmp = `${target}.tmp-${process.pid}-${Date.now()}`;
123572
124429
  let finalContent = content;
123573
124430
  if (mode === "append") {
@@ -123596,14 +124453,14 @@ ${content}
123596
124453
  init_zod();
123597
124454
  init_loader();
123598
124455
  import {
123599
- existsSync as existsSync84,
123600
- mkdirSync as mkdirSync35,
123601
- readFileSync as readFileSync71,
123602
- renameSync as renameSync21,
123603
- unlinkSync as unlinkSync19,
123604
- writeFileSync as writeFileSync29
124456
+ existsSync as existsSync85,
124457
+ mkdirSync as mkdirSync36,
124458
+ readFileSync as readFileSync72,
124459
+ renameSync as renameSync22,
124460
+ unlinkSync as unlinkSync20,
124461
+ writeFileSync as writeFileSync30
123605
124462
  } from "node:fs";
123606
- import path151 from "node:path";
124463
+ import path152 from "node:path";
123607
124464
  init_create_tool();
123608
124465
  init_resolve_working_directory();
123609
124466
  var VerdictSchema2 = exports_external.object({
@@ -123733,9 +124590,9 @@ var submit_phase_council_verdicts = createSwarmTool({
123733
124590
  }
123734
124591
  });
123735
124592
  function getPhaseMutationGapFinding(phaseNumber, workingDir) {
123736
- const mutationGatePath = path151.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
124593
+ const mutationGatePath = path152.join(workingDir, ".swarm", "evidence", String(phaseNumber), "mutation-gate.json");
123737
124594
  try {
123738
- const raw = readFileSync71(mutationGatePath, "utf-8");
124595
+ const raw = readFileSync72(mutationGatePath, "utf-8");
123739
124596
  const parsed = JSON.parse(raw);
123740
124597
  const gateEntry = (parsed.entries ?? []).find((entry) => entry?.type === "mutation-gate");
123741
124598
  if (!gateEntry) {
@@ -123795,9 +124652,9 @@ function getPhaseMutationGapFinding(phaseNumber, workingDir) {
123795
124652
  }
123796
124653
  }
123797
124654
  function writePhaseCouncilEvidence(workingDir, synthesis) {
123798
- const evidenceDir = path151.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
123799
- mkdirSync35(evidenceDir, { recursive: true });
123800
- const evidenceFile = path151.join(evidenceDir, "phase-council.json");
124655
+ const evidenceDir = path152.join(workingDir, ".swarm", "evidence", String(synthesis.phaseNumber));
124656
+ mkdirSync36(evidenceDir, { recursive: true });
124657
+ const evidenceFile = path152.join(evidenceDir, "phase-council.json");
123801
124658
  const evidenceBundle = {
123802
124659
  entries: [
123803
124660
  {
@@ -123830,11 +124687,11 @@ function writePhaseCouncilEvidence(workingDir, synthesis) {
123830
124687
  };
123831
124688
  const tempFile = `${evidenceFile}.tmp-${Date.now()}`;
123832
124689
  try {
123833
- writeFileSync29(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
123834
- renameSync21(tempFile, evidenceFile);
124690
+ writeFileSync30(tempFile, JSON.stringify(evidenceBundle, null, 2), "utf-8");
124691
+ renameSync22(tempFile, evidenceFile);
123835
124692
  } finally {
123836
- if (existsSync84(tempFile)) {
123837
- unlinkSync19(tempFile);
124693
+ if (existsSync85(tempFile)) {
124694
+ unlinkSync20(tempFile);
123838
124695
  }
123839
124696
  }
123840
124697
  }
@@ -123859,28 +124716,28 @@ init_zod();
123859
124716
  init_path_security();
123860
124717
  init_create_tool();
123861
124718
  import * as fs111 from "node:fs";
123862
- import * as path152 from "node:path";
123863
- var WINDOWS_RESERVED_NAMES4 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
123864
- function containsWindowsAttacks4(str) {
124719
+ import * as path153 from "node:path";
124720
+ var WINDOWS_RESERVED_NAMES5 = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
124721
+ function containsWindowsAttacks5(str) {
123865
124722
  if (/:[^\\/]/.test(str))
123866
124723
  return true;
123867
124724
  const parts2 = str.split(/[/\\]/);
123868
124725
  for (const part of parts2) {
123869
- if (WINDOWS_RESERVED_NAMES4.test(part))
124726
+ if (WINDOWS_RESERVED_NAMES5.test(part))
123870
124727
  return true;
123871
124728
  }
123872
124729
  return false;
123873
124730
  }
123874
124731
  function isPathInWorkspace4(filePath, workspace) {
123875
124732
  try {
123876
- const resolvedPath = path152.resolve(workspace, filePath);
124733
+ const resolvedPath = path153.resolve(workspace, filePath);
123877
124734
  if (!fs111.existsSync(resolvedPath)) {
123878
124735
  return true;
123879
124736
  }
123880
124737
  const realWorkspace = fs111.realpathSync(workspace);
123881
124738
  const realResolvedPath = fs111.realpathSync(resolvedPath);
123882
- const relativePath = path152.relative(realWorkspace, realResolvedPath);
123883
- if (relativePath.startsWith("..") || path152.isAbsolute(relativePath)) {
124739
+ const relativePath = path153.relative(realWorkspace, realResolvedPath);
124740
+ if (relativePath.startsWith("..") || path153.isAbsolute(relativePath)) {
123884
124741
  return false;
123885
124742
  }
123886
124743
  return true;
@@ -123895,7 +124752,7 @@ function validateFilePath(filePath, workspace) {
123895
124752
  return false;
123896
124753
  if (containsControlChars(filePath))
123897
124754
  return false;
123898
- if (containsWindowsAttacks4(filePath))
124755
+ if (containsWindowsAttacks5(filePath))
123899
124756
  return false;
123900
124757
  return isPathInWorkspace4(filePath, workspace);
123901
124758
  }
@@ -123908,12 +124765,12 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
123908
124765
  if (contextBefore && contextBefore.length > 0) {
123909
124766
  for (let i2 = 0;i2 <= lines.length - contextBefore.length; i2++) {
123910
124767
  const slice = lines.slice(i2, i2 + contextBefore.length);
123911
- if (arraysEqual(slice, contextBefore)) {
124768
+ if (arraysEqual2(slice, contextBefore)) {
123912
124769
  const afterStart = i2 + contextBefore.length;
123913
124770
  if (contextAfter && contextAfter.length > 0) {
123914
124771
  for (let j = afterStart;j <= lines.length - contextAfter.length; j++) {
123915
124772
  const afterSlice = lines.slice(j, j + contextAfter.length);
123916
- if (arraysEqual(afterSlice, contextAfter)) {
124773
+ if (arraysEqual2(afterSlice, contextAfter)) {
123917
124774
  if (j === afterStart) {
123918
124775
  return {
123919
124776
  startLineIndex: i2,
@@ -123926,7 +124783,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
123926
124783
  const oldContentLines = oldContent.split(`
123927
124784
  `);
123928
124785
  const betweenLines = lines.slice(afterStart, j);
123929
- if (arraysEqual(betweenLines, oldContentLines)) {
124786
+ if (arraysEqual2(betweenLines, oldContentLines)) {
123930
124787
  return {
123931
124788
  startLineIndex: i2,
123932
124789
  endLineIndex: j - 1,
@@ -123952,7 +124809,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
123952
124809
  `);
123953
124810
  for (let k = afterStart;k <= lines.length - oldContentLines.length; k++) {
123954
124811
  const candidate = lines.slice(k, k + oldContentLines.length);
123955
- if (arraysEqual(candidate, oldContentLines)) {
124812
+ if (arraysEqual2(candidate, oldContentLines)) {
123956
124813
  return {
123957
124814
  startLineIndex: i2,
123958
124815
  endLineIndex: k + oldContentLines.length - 1,
@@ -123976,7 +124833,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
123976
124833
  } else if (contextAfter && contextAfter.length > 0) {
123977
124834
  for (let j = 0;j <= lines.length - contextAfter.length; j++) {
123978
124835
  const afterSlice = lines.slice(j, j + contextAfter.length);
123979
- if (arraysEqual(afterSlice, contextAfter)) {
124836
+ if (arraysEqual2(afterSlice, contextAfter)) {
123980
124837
  return {
123981
124838
  startLineIndex: 0,
123982
124839
  endLineIndex: j - 1,
@@ -123988,7 +124845,7 @@ function findContextMatch(content, contextBefore, contextAfter, oldContent) {
123988
124845
  }
123989
124846
  return null;
123990
124847
  }
123991
- function arraysEqual(a, b) {
124848
+ function arraysEqual2(a, b) {
123992
124849
  if (a.length !== b.length)
123993
124850
  return false;
123994
124851
  for (let i2 = 0;i2 < a.length; i2++) {
@@ -124088,7 +124945,7 @@ var suggestPatch = createSwarmTool({
124088
124945
  });
124089
124946
  continue;
124090
124947
  }
124091
- const fullPath = path152.resolve(directory, change.file);
124948
+ const fullPath = path153.resolve(directory, change.file);
124092
124949
  if (!fs111.existsSync(fullPath)) {
124093
124950
  errors5.push({
124094
124951
  success: false,
@@ -124492,7 +125349,7 @@ init_zod();
124492
125349
  init_manager2();
124493
125350
  init_detector();
124494
125351
  import * as fs112 from "node:fs";
124495
- import * as path153 from "node:path";
125352
+ import * as path154 from "node:path";
124496
125353
  init_create_tool();
124497
125354
  var MAX_FILE_SIZE2 = 2 * 1024 * 1024;
124498
125355
  var BINARY_CHECK_BYTES = 8192;
@@ -124558,7 +125415,7 @@ async function syntaxCheck(input, directory, config3) {
124558
125415
  if (languages?.length) {
124559
125416
  const lowerLangs = languages.map((l) => l.toLowerCase());
124560
125417
  filesToCheck = filesToCheck.filter((file3) => {
124561
- const ext = path153.extname(file3.path).toLowerCase();
125418
+ const ext = path154.extname(file3.path).toLowerCase();
124562
125419
  const langDef = getLanguageForExtension(ext);
124563
125420
  const fileProfile = getProfileForFile(file3.path);
124564
125421
  const langId = fileProfile?.id || langDef?.id;
@@ -124571,7 +125428,7 @@ async function syntaxCheck(input, directory, config3) {
124571
125428
  let skippedCount = 0;
124572
125429
  for (const fileInfo of filesToCheck) {
124573
125430
  const { path: filePath } = fileInfo;
124574
- const fullPath = path153.isAbsolute(filePath) ? filePath : path153.join(directory, filePath);
125431
+ const fullPath = path154.isAbsolute(filePath) ? filePath : path154.join(directory, filePath);
124575
125432
  const result = {
124576
125433
  path: filePath,
124577
125434
  language: "",
@@ -124620,7 +125477,7 @@ async function syntaxCheck(input, directory, config3) {
124620
125477
  results.push(result);
124621
125478
  continue;
124622
125479
  }
124623
- const ext = path153.extname(filePath).toLowerCase();
125480
+ const ext = path154.extname(filePath).toLowerCase();
124624
125481
  const langDef = getLanguageForExtension(ext);
124625
125482
  result.language = profile?.id || langDef?.id || "unknown";
124626
125483
  const errors5 = extractSyntaxErrors(parser, content);
@@ -124719,7 +125576,7 @@ init_utils();
124719
125576
  init_create_tool();
124720
125577
  init_path_security();
124721
125578
  import * as fs113 from "node:fs";
124722
- import * as path154 from "node:path";
125579
+ import * as path155 from "node:path";
124723
125580
  var MAX_TEXT_LENGTH = 200;
124724
125581
  var MAX_FILE_SIZE_BYTES11 = 1024 * 1024;
124725
125582
  var SUPPORTED_EXTENSIONS4 = new Set([
@@ -124785,9 +125642,9 @@ function validatePathsInput(paths, cwd) {
124785
125642
  return { error: "paths contains path traversal", resolvedPath: null };
124786
125643
  }
124787
125644
  try {
124788
- const resolvedPath = path154.resolve(paths);
124789
- const normalizedCwd = path154.resolve(cwd);
124790
- const normalizedResolved = path154.resolve(resolvedPath);
125645
+ const resolvedPath = path155.resolve(paths);
125646
+ const normalizedCwd = path155.resolve(cwd);
125647
+ const normalizedResolved = path155.resolve(resolvedPath);
124791
125648
  if (!normalizedResolved.startsWith(normalizedCwd)) {
124792
125649
  return {
124793
125650
  error: "paths must be within the current working directory",
@@ -124803,7 +125660,7 @@ function validatePathsInput(paths, cwd) {
124803
125660
  }
124804
125661
  }
124805
125662
  function isSupportedExtension(filePath) {
124806
- const ext = path154.extname(filePath).toLowerCase();
125663
+ const ext = path155.extname(filePath).toLowerCase();
124807
125664
  return SUPPORTED_EXTENSIONS4.has(ext);
124808
125665
  }
124809
125666
  function findSourceFiles3(dir, files = []) {
@@ -124818,7 +125675,7 @@ function findSourceFiles3(dir, files = []) {
124818
125675
  if (SKIP_DIRECTORIES5.has(entry)) {
124819
125676
  continue;
124820
125677
  }
124821
- const fullPath = path154.join(dir, entry);
125678
+ const fullPath = path155.join(dir, entry);
124822
125679
  let stat9;
124823
125680
  try {
124824
125681
  stat9 = fs113.statSync(fullPath);
@@ -124930,7 +125787,7 @@ var todo_extract = createSwarmTool({
124930
125787
  filesToScan.push(scanPath);
124931
125788
  } else {
124932
125789
  const errorResult = {
124933
- error: `unsupported file extension: ${path154.extname(scanPath)}`,
125790
+ error: `unsupported file extension: ${path155.extname(scanPath)}`,
124934
125791
  total: 0,
124935
125792
  byPriority: { high: 0, medium: 0, low: 0 },
124936
125793
  entries: []
@@ -124980,17 +125837,17 @@ init_schema();
124980
125837
  init_qa_gate_profile();
124981
125838
  init_gate_evidence();
124982
125839
  import * as fs117 from "node:fs";
124983
- import * as path158 from "node:path";
125840
+ import * as path159 from "node:path";
124984
125841
 
124985
125842
  // src/hooks/diff-scope.ts
124986
125843
  init_bun_compat();
124987
125844
  import * as fs115 from "node:fs";
124988
- import * as path156 from "node:path";
125845
+ import * as path157 from "node:path";
124989
125846
 
124990
125847
  // src/utils/gitignore-warning.ts
124991
125848
  init_bun_compat();
124992
125849
  import * as fs114 from "node:fs";
124993
- import * as path155 from "node:path";
125850
+ import * as path156 from "node:path";
124994
125851
  var _internals67 = { bunSpawn };
124995
125852
  var _swarmGitExcludedChecked = false;
124996
125853
  function fileCoversSwarm(content) {
@@ -125064,10 +125921,10 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
125064
125921
  const excludeRelPath = excludePathRaw.trim();
125065
125922
  if (!excludeRelPath)
125066
125923
  return;
125067
- const excludePath = path155.isAbsolute(excludeRelPath) ? excludeRelPath : path155.join(directory, excludeRelPath);
125924
+ const excludePath = path156.isAbsolute(excludeRelPath) ? excludeRelPath : path156.join(directory, excludeRelPath);
125068
125925
  if (checkIgnoreExitCode !== 0) {
125069
125926
  try {
125070
- fs114.mkdirSync(path155.dirname(excludePath), { recursive: true });
125927
+ fs114.mkdirSync(path156.dirname(excludePath), { recursive: true });
125071
125928
  let existing = "";
125072
125929
  try {
125073
125930
  existing = fs114.readFileSync(excludePath, "utf8");
@@ -125111,7 +125968,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
125111
125968
  var _internals68 = { bunSpawn };
125112
125969
  function getDeclaredScope(taskId, directory) {
125113
125970
  try {
125114
- const planPath = path156.join(directory, ".swarm", "plan.json");
125971
+ const planPath = path157.join(directory, ".swarm", "plan.json");
125115
125972
  if (!fs115.existsSync(planPath))
125116
125973
  return null;
125117
125974
  const raw = fs115.readFileSync(planPath, "utf-8");
@@ -125217,7 +126074,7 @@ init_telemetry();
125217
126074
  // src/turbo/lean/task-completion.ts
125218
126075
  init_file_locks();
125219
126076
  import * as fs116 from "node:fs";
125220
- import * as path157 from "node:path";
126077
+ import * as path158 from "node:path";
125221
126078
  var _internals69 = {
125222
126079
  listActiveLocks,
125223
126080
  verifyLeanTurboTaskCompletion
@@ -125236,7 +126093,7 @@ var TIER_3_PATTERNS = [
125236
126093
  ];
125237
126094
  function matchesTier3Pattern(files) {
125238
126095
  for (const file3 of files) {
125239
- const fileName = path157.basename(file3);
126096
+ const fileName = path158.basename(file3);
125240
126097
  for (const pattern of TIER_3_PATTERNS) {
125241
126098
  if (pattern.test(fileName)) {
125242
126099
  return true;
@@ -125248,7 +126105,7 @@ function matchesTier3Pattern(files) {
125248
126105
  function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
125249
126106
  let persisted = null;
125250
126107
  try {
125251
- const statePath = path157.join(directory, ".swarm", "turbo-state.json");
126108
+ const statePath = path158.join(directory, ".swarm", "turbo-state.json");
125252
126109
  if (!fs116.existsSync(statePath)) {
125253
126110
  return {
125254
126111
  ok: false,
@@ -125332,11 +126189,11 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
125332
126189
  };
125333
126190
  }
125334
126191
  const phase = runState.phase ?? 0;
125335
- const evidencePath = path157.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
125336
- const expectedDir = path157.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
125337
- const resolvedPath = path157.resolve(evidencePath);
125338
- const resolvedDir = path157.resolve(expectedDir);
125339
- if (!resolvedPath.startsWith(resolvedDir + path157.sep) && resolvedPath !== resolvedDir) {
126192
+ const evidencePath = path158.join(directory, ".swarm", "evidence", String(phase), "lean-turbo", `${lane.laneId}.json`);
126193
+ const expectedDir = path158.join(directory, ".swarm", "evidence", String(phase), "lean-turbo");
126194
+ const resolvedPath = path158.resolve(evidencePath);
126195
+ const resolvedDir = path158.resolve(expectedDir);
126196
+ if (!resolvedPath.startsWith(resolvedDir + path158.sep) && resolvedPath !== resolvedDir) {
125340
126197
  return {
125341
126198
  ok: false,
125342
126199
  reason: `Lane ID causes path traversal: ${lane.laneId}`,
@@ -125376,7 +126233,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
125376
126233
  }
125377
126234
  let filesTouched = [];
125378
126235
  try {
125379
- const planPath = path157.join(directory, ".swarm", "plan.json");
126236
+ const planPath = path158.join(directory, ".swarm", "plan.json");
125380
126237
  const planRaw = fs116.readFileSync(planPath, "utf-8");
125381
126238
  const plan = JSON.parse(planRaw);
125382
126239
  for (const planPhase of plan.phases ?? []) {
@@ -125460,7 +126317,7 @@ var TIER_3_PATTERNS2 = [
125460
126317
  ];
125461
126318
  function matchesTier3Pattern2(files) {
125462
126319
  for (const file3 of files) {
125463
- const fileName = path158.basename(file3);
126320
+ const fileName = path159.basename(file3);
125464
126321
  for (const pattern of TIER_3_PATTERNS2) {
125465
126322
  if (pattern.test(fileName)) {
125466
126323
  return true;
@@ -125499,7 +126356,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
125499
126356
  if (!skipStandardTurboBypass && hasActiveTurboMode()) {
125500
126357
  const resolvedDir2 = workingDirectory;
125501
126358
  try {
125502
- const planPath = path158.join(resolvedDir2, ".swarm", "plan.json");
126359
+ const planPath = path159.join(resolvedDir2, ".swarm", "plan.json");
125503
126360
  const planRaw = fs117.readFileSync(planPath, "utf-8");
125504
126361
  const plan = JSON.parse(planRaw);
125505
126362
  for (const planPhase of plan.phases ?? []) {
@@ -125577,7 +126434,7 @@ function checkReviewerGate(taskId, workingDirectory, stageBParallelEnabled = fal
125577
126434
  }
125578
126435
  if (resolvedDir) {
125579
126436
  try {
125580
- const planPath = path158.join(resolvedDir, ".swarm", "plan.json");
126437
+ const planPath = path159.join(resolvedDir, ".swarm", "plan.json");
125581
126438
  const planRaw = fs117.readFileSync(planPath, "utf-8");
125582
126439
  const plan = JSON.parse(planRaw);
125583
126440
  for (const planPhase of plan.phases ?? []) {
@@ -125813,7 +126670,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
125813
126670
  };
125814
126671
  }
125815
126672
  directory = resolveResult.directory;
125816
- const planPath = path158.join(directory, ".swarm", "plan.json");
126673
+ const planPath = path159.join(directory, ".swarm", "plan.json");
125817
126674
  if (!fs117.existsSync(planPath)) {
125818
126675
  return {
125819
126676
  success: false,
@@ -125822,9 +126679,9 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
125822
126679
  };
125823
126680
  }
125824
126681
  if (fallbackDir && directory !== fallbackDir) {
125825
- const canonicalDir = fs117.realpathSync(path158.resolve(directory));
125826
- const canonicalRoot = fs117.realpathSync(path158.resolve(fallbackDir));
125827
- if (canonicalDir.startsWith(canonicalRoot + path158.sep)) {
126682
+ const canonicalDir = fs117.realpathSync(path159.resolve(directory));
126683
+ const canonicalRoot = fs117.realpathSync(path159.resolve(fallbackDir));
126684
+ if (canonicalDir.startsWith(canonicalRoot + path159.sep)) {
125828
126685
  return {
125829
126686
  success: false,
125830
126687
  message: `Invalid working_directory: "${directory}" is a subdirectory of ` + `the project root "${fallbackDir}". Pass the project root path or ` + `omit working_directory entirely.`,
@@ -125836,8 +126693,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
125836
126693
  }
125837
126694
  if (args2.status === "in_progress") {
125838
126695
  try {
125839
- const evidencePath = path158.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
125840
- fs117.mkdirSync(path158.dirname(evidencePath), { recursive: true });
126696
+ const evidencePath = path159.join(directory, ".swarm", "evidence", `${args2.task_id}.json`);
126697
+ fs117.mkdirSync(path159.dirname(evidencePath), { recursive: true });
125841
126698
  const fd = fs117.openSync(evidencePath, "wx");
125842
126699
  let writeOk = false;
125843
126700
  try {
@@ -125861,7 +126718,7 @@ async function executeUpdateTaskStatus(args2, fallbackDir, ctx) {
125861
126718
  recoverTaskStateFromDelegations(args2.task_id, directory);
125862
126719
  let phaseRequiresReviewer = true;
125863
126720
  try {
125864
- const planPath2 = path158.join(directory, ".swarm", "plan.json");
126721
+ const planPath2 = path159.join(directory, ".swarm", "plan.json");
125865
126722
  const planRaw = fs117.readFileSync(planPath2, "utf-8");
125866
126723
  const plan = JSON.parse(planRaw);
125867
126724
  const taskPhase = plan.phases.find((p) => p.tasks.some((t) => t.id === args2.task_id));
@@ -126090,7 +126947,7 @@ init_utils2();
126090
126947
  init_redaction();
126091
126948
  import { createHash as createHash12 } from "node:crypto";
126092
126949
  import { appendFile as appendFile14, mkdir as mkdir25 } from "node:fs/promises";
126093
- import * as path159 from "node:path";
126950
+ import * as path160 from "node:path";
126094
126951
  var EVIDENCE_CACHE_FILE = "evidence-cache/documents.jsonl";
126095
126952
  var MAX_EVIDENCE_TEXT_LENGTH = 4000;
126096
126953
  async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
@@ -126098,7 +126955,7 @@ async function writeEvidenceDocuments(directory, inputs, now = () => new Date) {
126098
126955
  const capturedAt = now().toISOString();
126099
126956
  const records = inputs.map((input) => createEvidenceDocumentRecord(input, capturedAt)).filter((record3) => record3 !== null);
126100
126957
  if (records.length > 0) {
126101
- await mkdir25(path159.dirname(filePath), { recursive: true });
126958
+ await mkdir25(path160.dirname(filePath), { recursive: true });
126102
126959
  await appendFile14(filePath, `${records.map((record3) => JSON.stringify(record3)).join(`
126103
126960
  `)}
126104
126961
  `, "utf-8");
@@ -126295,7 +127152,7 @@ init_schema3();
126295
127152
  init_store();
126296
127153
  init_create_tool();
126297
127154
  init_resolve_working_directory();
126298
- import * as path160 from "node:path";
127155
+ import * as path161 from "node:path";
126299
127156
  var FindingSchema2 = exports_external.object({
126300
127157
  severity: exports_external.enum(["low", "medium", "high", "critical"]),
126301
127158
  category: exports_external.string().min(1),
@@ -126359,7 +127216,7 @@ var write_architecture_supervisor_evidence = createSwarmTool({
126359
127216
  if (config3.architectural_supervision?.persist_knowledge_recommendations && args2.knowledge_recommendations.length > 0) {
126360
127217
  const knowledgeConfig = KnowledgeConfigSchema.parse(config3.knowledge ?? {});
126361
127218
  const lessons = args2.knowledge_recommendations.map((r) => r.lesson);
126362
- const result = await curateAndStoreSwarm(lessons, path160.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, { skipAutoPromotion: true });
127219
+ const result = await curateAndStoreSwarm(lessons, path161.basename(dirResult.directory), { phase_number: args2.phase }, dirResult.directory, knowledgeConfig, { skipAutoPromotion: true });
126363
127220
  knowledgeProposed = result.stored;
126364
127221
  }
126365
127222
  } catch {}
@@ -126395,7 +127252,7 @@ init_ledger();
126395
127252
  init_manager();
126396
127253
  init_create_tool();
126397
127254
  import fs118 from "node:fs";
126398
- import path161 from "node:path";
127255
+ import path162 from "node:path";
126399
127256
  function normalizeVerdict(verdict) {
126400
127257
  switch (verdict) {
126401
127258
  case "APPROVED":
@@ -126443,7 +127300,7 @@ async function executeWriteDriftEvidence(args2, directory) {
126443
127300
  entries: [evidenceEntry]
126444
127301
  };
126445
127302
  const filename = "drift-verifier.json";
126446
- const relativePath = path161.join("evidence", String(phase), filename);
127303
+ const relativePath = path162.join("evidence", String(phase), filename);
126447
127304
  let validatedPath;
126448
127305
  try {
126449
127306
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -126454,10 +127311,10 @@ async function executeWriteDriftEvidence(args2, directory) {
126454
127311
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
126455
127312
  }, null, 2);
126456
127313
  }
126457
- const evidenceDir = path161.dirname(validatedPath);
127314
+ const evidenceDir = path162.dirname(validatedPath);
126458
127315
  try {
126459
127316
  await fs118.promises.mkdir(evidenceDir, { recursive: true });
126460
- const tempPath = path161.join(evidenceDir, `.${filename}.tmp`);
127317
+ const tempPath = path162.join(evidenceDir, `.${filename}.tmp`);
126461
127318
  await fs118.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
126462
127319
  await fs118.promises.rename(tempPath, validatedPath);
126463
127320
  let snapshotInfo;
@@ -126554,7 +127411,7 @@ var write_drift_evidence = createSwarmTool({
126554
127411
  init_zod();
126555
127412
  init_loader();
126556
127413
  import fs119 from "node:fs";
126557
- import path162 from "node:path";
127414
+ import path163 from "node:path";
126558
127415
  init_utils2();
126559
127416
  init_manager();
126560
127417
  init_create_tool();
@@ -126642,7 +127499,7 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
126642
127499
  timestamp: synthesis.timestamp
126643
127500
  };
126644
127501
  const filename = "final-council.json";
126645
- const relativePath = path162.join("evidence", filename);
127502
+ const relativePath = path163.join("evidence", filename);
126646
127503
  let validatedPath;
126647
127504
  try {
126648
127505
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -126656,10 +127513,10 @@ async function executeWriteFinalCouncilEvidence(args2, directory) {
126656
127513
  const evidenceContent = {
126657
127514
  entries: [evidenceEntry]
126658
127515
  };
126659
- const evidenceDir = path162.dirname(validatedPath);
127516
+ const evidenceDir = path163.dirname(validatedPath);
126660
127517
  try {
126661
127518
  await fs119.promises.mkdir(evidenceDir, { recursive: true });
126662
- const tempPath = path162.join(evidenceDir, `.${filename}.tmp`);
127519
+ const tempPath = path163.join(evidenceDir, `.${filename}.tmp`);
126663
127520
  await fs119.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
126664
127521
  await fs119.promises.rename(tempPath, validatedPath);
126665
127522
  return JSON.stringify({
@@ -126719,7 +127576,7 @@ init_zod();
126719
127576
  init_utils2();
126720
127577
  init_create_tool();
126721
127578
  import fs120 from "node:fs";
126722
- import path163 from "node:path";
127579
+ import path164 from "node:path";
126723
127580
  function normalizeVerdict2(verdict) {
126724
127581
  switch (verdict) {
126725
127582
  case "APPROVED":
@@ -126767,7 +127624,7 @@ async function executeWriteHallucinationEvidence(args2, directory) {
126767
127624
  entries: [evidenceEntry]
126768
127625
  };
126769
127626
  const filename = "hallucination-guard.json";
126770
- const relativePath = path163.join("evidence", String(phase), filename);
127627
+ const relativePath = path164.join("evidence", String(phase), filename);
126771
127628
  let validatedPath;
126772
127629
  try {
126773
127630
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -126778,10 +127635,10 @@ async function executeWriteHallucinationEvidence(args2, directory) {
126778
127635
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
126779
127636
  }, null, 2);
126780
127637
  }
126781
- const evidenceDir = path163.dirname(validatedPath);
127638
+ const evidenceDir = path164.dirname(validatedPath);
126782
127639
  try {
126783
127640
  await fs120.promises.mkdir(evidenceDir, { recursive: true });
126784
- const tempPath = path163.join(evidenceDir, `.${filename}.tmp`);
127641
+ const tempPath = path164.join(evidenceDir, `.${filename}.tmp`);
126785
127642
  await fs120.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
126786
127643
  await fs120.promises.rename(tempPath, validatedPath);
126787
127644
  return JSON.stringify({
@@ -126831,7 +127688,7 @@ init_zod();
126831
127688
  init_utils2();
126832
127689
  init_create_tool();
126833
127690
  import fs121 from "node:fs";
126834
- import path164 from "node:path";
127691
+ import path165 from "node:path";
126835
127692
  function normalizeVerdict3(verdict) {
126836
127693
  switch (verdict) {
126837
127694
  case "PASS":
@@ -126905,7 +127762,7 @@ async function executeWriteMutationEvidence(args2, directory) {
126905
127762
  entries: [evidenceEntry]
126906
127763
  };
126907
127764
  const filename = "mutation-gate.json";
126908
- const relativePath = path164.join("evidence", String(phase), filename);
127765
+ const relativePath = path165.join("evidence", String(phase), filename);
126909
127766
  let validatedPath;
126910
127767
  try {
126911
127768
  validatedPath = validateSwarmPath(directory, relativePath);
@@ -126916,10 +127773,10 @@ async function executeWriteMutationEvidence(args2, directory) {
126916
127773
  message: error93 instanceof Error ? error93.message : "Failed to validate path"
126917
127774
  }, null, 2);
126918
127775
  }
126919
- const evidenceDir = path164.dirname(validatedPath);
127776
+ const evidenceDir = path165.dirname(validatedPath);
126920
127777
  try {
126921
127778
  await fs121.promises.mkdir(evidenceDir, { recursive: true });
126922
- const tempPath = path164.join(evidenceDir, `.${filename}.tmp`);
127779
+ const tempPath = path165.join(evidenceDir, `.${filename}.tmp`);
126923
127780
  await fs121.promises.writeFile(tempPath, JSON.stringify(evidenceContent, null, 2), "utf-8");
126924
127781
  await fs121.promises.rename(tempPath, validatedPath);
126925
127782
  return JSON.stringify({
@@ -127055,7 +127912,8 @@ var TOOL_MANIFEST = defineHandlers({
127055
127912
  lean_turbo_runner_status: () => lean_turbo_runner_status,
127056
127913
  lean_turbo_review: () => lean_turbo_review,
127057
127914
  lean_turbo_run_phase: () => lean_turbo_run_phase,
127058
- lean_turbo_status: () => lean_turbo_status
127915
+ lean_turbo_status: () => lean_turbo_status,
127916
+ apply_patch: () => applyPatch
127059
127917
  });
127060
127918
 
127061
127919
  // src/tools/plugin-registration.ts
@@ -127366,7 +128224,7 @@ async function initializeOpenCodeSwarm(ctx) {
127366
128224
  const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
127367
128225
  preflightTriggerManager = new PTM(automationConfig);
127368
128226
  const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
127369
- const swarmDir = path166.resolve(ctx.directory, ".swarm");
128227
+ const swarmDir = path167.resolve(ctx.directory, ".swarm");
127370
128228
  statusArtifact = new ASA(swarmDir);
127371
128229
  statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
127372
128230
  if (automationConfig.capabilities?.evidence_auto_summaries === true) {
@@ -127880,7 +128738,7 @@ ${promptRaw}`;
127880
128738
  const meta3 = readSkillMetadata(s.skillPath, ctx.directory);
127881
128739
  let desc = meta3.description || "";
127882
128740
  if (!desc || desc === "No description provided") {
127883
- desc = path166.basename(path166.dirname(s.skillPath));
128741
+ desc = path167.basename(path167.dirname(s.skillPath));
127884
128742
  }
127885
128743
  desc = desc.replace(/,/g, ";");
127886
128744
  return `file:${s.skillPath} (-- ${desc})`;
@@ -127890,7 +128748,7 @@ ${promptRaw}`;
127890
128748
 
127891
128749
  ${promptRaw}`;
127892
128750
  argsRecord.prompt = newPrompt;
127893
- const skillNames = topSkills.map((s) => `${path166.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
128751
+ const skillNames = topSkills.map((s) => `${path167.basename(s.skillPath)} (score: ${s.score.toFixed(2)})`).join(", ");
127894
128752
  console.warn(`[skill-propagation-gate] Injected skills: ${skillNames}`);
127895
128753
  for (const skill of topSkills) {
127896
128754
  try {