opencode-swarm 7.88.4 → 7.90.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.
@@ -20,7 +20,7 @@ import {
20
20
  validateActionability,
21
21
  validateActionableFields,
22
22
  validateLesson
23
- } from "./index-rh53rrpt.js";
23
+ } from "./index-1ccnwh54.js";
24
24
  import {
25
25
  appendKnowledge,
26
26
  appendRejectedLesson,
@@ -31,17 +31,24 @@ import {
31
31
  enforceKnowledgeCap,
32
32
  findNearDuplicate,
33
33
  inferTags,
34
+ isLinked,
34
35
  normalize,
35
36
  readKnowledge,
37
+ readLinkPointer,
36
38
  readRejectedLessons,
37
39
  readRetractionRecords,
40
+ removeLinkPointer,
38
41
  resolveHiveKnowledgePath,
39
42
  resolveHiveRejectedPath,
43
+ resolveKnowledgeStoreDir,
44
+ resolveLinkDir,
40
45
  resolveSwarmKnowledgePath,
41
46
  rewriteKnowledge,
47
+ sanitizeLinkId,
42
48
  transactFile,
43
- transactKnowledge
44
- } from "./index-e8pk68cc.js";
49
+ transactKnowledge,
50
+ writeLinkPointer
51
+ } from "./index-axwxkbdd.js";
45
52
  import {
46
53
  detectStraySwarmDirs,
47
54
  readDoctorArtifact,
@@ -899,7 +906,7 @@ var init_executor = __esm(() => {
899
906
  // package.json
900
907
  var package_default = {
901
908
  name: "opencode-swarm",
902
- version: "7.88.4",
909
+ version: "7.90.0",
903
910
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
904
911
  main: "dist/index.js",
905
912
  types: "dist/index.d.ts",
@@ -960,6 +967,10 @@ var package_default = {
960
967
  ".opencode/skills/execute",
961
968
  ".opencode/skills/phase-wrap",
962
969
  ".opencode/skills/loop",
970
+ ".opencode/skills/writing-tests",
971
+ ".opencode/skills/running-tests",
972
+ ".opencode/skills/engineering-conventions",
973
+ ".opencode/skills/commit-pr",
963
974
  "tests/fixtures/memory-recall",
964
975
  "README.md",
965
976
  "LICENSE"
@@ -970,6 +981,7 @@ var package_default = {
970
981
  typecheck: "tsc --noEmit",
971
982
  test: "bun test",
972
983
  lint: "biome lint .",
984
+ "drift:check": "bun run scripts/drift-check.ts",
973
985
  format: "biome format . --write",
974
986
  check: "biome check --write .",
975
987
  dev: "bun run build && opencode",
@@ -1397,7 +1409,11 @@ var BUNDLED_PROJECT_SKILLS = [
1397
1409
  "critic-gate",
1398
1410
  "execute",
1399
1411
  "phase-wrap",
1400
- "loop"
1412
+ "loop",
1413
+ "writing-tests",
1414
+ "running-tests",
1415
+ "engineering-conventions",
1416
+ "commit-pr"
1401
1417
  ];
1402
1418
  var MAX_SKILL_FILES = 64;
1403
1419
  var MAX_SKILL_BYTES = 512000;
@@ -4074,6 +4090,64 @@ function readEarliestSessionStart(directory) {
4074
4090
  }
4075
4091
  }
4076
4092
 
4093
+ // src/session/worktree-link-suggestion.ts
4094
+ import { execFile } from "child_process";
4095
+ var GIT_TIMEOUT_MS = 1500;
4096
+ var MAX_SUGGESTED_SESSIONS = 500;
4097
+ var _suggestedSessions = new Set;
4098
+ function markSuggested(sessionId) {
4099
+ if (_suggestedSessions.has(sessionId)) {
4100
+ return;
4101
+ }
4102
+ if (_suggestedSessions.size >= MAX_SUGGESTED_SESSIONS) {
4103
+ const oldest = _suggestedSessions.values().next().value;
4104
+ if (oldest !== undefined) {
4105
+ _suggestedSessions.delete(oldest);
4106
+ }
4107
+ }
4108
+ _suggestedSessions.add(sessionId);
4109
+ }
4110
+ function countWorktrees(directory) {
4111
+ return new Promise((resolve4) => {
4112
+ try {
4113
+ const child = execFile("git", ["-C", directory, "worktree", "list", "--porcelain"], { timeout: GIT_TIMEOUT_MS, windowsHide: true, encoding: "utf-8" }, (err, stdout) => {
4114
+ if (err || typeof stdout !== "string") {
4115
+ resolve4(0);
4116
+ return;
4117
+ }
4118
+ let count = 0;
4119
+ for (const line of stdout.split(`
4120
+ `)) {
4121
+ if (line.startsWith("worktree "))
4122
+ count++;
4123
+ }
4124
+ resolve4(count);
4125
+ });
4126
+ try {
4127
+ child.stdin?.end();
4128
+ } catch {}
4129
+ child.on("error", () => resolve4(0));
4130
+ } catch {
4131
+ resolve4(0);
4132
+ }
4133
+ });
4134
+ }
4135
+ async function maybeSuggestWorktreeLink(directory, sessionId) {
4136
+ try {
4137
+ if (!directory || !sessionId)
4138
+ return;
4139
+ if (_suggestedSessions.has(sessionId))
4140
+ return;
4141
+ markSuggested(sessionId);
4142
+ if (isLinked(directory))
4143
+ return;
4144
+ const worktrees = await countWorktrees(directory);
4145
+ if (worktrees > 1) {
4146
+ console.warn(`[opencode-swarm] Detected ${worktrees} git worktrees of this repo. ` + "Run `/swarm link` in each to share swarm knowledge across them " + "(or `/swarm link <name>` to share with similar projects).");
4147
+ }
4148
+ } catch {}
4149
+ }
4150
+
4077
4151
  // src/state/agent-run-context.ts
4078
4152
  class AgentRunContext {
4079
4153
  runId;
@@ -4255,6 +4329,9 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, dire
4255
4329
  try {
4256
4330
  recordSessionStart(directory, now);
4257
4331
  } catch {}
4332
+ queueMicrotask(() => {
4333
+ maybeSuggestWorktreeLink(directory, sessionId);
4334
+ });
4258
4335
  }
4259
4336
  telemetry.sessionStarted(sessionId, agentName);
4260
4337
  swarmState.activeAgent.set(sessionId, agentName);
@@ -5239,7 +5316,7 @@ function createSwarmTool(opts) {
5239
5316
  // src/tools/checkpoint.ts
5240
5317
  var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
5241
5318
  var MAX_LABEL_LENGTH = 100;
5242
- var GIT_TIMEOUT_MS = 30000;
5319
+ var GIT_TIMEOUT_MS2 = 30000;
5243
5320
  var GIT_MAX_BUFFER_BYTES = 5 * 1024 * 1024;
5244
5321
  var SHELL_METACHARACTERS = /[;|&$`(){}<>!'"]/;
5245
5322
  var SAFE_LABEL_PATTERN = /^[a-zA-Z0-9_ -]+$/;
@@ -5319,7 +5396,7 @@ function gitExec(args, cwd) {
5319
5396
  const result = child_process.spawnSync("git", args, {
5320
5397
  cwd,
5321
5398
  encoding: "utf-8",
5322
- timeout: GIT_TIMEOUT_MS,
5399
+ timeout: GIT_TIMEOUT_MS2,
5323
5400
  stdio: ["ignore", "pipe", "pipe"],
5324
5401
  windowsHide: true,
5325
5402
  maxBuffer: GIT_MAX_BUFFER_BYTES
@@ -6177,7 +6254,7 @@ async function runCuratorPostMortem(directory, options = {}) {
6177
6254
  warnings.push(`Pending proposals capped at ${MAX_PROPOSALS} (had ${proposals.length}); older entries truncated.`);
6178
6255
  proposals = proposals.slice(0, MAX_PROPOSALS);
6179
6256
  }
6180
- const unactionablePath = path13.join(directory, ".swarm", "knowledge-unactionable.jsonl");
6257
+ const unactionablePath = path13.join(resolveKnowledgeStoreDir(directory), "knowledge-unactionable.jsonl");
6181
6258
  let unactionable = readJsonlFile(unactionablePath, MAX_UNACTIONABLE);
6182
6259
  if (unactionable.length > MAX_UNACTIONABLE) {
6183
6260
  warnings.push(`Unactionable entries capped at ${MAX_UNACTIONABLE} (had ${unactionable.length}); older entries truncated.`);
@@ -11288,6 +11365,10 @@ var ACTIVE_STATE_TO_CLEAN = [
11288
11365
  "swarm.db-shm",
11289
11366
  "swarm.db-wal"
11290
11367
  ];
11368
+ var KNOWLEDGE_FAMILY_ARTIFACTS = new Set([
11369
+ "knowledge.jsonl",
11370
+ "knowledge-rejected.jsonl"
11371
+ ]);
11291
11372
  var ACTIVE_STATE_DIRS_TO_CLEAN = [
11292
11373
  "evidence",
11293
11374
  "session",
@@ -11647,10 +11728,17 @@ async function runArchiveStage(ctx) {
11647
11728
  try {
11648
11729
  await fs11.mkdir(ctx.archiveDir, { recursive: true });
11649
11730
  const WAL_SIDECAR_FILES = new Set(["swarm.db-shm", "swarm.db-wal"]);
11731
+ const linkedKnowledgeShared = isLinked(ctx.directory);
11732
+ if (linkedKnowledgeShared) {
11733
+ ctx.warnings.push("Worktree is linked: shared knowledge (knowledge.jsonl, knowledge-rejected.jsonl) lives in the link store and is not archived or cleaned by /swarm close. Manage it via the link.");
11734
+ }
11650
11735
  for (const artifact of ARCHIVE_ARTIFACTS) {
11651
11736
  if (WAL_SIDECAR_FILES.has(artifact)) {
11652
11737
  continue;
11653
11738
  }
11739
+ if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
11740
+ continue;
11741
+ }
11654
11742
  const srcPath = path24.join(ctx.swarmDir, artifact);
11655
11743
  const destPath = path24.join(ctx.archiveDir, artifact);
11656
11744
  if (artifact === "swarm.db") {
@@ -11740,8 +11828,19 @@ async function runArchiveEvidenceRetention(ctx) {
11740
11828
  async function runCleanStage(ctx) {
11741
11829
  let configBackupsRemoved = 0;
11742
11830
  const cleanedFiles = [];
11831
+ const linkedKnowledgeShared = isLinked(ctx.directory);
11832
+ if (linkedKnowledgeShared) {
11833
+ for (const artifact of KNOWLEDGE_FAMILY_ARTIFACTS) {
11834
+ if (ctx.archivedActiveStateFiles.has(artifact)) {
11835
+ ctx.warnings.push(`[link-guard] Shared knowledge artifact "${artifact}" appears in ` + "the archive set while this worktree is linked \u2014 archive stage " + "should have skipped it. Artifact will NOT be deleted.");
11836
+ }
11837
+ }
11838
+ }
11743
11839
  if (ctx.archivedActiveStateFiles.size > 0) {
11744
11840
  for (const artifact of ACTIVE_STATE_TO_CLEAN) {
11841
+ if (linkedKnowledgeShared && KNOWLEDGE_FAMILY_ARTIFACTS.has(artifact)) {
11842
+ continue;
11843
+ }
11745
11844
  if (!ctx.archivedActiveStateFiles.has(artifact)) {
11746
11845
  const reason = ctx.archiveFailureReasons?.get(artifact);
11747
11846
  ctx.warnings.push(reason ? `Preserved ${artifact} because it was not successfully archived: ${reason}.` : `Preserved ${artifact} because it was not successfully archived.`);
@@ -17975,7 +18074,7 @@ async function handleKnowledgeRestoreCommand(directory, args) {
17975
18074
  return "Invalid entry ID. IDs must be 1-64 characters: letters, digits, hyphens, underscores only.";
17976
18075
  }
17977
18076
  try {
17978
- const quarantinePath = join30(directory, ".swarm", "knowledge-quarantined.jsonl");
18077
+ const quarantinePath = join30(resolveKnowledgeStoreDir(directory), "knowledge-quarantined.jsonl");
17979
18078
  const entries = await readKnowledge(quarantinePath);
17980
18079
  const resolved = resolveEntryByPrefix(entries, inputId);
17981
18080
  if ("error" in resolved) {
@@ -18225,6 +18324,163 @@ var _internals31 = {
18225
18324
  computeLearningMetrics
18226
18325
  };
18227
18326
 
18327
+ // src/commands/link.ts
18328
+ import { existsSync as existsSync23 } from "fs";
18329
+ import * as path39 from "path";
18330
+
18331
+ // src/knowledge/identity.ts
18332
+ import * as child_process5 from "child_process";
18333
+ import { createHash as createHash4 } from "crypto";
18334
+ import * as path38 from "path";
18335
+ function deriveProjectHash(directory) {
18336
+ const absolutePath = path38.resolve(directory);
18337
+ let hashInput;
18338
+ try {
18339
+ const remoteUrl = child_process5.execSync("git remote get-url origin", {
18340
+ cwd: directory,
18341
+ encoding: "utf-8",
18342
+ stdio: ["pipe", "pipe", "ignore"],
18343
+ timeout: 1500
18344
+ }).trim();
18345
+ hashInput = remoteUrl.length > 0 ? remoteUrl : absolutePath;
18346
+ } catch {
18347
+ hashInput = absolutePath;
18348
+ }
18349
+ const hash = createHash4("sha256").update(hashInput).digest("hex");
18350
+ return hash.slice(0, 12);
18351
+ }
18352
+
18353
+ // src/commands/link.ts
18354
+ var DEDUP_THRESHOLD = 0.6;
18355
+ async function mergeLocalKnowledgeIntoLink(localSwarmDir, linkDir) {
18356
+ const localPath = path39.join(localSwarmDir, "knowledge.jsonl");
18357
+ const sharedPath = path39.join(linkDir, "knowledge.jsonl");
18358
+ if (!existsSync23(localPath))
18359
+ return { merged: 0, skipped: 0 };
18360
+ let merged = 0;
18361
+ let skipped = 0;
18362
+ const { readFileSync: readFileSync15 } = await import("fs");
18363
+ let changed = false;
18364
+ await transactKnowledge(sharedPath, (sharedEntries) => {
18365
+ const localEntries = [];
18366
+ try {
18367
+ const content = readFileSync15(localPath, "utf-8");
18368
+ for (const line of content.split(`
18369
+ `)) {
18370
+ if (line.trim()) {
18371
+ try {
18372
+ localEntries.push(JSON.parse(line));
18373
+ } catch {}
18374
+ }
18375
+ }
18376
+ } catch {
18377
+ return null;
18378
+ }
18379
+ if (localEntries.length === 0)
18380
+ return null;
18381
+ const result = [...sharedEntries];
18382
+ const seenIds = new Set(result.map((e) => e.id));
18383
+ changed = false;
18384
+ for (const entry of localEntries) {
18385
+ if (seenIds.has(entry.id)) {
18386
+ skipped++;
18387
+ continue;
18388
+ }
18389
+ if (findNearDuplicate(entry.lesson, result, DEDUP_THRESHOLD)) {
18390
+ skipped++;
18391
+ continue;
18392
+ }
18393
+ result.push(entry);
18394
+ seenIds.add(entry.id);
18395
+ merged++;
18396
+ changed = true;
18397
+ }
18398
+ return changed ? result : null;
18399
+ });
18400
+ return { merged, skipped };
18401
+ }
18402
+ function formatStatus(directory) {
18403
+ const pointer = readLinkPointer(directory);
18404
+ if (!pointer) {
18405
+ return [
18406
+ "\u2139\uFE0F This worktree is NOT linked. Its swarm knowledge is local to `.swarm/`.",
18407
+ "Run `/swarm link` to share knowledge across worktrees of this repo,",
18408
+ "or `/swarm link <name>` to share with deliberately similar projects."
18409
+ ].join(`
18410
+ `);
18411
+ }
18412
+ const linkDir = resolveLinkDir(pointer.linkId);
18413
+ const lines = [
18414
+ "\uD83D\uDD17 Linked \u2014 swarm knowledge is shared.",
18415
+ ` link id: ${pointer.linkId}`
18416
+ ];
18417
+ if (pointer.name)
18418
+ lines.push(` name: ${pointer.name}`);
18419
+ lines.push(` shared at: ${linkDir}`);
18420
+ lines.push(` since: ${pointer.createdAt}`);
18421
+ lines.push("Run `/swarm unlink` to stop sharing (keeps a local copy).");
18422
+ return lines.join(`
18423
+ `);
18424
+ }
18425
+ async function handleLinkCommand(directory, args) {
18426
+ const first = args[0];
18427
+ if (first === "status") {
18428
+ return formatStatus(directory);
18429
+ }
18430
+ const nameArg = args.find((a) => !a.startsWith("--"));
18431
+ let linkId;
18432
+ let displayName;
18433
+ if (nameArg) {
18434
+ const sanitized = sanitizeLinkId(nameArg);
18435
+ if (!sanitized) {
18436
+ return `\u274C Invalid link name "${nameArg}". Use letters, digits, '.', '-', or '_'.`;
18437
+ }
18438
+ linkId = sanitized;
18439
+ displayName = nameArg;
18440
+ } else {
18441
+ try {
18442
+ linkId = deriveProjectHash(directory);
18443
+ } catch (error2) {
18444
+ return `\u274C Failed to derive project hash: ${error2 instanceof Error ? error2.message : String(error2)}`;
18445
+ }
18446
+ }
18447
+ const existing = readLinkPointer(directory);
18448
+ if (existing && existing.linkId === linkId) {
18449
+ return `\u2139\uFE0F Already linked to "${linkId}".
18450
+ ${formatStatus(directory)}`;
18451
+ }
18452
+ const linkDir = resolveLinkDir(linkId);
18453
+ let merge;
18454
+ try {
18455
+ merge = await mergeLocalKnowledgeIntoLink(path39.join(directory, ".swarm"), linkDir);
18456
+ } catch (error2) {
18457
+ return `\u274C Failed to merge local knowledge into the link store: ${error2 instanceof Error ? error2.message : String(error2)}`;
18458
+ }
18459
+ const pointer = {
18460
+ version: 1,
18461
+ linkId,
18462
+ name: displayName,
18463
+ createdAt: new Date().toISOString(),
18464
+ source: "manual"
18465
+ };
18466
+ try {
18467
+ await writeLinkPointer(directory, pointer);
18468
+ } catch (error2) {
18469
+ return `\u274C Failed to write link pointer: ${error2 instanceof Error ? error2.message : String(error2)}`;
18470
+ }
18471
+ const relinkNote = existing ? `
18472
+ (Re-linked from previous link "${existing.linkId}".)` : "";
18473
+ const historyNote = merge.merged > 0 ? `
18474
+ note: merged lessons keep their text; their outcome-history counters re-accrue in the shared store.` : "";
18475
+ return [
18476
+ `\uD83D\uDD17 Linked this worktree to shared knowledge store "${linkId}".`,
18477
+ ` merged ${merge.merged} local lesson(s) into the shared store` + (merge.skipped > 0 ? ` (${merge.skipped} already present)` : "") + ".",
18478
+ ` shared at: ${linkDir}`,
18479
+ "All swarms linked to this id now read and write the same knowledge." + relinkNote + historyNote
18480
+ ].join(`
18481
+ `);
18482
+ }
18483
+
18228
18484
  // src/commands/loop.ts
18229
18485
  var MAX_OBJECTIVE_LEN = 2000;
18230
18486
  var DEPTHS2 = new Set(["standard", "exhaustive"]);
@@ -18340,8 +18596,8 @@ ${USAGE7}`;
18340
18596
  }
18341
18597
 
18342
18598
  // src/commands/memory.ts
18343
- import { existsSync as existsSync25 } from "fs";
18344
- import * as path44 from "path";
18599
+ import { existsSync as existsSync26 } from "fs";
18600
+ import * as path46 from "path";
18345
18601
  import { fileURLToPath as fileURLToPath2 } from "url";
18346
18602
 
18347
18603
  // src/memory/config.ts
@@ -18483,11 +18739,11 @@ class MemoryValidationError extends Error {
18483
18739
  // src/memory/evaluation.ts
18484
18740
  import * as fs17 from "fs/promises";
18485
18741
  import * as os9 from "os";
18486
- import * as path42 from "path";
18742
+ import * as path44 from "path";
18487
18743
 
18488
18744
  // src/memory/local-jsonl-provider.ts
18489
18745
  import { randomUUID as randomUUID5 } from "crypto";
18490
- import { existsSync as existsSync23 } from "fs";
18746
+ import { existsSync as existsSync24 } from "fs";
18491
18747
  import {
18492
18748
  appendFile as appendFile3,
18493
18749
  mkdir as mkdir10,
@@ -18495,10 +18751,10 @@ import {
18495
18751
  rename as rename5,
18496
18752
  writeFile as writeFile10
18497
18753
  } from "fs/promises";
18498
- import * as path38 from "path";
18754
+ import * as path40 from "path";
18499
18755
 
18500
18756
  // src/memory/schema.ts
18501
- import { createHash as createHash4 } from "crypto";
18757
+ import { createHash as createHash5 } from "crypto";
18502
18758
 
18503
18759
  // src/memory/redaction.ts
18504
18760
  var SECRET_PATTERNS = [
@@ -18741,7 +18997,7 @@ function stableScopeKey(scope) {
18741
18997
  }
18742
18998
  function computeMemoryContentHash(recordLike) {
18743
18999
  const normalized = normalizeMemoryText(recordLike.text).toLowerCase();
18744
- return createHash4("sha256").update(`${stableScopeKey(recordLike.scope)}
19000
+ return createHash5("sha256").update(`${stableScopeKey(recordLike.scope)}
18745
19001
  ${recordLike.kind}
18746
19002
  ${normalized}`).digest("hex");
18747
19003
  }
@@ -19356,7 +19612,7 @@ class LocalJsonlMemoryProvider {
19356
19612
  pathFor(file) {
19357
19613
  const storageDir = this.config.storageDir.replace(/^\.swarm[/\\]?/, "");
19358
19614
  const filename = file === "memories" ? "memories.jsonl" : file === "proposals" ? "proposals.jsonl" : "audit.jsonl";
19359
- return validateSwarmPath(this.rootDirectory, path38.join(storageDir, filename));
19615
+ return validateSwarmPath(this.rootDirectory, path40.join(storageDir, filename));
19360
19616
  }
19361
19617
  async initialize() {
19362
19618
  if (this.initialized)
@@ -19683,7 +19939,7 @@ function validateLoadedProposals(values, config) {
19683
19939
  return { records, invalidCount };
19684
19940
  }
19685
19941
  async function readJsonl(filePath) {
19686
- if (!existsSync23(filePath))
19942
+ if (!existsSync24(filePath))
19687
19943
  return [];
19688
19944
  const content = await readFile12(filePath, "utf-8");
19689
19945
  const records = [];
@@ -19739,12 +19995,12 @@ function parseRecallUsageEvent(event) {
19739
19995
  }
19740
19996
  }
19741
19997
  async function appendJsonl(filePath, value) {
19742
- await mkdir10(path38.dirname(filePath), { recursive: true });
19998
+ await mkdir10(path40.dirname(filePath), { recursive: true });
19743
19999
  await appendFile3(filePath, `${JSON.stringify(value)}
19744
20000
  `, "utf-8");
19745
20001
  }
19746
20002
  async function writeJsonlAtomic(filePath, values) {
19747
- await mkdir10(path38.dirname(filePath), { recursive: true });
20003
+ await mkdir10(path40.dirname(filePath), { recursive: true });
19748
20004
  const tmp = `${filePath}.tmp.${randomUUID5()}`;
19749
20005
  const content = values.map((value) => JSON.stringify(value)).join(`
19750
20006
  `) + (values.length > 0 ? `
@@ -19755,18 +20011,18 @@ async function writeJsonlAtomic(filePath, values) {
19755
20011
 
19756
20012
  // src/memory/provider-pool.ts
19757
20013
  import { realpathSync as realpathSync2 } from "fs";
19758
- import * as path41 from "path";
20014
+ import * as path43 from "path";
19759
20015
 
19760
20016
  // src/memory/sqlite-provider.ts
19761
20017
  import { randomUUID as randomUUID6 } from "crypto";
19762
20018
  import { mkdirSync as mkdirSync15 } from "fs";
19763
20019
  import { createRequire as createRequire2 } from "module";
19764
- import * as path40 from "path";
20020
+ import * as path42 from "path";
19765
20021
 
19766
20022
  // src/memory/jsonl-migration.ts
19767
- import { existsSync as existsSync24, renameSync as renameSync10, unlinkSync as unlinkSync6 } from "fs";
20023
+ import { existsSync as existsSync25, renameSync as renameSync10, unlinkSync as unlinkSync6 } from "fs";
19768
20024
  import { copyFile as copyFile2, mkdir as mkdir11, readFile as readFile13, stat as stat5, writeFile as writeFile11 } from "fs/promises";
19769
- import * as path39 from "path";
20025
+ import * as path41 from "path";
19770
20026
  var LEGACY_JSONL_MIGRATION_VERSION = 2;
19771
20027
  var LEGACY_JSONL_MIGRATION_NAME = "legacy_jsonl_import_complete";
19772
20028
  function resolveMemoryStorageDir(rootDirectory, config = {}) {
@@ -19782,8 +20038,8 @@ function resolveSqliteDatabasePath(rootDirectory, config = {}) {
19782
20038
  async function readLegacyJsonl(rootDirectory, config = {}) {
19783
20039
  const resolved = resolveConfig(config);
19784
20040
  const storageDir = resolveMemoryStorageDir(rootDirectory, resolved);
19785
- const memoryLoad = await readMemoryJsonl(path39.join(storageDir, "memories.jsonl"), resolved);
19786
- const proposalLoad = await readProposalJsonl(path39.join(storageDir, "proposals.jsonl"), resolved);
20041
+ const memoryLoad = await readMemoryJsonl(path41.join(storageDir, "memories.jsonl"), resolved);
20042
+ const proposalLoad = await readProposalJsonl(path41.join(storageDir, "proposals.jsonl"), resolved);
19787
20043
  return {
19788
20044
  memories: memoryLoad.records,
19789
20045
  proposals: proposalLoad.records,
@@ -19793,15 +20049,15 @@ async function readLegacyJsonl(rootDirectory, config = {}) {
19793
20049
  }
19794
20050
  async function backupLegacyJsonl(rootDirectory, config = {}) {
19795
20051
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
19796
- const backupDir = path39.join(storageDir, "backups");
20052
+ const backupDir = path41.join(storageDir, "backups");
19797
20053
  await mkdir11(backupDir, { recursive: true });
19798
20054
  const results = [];
19799
20055
  for (const filename of ["memories.jsonl", "proposals.jsonl"]) {
19800
- const source = path39.join(storageDir, filename);
19801
- if (!existsSync24(source))
20056
+ const source = path41.join(storageDir, filename);
20057
+ if (!existsSync25(source))
19802
20058
  continue;
19803
- const backup = path39.join(backupDir, `${filename}.pre-sqlite-migration`);
19804
- if (existsSync24(backup)) {
20059
+ const backup = path41.join(backupDir, `${filename}.pre-sqlite-migration`);
20060
+ if (existsSync25(backup)) {
19805
20061
  results.push({ source, backup, created: false });
19806
20062
  continue;
19807
20063
  }
@@ -19811,11 +20067,11 @@ async function backupLegacyJsonl(rootDirectory, config = {}) {
19811
20067
  return results;
19812
20068
  }
19813
20069
  async function writeJsonlExport(rootDirectory, config, memories, proposals) {
19814
- const exportDir = path39.join(resolveMemoryStorageDir(rootDirectory, config), "export");
20070
+ const exportDir = path41.join(resolveMemoryStorageDir(rootDirectory, config), "export");
19815
20071
  await mkdir11(exportDir, { recursive: true });
19816
- const memoriesPath = path39.join(exportDir, "memories.jsonl");
19817
- const proposalsPath = path39.join(exportDir, "proposals.jsonl");
19818
- const memoriesTempPath = path39.join(path39.dirname(memoriesPath), `${path39.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20072
+ const memoriesPath = path41.join(exportDir, "memories.jsonl");
20073
+ const proposalsPath = path41.join(exportDir, "proposals.jsonl");
20074
+ const memoriesTempPath = path41.join(path41.dirname(memoriesPath), `${path41.basename(memoriesPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
19819
20075
  try {
19820
20076
  await writeFile11(memoriesTempPath, toJsonl(memories), "utf-8");
19821
20077
  renameSync10(memoriesTempPath, memoriesPath);
@@ -19825,7 +20081,7 @@ async function writeJsonlExport(rootDirectory, config, memories, proposals) {
19825
20081
  } catch {}
19826
20082
  throw err;
19827
20083
  }
19828
- const proposalsTempPath = path39.join(path39.dirname(proposalsPath), `${path39.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20084
+ const proposalsTempPath = path41.join(path41.dirname(proposalsPath), `${path41.basename(proposalsPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
19829
20085
  try {
19830
20086
  await writeFile11(proposalsTempPath, toJsonl(proposals), "utf-8");
19831
20087
  renameSync10(proposalsTempPath, proposalsPath);
@@ -19838,9 +20094,9 @@ async function writeJsonlExport(rootDirectory, config, memories, proposals) {
19838
20094
  return { directory: exportDir, memoriesPath, proposalsPath };
19839
20095
  }
19840
20096
  async function writeMigrationReport(rootDirectory, report, config = {}) {
19841
- const reportPath = path39.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
19842
- await mkdir11(path39.dirname(reportPath), { recursive: true });
19843
- const reportTempPath = path39.join(path39.dirname(reportPath), `${path39.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
20097
+ const reportPath = path41.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
20098
+ await mkdir11(path41.dirname(reportPath), { recursive: true });
20099
+ const reportTempPath = path41.join(path41.dirname(reportPath), `${path41.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
19844
20100
  try {
19845
20101
  await writeFile11(reportTempPath, `${JSON.stringify(report, null, 2)}
19846
20102
  `, "utf-8");
@@ -19854,8 +20110,8 @@ async function writeMigrationReport(rootDirectory, report, config = {}) {
19854
20110
  return reportPath;
19855
20111
  }
19856
20112
  async function readMigrationReport(rootDirectory, config = {}) {
19857
- const reportPath = path39.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
19858
- if (!existsSync24(reportPath))
20113
+ const reportPath = path41.join(resolveMemoryStorageDir(rootDirectory, config), "migration-report.json");
20114
+ if (!existsSync25(reportPath))
19859
20115
  return null;
19860
20116
  try {
19861
20117
  return JSON.parse(await readFile13(reportPath, "utf-8"));
@@ -19867,15 +20123,15 @@ async function getLegacyJsonlFileStatus(rootDirectory, config = {}) {
19867
20123
  const storageDir = resolveMemoryStorageDir(rootDirectory, config);
19868
20124
  const statuses = [];
19869
20125
  for (const file of ["memories.jsonl", "proposals.jsonl"]) {
19870
- const filePath = path39.join(storageDir, file);
20126
+ const filePath = path41.join(storageDir, file);
19871
20127
  let sizeBytes = 0;
19872
- if (existsSync24(filePath)) {
20128
+ if (existsSync25(filePath)) {
19873
20129
  sizeBytes = (await stat5(filePath)).size;
19874
20130
  }
19875
20131
  statuses.push({
19876
20132
  file,
19877
20133
  path: filePath,
19878
- exists: existsSync24(filePath),
20134
+ exists: existsSync25(filePath),
19879
20135
  sizeBytes
19880
20136
  });
19881
20137
  }
@@ -19956,7 +20212,7 @@ async function readProposalJsonl(filePath, config) {
19956
20212
  return { records, invalidRows, totalRows: rows.totalRows };
19957
20213
  }
19958
20214
  async function readJsonlRows(filePath) {
19959
- if (!existsSync24(filePath)) {
20215
+ if (!existsSync25(filePath)) {
19960
20216
  return { rows: [], invalidRows: [], totalRows: 0 };
19961
20217
  }
19962
20218
  const content = await readFile13(filePath, "utf-8");
@@ -20175,7 +20431,7 @@ class SQLiteMemoryProvider {
20175
20431
  }
20176
20432
  async doInitialize() {
20177
20433
  const dbPath = this.databasePath();
20178
- mkdirSync15(path40.dirname(dbPath), { recursive: true });
20434
+ mkdirSync15(path42.dirname(dbPath), { recursive: true });
20179
20435
  const Db = loadDatabaseCtor2();
20180
20436
  this.db = new Db(dbPath);
20181
20437
  this.db.run("PRAGMA journal_mode = WAL;");
@@ -21204,7 +21460,7 @@ function resolvePoolKey(directory) {
21204
21460
  try {
21205
21461
  return realpathSync2(directory);
21206
21462
  } catch {
21207
- return path41.resolve(directory);
21463
+ return path43.resolve(directory);
21208
21464
  }
21209
21465
  }
21210
21466
 
@@ -21276,7 +21532,7 @@ var DEFAULT_MODES = [
21276
21532
  ];
21277
21533
  var DEFAULT_TIMESTAMP = "2026-05-26T12:00:00.000Z";
21278
21534
  async function evaluateMemoryRecallFixtures(options) {
21279
- const fixtureDirectory = path42.resolve(options.fixtureDirectory);
21535
+ const fixtureDirectory = path44.resolve(options.fixtureDirectory);
21280
21536
  const providers = options.providers ?? DEFAULT_PROVIDERS;
21281
21537
  const modes = options.modes ?? DEFAULT_MODES;
21282
21538
  const generatedAt = new Date().toISOString();
@@ -21285,7 +21541,7 @@ async function evaluateMemoryRecallFixtures(options) {
21285
21541
  for (const fixture of fixtures) {
21286
21542
  const materialized = materializeFixture(fixture);
21287
21543
  for (const providerName of providers) {
21288
- const tempRoot = await fs17.realpath(await fs17.mkdtemp(path42.join(os9.tmpdir(), "swarm-memory-eval-")));
21544
+ const tempRoot = await fs17.realpath(await fs17.mkdtemp(path44.join(os9.tmpdir(), "swarm-memory-eval-")));
21289
21545
  const provider = createEvaluationProvider(providerName, tempRoot);
21290
21546
  try {
21291
21547
  await provider.initialize?.();
@@ -21329,7 +21585,7 @@ async function loadRecallEvaluationFixtures(fixtureDirectory) {
21329
21585
  const files = entries.filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name).sort((a, b) => a.localeCompare(b));
21330
21586
  const fixtures = [];
21331
21587
  for (const file of files) {
21332
- const raw = await fs17.readFile(path42.join(fixtureDirectory, file), "utf-8");
21588
+ const raw = await fs17.readFile(path44.join(fixtureDirectory, file), "utf-8");
21333
21589
  fixtures.push(validateFixture(JSON.parse(raw), file));
21334
21590
  }
21335
21591
  return fixtures;
@@ -21606,8 +21862,8 @@ var CuratorOutputMemoryDecisionSchema = exports_external.object({
21606
21862
  }).passthrough();
21607
21863
  // src/memory/consolidation-log.ts
21608
21864
  import { appendFile as appendFile4, mkdir as mkdir12, readFile as readFile15 } from "fs/promises";
21609
- import * as path43 from "path";
21610
- var LOG_RELATIVE_PATH = path43.join("memory", "consolidation-log.jsonl");
21865
+ import * as path45 from "path";
21866
+ var LOG_RELATIVE_PATH = path45.join("memory", "consolidation-log.jsonl");
21611
21867
  async function readConsolidationLog(directory) {
21612
21868
  const filePath = validateSwarmPath(directory, LOG_RELATIVE_PATH);
21613
21869
  let raw;
@@ -21630,7 +21886,7 @@ async function readConsolidationLog(directory) {
21630
21886
  }
21631
21887
 
21632
21888
  // src/commands/memory.ts
21633
- var PACKAGE_ROOT = path44.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
21889
+ var PACKAGE_ROOT = path46.resolve(resolvePackageRootFromModule(fileURLToPath2(import.meta.url)));
21634
21890
  async function handleMemoryCommand(_directory, _args) {
21635
21891
  return [
21636
21892
  "## Swarm Memory",
@@ -21688,7 +21944,7 @@ async function handleMemoryStatusCommand(directory, _args) {
21688
21944
  `- Provider: \`${config.provider}\``,
21689
21945
  `- Storage: \`${storageDir}\``,
21690
21946
  `- SQLite path: \`${sqlitePath}\``,
21691
- `- SQLite database exists: \`${existsSync25(sqlitePath)}\``,
21947
+ `- SQLite database exists: \`${existsSync26(sqlitePath)}\``,
21692
21948
  `- Automatic destructive cleanup: \`disabled\``,
21693
21949
  "",
21694
21950
  "### Legacy JSONL"
@@ -21928,7 +22184,7 @@ function resolveCommandMemoryConfig(directory) {
21928
22184
  }
21929
22185
  function parseEvaluateArgs(directory, args) {
21930
22186
  let json = false;
21931
- let fixtureDirectory = path44.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
22187
+ let fixtureDirectory = path46.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall");
21932
22188
  for (let i = 0;i < args.length; i++) {
21933
22189
  const arg = args[i];
21934
22190
  if (arg === "--json") {
@@ -21942,10 +22198,10 @@ function parseEvaluateArgs(directory, args) {
21942
22198
  error: "Usage: /swarm memory evaluate [--json] [--fixtures <directory>]"
21943
22199
  };
21944
22200
  }
21945
- const resolvedFixtures = path44.resolve(directory, next);
21946
- const canonical = path44.normalize(resolvedFixtures) + path44.sep;
21947
- const allowedRootA = path44.normalize(directory) + path44.sep;
21948
- const allowedRootB = path44.normalize(path44.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path44.sep;
22201
+ const resolvedFixtures = path46.resolve(directory, next);
22202
+ const canonical = path46.normalize(resolvedFixtures) + path46.sep;
22203
+ const allowedRootA = path46.normalize(directory) + path46.sep;
22204
+ const allowedRootB = path46.normalize(path46.join(PACKAGE_ROOT, "tests", "fixtures", "memory-recall")) + path46.sep;
21949
22205
  if (!canonical.startsWith(allowedRootA) && !canonical.startsWith(allowedRootB)) {
21950
22206
  return {
21951
22207
  error: "--fixtures <directory> must resolve under the project directory or the bundled tests/fixtures/memory-recall directory"
@@ -21984,15 +22240,15 @@ function parseMaintenanceArgs(args, options) {
21984
22240
  return { limit, confirm };
21985
22241
  }
21986
22242
  function resolvePackageRootFromModule(modulePath) {
21987
- const moduleDir = path44.dirname(modulePath);
21988
- const leaf = path44.basename(moduleDir);
22243
+ const moduleDir = path46.dirname(modulePath);
22244
+ const leaf = path46.basename(moduleDir);
21989
22245
  if (leaf === "commands" || leaf === "cli") {
21990
- return path44.resolve(moduleDir, "..", "..");
22246
+ return path46.resolve(moduleDir, "..", "..");
21991
22247
  }
21992
22248
  if (leaf === "dist") {
21993
- return path44.resolve(moduleDir, "..");
22249
+ return path46.resolve(moduleDir, "..");
21994
22250
  }
21995
- return path44.resolve(moduleDir, "..");
22251
+ return path46.resolve(moduleDir, "..");
21996
22252
  }
21997
22253
  function formatMigrationResult(label, report) {
21998
22254
  if (!report) {
@@ -22687,11 +22943,11 @@ var _internals36 = {
22687
22943
 
22688
22944
  // src/services/preflight-service.ts
22689
22945
  import * as fs24 from "fs";
22690
- import * as path51 from "path";
22946
+ import * as path53 from "path";
22691
22947
 
22692
22948
  // src/tools/lint.ts
22693
22949
  import * as fs18 from "fs";
22694
- import * as path45 from "path";
22950
+ import * as path47 from "path";
22695
22951
 
22696
22952
  // src/utils/path-security.ts
22697
22953
  function containsPathTraversal(str) {
@@ -22747,9 +23003,9 @@ function validateArgs(args) {
22747
23003
  }
22748
23004
  function getLinterCommand(linter, mode, projectDir) {
22749
23005
  const isWindows = process.platform === "win32";
22750
- const binDir = path45.join(projectDir, "node_modules", ".bin");
22751
- const biomeBin = isWindows ? path45.join(binDir, "biome.EXE") : path45.join(binDir, "biome");
22752
- const eslintBin = isWindows ? path45.join(binDir, "eslint.cmd") : path45.join(binDir, "eslint");
23006
+ const binDir = path47.join(projectDir, "node_modules", ".bin");
23007
+ const biomeBin = isWindows ? path47.join(binDir, "biome.EXE") : path47.join(binDir, "biome");
23008
+ const eslintBin = isWindows ? path47.join(binDir, "eslint.cmd") : path47.join(binDir, "eslint");
22753
23009
  switch (linter) {
22754
23010
  case "biome":
22755
23011
  if (mode === "fix") {
@@ -22765,7 +23021,7 @@ function getLinterCommand(linter, mode, projectDir) {
22765
23021
  }
22766
23022
  function getAdditionalLinterCommand(linter, mode, cwd) {
22767
23023
  const gradlewName = process.platform === "win32" ? "gradlew.bat" : "gradlew";
22768
- const gradlew = fs18.existsSync(path45.join(cwd, gradlewName)) ? path45.join(cwd, gradlewName) : null;
23024
+ const gradlew = fs18.existsSync(path47.join(cwd, gradlewName)) ? path47.join(cwd, gradlewName) : null;
22769
23025
  switch (linter) {
22770
23026
  case "ruff":
22771
23027
  return mode === "fix" ? ["ruff", "check", "--fix", "."] : ["ruff", "check", "."];
@@ -22799,10 +23055,10 @@ function getAdditionalLinterCommand(linter, mode, cwd) {
22799
23055
  }
22800
23056
  }
22801
23057
  function detectRuff(cwd) {
22802
- if (fs18.existsSync(path45.join(cwd, "ruff.toml")))
23058
+ if (fs18.existsSync(path47.join(cwd, "ruff.toml")))
22803
23059
  return isCommandAvailable("ruff");
22804
23060
  try {
22805
- const pyproject = path45.join(cwd, "pyproject.toml");
23061
+ const pyproject = path47.join(cwd, "pyproject.toml");
22806
23062
  if (fs18.existsSync(pyproject)) {
22807
23063
  const content = fs18.readFileSync(pyproject, "utf-8");
22808
23064
  if (content.includes("[tool.ruff]"))
@@ -22812,19 +23068,19 @@ function detectRuff(cwd) {
22812
23068
  return false;
22813
23069
  }
22814
23070
  function detectClippy(cwd) {
22815
- return fs18.existsSync(path45.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
23071
+ return fs18.existsSync(path47.join(cwd, "Cargo.toml")) && isCommandAvailable("cargo");
22816
23072
  }
22817
23073
  function detectGolangciLint(cwd) {
22818
- return fs18.existsSync(path45.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
23074
+ return fs18.existsSync(path47.join(cwd, "go.mod")) && isCommandAvailable("golangci-lint");
22819
23075
  }
22820
23076
  function detectCheckstyle(cwd) {
22821
- const hasMaven = fs18.existsSync(path45.join(cwd, "pom.xml"));
22822
- const hasGradle = fs18.existsSync(path45.join(cwd, "build.gradle")) || fs18.existsSync(path45.join(cwd, "build.gradle.kts"));
22823
- const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs18.existsSync(path45.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
23077
+ const hasMaven = fs18.existsSync(path47.join(cwd, "pom.xml"));
23078
+ const hasGradle = fs18.existsSync(path47.join(cwd, "build.gradle")) || fs18.existsSync(path47.join(cwd, "build.gradle.kts"));
23079
+ const hasBinary = hasMaven && isCommandAvailable("mvn") || hasGradle && (fs18.existsSync(path47.join(cwd, "gradlew")) || isCommandAvailable("gradle"));
22824
23080
  return (hasMaven || hasGradle) && hasBinary;
22825
23081
  }
22826
23082
  function detectKtlint(cwd) {
22827
- const hasKotlin = fs18.existsSync(path45.join(cwd, "build.gradle.kts")) || fs18.existsSync(path45.join(cwd, "build.gradle")) || (() => {
23083
+ const hasKotlin = fs18.existsSync(path47.join(cwd, "build.gradle.kts")) || fs18.existsSync(path47.join(cwd, "build.gradle")) || (() => {
22828
23084
  try {
22829
23085
  return fs18.readdirSync(cwd).some((f) => f.endsWith(".kt") || f.endsWith(".kts"));
22830
23086
  } catch {
@@ -22843,11 +23099,11 @@ function detectDotnetFormat(cwd) {
22843
23099
  }
22844
23100
  }
22845
23101
  function detectCppcheck(cwd) {
22846
- if (fs18.existsSync(path45.join(cwd, "CMakeLists.txt"))) {
23102
+ if (fs18.existsSync(path47.join(cwd, "CMakeLists.txt"))) {
22847
23103
  return isCommandAvailable("cppcheck");
22848
23104
  }
22849
23105
  try {
22850
- const dirsToCheck = [cwd, path45.join(cwd, "src")];
23106
+ const dirsToCheck = [cwd, path47.join(cwd, "src")];
22851
23107
  const hasCpp = dirsToCheck.some((dir) => {
22852
23108
  try {
22853
23109
  return fs18.readdirSync(dir).some((f) => /\.(c|cpp|cc|cxx|h|hpp)$/.test(f));
@@ -22861,13 +23117,13 @@ function detectCppcheck(cwd) {
22861
23117
  }
22862
23118
  }
22863
23119
  function detectSwiftlint(cwd) {
22864
- return fs18.existsSync(path45.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
23120
+ return fs18.existsSync(path47.join(cwd, "Package.swift")) && isCommandAvailable("swiftlint");
22865
23121
  }
22866
23122
  function detectDartAnalyze(cwd) {
22867
- return fs18.existsSync(path45.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
23123
+ return fs18.existsSync(path47.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
22868
23124
  }
22869
23125
  function detectRubocop(cwd) {
22870
- return (fs18.existsSync(path45.join(cwd, "Gemfile")) || fs18.existsSync(path45.join(cwd, "gems.rb")) || fs18.existsSync(path45.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
23126
+ return (fs18.existsSync(path47.join(cwd, "Gemfile")) || fs18.existsSync(path47.join(cwd, "gems.rb")) || fs18.existsSync(path47.join(cwd, ".rubocop.yml"))) && (isCommandAvailable("rubocop") || isCommandAvailable("bundle"));
22871
23127
  }
22872
23128
  function detectAdditionalLinter(cwd) {
22873
23129
  if (detectRuff(cwd))
@@ -22895,10 +23151,10 @@ function detectAdditionalLinter(cwd) {
22895
23151
  function findBinInAncestors(startDir, binName) {
22896
23152
  let dir = startDir;
22897
23153
  while (true) {
22898
- const candidate = path45.join(dir, "node_modules", ".bin", binName);
23154
+ const candidate = path47.join(dir, "node_modules", ".bin", binName);
22899
23155
  if (fs18.existsSync(candidate))
22900
23156
  return candidate;
22901
- const parent = path45.dirname(dir);
23157
+ const parent = path47.dirname(dir);
22902
23158
  if (parent === dir)
22903
23159
  break;
22904
23160
  dir = parent;
@@ -22907,10 +23163,10 @@ function findBinInAncestors(startDir, binName) {
22907
23163
  }
22908
23164
  function findBinInEnvPath(binName) {
22909
23165
  const searchPath = process.env.PATH ?? "";
22910
- for (const dir of searchPath.split(path45.delimiter)) {
23166
+ for (const dir of searchPath.split(path47.delimiter)) {
22911
23167
  if (!dir)
22912
23168
  continue;
22913
- const candidate = path45.join(dir, binName);
23169
+ const candidate = path47.join(dir, binName);
22914
23170
  if (fs18.existsSync(candidate))
22915
23171
  return candidate;
22916
23172
  }
@@ -22923,13 +23179,13 @@ async function detectAvailableLinter(directory) {
22923
23179
  return null;
22924
23180
  const projectDir = directory;
22925
23181
  const isWindows = process.platform === "win32";
22926
- const biomeBin = isWindows ? path45.join(projectDir, "node_modules", ".bin", "biome.EXE") : path45.join(projectDir, "node_modules", ".bin", "biome");
22927
- const eslintBin = isWindows ? path45.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path45.join(projectDir, "node_modules", ".bin", "eslint");
23182
+ const biomeBin = isWindows ? path47.join(projectDir, "node_modules", ".bin", "biome.EXE") : path47.join(projectDir, "node_modules", ".bin", "biome");
23183
+ const eslintBin = isWindows ? path47.join(projectDir, "node_modules", ".bin", "eslint.cmd") : path47.join(projectDir, "node_modules", ".bin", "eslint");
22928
23184
  const localResult = await _detectAvailableLinter(projectDir, biomeBin, eslintBin);
22929
23185
  if (localResult)
22930
23186
  return localResult;
22931
- const biomeAncestor = findBinInAncestors(path45.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
22932
- const eslintAncestor = findBinInAncestors(path45.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
23187
+ const biomeAncestor = findBinInAncestors(path47.dirname(projectDir), isWindows ? "biome.EXE" : "biome");
23188
+ const eslintAncestor = findBinInAncestors(path47.dirname(projectDir), isWindows ? "eslint.cmd" : "eslint");
22933
23189
  if (biomeAncestor || eslintAncestor) {
22934
23190
  return _detectAvailableLinter(projectDir, biomeAncestor ?? biomeBin, eslintAncestor ?? eslintBin);
22935
23191
  }
@@ -22948,7 +23204,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
22948
23204
  stderr: "pipe"
22949
23205
  });
22950
23206
  const biomeExit = biomeProc.exited;
22951
- const timeout = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), DETECT_TIMEOUT));
23207
+ const timeout = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), DETECT_TIMEOUT));
22952
23208
  const result = await Promise.race([biomeExit, timeout]);
22953
23209
  if (result === "timeout") {
22954
23210
  biomeProc.kill();
@@ -22962,7 +23218,7 @@ async function _detectAvailableLinter(_projectDir, biomeBin, eslintBin) {
22962
23218
  stderr: "pipe"
22963
23219
  });
22964
23220
  const eslintExit = eslintProc.exited;
22965
- const timeout = new Promise((resolve13) => setTimeout(() => resolve13("timeout"), DETECT_TIMEOUT));
23221
+ const timeout = new Promise((resolve14) => setTimeout(() => resolve14("timeout"), DETECT_TIMEOUT));
22966
23222
  const result = await Promise.race([eslintExit, timeout]);
22967
23223
  if (result === "timeout") {
22968
23224
  eslintProc.kill();
@@ -23143,7 +23399,7 @@ var _internals37 = {
23143
23399
 
23144
23400
  // src/tools/secretscan.ts
23145
23401
  import * as fs19 from "fs";
23146
- import * as path46 from "path";
23402
+ import * as path48 from "path";
23147
23403
  var MAX_FILE_PATH_LENGTH = 500;
23148
23404
  var MAX_FILE_SIZE_BYTES = 512 * 1024;
23149
23405
  var MAX_FILES_SCANNED = 1000;
@@ -23370,7 +23626,7 @@ function isGlobOrPathPattern(pattern) {
23370
23626
  return pattern.includes("/") || pattern.includes("\\") || /[*?[\]{}]/.test(pattern);
23371
23627
  }
23372
23628
  function loadSecretScanIgnore(scanDir) {
23373
- const ignorePath = path46.join(scanDir, ".secretscanignore");
23629
+ const ignorePath = path48.join(scanDir, ".secretscanignore");
23374
23630
  try {
23375
23631
  if (!fs19.existsSync(ignorePath))
23376
23632
  return [];
@@ -23393,7 +23649,7 @@ function isExcluded(entry, relPath, exactNames, globPatterns) {
23393
23649
  if (exactNames.has(entry))
23394
23650
  return true;
23395
23651
  for (const pattern of globPatterns) {
23396
- if (path46.matchesGlob(relPath, pattern))
23652
+ if (path48.matchesGlob(relPath, pattern))
23397
23653
  return true;
23398
23654
  }
23399
23655
  return false;
@@ -23414,7 +23670,7 @@ function validateDirectoryInput(dir) {
23414
23670
  return null;
23415
23671
  }
23416
23672
  function isBinaryFile(filePath, buffer) {
23417
- const ext = path46.extname(filePath).toLowerCase();
23673
+ const ext = path48.extname(filePath).toLowerCase();
23418
23674
  if (DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
23419
23675
  return true;
23420
23676
  }
@@ -23551,9 +23807,9 @@ function isSymlinkLoop(realPath, visited) {
23551
23807
  return false;
23552
23808
  }
23553
23809
  function isPathWithinScope(realPath, scanDir) {
23554
- const resolvedScanDir = path46.resolve(scanDir);
23555
- const resolvedRealPath = path46.resolve(realPath);
23556
- return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path46.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
23810
+ const resolvedScanDir = path48.resolve(scanDir);
23811
+ const resolvedRealPath = path48.resolve(realPath);
23812
+ return resolvedRealPath === resolvedScanDir || resolvedRealPath.startsWith(resolvedScanDir + path48.sep) || resolvedRealPath.startsWith(`${resolvedScanDir}/`) || resolvedRealPath.startsWith(`${resolvedScanDir}\\`);
23557
23813
  }
23558
23814
  function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, stats = {
23559
23815
  skippedDirs: 0,
@@ -23579,8 +23835,8 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
23579
23835
  return a.localeCompare(b);
23580
23836
  });
23581
23837
  for (const entry of entries) {
23582
- const fullPath = path46.join(dir, entry);
23583
- const relPath = path46.relative(scanDir, fullPath).replace(/\\/g, "/");
23838
+ const fullPath = path48.join(dir, entry);
23839
+ const relPath = path48.relative(scanDir, fullPath).replace(/\\/g, "/");
23584
23840
  if (isExcluded(entry, relPath, excludeExact, excludeGlobs)) {
23585
23841
  stats.skippedDirs++;
23586
23842
  continue;
@@ -23615,7 +23871,7 @@ function findScannableFiles(dir, excludeExact, excludeGlobs, scanDir, visited, s
23615
23871
  const subFiles = findScannableFiles(fullPath, excludeExact, excludeGlobs, scanDir, visited, stats);
23616
23872
  files.push(...subFiles);
23617
23873
  } else if (lstat2.isFile()) {
23618
- const ext = path46.extname(fullPath).toLowerCase();
23874
+ const ext = path48.extname(fullPath).toLowerCase();
23619
23875
  if (!DEFAULT_EXCLUDE_EXTENSIONS.has(ext)) {
23620
23876
  files.push(fullPath);
23621
23877
  } else {
@@ -23681,7 +23937,7 @@ var secretscan = createSwarmTool({
23681
23937
  }
23682
23938
  }
23683
23939
  try {
23684
- const _scanDirRaw = path46.resolve(directory);
23940
+ const _scanDirRaw = path48.resolve(directory);
23685
23941
  const scanDir = (() => {
23686
23942
  try {
23687
23943
  return fs19.realpathSync(_scanDirRaw);
@@ -23844,11 +24100,11 @@ var _internals38 = {
23844
24100
 
23845
24101
  // src/tools/test-runner.ts
23846
24102
  import * as fs23 from "fs";
23847
- import * as path50 from "path";
24103
+ import * as path52 from "path";
23848
24104
 
23849
24105
  // src/test-impact/analyzer.ts
23850
24106
  import fs20 from "fs";
23851
- import path47 from "path";
24107
+ import path49 from "path";
23852
24108
  var IMPORT_REGEX_ES = /import\s+[\s\S]*?\s+from\s+['"]([^'"]+)['"]/g;
23853
24109
  var IMPORT_REGEX_REQUIRE = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
23854
24110
  var IMPORT_REGEX_REEXPORT = /export\s+(?:\{[^}]*\}|\*)\s+from\s+['"]([^'"]+)['"]/g;
@@ -23889,8 +24145,8 @@ function resolveRelativeImport(fromDir, importPath) {
23889
24145
  if (!importPath.startsWith(".")) {
23890
24146
  return null;
23891
24147
  }
23892
- const resolved = path47.resolve(fromDir, importPath);
23893
- if (path47.extname(resolved)) {
24148
+ const resolved = path49.resolve(fromDir, importPath);
24149
+ if (path49.extname(resolved)) {
23894
24150
  if (fs20.existsSync(resolved) && fs20.statSync(resolved).isFile()) {
23895
24151
  return normalizePath2(resolved);
23896
24152
  }
@@ -23910,20 +24166,20 @@ function resolvePythonImport(fromDir, module) {
23910
24166
  const leadingDots = module.match(/^\.+/)?.[0].length ?? 0;
23911
24167
  let baseDir = fromDir;
23912
24168
  for (let i = 1;i < leadingDots; i++) {
23913
- baseDir = path47.dirname(baseDir);
24169
+ baseDir = path49.dirname(baseDir);
23914
24170
  }
23915
24171
  const rest = module.slice(leadingDots);
23916
24172
  if (rest.length === 0) {
23917
- const initPath = path47.join(baseDir, "__init__.py");
24173
+ const initPath = path49.join(baseDir, "__init__.py");
23918
24174
  if (fs20.existsSync(initPath) && fs20.statSync(initPath).isFile()) {
23919
24175
  return normalizePath2(initPath);
23920
24176
  }
23921
24177
  return null;
23922
24178
  }
23923
- const subpath = rest.replace(/\./g, path47.sep);
24179
+ const subpath = rest.replace(/\./g, path49.sep);
23924
24180
  const candidates = [
23925
- `${path47.join(baseDir, subpath)}.py`,
23926
- path47.join(baseDir, subpath, "__init__.py")
24181
+ `${path49.join(baseDir, subpath)}.py`,
24182
+ path49.join(baseDir, subpath, "__init__.py")
23927
24183
  ];
23928
24184
  for (const c of candidates) {
23929
24185
  if (fs20.existsSync(c) && fs20.statSync(c).isFile())
@@ -23933,7 +24189,7 @@ function resolvePythonImport(fromDir, module) {
23933
24189
  }
23934
24190
  var goModuleCache = new Map;
23935
24191
  function findGoModule(fromDir) {
23936
- const resolved = path47.resolve(fromDir);
24192
+ const resolved = path49.resolve(fromDir);
23937
24193
  let cur = resolved;
23938
24194
  const walked = [];
23939
24195
  for (let i = 0;i < 16; i++) {
@@ -23945,7 +24201,7 @@ function findGoModule(fromDir) {
23945
24201
  }
23946
24202
  walked.push(cur);
23947
24203
  try {
23948
- const goMod = path47.join(cur, "go.mod");
24204
+ const goMod = path49.join(cur, "go.mod");
23949
24205
  const content = fs20.readFileSync(goMod, "utf-8");
23950
24206
  const moduleMatch = content.match(/^\s*module\s+"?([^"\s/]+(?:\/[^"\s]+)*)"?/m);
23951
24207
  if (moduleMatch) {
@@ -23956,10 +24212,10 @@ function findGoModule(fromDir) {
23956
24212
  }
23957
24213
  } catch {}
23958
24214
  try {
23959
- fs20.accessSync(path47.join(cur, ".git"));
24215
+ fs20.accessSync(path49.join(cur, ".git"));
23960
24216
  break;
23961
24217
  } catch {}
23962
- const parent = path47.dirname(cur);
24218
+ const parent = path49.dirname(cur);
23963
24219
  if (parent === cur)
23964
24220
  break;
23965
24221
  cur = parent;
@@ -23971,12 +24227,12 @@ function findGoModule(fromDir) {
23971
24227
  function resolveGoImport(fromDir, importPath) {
23972
24228
  let dir = null;
23973
24229
  if (importPath.startsWith(".")) {
23974
- dir = path47.resolve(fromDir, importPath);
24230
+ dir = path49.resolve(fromDir, importPath);
23975
24231
  } else {
23976
24232
  const mod = findGoModule(fromDir);
23977
24233
  if (mod && (importPath === mod.modulePath || importPath.startsWith(`${mod.modulePath}/`))) {
23978
24234
  const subpath = importPath.slice(mod.modulePath.length);
23979
- dir = path47.join(mod.moduleRoot, subpath);
24235
+ dir = path49.join(mod.moduleRoot, subpath);
23980
24236
  }
23981
24237
  }
23982
24238
  if (dir === null)
@@ -23984,7 +24240,7 @@ function resolveGoImport(fromDir, importPath) {
23984
24240
  if (!fs20.existsSync(dir) || !fs20.statSync(dir).isDirectory())
23985
24241
  return [];
23986
24242
  try {
23987
- return fs20.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path47.join(dir, f)));
24243
+ return fs20.readdirSync(dir).filter((f) => f.endsWith(".go") && !f.endsWith("_test.go")).map((f) => normalizePath2(path49.join(dir, f)));
23988
24244
  } catch {
23989
24245
  return [];
23990
24246
  }
@@ -24023,15 +24279,15 @@ function findTestFilesSync(cwd) {
24023
24279
  for (const entry of entries) {
24024
24280
  if (entry.isDirectory()) {
24025
24281
  if (!skipDirs.has(entry.name)) {
24026
- walk(path47.join(dir, entry.name), visitedInodes);
24282
+ walk(path49.join(dir, entry.name), visitedInodes);
24027
24283
  }
24028
24284
  } else if (entry.isFile()) {
24029
24285
  const name = entry.name;
24030
24286
  const isTsTest = /\.(test|spec)\.(ts|tsx|js|jsx)$/.test(name) || dir.includes("__tests__") && /\.(ts|tsx|js|jsx)$/.test(name);
24031
- const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path47.sep}tests${path47.sep}`) && name.endsWith(".py");
24287
+ const isPyTest = /^test_.+\.py$/.test(name) || /.+_test\.py$/.test(name) || dir.includes(`${path49.sep}tests${path49.sep}`) && name.endsWith(".py");
24032
24288
  const isGoTest = /.+_test\.go$/.test(name);
24033
24289
  if (isTsTest || isPyTest || isGoTest) {
24034
- testFiles.push(normalizePath2(path47.join(dir, entry.name)));
24290
+ testFiles.push(normalizePath2(path49.join(dir, entry.name)));
24035
24291
  }
24036
24292
  }
24037
24293
  }
@@ -24056,8 +24312,8 @@ function extractImports(content) {
24056
24312
  ];
24057
24313
  }
24058
24314
  function addImpactEdgesForTestFile(testFile, content, impactMap) {
24059
- const ext = path47.extname(testFile).toLowerCase();
24060
- const testDir = path47.dirname(testFile);
24315
+ const ext = path49.extname(testFile).toLowerCase();
24316
+ const testDir = path49.dirname(testFile);
24061
24317
  function addEdge(source) {
24062
24318
  if (!impactMap[source])
24063
24319
  impactMap[source] = [];
@@ -24130,7 +24386,7 @@ async function buildImpactMap(cwd) {
24130
24386
  return impactMap;
24131
24387
  }
24132
24388
  async function loadImpactMap(cwd, options) {
24133
- const cachePath = path47.join(cwd, ".swarm", "cache", "impact-map.json");
24389
+ const cachePath = path49.join(cwd, ".swarm", "cache", "impact-map.json");
24134
24390
  if (fs20.existsSync(cachePath)) {
24135
24391
  try {
24136
24392
  const content = fs20.readFileSync(cachePath, "utf-8");
@@ -24163,12 +24419,12 @@ async function loadImpactMap(cwd, options) {
24163
24419
  return _internals39.buildImpactMap(cwd);
24164
24420
  }
24165
24421
  async function saveImpactMap(cwd, impactMap) {
24166
- if (!path47.isAbsolute(cwd)) {
24422
+ if (!path49.isAbsolute(cwd)) {
24167
24423
  throw new Error(`saveImpactMap requires an absolute project root path, got: "${cwd}"`);
24168
24424
  }
24169
24425
  _internals39.validateProjectRoot(cwd);
24170
- const cacheDir2 = path47.join(cwd, ".swarm", "cache");
24171
- const cachePath = path47.join(cacheDir2, "impact-map.json");
24426
+ const cacheDir2 = path49.join(cwd, ".swarm", "cache");
24427
+ const cachePath = path49.join(cacheDir2, "impact-map.json");
24172
24428
  if (!fs20.existsSync(cacheDir2)) {
24173
24429
  fs20.mkdirSync(cacheDir2, { recursive: true });
24174
24430
  }
@@ -24200,7 +24456,7 @@ async function analyzeImpact(changedFiles, cwd, budget) {
24200
24456
  budgetExceeded = true;
24201
24457
  break;
24202
24458
  }
24203
- const normalizedChanged = normalizePath2(path47.resolve(changedFile));
24459
+ const normalizedChanged = normalizePath2(path49.resolve(changedFile));
24204
24460
  const tests = impactMap[normalizedChanged];
24205
24461
  if (tests && tests.length > 0) {
24206
24462
  for (const test of tests) {
@@ -24214,13 +24470,13 @@ async function analyzeImpact(changedFiles, cwd, budget) {
24214
24470
  if (budgetExceeded)
24215
24471
  break;
24216
24472
  } else {
24217
- const changedDir = normalizePath2(path47.dirname(normalizedChanged));
24218
- const changedInputDir = normalizePath2(path47.dirname(changedFile));
24473
+ const changedDir = normalizePath2(path49.dirname(normalizedChanged));
24474
+ const changedInputDir = normalizePath2(path49.dirname(changedFile));
24219
24475
  const suffixMatches = Object.entries(impactMap).filter(([sourcePath]) => {
24220
24476
  return sourcePath.endsWith(changedFile) || changedFile.endsWith(sourcePath) || sourcePath.endsWith(normalizedChanged) || normalizedChanged.endsWith(sourcePath);
24221
24477
  }).sort(([sourceA], [sourceB]) => {
24222
- const sourceDirA = normalizePath2(path47.dirname(sourceA));
24223
- const sourceDirB = normalizePath2(path47.dirname(sourceB));
24478
+ const sourceDirA = normalizePath2(path49.dirname(sourceA));
24479
+ const sourceDirB = normalizePath2(path49.dirname(sourceB));
24224
24480
  const exactA = sourceDirA === changedDir || changedInputDir !== "." && (sourceDirA === changedInputDir || sourceDirA.endsWith(`/${changedInputDir}`));
24225
24481
  const exactB = sourceDirB === changedDir || changedInputDir !== "." && (sourceDirB === changedInputDir || sourceDirB.endsWith(`/${changedInputDir}`));
24226
24482
  if (exactA !== exactB)
@@ -24547,7 +24803,7 @@ function detectFlakyTests(allHistory) {
24547
24803
 
24548
24804
  // src/test-impact/history-store.ts
24549
24805
  import fs21 from "fs";
24550
- import path48 from "path";
24806
+ import path50 from "path";
24551
24807
  var MAX_HISTORY_PER_TEST = 20;
24552
24808
  var MAX_ERROR_LENGTH = 500;
24553
24809
  var MAX_STACK_LENGTH = 200;
@@ -24559,10 +24815,10 @@ function getHistoryPath(workingDir) {
24559
24815
  if (!workingDir) {
24560
24816
  throw new Error("getHistoryPath requires a working directory \u2014 project root must be provided by the caller");
24561
24817
  }
24562
- if (!path48.isAbsolute(workingDir)) {
24818
+ if (!path50.isAbsolute(workingDir)) {
24563
24819
  throw new Error(`getHistoryPath requires an absolute project root path, got: "${workingDir}"`);
24564
24820
  }
24565
- return path48.join(workingDir, ".swarm", "cache", "test-history.jsonl");
24821
+ return path50.join(workingDir, ".swarm", "cache", "test-history.jsonl");
24566
24822
  }
24567
24823
  function sanitizeErrorMessage(errorMessage) {
24568
24824
  if (errorMessage === undefined) {
@@ -24654,7 +24910,7 @@ function batchAppendTestRuns(records, workingDir) {
24654
24910
  }
24655
24911
  }
24656
24912
  const historyPath = getHistoryPath(workingDir);
24657
- const historyDir = path48.dirname(historyPath);
24913
+ const historyDir = path50.dirname(historyPath);
24658
24914
  _internals40.validateProjectRoot(workingDir);
24659
24915
  if (!fs21.existsSync(historyDir)) {
24660
24916
  fs21.mkdirSync(historyDir, { recursive: true });
@@ -24784,7 +25040,7 @@ var _internals40 = {
24784
25040
 
24785
25041
  // src/tools/resolve-working-directory.ts
24786
25042
  import * as fs22 from "fs";
24787
- import * as path49 from "path";
25043
+ import * as path51 from "path";
24788
25044
  function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
24789
25045
  if (workingDirectory == null || workingDirectory === "") {
24790
25046
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
@@ -24816,15 +25072,15 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
24816
25072
  };
24817
25073
  }
24818
25074
  }
24819
- const rawPathParts = workingDirectory.split(path49.sep);
25075
+ const rawPathParts = workingDirectory.split(path51.sep);
24820
25076
  if (rawPathParts.includes("..")) {
24821
25077
  return {
24822
25078
  success: false,
24823
25079
  message: "Invalid working_directory: path traversal sequences (..) are not allowed"
24824
25080
  };
24825
25081
  }
24826
- const normalizedDir = path49.normalize(workingDirectory);
24827
- const resolvedDir = path49.resolve(normalizedDir);
25082
+ const normalizedDir = path51.normalize(workingDirectory);
25083
+ const resolvedDir = path51.resolve(normalizedDir);
24828
25084
  let statResult;
24829
25085
  try {
24830
25086
  statResult = fs22.statSync(resolvedDir);
@@ -24843,7 +25099,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
24843
25099
  if (typeof fallbackDirectory !== "string" || fallbackDirectory === "") {
24844
25100
  return { success: true, directory: resolvedDir };
24845
25101
  }
24846
- const resolvedFallback = path49.resolve(fallbackDirectory);
25102
+ const resolvedFallback = path51.resolve(fallbackDirectory);
24847
25103
  let fallbackExists = false;
24848
25104
  try {
24849
25105
  fs22.statSync(resolvedFallback);
@@ -24852,7 +25108,7 @@ function resolveWorkingDirectory(workingDirectory, fallbackDirectory) {
24852
25108
  fallbackExists = false;
24853
25109
  }
24854
25110
  if (fallbackExists) {
24855
- const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path49.sep);
25111
+ const isSubdirectory = resolvedDir.startsWith(resolvedFallback + path51.sep);
24856
25112
  if (isSubdirectory) {
24857
25113
  return {
24858
25114
  success: false,
@@ -24875,7 +25131,7 @@ async function estimateFanOut(sourceFiles, cwd) {
24875
25131
  const impactMap = await loadImpactMap(cwd, { skipRebuild: true });
24876
25132
  const uniqueTestFiles = new Set;
24877
25133
  for (const sourceFile of sourceFiles) {
24878
- const resolvedPath = path50.resolve(cwd, sourceFile);
25134
+ const resolvedPath = path52.resolve(cwd, sourceFile);
24879
25135
  const normalizedPath = resolvedPath.replace(/\\/g, "/");
24880
25136
  const testFiles = impactMap[normalizedPath];
24881
25137
  if (testFiles) {
@@ -24960,14 +25216,14 @@ function hasDevDependency(devDeps, ...patterns) {
24960
25216
  return hasPackageJsonDependency(devDeps, ...patterns);
24961
25217
  }
24962
25218
  function detectGoTest(cwd) {
24963
- return fs23.existsSync(path50.join(cwd, "go.mod")) && isCommandAvailable("go");
25219
+ return fs23.existsSync(path52.join(cwd, "go.mod")) && isCommandAvailable("go");
24964
25220
  }
24965
25221
  function detectJavaMaven(cwd) {
24966
- return fs23.existsSync(path50.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
25222
+ return fs23.existsSync(path52.join(cwd, "pom.xml")) && isCommandAvailable("mvn");
24967
25223
  }
24968
25224
  function detectGradle(cwd) {
24969
- const hasBuildFile = fs23.existsSync(path50.join(cwd, "build.gradle")) || fs23.existsSync(path50.join(cwd, "build.gradle.kts"));
24970
- const hasGradlew = fs23.existsSync(path50.join(cwd, "gradlew")) || fs23.existsSync(path50.join(cwd, "gradlew.bat"));
25225
+ const hasBuildFile = fs23.existsSync(path52.join(cwd, "build.gradle")) || fs23.existsSync(path52.join(cwd, "build.gradle.kts"));
25226
+ const hasGradlew = fs23.existsSync(path52.join(cwd, "gradlew")) || fs23.existsSync(path52.join(cwd, "gradlew.bat"));
24971
25227
  return hasBuildFile && (hasGradlew || isCommandAvailable("gradle"));
24972
25228
  }
24973
25229
  function detectDotnetTest(cwd) {
@@ -24980,25 +25236,25 @@ function detectDotnetTest(cwd) {
24980
25236
  }
24981
25237
  }
24982
25238
  function detectCTest(cwd) {
24983
- const hasSource = fs23.existsSync(path50.join(cwd, "CMakeLists.txt"));
24984
- const hasBuildCache = fs23.existsSync(path50.join(cwd, "CMakeCache.txt")) || fs23.existsSync(path50.join(cwd, "build", "CMakeCache.txt"));
25239
+ const hasSource = fs23.existsSync(path52.join(cwd, "CMakeLists.txt"));
25240
+ const hasBuildCache = fs23.existsSync(path52.join(cwd, "CMakeCache.txt")) || fs23.existsSync(path52.join(cwd, "build", "CMakeCache.txt"));
24985
25241
  return (hasSource || hasBuildCache) && isCommandAvailable("ctest");
24986
25242
  }
24987
25243
  function detectSwiftTest(cwd) {
24988
- return fs23.existsSync(path50.join(cwd, "Package.swift")) && isCommandAvailable("swift");
25244
+ return fs23.existsSync(path52.join(cwd, "Package.swift")) && isCommandAvailable("swift");
24989
25245
  }
24990
25246
  function detectDartTest(cwd) {
24991
- return fs23.existsSync(path50.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
25247
+ return fs23.existsSync(path52.join(cwd, "pubspec.yaml")) && (isCommandAvailable("dart") || isCommandAvailable("flutter"));
24992
25248
  }
24993
25249
  function detectRSpec(cwd) {
24994
- const hasRSpecFile = fs23.existsSync(path50.join(cwd, ".rspec"));
24995
- const hasGemfile = fs23.existsSync(path50.join(cwd, "Gemfile"));
24996
- const hasSpecDir = fs23.existsSync(path50.join(cwd, "spec"));
25250
+ const hasRSpecFile = fs23.existsSync(path52.join(cwd, ".rspec"));
25251
+ const hasGemfile = fs23.existsSync(path52.join(cwd, "Gemfile"));
25252
+ const hasSpecDir = fs23.existsSync(path52.join(cwd, "spec"));
24997
25253
  const hasRSpec = hasRSpecFile || hasGemfile && hasSpecDir;
24998
25254
  return hasRSpec && (isCommandAvailable("bundle") || isCommandAvailable("rspec"));
24999
25255
  }
25000
25256
  function detectMinitest(cwd) {
25001
- return fs23.existsSync(path50.join(cwd, "test")) && (fs23.existsSync(path50.join(cwd, "Gemfile")) || fs23.existsSync(path50.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
25257
+ return fs23.existsSync(path52.join(cwd, "test")) && (fs23.existsSync(path52.join(cwd, "Gemfile")) || fs23.existsSync(path52.join(cwd, "Rakefile"))) && isCommandAvailable("ruby");
25002
25258
  }
25003
25259
  var DISPATCH_FRAMEWORK_MAP = {
25004
25260
  bun: "bun",
@@ -25083,7 +25339,7 @@ async function parseTestOutputViaDispatch(framework, output, baseDir) {
25083
25339
  async function detectTestFramework(cwd) {
25084
25340
  const baseDir = cwd;
25085
25341
  try {
25086
- const packageJsonPath = path50.join(baseDir, "package.json");
25342
+ const packageJsonPath = path52.join(baseDir, "package.json");
25087
25343
  if (fs23.existsSync(packageJsonPath)) {
25088
25344
  const content = fs23.readFileSync(packageJsonPath, "utf-8");
25089
25345
  const pkg = JSON.parse(content);
@@ -25104,16 +25360,16 @@ async function detectTestFramework(cwd) {
25104
25360
  return "jest";
25105
25361
  if (hasDevDependency(devDeps, "mocha", "@types/mocha"))
25106
25362
  return "mocha";
25107
- if (fs23.existsSync(path50.join(baseDir, "bun.lockb")) || fs23.existsSync(path50.join(baseDir, "bun.lock"))) {
25363
+ if (fs23.existsSync(path52.join(baseDir, "bun.lockb")) || fs23.existsSync(path52.join(baseDir, "bun.lock"))) {
25108
25364
  if (scripts.test?.includes("bun"))
25109
25365
  return "bun";
25110
25366
  }
25111
25367
  }
25112
25368
  } catch {}
25113
25369
  try {
25114
- const pyprojectTomlPath = path50.join(baseDir, "pyproject.toml");
25115
- const setupCfgPath = path50.join(baseDir, "setup.cfg");
25116
- const requirementsTxtPath = path50.join(baseDir, "requirements.txt");
25370
+ const pyprojectTomlPath = path52.join(baseDir, "pyproject.toml");
25371
+ const setupCfgPath = path52.join(baseDir, "setup.cfg");
25372
+ const requirementsTxtPath = path52.join(baseDir, "requirements.txt");
25117
25373
  if (fs23.existsSync(pyprojectTomlPath)) {
25118
25374
  const content = fs23.readFileSync(pyprojectTomlPath, "utf-8");
25119
25375
  if (content.includes("[tool.pytest"))
@@ -25133,7 +25389,7 @@ async function detectTestFramework(cwd) {
25133
25389
  }
25134
25390
  } catch {}
25135
25391
  try {
25136
- const cargoTomlPath = path50.join(baseDir, "Cargo.toml");
25392
+ const cargoTomlPath = path52.join(baseDir, "Cargo.toml");
25137
25393
  if (fs23.existsSync(cargoTomlPath)) {
25138
25394
  const content = fs23.readFileSync(cargoTomlPath, "utf-8");
25139
25395
  if (content.includes("[dev-dependencies]")) {
@@ -25144,9 +25400,9 @@ async function detectTestFramework(cwd) {
25144
25400
  }
25145
25401
  } catch {}
25146
25402
  try {
25147
- const pesterConfigPath = path50.join(baseDir, "pester.config.ps1");
25148
- const pesterConfigJsonPath = path50.join(baseDir, "pester.config.ps1.json");
25149
- const pesterPs1Path = path50.join(baseDir, "tests.ps1");
25403
+ const pesterConfigPath = path52.join(baseDir, "pester.config.ps1");
25404
+ const pesterConfigJsonPath = path52.join(baseDir, "pester.config.ps1.json");
25405
+ const pesterPs1Path = path52.join(baseDir, "tests.ps1");
25150
25406
  if (fs23.existsSync(pesterConfigPath) || fs23.existsSync(pesterConfigJsonPath) || fs23.existsSync(pesterPs1Path)) {
25151
25407
  return "pester";
25152
25408
  }
@@ -25189,12 +25445,12 @@ function isTestDirectoryPath(normalizedPath) {
25189
25445
  return normalizedPath.split("/").some((segment) => TEST_DIRECTORY_NAMES.includes(segment));
25190
25446
  }
25191
25447
  function resolveWorkspacePath(file, workingDir) {
25192
- return path50.isAbsolute(file) ? path50.resolve(file) : path50.resolve(workingDir, file);
25448
+ return path52.isAbsolute(file) ? path52.resolve(file) : path52.resolve(workingDir, file);
25193
25449
  }
25194
25450
  function toWorkspaceOutputPath(absolutePath, workingDir, preferRelative) {
25195
25451
  if (!preferRelative)
25196
25452
  return absolutePath;
25197
- return path50.relative(workingDir, absolutePath);
25453
+ return path52.relative(workingDir, absolutePath);
25198
25454
  }
25199
25455
  function dedupePush(target, value) {
25200
25456
  if (!target.includes(value)) {
@@ -25231,18 +25487,18 @@ function buildLanguageSpecificTestNames(nameWithoutExt, ext) {
25231
25487
  }
25232
25488
  }
25233
25489
  function getRepoLevelCandidateDirectories(workingDir, relativePath, ext) {
25234
- const relativeDir = path50.dirname(relativePath);
25490
+ const relativeDir = path52.dirname(relativePath);
25235
25491
  const nestedRelativeDir = relativeDir === "." ? "" : relativeDir;
25236
25492
  const directories = TEST_DIRECTORY_NAMES.flatMap((dirName) => {
25237
- const rootDir = path50.join(workingDir, dirName);
25238
- return nestedRelativeDir ? [rootDir, path50.join(rootDir, nestedRelativeDir)] : [rootDir];
25493
+ const rootDir = path52.join(workingDir, dirName);
25494
+ return nestedRelativeDir ? [rootDir, path52.join(rootDir, nestedRelativeDir)] : [rootDir];
25239
25495
  });
25240
25496
  const normalizedRelativePath = relativePath.replace(/\\/g, "/");
25241
25497
  if (ext === ".java" && normalizedRelativePath.startsWith("src/main/java/")) {
25242
- directories.push(path50.join(workingDir, "src/test/java", path50.dirname(normalizedRelativePath.slice("src/main/java/".length))));
25498
+ directories.push(path52.join(workingDir, "src/test/java", path52.dirname(normalizedRelativePath.slice("src/main/java/".length))));
25243
25499
  }
25244
25500
  if ((ext === ".kt" || ext === ".java") && normalizedRelativePath.startsWith("src/main/kotlin/")) {
25245
- directories.push(path50.join(workingDir, "src/test/kotlin", path50.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
25501
+ directories.push(path52.join(workingDir, "src/test/kotlin", path52.dirname(normalizedRelativePath.slice("src/main/kotlin/".length))));
25246
25502
  }
25247
25503
  return [...new Set(directories)];
25248
25504
  }
@@ -25270,23 +25526,23 @@ function isLanguageSpecificTestFile(basename9) {
25270
25526
  }
25271
25527
  function isConventionTestFilePath(filePath) {
25272
25528
  const normalizedPath = filePath.replace(/\\/g, "/");
25273
- const basename9 = path50.basename(filePath);
25529
+ const basename9 = path52.basename(filePath);
25274
25530
  return hasCompoundTestExtension(basename9) || basename9.includes(".spec.") || basename9.includes(".test.") || isLanguageSpecificTestFile(basename9) || isTestDirectoryPath(normalizedPath);
25275
25531
  }
25276
25532
  function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
25277
25533
  const testFiles = [];
25278
25534
  for (const file of sourceFiles) {
25279
25535
  const absoluteFile = resolveWorkspacePath(file, workingDir);
25280
- const relativeFile = path50.relative(workingDir, absoluteFile);
25281
- const basename9 = path50.basename(absoluteFile);
25282
- const dirname24 = path50.dirname(absoluteFile);
25283
- const preferRelativeOutput = !path50.isAbsolute(file);
25536
+ const relativeFile = path52.relative(workingDir, absoluteFile);
25537
+ const basename9 = path52.basename(absoluteFile);
25538
+ const dirname25 = path52.dirname(absoluteFile);
25539
+ const preferRelativeOutput = !path52.isAbsolute(file);
25284
25540
  if (isConventionTestFilePath(relativeFile) || isConventionTestFilePath(file)) {
25285
25541
  dedupePush(testFiles, toWorkspaceOutputPath(absoluteFile, workingDir, preferRelativeOutput));
25286
25542
  continue;
25287
25543
  }
25288
25544
  const nameWithoutExt = basename9.replace(/\.[^.]+$/, "");
25289
- const ext = path50.extname(basename9);
25545
+ const ext = path52.extname(basename9);
25290
25546
  const genericTestNames = [
25291
25547
  `${nameWithoutExt}.spec${ext}`,
25292
25548
  `${nameWithoutExt}.test${ext}`
@@ -25295,7 +25551,7 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
25295
25551
  const colocatedCandidates = [
25296
25552
  ...genericTestNames,
25297
25553
  ...languageSpecificTestNames
25298
- ].map((candidateName) => path50.join(dirname24, candidateName));
25554
+ ].map((candidateName) => path52.join(dirname25, candidateName));
25299
25555
  const testDirectoryNames = [
25300
25556
  basename9,
25301
25557
  ...genericTestNames,
@@ -25304,8 +25560,8 @@ function getTestFilesFromConvention(sourceFiles, workingDir = process.cwd()) {
25304
25560
  const repoLevelDirectories = getRepoLevelCandidateDirectories(workingDir, relativeFile, ext);
25305
25561
  const possibleTestFiles = [
25306
25562
  ...colocatedCandidates,
25307
- ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path50.join(dirname24, dirName, candidateName))),
25308
- ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path50.join(candidateDir, candidateName)))
25563
+ ...TEST_DIRECTORY_NAMES.flatMap((dirName) => testDirectoryNames.map((candidateName) => path52.join(dirname25, dirName, candidateName))),
25564
+ ...repoLevelDirectories.flatMap((candidateDir) => testDirectoryNames.map((candidateName) => path52.join(candidateDir, candidateName)))
25309
25565
  ];
25310
25566
  for (const testFile of possibleTestFiles) {
25311
25567
  if (fs23.existsSync(testFile)) {
@@ -25326,7 +25582,7 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25326
25582
  try {
25327
25583
  const absoluteTestFile = resolveWorkspacePath(testFile, workingDir);
25328
25584
  const content = fs23.readFileSync(absoluteTestFile, "utf-8");
25329
- const testDir = path50.dirname(absoluteTestFile);
25585
+ const testDir = path52.dirname(absoluteTestFile);
25330
25586
  const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
25331
25587
  let match;
25332
25588
  match = importRegex.exec(content);
@@ -25334,8 +25590,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25334
25590
  const importPath = match[1];
25335
25591
  let resolvedImport;
25336
25592
  if (importPath.startsWith(".")) {
25337
- resolvedImport = path50.resolve(testDir, importPath);
25338
- const existingExt = path50.extname(resolvedImport);
25593
+ resolvedImport = path52.resolve(testDir, importPath);
25594
+ const existingExt = path52.extname(resolvedImport);
25339
25595
  if (!existingExt) {
25340
25596
  for (const extToTry of [
25341
25597
  ".ts",
@@ -25355,12 +25611,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25355
25611
  } else {
25356
25612
  continue;
25357
25613
  }
25358
- const importBasename = path50.basename(resolvedImport, path50.extname(resolvedImport));
25359
- const importDir = path50.dirname(resolvedImport);
25614
+ const importBasename = path52.basename(resolvedImport, path52.extname(resolvedImport));
25615
+ const importDir = path52.dirname(resolvedImport);
25360
25616
  for (const sourceFile of absoluteSourceFiles) {
25361
- const sourceDir = path50.dirname(sourceFile);
25362
- const sourceBasename = path50.basename(sourceFile, path50.extname(sourceFile));
25363
- const isRelatedDir = importDir === sourceDir || importDir === path50.join(sourceDir, "__tests__") || importDir === path50.join(sourceDir, "tests") || importDir === path50.join(sourceDir, "test") || importDir === path50.join(sourceDir, "spec");
25617
+ const sourceDir = path52.dirname(sourceFile);
25618
+ const sourceBasename = path52.basename(sourceFile, path52.extname(sourceFile));
25619
+ const isRelatedDir = importDir === sourceDir || importDir === path52.join(sourceDir, "__tests__") || importDir === path52.join(sourceDir, "tests") || importDir === path52.join(sourceDir, "test") || importDir === path52.join(sourceDir, "spec");
25364
25620
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
25365
25621
  dedupePush(testFiles, testFile);
25366
25622
  break;
@@ -25373,8 +25629,8 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25373
25629
  while (match !== null) {
25374
25630
  const importPath = match[1];
25375
25631
  if (importPath.startsWith(".")) {
25376
- let resolvedImport = path50.resolve(testDir, importPath);
25377
- const existingExt = path50.extname(resolvedImport);
25632
+ let resolvedImport = path52.resolve(testDir, importPath);
25633
+ const existingExt = path52.extname(resolvedImport);
25378
25634
  if (!existingExt) {
25379
25635
  for (const extToTry of [
25380
25636
  ".ts",
@@ -25391,12 +25647,12 @@ async function getTestFilesFromGraph(sourceFiles, workingDir) {
25391
25647
  }
25392
25648
  }
25393
25649
  }
25394
- const importDir = path50.dirname(resolvedImport);
25395
- const importBasename = path50.basename(resolvedImport, path50.extname(resolvedImport));
25650
+ const importDir = path52.dirname(resolvedImport);
25651
+ const importBasename = path52.basename(resolvedImport, path52.extname(resolvedImport));
25396
25652
  for (const sourceFile of absoluteSourceFiles) {
25397
- const sourceDir = path50.dirname(sourceFile);
25398
- const sourceBasename = path50.basename(sourceFile, path50.extname(sourceFile));
25399
- const isRelatedDir = importDir === sourceDir || importDir === path50.join(sourceDir, "__tests__") || importDir === path50.join(sourceDir, "tests") || importDir === path50.join(sourceDir, "test") || importDir === path50.join(sourceDir, "spec");
25653
+ const sourceDir = path52.dirname(sourceFile);
25654
+ const sourceBasename = path52.basename(sourceFile, path52.extname(sourceFile));
25655
+ const isRelatedDir = importDir === sourceDir || importDir === path52.join(sourceDir, "__tests__") || importDir === path52.join(sourceDir, "tests") || importDir === path52.join(sourceDir, "test") || importDir === path52.join(sourceDir, "spec");
25400
25656
  if (resolvedImport === sourceFile || importBasename === sourceBasename && isRelatedDir) {
25401
25657
  dedupePush(testFiles, testFile);
25402
25658
  break;
@@ -25516,8 +25772,8 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
25516
25772
  return ["mvn", "test"];
25517
25773
  case "gradle": {
25518
25774
  const isWindows = process.platform === "win32";
25519
- const hasGradlewBat = fs23.existsSync(path50.join(baseDir, "gradlew.bat"));
25520
- const hasGradlew = fs23.existsSync(path50.join(baseDir, "gradlew"));
25775
+ const hasGradlewBat = fs23.existsSync(path52.join(baseDir, "gradlew.bat"));
25776
+ const hasGradlew = fs23.existsSync(path52.join(baseDir, "gradlew"));
25521
25777
  if (hasGradlewBat && isWindows)
25522
25778
  return ["gradlew.bat", "test"];
25523
25779
  if (hasGradlew)
@@ -25534,7 +25790,7 @@ function buildTestCommand(framework, scope, files, coverage, baseDir, bail) {
25534
25790
  "cmake-build-release",
25535
25791
  "out"
25536
25792
  ];
25537
- const actualBuildDir = buildDirCandidates.find((d) => fs23.existsSync(path50.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
25793
+ const actualBuildDir = buildDirCandidates.find((d) => fs23.existsSync(path52.join(baseDir, d, "CMakeCache.txt"))) ?? "build";
25538
25794
  return ["ctest", "--test-dir", actualBuildDir];
25539
25795
  }
25540
25796
  case "swift-test":
@@ -25968,11 +26224,11 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
25968
26224
  };
25969
26225
  }
25970
26226
  const startTime = Date.now();
25971
- const vitestJsonOutputPath = framework === "vitest" ? path50.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
26227
+ const vitestJsonOutputPath = framework === "vitest" ? path52.join(cwd, ".swarm", "cache", "test-runner-vitest.json") : undefined;
25972
26228
  try {
25973
26229
  if (vitestJsonOutputPath) {
25974
26230
  try {
25975
- fs23.mkdirSync(path50.dirname(vitestJsonOutputPath), { recursive: true });
26231
+ fs23.mkdirSync(path52.dirname(vitestJsonOutputPath), { recursive: true });
25976
26232
  if (fs23.existsSync(vitestJsonOutputPath)) {
25977
26233
  fs23.unlinkSync(vitestJsonOutputPath);
25978
26234
  }
@@ -25983,9 +26239,9 @@ async function runTests(framework, scope, files, coverage, timeout_ms, cwd, bail
25983
26239
  stderr: "pipe",
25984
26240
  cwd
25985
26241
  });
25986
- const timeoutPromise = new Promise((resolve16) => setTimeout(() => {
26242
+ const timeoutPromise = new Promise((resolve17) => setTimeout(() => {
25987
26243
  proc.kill();
25988
- resolve16(-1);
26244
+ resolve17(-1);
25989
26245
  }, timeout_ms));
25990
26246
  const [exitCode, stdoutResult, stderrResult] = await Promise.all([
25991
26247
  Promise.race([proc.exited, timeoutPromise]),
@@ -26140,10 +26396,10 @@ var SKIP_DIRECTORIES = new Set([
26140
26396
  ]);
26141
26397
  function normalizeHistoryTestFile(testFile, workingDir) {
26142
26398
  const normalized = testFile.replace(/\\/g, "/");
26143
- if (!path50.isAbsolute(testFile))
26399
+ if (!path52.isAbsolute(testFile))
26144
26400
  return normalized;
26145
- const relative8 = path50.relative(workingDir, testFile);
26146
- if (relative8.startsWith("..") || path50.isAbsolute(relative8)) {
26401
+ const relative8 = path52.relative(workingDir, testFile);
26402
+ if (relative8.startsWith("..") || path52.isAbsolute(relative8)) {
26147
26403
  return normalized;
26148
26404
  }
26149
26405
  return relative8.replace(/\\/g, "/");
@@ -26382,7 +26638,7 @@ var test_runner = createSwarmTool({
26382
26638
  const sourceFiles = args.files.filter((file) => {
26383
26639
  if (directTestFiles.includes(file))
26384
26640
  return false;
26385
- const ext = path50.extname(file).toLowerCase();
26641
+ const ext = path52.extname(file).toLowerCase();
26386
26642
  return SOURCE_EXTENSIONS.has(ext);
26387
26643
  });
26388
26644
  const invalidFiles = args.files.filter((file) => !directTestFiles.includes(file) && !sourceFiles.includes(file));
@@ -26428,7 +26684,7 @@ var test_runner = createSwarmTool({
26428
26684
  if (isConventionTestFilePath(f)) {
26429
26685
  return false;
26430
26686
  }
26431
- const ext = path50.extname(f).toLowerCase();
26687
+ const ext = path52.extname(f).toLowerCase();
26432
26688
  return SOURCE_EXTENSIONS.has(ext);
26433
26689
  });
26434
26690
  if (sourceFiles.length === 0) {
@@ -26478,7 +26734,7 @@ var test_runner = createSwarmTool({
26478
26734
  if (isConventionTestFilePath(f)) {
26479
26735
  return false;
26480
26736
  }
26481
- const ext = path50.extname(f).toLowerCase();
26737
+ const ext = path52.extname(f).toLowerCase();
26482
26738
  return SOURCE_EXTENSIONS.has(ext);
26483
26739
  });
26484
26740
  if (sourceFiles.length === 0) {
@@ -26530,8 +26786,8 @@ var test_runner = createSwarmTool({
26530
26786
  }
26531
26787
  if (impactResult.impactedTests.length > 0) {
26532
26788
  testFiles = impactResult.impactedTests.map((absPath) => {
26533
- const relativePath = path50.relative(workingDir, absPath);
26534
- return path50.isAbsolute(relativePath) ? absPath : relativePath;
26789
+ const relativePath = path52.relative(workingDir, absPath);
26790
+ return path52.isAbsolute(relativePath) ? absPath : relativePath;
26535
26791
  });
26536
26792
  } else {
26537
26793
  graphFallbackReason = "no impacted tests found via impact analysis, falling back to graph";
@@ -26626,8 +26882,8 @@ function validateDirectoryPath(dir) {
26626
26882
  if (dir.includes("..")) {
26627
26883
  throw new Error("Directory path must not contain path traversal sequences");
26628
26884
  }
26629
- const normalized = path51.normalize(dir);
26630
- const absolutePath = path51.isAbsolute(normalized) ? normalized : path51.resolve(normalized);
26885
+ const normalized = path53.normalize(dir);
26886
+ const absolutePath = path53.isAbsolute(normalized) ? normalized : path53.resolve(normalized);
26631
26887
  return absolutePath;
26632
26888
  }
26633
26889
  function validateTimeout(timeoutMs, defaultValue) {
@@ -26650,7 +26906,7 @@ function validateTimeout(timeoutMs, defaultValue) {
26650
26906
  }
26651
26907
  function getPackageVersion(dir) {
26652
26908
  try {
26653
- const packagePath = path51.join(dir, "package.json");
26909
+ const packagePath = path53.join(dir, "package.json");
26654
26910
  if (fs24.existsSync(packagePath)) {
26655
26911
  const content = fs24.readFileSync(packagePath, "utf-8");
26656
26912
  const pkg = JSON.parse(content);
@@ -26661,7 +26917,7 @@ function getPackageVersion(dir) {
26661
26917
  }
26662
26918
  function getChangelogVersion(dir) {
26663
26919
  try {
26664
- const changelogPath = path51.join(dir, "CHANGELOG.md");
26920
+ const changelogPath = path53.join(dir, "CHANGELOG.md");
26665
26921
  if (fs24.existsSync(changelogPath)) {
26666
26922
  const content = fs24.readFileSync(changelogPath, "utf-8");
26667
26923
  const match = content.match(/^##\s*\[?(\d+\.\d+\.\d+)\]?/m);
@@ -26675,7 +26931,7 @@ function getChangelogVersion(dir) {
26675
26931
  function getVersionFileVersion(dir) {
26676
26932
  const possibleFiles = ["VERSION.txt", "version.txt", "VERSION", "version"];
26677
26933
  for (const file of possibleFiles) {
26678
- const filePath = path51.join(dir, file);
26934
+ const filePath = path53.join(dir, file);
26679
26935
  if (fs24.existsSync(filePath)) {
26680
26936
  try {
26681
26937
  const content = fs24.readFileSync(filePath, "utf-8").trim();
@@ -27413,7 +27669,7 @@ async function handleQaGatesCommand(directory, args, sessionID) {
27413
27669
 
27414
27670
  // src/commands/reset.ts
27415
27671
  import * as fs25 from "fs";
27416
- import * as path52 from "path";
27672
+ import * as path54 from "path";
27417
27673
 
27418
27674
  // src/background/circuit-breaker.ts
27419
27675
  class CircuitBreaker {
@@ -27465,13 +27721,13 @@ class CircuitBreaker {
27465
27721
  if (this.config.callTimeoutMs <= 0) {
27466
27722
  return fn();
27467
27723
  }
27468
- return new Promise((resolve17, reject) => {
27724
+ return new Promise((resolve18, reject) => {
27469
27725
  const timeout = setTimeout(() => {
27470
27726
  reject(new Error(`Call timeout after ${this.config.callTimeoutMs}ms`));
27471
27727
  }, this.config.callTimeoutMs);
27472
27728
  fn().then((result) => {
27473
27729
  clearTimeout(timeout);
27474
- resolve17(result);
27730
+ resolve18(result);
27475
27731
  }).catch((error2) => {
27476
27732
  clearTimeout(timeout);
27477
27733
  reject(error2);
@@ -27755,7 +28011,7 @@ class AutomationQueue {
27755
28011
 
27756
28012
  // src/background/worker.ts
27757
28013
  function sleep(ms) {
27758
- return new Promise((resolve17) => setTimeout(resolve17, ms));
28014
+ return new Promise((resolve18) => setTimeout(resolve18, ms));
27759
28015
  }
27760
28016
 
27761
28017
  class WorkerManager {
@@ -28130,7 +28386,7 @@ async function handleResetCommand(directory, args) {
28130
28386
  }
28131
28387
  for (const filename of ["SWARM_PLAN.md", "SWARM_PLAN.json"]) {
28132
28388
  try {
28133
- const rootPath = path52.join(directory, filename);
28389
+ const rootPath = path54.join(directory, filename);
28134
28390
  if (fs25.existsSync(rootPath)) {
28135
28391
  fs25.unlinkSync(rootPath);
28136
28392
  results.push(`- \u2705 Deleted ${filename} (root)`);
@@ -28168,7 +28424,7 @@ async function handleResetCommand(directory, args) {
28168
28424
 
28169
28425
  // src/commands/reset-session.ts
28170
28426
  import * as fs27 from "fs";
28171
- import * as path54 from "path";
28427
+ import * as path56 from "path";
28172
28428
 
28173
28429
  // src/hooks/trajectory-logger.ts
28174
28430
  var callStartTimes = new Map;
@@ -28575,16 +28831,16 @@ function detectPatterns(trajectory, config, lastProcessedStep = 0) {
28575
28831
  }
28576
28832
  // src/prm/replay.ts
28577
28833
  import { promises as fs26 } from "fs";
28578
- import path53 from "path";
28834
+ import path55 from "path";
28579
28835
  function isPathSafe(targetPath, basePath) {
28580
- const resolvedTarget = path53.resolve(targetPath);
28581
- const resolvedBase = path53.resolve(basePath);
28582
- const rel = path53.relative(resolvedBase, resolvedTarget);
28583
- return !rel.startsWith("..") && !path53.isAbsolute(rel);
28836
+ const resolvedTarget = path55.resolve(targetPath);
28837
+ const resolvedBase = path55.resolve(basePath);
28838
+ const rel = path55.relative(resolvedBase, resolvedTarget);
28839
+ return !rel.startsWith("..") && !path55.isAbsolute(rel);
28584
28840
  }
28585
28841
  function isWithinReplaysDir(targetPath) {
28586
- const resolved = path53.resolve(targetPath);
28587
- const parts = resolved.split(path53.sep);
28842
+ const resolved = path55.resolve(targetPath);
28843
+ const parts = resolved.split(path55.sep);
28588
28844
  for (let i = 0;i < parts.length - 1; i++) {
28589
28845
  if (parts[i] === ".swarm" && parts[i + 1] === "replays") {
28590
28846
  return true;
@@ -28597,10 +28853,10 @@ function sanitizeFilename(input) {
28597
28853
  }
28598
28854
  async function startReplayRecording(sessionID, directory) {
28599
28855
  try {
28600
- const replayDir = path53.join(directory, ".swarm", "replays");
28856
+ const replayDir = path55.join(directory, ".swarm", "replays");
28601
28857
  const safeSessionID = sanitizeFilename(sessionID);
28602
28858
  const filename = `${safeSessionID}-${Date.now()}.jsonl`;
28603
- const filepath = path53.join(replayDir, filename);
28859
+ const filepath = path55.join(replayDir, filename);
28604
28860
  if (!isPathSafe(filepath, replayDir)) {
28605
28861
  console.warn(`[replay] Invalid path detected - path traversal attempt blocked for session ${sessionID}`);
28606
28862
  return null;
@@ -28678,7 +28934,7 @@ async function handleResetSessionCommand(directory, _args) {
28678
28934
  } catch {
28679
28935
  results.push("\u274C Failed to delete state.json");
28680
28936
  }
28681
- const sessionDir = path54.dirname(validateSwarmPath(directory, "session/state.json"));
28937
+ const sessionDir = path56.dirname(validateSwarmPath(directory, "session/state.json"));
28682
28938
  let sessionFiles = [];
28683
28939
  if (fs27.existsSync(sessionDir)) {
28684
28940
  try {
@@ -28690,7 +28946,7 @@ async function handleResetSessionCommand(directory, _args) {
28690
28946
  for (const file of sessionFiles) {
28691
28947
  if (file === "state.json")
28692
28948
  continue;
28693
- const filePath = path54.join(sessionDir, file);
28949
+ const filePath = path56.join(sessionDir, file);
28694
28950
  try {
28695
28951
  if (!fs27.existsSync(filePath))
28696
28952
  continue;
@@ -28725,7 +28981,7 @@ async function handleResetSessionCommand(directory, _args) {
28725
28981
  }
28726
28982
 
28727
28983
  // src/summaries/manager.ts
28728
- import * as path55 from "path";
28984
+ import * as path57 from "path";
28729
28985
  var SUMMARY_ID_REGEX = /^S\d+$/;
28730
28986
  function sanitizeSummaryId(id) {
28731
28987
  if (!id || id.length === 0) {
@@ -28749,7 +29005,7 @@ function sanitizeSummaryId(id) {
28749
29005
  }
28750
29006
  async function loadFullOutput(directory, id) {
28751
29007
  const sanitizedId = sanitizeSummaryId(id);
28752
- const relativePath = path55.join("summaries", `${sanitizedId}.json`);
29008
+ const relativePath = path57.join("summaries", `${sanitizedId}.json`);
28753
29009
  validateSwarmPath(directory, relativePath);
28754
29010
  const content = await readSwarmFileAsync(directory, relativePath);
28755
29011
  if (content === null) {
@@ -28802,7 +29058,7 @@ ${error2 instanceof Error ? error2.message : String(error2)}`;
28802
29058
 
28803
29059
  // src/commands/rollback.ts
28804
29060
  import * as fs28 from "fs";
28805
- import * as path56 from "path";
29061
+ import * as path58 from "path";
28806
29062
  async function handleRollbackCommand(directory, args) {
28807
29063
  const phaseArg = args[0];
28808
29064
  if (!phaseArg) {
@@ -28868,8 +29124,8 @@ async function handleRollbackCommand(directory, args) {
28868
29124
  if (EXCLUDE_FILES.has(file) || file.startsWith("plan-ledger.archived-")) {
28869
29125
  continue;
28870
29126
  }
28871
- const src = path56.join(checkpointDir, file);
28872
- const dest = path56.join(swarmDir, file);
29127
+ const src = path58.join(checkpointDir, file);
29128
+ const dest = path58.join(swarmDir, file);
28873
29129
  try {
28874
29130
  fs28.cpSync(src, dest, { recursive: true, force: true });
28875
29131
  successes.push(file);
@@ -28888,7 +29144,7 @@ async function handleRollbackCommand(directory, args) {
28888
29144
  ].join(`
28889
29145
  `);
28890
29146
  }
28891
- const existingLedgerPath = path56.join(swarmDir, "plan-ledger.jsonl");
29147
+ const existingLedgerPath = path58.join(swarmDir, "plan-ledger.jsonl");
28892
29148
  let ledgerDeletionFailed = false;
28893
29149
  if (fs28.existsSync(existingLedgerPath)) {
28894
29150
  try {
@@ -28901,7 +29157,7 @@ async function handleRollbackCommand(directory, args) {
28901
29157
  }
28902
29158
  if (!ledgerDeletionFailed) {
28903
29159
  try {
28904
- const planJsonPath = path56.join(swarmDir, "plan.json");
29160
+ const planJsonPath = path58.join(swarmDir, "plan.json");
28905
29161
  if (fs28.existsSync(planJsonPath)) {
28906
29162
  const planRaw = fs28.readFileSync(planJsonPath, "utf-8");
28907
29163
  const plan = PlanSchema.parse(JSON.parse(planRaw));
@@ -29162,10 +29418,10 @@ Ensure this is a git repository with commit history.`;
29162
29418
  `);
29163
29419
  try {
29164
29420
  const fs29 = await import("fs/promises");
29165
- const path57 = await import("path");
29166
- const reportPath = path57.join(directory, ".swarm", "simulate-report.md");
29167
- await fs29.mkdir(path57.dirname(reportPath), { recursive: true });
29168
- const reportTempPath = path57.join(path57.dirname(reportPath), `${path57.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
29421
+ const path59 = await import("path");
29422
+ const reportPath = path59.join(directory, ".swarm", "simulate-report.md");
29423
+ await fs29.mkdir(path59.dirname(reportPath), { recursive: true });
29424
+ const reportTempPath = path59.join(path59.dirname(reportPath), `${path59.basename(reportPath)}.tmp.${Date.now()}.${Math.floor(Math.random() * 1e9)}`);
29169
29425
  try {
29170
29426
  await fs29.writeFile(reportTempPath, report, "utf-8");
29171
29427
  renameSync11(reportTempPath, reportPath);
@@ -29194,18 +29450,18 @@ async function handleSpecifyCommand(_directory, args) {
29194
29450
  // src/services/status-service.ts
29195
29451
  import * as fsSync3 from "fs";
29196
29452
  import { readFile as readFile16 } from "fs/promises";
29197
- import * as path58 from "path";
29453
+ import * as path60 from "path";
29198
29454
 
29199
29455
  // src/turbo/lean/state.ts
29200
29456
  init_logger();
29201
29457
  import * as fs29 from "fs";
29202
- import * as path57 from "path";
29458
+ import * as path59 from "path";
29203
29459
  var STATE_FILE3 = "turbo-state.json";
29204
29460
  function nowISO3() {
29205
29461
  return new Date().toISOString();
29206
29462
  }
29207
29463
  function ensureSwarmDir2(directory) {
29208
- const swarmDir = path57.resolve(directory, ".swarm");
29464
+ const swarmDir = path59.resolve(directory, ".swarm");
29209
29465
  if (!fs29.existsSync(swarmDir)) {
29210
29466
  fs29.mkdirSync(swarmDir, { recursive: true });
29211
29467
  }
@@ -29250,7 +29506,7 @@ function markStateUnreadable2(directory, reason) {
29250
29506
  }
29251
29507
  function readPersisted2(directory) {
29252
29508
  try {
29253
- const filePath = path57.join(directory, ".swarm", STATE_FILE3);
29509
+ const filePath = path59.join(directory, ".swarm", STATE_FILE3);
29254
29510
  if (!fs29.existsSync(filePath)) {
29255
29511
  const seed = emptyPersisted2();
29256
29512
  try {
@@ -29286,7 +29542,7 @@ function writePersisted2(directory, persisted) {
29286
29542
  let payload;
29287
29543
  try {
29288
29544
  ensureSwarmDir2(directory);
29289
- filePath = path57.join(directory, ".swarm", STATE_FILE3);
29545
+ filePath = path59.join(directory, ".swarm", STATE_FILE3);
29290
29546
  tmpPath = `${filePath}.tmp.${Date.now()}`;
29291
29547
  persisted.updatedAt = nowISO3();
29292
29548
  payload = `${JSON.stringify(persisted, null, 2)}
@@ -29404,7 +29660,7 @@ var _internals43 = {
29404
29660
  };
29405
29661
  function readSpecStalenessSnapshot(directory) {
29406
29662
  try {
29407
- const p = path58.join(directory, ".swarm", "spec-staleness.json");
29663
+ const p = path60.join(directory, ".swarm", "spec-staleness.json");
29408
29664
  if (!fsSync3.existsSync(p))
29409
29665
  return { stale: false };
29410
29666
  const raw = fsSync3.readFileSync(p, "utf-8");
@@ -29496,7 +29752,7 @@ async function getStatusData(directory, agents) {
29496
29752
  }
29497
29753
  status.recentEscalations = await readRecentEscalations(directory);
29498
29754
  status.pendingProposals = await countProposals(directory);
29499
- status.unactionableQueueDepth = await safeLineCount(validateSwarmPath(directory, "knowledge-unactionable.jsonl"));
29755
+ status.unactionableQueueDepth = await safeLineCount(resolveUnactionablePath(directory));
29500
29756
  status.insightCandidatesPending = await safeLineCount(validateSwarmPath(directory, "insight-candidates.jsonl"));
29501
29757
  return enrichWithLeanTurbo(status, directory);
29502
29758
  }
@@ -29935,6 +30191,66 @@ function buildStatusMessage2(session, directory, sessionID) {
29935
30191
  `);
29936
30192
  }
29937
30193
 
30194
+ // src/commands/unlink.ts
30195
+ import { existsSync as existsSync36 } from "fs";
30196
+ import * as path61 from "path";
30197
+ var DEDUP_THRESHOLD2 = 0.6;
30198
+ async function copySharedKnowledgeToLocal(linkDir, localSwarmDir) {
30199
+ const sharedPath = path61.join(linkDir, "knowledge.jsonl");
30200
+ const localPath = path61.join(localSwarmDir, "knowledge.jsonl");
30201
+ if (!existsSync36(sharedPath))
30202
+ return 0;
30203
+ const sharedEntries = await readKnowledge(sharedPath);
30204
+ if (sharedEntries.length === 0)
30205
+ return 0;
30206
+ let copied = 0;
30207
+ await transactKnowledge(localPath, (localEntries) => {
30208
+ const result = [...localEntries];
30209
+ const seenIds = new Set(result.map((e) => e.id));
30210
+ let changed = false;
30211
+ for (const entry of sharedEntries) {
30212
+ if (seenIds.has(entry.id))
30213
+ continue;
30214
+ if (findNearDuplicate(entry.lesson, result, DEDUP_THRESHOLD2))
30215
+ continue;
30216
+ result.push(entry);
30217
+ seenIds.add(entry.id);
30218
+ copied++;
30219
+ changed = true;
30220
+ }
30221
+ return changed ? result : null;
30222
+ });
30223
+ return copied;
30224
+ }
30225
+ async function handleUnlinkCommand(directory, args) {
30226
+ const pointer = readLinkPointer(directory);
30227
+ if (!pointer) {
30228
+ return "\u2139\uFE0F This worktree is not linked. Nothing to unlink.";
30229
+ }
30230
+ const copyBack = !args.includes("--no-copy");
30231
+ const linkDir = resolveLinkDir(pointer.linkId);
30232
+ let copied = 0;
30233
+ if (copyBack) {
30234
+ try {
30235
+ copied = await copySharedKnowledgeToLocal(linkDir, path61.join(directory, ".swarm"));
30236
+ } catch (error2) {
30237
+ return `\u274C Failed to copy shared knowledge back to local: ${error2 instanceof Error ? error2.message : String(error2)}`;
30238
+ }
30239
+ }
30240
+ try {
30241
+ await removeLinkPointer(directory);
30242
+ } catch (error2) {
30243
+ return `\u274C Failed to remove link pointer: ${error2 instanceof Error ? error2.message : String(error2)}`;
30244
+ }
30245
+ const copyNote = copyBack ? ` copied ${copied} shared lesson(s) back into local \`.swarm/knowledge.jsonl\`.` : " shared lessons were NOT copied back (--no-copy).";
30246
+ return [
30247
+ `\uD83D\uDD13 Unlinked this worktree from shared knowledge store "${pointer.linkId}".`,
30248
+ copyNote,
30249
+ "This worktree now uses its local `.swarm/` knowledge again."
30250
+ ].join(`
30251
+ `);
30252
+ }
30253
+
29938
30254
  // src/commands/write-retro.ts
29939
30255
  async function handleWriteRetroCommand(directory, args) {
29940
30256
  if (args.length === 0 || !args[0] || args[0].trim() === "") {
@@ -30071,7 +30387,7 @@ function buildDetailedHelp(commandName, entry) {
30071
30387
  async function handleHelpCommand(ctx) {
30072
30388
  const targetCommand = ctx.args.join(" ");
30073
30389
  if (!targetCommand) {
30074
- const { buildHelpText } = await import("./index-5p1gvn98.js");
30390
+ const { buildHelpText } = await import("./index-q3265fxa.js");
30075
30391
  return buildHelpText();
30076
30392
  }
30077
30393
  const tokens = targetCommand.split(/\s+/);
@@ -30080,7 +30396,7 @@ async function handleHelpCommand(ctx) {
30080
30396
  return _internals45.buildDetailedHelp(resolved.key, resolved.entry);
30081
30397
  }
30082
30398
  const similar = _internals45.findSimilarCommands(targetCommand);
30083
- const { buildHelpText: fullHelp } = await import("./index-5p1gvn98.js");
30399
+ const { buildHelpText: fullHelp } = await import("./index-q3265fxa.js");
30084
30400
  if (similar.length > 0) {
30085
30401
  return `Command '/swarm ${targetCommand}' not found.
30086
30402
 
@@ -30213,7 +30529,7 @@ var COMMAND_REGISTRY = {
30213
30529
  },
30214
30530
  "guardrail explain": {
30215
30531
  handler: async (ctx) => {
30216
- const { handleGuardrailExplain } = await import("./guardrail-explain-xe0wjnxz.js");
30532
+ const { handleGuardrailExplain } = await import("./guardrail-explain-han9f51y.js");
30217
30533
  return handleGuardrailExplain(ctx.directory, ctx.args);
30218
30534
  },
30219
30535
  description: "Dry-run: show what the guardrails would do to a command or write target (executes nothing)",
@@ -30676,6 +30992,29 @@ Subcommands:
30676
30992
  category: "config",
30677
30993
  toolPolicy: "none"
30678
30994
  },
30995
+ link: {
30996
+ handler: (ctx) => handleLinkCommand(ctx.directory, ctx.args),
30997
+ description: "Tie this worktree to a shared swarm knowledge store [name]",
30998
+ details: "Links the current worktree to a shared knowledge store so multiple swarms working on the same project (e.g. separate git worktrees) pool their lessons instead of each keeping an isolated .swarm/knowledge.jsonl. With no name, ties all worktrees of the same repo via the project hash; with a name, ties any worktrees/repos that use the same name. Existing local lessons are merged (deduped) into the shared store. Use `/swarm link status` to inspect.",
30999
+ args: "[<name> | status]",
31000
+ category: "utility",
31001
+ toolPolicy: "none"
31002
+ },
31003
+ "link status": {
31004
+ handler: (ctx) => handleLinkCommand(ctx.directory, ["status"]),
31005
+ description: "Show whether this worktree shares knowledge via a link",
31006
+ subcommandOf: "link",
31007
+ category: "utility",
31008
+ toolPolicy: "none"
31009
+ },
31010
+ unlink: {
31011
+ handler: (ctx) => handleUnlinkCommand(ctx.directory, ctx.args),
31012
+ description: "Stop sharing swarm knowledge for this worktree [--no-copy]",
31013
+ details: "Unlinks the current worktree from its shared knowledge store and returns it to a local .swarm/knowledge.jsonl. By default the shared lessons are copied back into the local store (deduped) so nothing is lost; pass --no-copy to skip the copy-back.",
31014
+ args: "[--no-copy]",
31015
+ category: "utility",
31016
+ toolPolicy: "none"
31017
+ },
30679
31018
  promote: {
30680
31019
  handler: (ctx) => handlePromoteCommand(ctx.directory, ctx.args),
30681
31020
  description: "Manually promote lesson to hive knowledge",
@@ -30961,24 +31300,24 @@ function validateAliases() {
30961
31300
  }
30962
31301
  aliasTargets.get(target).push(name);
30963
31302
  const visited = new Set;
30964
- const path59 = [];
31303
+ const path62 = [];
30965
31304
  let current = target;
30966
31305
  while (current) {
30967
31306
  const currentEntry = COMMAND_REGISTRY[current];
30968
31307
  if (!currentEntry)
30969
31308
  break;
30970
31309
  if (visited.has(current)) {
30971
- const cycleStart = path59.indexOf(current);
31310
+ const cycleStart = path62.indexOf(current);
30972
31311
  const fullChain = [
30973
31312
  name,
30974
- ...path59.slice(0, cycleStart > 0 ? cycleStart : path59.length),
31313
+ ...path62.slice(0, cycleStart > 0 ? cycleStart : path62.length),
30975
31314
  current
30976
31315
  ].join(" \u2192 ");
30977
31316
  errors.push(`Circular alias detected: ${fullChain}`);
30978
31317
  break;
30979
31318
  }
30980
31319
  visited.add(current);
30981
- path59.push(current);
31320
+ path62.push(current);
30982
31321
  current = currentEntry.aliasOf || "";
30983
31322
  }
30984
31323
  }
@@ -31144,4 +31483,4 @@ ${text}`;
31144
31483
  };
31145
31484
  }
31146
31485
 
31147
- export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleClarifyCommand, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals45 as _internals, resolveCommand };
31486
+ export { package_default, handleAcknowledgeSpecDriftCommand, handleAgentsCommand, handleAnalyzeCommand, handleArchiveCommand, DC_SAFE_TARGETS, dcNormalizeCommand, dcUnwrapWrappers, dcSplitSegments, dcValidateTargets, dcCheckJunctionCreation, dcExtractWindowsCmdTargets, dcExtractPowerShellTargets, normalizeSwarmCommandInput, canonicalCommandKey, formatCommandNotFound, executeSwarmCommand, SWARM_COMMAND_TOOL_COMMANDS, SWARM_COMMAND_TOOL_ALLOWLIST, HUMAN_ONLY_SWARM_COMMANDS, classifySwarmCommandToolUse, classifySwarmCommandChatFallbackUse, detectPosixWrites, detectWindowsWrites, resolveWriteTargets, handleAutoProceedCommand, handleBenchmarkCommand, handleBrainstormCommand, handleCheckpointCommand, handleClarifyCommand, handleCloseCommand, handleCodebaseReviewCommand, handleConcurrencyCommand, handleConfigCommand, handleConsolidateCommand, handleCouncilCommand, handleCurateCommand, handleDarkMatterCommand, handleDeepDiveCommand, handleDeepResearchCommand, getPluginConfigDir, getPluginCachePaths, getPluginLockFilePaths, handleDiagnoseCommand, handleDoctorCommand, handleEvidenceCommand, handleEvidenceSummaryCommand, handleExportCommand, handleFullAutoCommand, handleHandoffCommand, handleHistoryCommand, handleKnowledgeQuarantineCommand, handleKnowledgeRestoreCommand, handleKnowledgeMigrateCommand, handleKnowledgeListCommand, handleKnowledgeUnactionableCommand, handleKnowledgeRetryHardeningCommand, handleLearningCommand, handleLinkCommand, handleMemoryCommand, handleMemoryStatusCommand, handleMemoryMigrateCommand, handleMemoryImportCommand, handleMemoryExportCommand, handlePlanCommand, handlePreflightCommand, handlePromoteCommand, handleQaGatesCommand, handleResetCommand, handleResetSessionCommand, handleRetrieveCommand, handleRollbackCommand, handleSddStatusCommand, handleSddValidateCommand, handleSddProjectCommand, handleSddCommand, handleSimulateCommand, handleSpecifyCommand, handleStatusCommand, handleSyncPlanCommand, handleTurboCommand, handleUnlinkCommand, handleWriteRetroCommand, handleHelpCommand, COMMAND_REGISTRY, VALID_COMMANDS, _internals45 as _internals, resolveCommand };