opencode-swarm 6.29.5 → 6.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -37604,11 +37604,11 @@ ${JSON.stringify(symbolNames, null, 2)}`);
37604
37604
  throw toThrow;
37605
37605
  }, "quit_");
37606
37606
  var scriptDirectory = "";
37607
- function locateFile(path47) {
37607
+ function locateFile(path46) {
37608
37608
  if (Module["locateFile"]) {
37609
- return Module["locateFile"](path47, scriptDirectory);
37609
+ return Module["locateFile"](path46, scriptDirectory);
37610
37610
  }
37611
- return scriptDirectory + path47;
37611
+ return scriptDirectory + path46;
37612
37612
  }
37613
37613
  __name(locateFile, "locateFile");
37614
37614
  var readAsync, readBinary;
@@ -39356,7 +39356,7 @@ var init_runtime = __esm(() => {
39356
39356
  });
39357
39357
 
39358
39358
  // src/index.ts
39359
- import * as path57 from "path";
39359
+ import * as path56 from "path";
39360
39360
 
39361
39361
  // src/agents/index.ts
39362
39362
  init_config();
@@ -39369,6 +39369,7 @@ init_plan_schema();
39369
39369
  init_schema();
39370
39370
  import * as fs3 from "fs/promises";
39371
39371
  import * as path2 from "path";
39372
+ var _rehydrationCache = null;
39372
39373
  var swarmState = {
39373
39374
  activeToolCalls: new Map,
39374
39375
  toolAggregates: new Map,
@@ -39378,7 +39379,7 @@ var swarmState = {
39378
39379
  lastBudgetPct: 0,
39379
39380
  agentSessions: new Map
39380
39381
  };
39381
- function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, directory) {
39382
+ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, _directory) {
39382
39383
  const now = Date.now();
39383
39384
  const staleIds = [];
39384
39385
  for (const [id, session] of swarmState.agentSessions) {
@@ -39426,14 +39427,12 @@ function startAgentSession(sessionId, agentName, staleDurationMs = 7200000, dire
39426
39427
  };
39427
39428
  swarmState.agentSessions.set(sessionId, sessionState);
39428
39429
  swarmState.activeAgent.set(sessionId, agentName);
39429
- if (directory) {
39430
- rehydrateSessionFromDisk(directory, sessionState).catch(() => {});
39431
- }
39430
+ applyRehydrationCache(sessionState);
39432
39431
  }
39433
39432
  function getAgentSession(sessionId) {
39434
39433
  return swarmState.agentSessions.get(sessionId);
39435
39434
  }
39436
- function ensureAgentSession(sessionId, agentName, directory) {
39435
+ function ensureAgentSession(sessionId, agentName, _directory) {
39437
39436
  const now = Date.now();
39438
39437
  let session = swarmState.agentSessions.get(sessionId);
39439
39438
  if (session) {
@@ -39533,7 +39532,7 @@ function ensureAgentSession(sessionId, agentName, directory) {
39533
39532
  session.lastToolCallTime = now;
39534
39533
  return session;
39535
39534
  }
39536
- startAgentSession(sessionId, agentName ?? "unknown", 7200000, directory);
39535
+ startAgentSession(sessionId, agentName ?? "unknown", 7200000);
39537
39536
  session = swarmState.agentSessions.get(sessionId);
39538
39537
  if (!session) {
39539
39538
  throw new Error(`Failed to create guardrail session for ${sessionId}`);
@@ -39718,43 +39717,47 @@ async function readEvidenceFromDisk(directory) {
39718
39717
  } catch {}
39719
39718
  return evidenceMap;
39720
39719
  }
39721
- async function rehydrateSessionFromDisk(directory, session) {
39722
- if (!session.taskWorkflowStates) {
39723
- session.taskWorkflowStates = new Map;
39724
- }
39725
- const plan = await readPlanFromDisk(directory);
39726
- if (!plan) {
39727
- return;
39728
- }
39720
+ async function buildRehydrationCache(directory) {
39729
39721
  const planTaskStates = new Map;
39730
- for (const phase of plan.phases ?? []) {
39731
- for (const task of phase.tasks ?? []) {
39732
- const taskState = planStatusToWorkflowState(task.status);
39733
- planTaskStates.set(task.id, taskState);
39722
+ const plan = await readPlanFromDisk(directory);
39723
+ if (plan) {
39724
+ for (const phase of plan.phases ?? []) {
39725
+ for (const task of phase.tasks ?? []) {
39726
+ planTaskStates.set(task.id, planStatusToWorkflowState(task.status));
39727
+ }
39734
39728
  }
39735
39729
  }
39736
39730
  const evidenceMap = await readEvidenceFromDisk(directory);
39731
+ _rehydrationCache = { planTaskStates, evidenceMap };
39732
+ }
39733
+ function applyRehydrationCache(session) {
39734
+ if (!_rehydrationCache) {
39735
+ return;
39736
+ }
39737
+ if (!session.taskWorkflowStates) {
39738
+ session.taskWorkflowStates = new Map;
39739
+ }
39740
+ const { planTaskStates, evidenceMap } = _rehydrationCache;
39741
+ const STATE_ORDER = [
39742
+ "idle",
39743
+ "coder_delegated",
39744
+ "pre_check_passed",
39745
+ "reviewer_run",
39746
+ "tests_run",
39747
+ "complete"
39748
+ ];
39737
39749
  for (const [taskId, planState] of planTaskStates) {
39738
39750
  const existingState = session.taskWorkflowStates.get(taskId);
39739
39751
  const evidence = evidenceMap.get(taskId);
39740
- let derivedState;
39741
39752
  if (evidence) {
39742
- derivedState = evidenceToWorkflowState(evidence);
39743
- } else {
39744
- derivedState = planState;
39745
- }
39746
- const STATE_ORDER = [
39747
- "idle",
39748
- "coder_delegated",
39749
- "pre_check_passed",
39750
- "reviewer_run",
39751
- "tests_run",
39752
- "complete"
39753
- ];
39754
- const existingIndex = existingState ? STATE_ORDER.indexOf(existingState) : -1;
39755
- const derivedIndex = STATE_ORDER.indexOf(derivedState);
39756
- if (derivedIndex > existingIndex) {
39753
+ const derivedState = evidenceToWorkflowState(evidence);
39757
39754
  session.taskWorkflowStates.set(taskId, derivedState);
39755
+ } else {
39756
+ const existingIndex = existingState ? STATE_ORDER.indexOf(existingState) : -1;
39757
+ const derivedIndex = STATE_ORDER.indexOf(planState);
39758
+ if (derivedIndex > existingIndex) {
39759
+ session.taskWorkflowStates.set(taskId, planState);
39760
+ }
39758
39761
  }
39759
39762
  }
39760
39763
  }
@@ -53855,7 +53858,6 @@ init_config_doctor();
53855
53858
 
53856
53859
  // src/session/snapshot-reader.ts
53857
53860
  init_utils2();
53858
- import path37 from "path";
53859
53861
  var VALID_TASK_WORKFLOW_STATES = [
53860
53862
  "idle",
53861
53863
  "coder_delegated",
@@ -53978,53 +53980,15 @@ function rehydrateState(snapshot) {
53978
53980
  }
53979
53981
  }
53980
53982
  }
53981
- async function reconcileTaskStatesFromPlan(directory) {
53982
- let raw;
53983
- try {
53984
- raw = await Bun.file(path37.join(directory, ".swarm/plan.json")).text();
53985
- } catch {
53986
- return;
53987
- }
53988
- let plan;
53989
- try {
53990
- plan = JSON.parse(raw);
53991
- } catch {
53992
- return;
53993
- }
53994
- if (!plan?.phases || !Array.isArray(plan.phases)) {
53995
- return;
53996
- }
53997
- for (const phase of plan.phases) {
53998
- if (!phase?.tasks || !Array.isArray(phase.tasks)) {
53999
- continue;
54000
- }
54001
- for (const task of phase.tasks) {
54002
- if (!task?.id || typeof task.id !== "string") {
54003
- continue;
54004
- }
54005
- const taskId = task.id;
54006
- const planStatus = task.status;
54007
- for (const session of swarmState.agentSessions.values()) {
54008
- const currentState = getTaskState(session, taskId);
54009
- if (planStatus === "completed" && currentState !== "tests_run" && currentState !== "complete") {
54010
- try {
54011
- advanceTaskState(session, taskId, "tests_run");
54012
- } catch {}
54013
- } else if (planStatus === "in_progress" && currentState === "idle") {
54014
- try {
54015
- advanceTaskState(session, taskId, "coder_delegated");
54016
- } catch {}
54017
- }
54018
- }
54019
- }
54020
- }
54021
- }
54022
53983
  async function loadSnapshot(directory) {
54023
53984
  try {
53985
+ await buildRehydrationCache(directory);
54024
53986
  const snapshot = await readSnapshot(directory);
54025
53987
  if (snapshot !== null) {
54026
53988
  rehydrateState(snapshot);
54027
- await reconcileTaskStatesFromPlan(directory);
53989
+ for (const session of swarmState.agentSessions.values()) {
53990
+ applyRehydrationCache(session);
53991
+ }
54028
53992
  }
54029
53993
  } catch {}
54030
53994
  }
@@ -54204,7 +54168,7 @@ var build_check = createSwarmTool({
54204
54168
  init_dist();
54205
54169
  init_create_tool();
54206
54170
  import * as fs24 from "fs";
54207
- import * as path38 from "path";
54171
+ import * as path37 from "path";
54208
54172
  var EVIDENCE_DIR = ".swarm/evidence";
54209
54173
  var TASK_ID_PATTERN2 = /^\d+\.\d+(\.\d+)*$/;
54210
54174
  function isValidTaskId3(taskId) {
@@ -54221,9 +54185,9 @@ function isValidTaskId3(taskId) {
54221
54185
  return TASK_ID_PATTERN2.test(taskId);
54222
54186
  }
54223
54187
  function isPathWithinSwarm(filePath, workspaceRoot) {
54224
- const normalizedWorkspace = path38.resolve(workspaceRoot);
54225
- const swarmPath = path38.join(normalizedWorkspace, ".swarm", "evidence");
54226
- const normalizedPath = path38.resolve(filePath);
54188
+ const normalizedWorkspace = path37.resolve(workspaceRoot);
54189
+ const swarmPath = path37.join(normalizedWorkspace, ".swarm", "evidence");
54190
+ const normalizedPath = path37.resolve(filePath);
54227
54191
  return normalizedPath.startsWith(swarmPath);
54228
54192
  }
54229
54193
  function readEvidenceFile(evidencePath) {
@@ -54284,7 +54248,7 @@ var check_gate_status = createSwarmTool({
54284
54248
  };
54285
54249
  return JSON.stringify(errorResult, null, 2);
54286
54250
  }
54287
- const evidencePath = path38.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
54251
+ const evidencePath = path37.join(directory, EVIDENCE_DIR, `${taskIdInput}.json`);
54288
54252
  if (!isPathWithinSwarm(evidencePath, directory)) {
54289
54253
  const errorResult = {
54290
54254
  taskId: taskIdInput,
@@ -54345,7 +54309,7 @@ init_tool();
54345
54309
  init_create_tool();
54346
54310
  import { spawnSync } from "child_process";
54347
54311
  import * as fs25 from "fs";
54348
- import * as path39 from "path";
54312
+ import * as path38 from "path";
54349
54313
  var CHECKPOINT_LOG_PATH = ".swarm/checkpoints.json";
54350
54314
  var MAX_LABEL_LENGTH = 100;
54351
54315
  var GIT_TIMEOUT_MS = 30000;
@@ -54396,7 +54360,7 @@ function validateLabel(label) {
54396
54360
  return null;
54397
54361
  }
54398
54362
  function getCheckpointLogPath(directory) {
54399
- return path39.join(directory, CHECKPOINT_LOG_PATH);
54363
+ return path38.join(directory, CHECKPOINT_LOG_PATH);
54400
54364
  }
54401
54365
  function readCheckpointLog(directory) {
54402
54366
  const logPath = getCheckpointLogPath(directory);
@@ -54414,7 +54378,7 @@ function readCheckpointLog(directory) {
54414
54378
  }
54415
54379
  function writeCheckpointLog(log2, directory) {
54416
54380
  const logPath = getCheckpointLogPath(directory);
54417
- const dir = path39.dirname(logPath);
54381
+ const dir = path38.dirname(logPath);
54418
54382
  if (!fs25.existsSync(dir)) {
54419
54383
  fs25.mkdirSync(dir, { recursive: true });
54420
54384
  }
@@ -54622,7 +54586,7 @@ var checkpoint = createSwarmTool({
54622
54586
  init_dist();
54623
54587
  init_create_tool();
54624
54588
  import * as fs26 from "fs";
54625
- import * as path40 from "path";
54589
+ import * as path39 from "path";
54626
54590
  var MAX_FILE_SIZE_BYTES2 = 256 * 1024;
54627
54591
  var DEFAULT_DAYS = 90;
54628
54592
  var DEFAULT_TOP_N = 20;
@@ -54766,7 +54730,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
54766
54730
  const extSet = new Set(extensions.map((e) => e.startsWith(".") ? e : `.${e}`));
54767
54731
  const filteredChurn = new Map;
54768
54732
  for (const [file3, count] of churnMap) {
54769
- const ext = path40.extname(file3).toLowerCase();
54733
+ const ext = path39.extname(file3).toLowerCase();
54770
54734
  if (extSet.has(ext)) {
54771
54735
  filteredChurn.set(file3, count);
54772
54736
  }
@@ -54777,7 +54741,7 @@ async function analyzeHotspots(days, topN, extensions, directory) {
54777
54741
  for (const [file3, churnCount] of filteredChurn) {
54778
54742
  let fullPath = file3;
54779
54743
  if (!fs26.existsSync(fullPath)) {
54780
- fullPath = path40.join(cwd, file3);
54744
+ fullPath = path39.join(cwd, file3);
54781
54745
  }
54782
54746
  const complexity = getComplexityForFile(fullPath);
54783
54747
  if (complexity !== null) {
@@ -54925,7 +54889,7 @@ var complexity_hotspots = createSwarmTool({
54925
54889
  // src/tools/declare-scope.ts
54926
54890
  init_tool();
54927
54891
  import * as fs27 from "fs";
54928
- import * as path41 from "path";
54892
+ import * as path40 from "path";
54929
54893
  init_create_tool();
54930
54894
  function validateTaskIdFormat(taskId) {
54931
54895
  const taskIdPattern = /^\d+\.\d+(\.\d+)*$/;
@@ -55004,8 +54968,8 @@ async function executeDeclareScope(args2, fallbackDir) {
55004
54968
  };
55005
54969
  }
55006
54970
  }
55007
- normalizedDir = path41.normalize(args2.working_directory);
55008
- const pathParts = normalizedDir.split(path41.sep);
54971
+ normalizedDir = path40.normalize(args2.working_directory);
54972
+ const pathParts = normalizedDir.split(path40.sep);
55009
54973
  if (pathParts.includes("..")) {
55010
54974
  return {
55011
54975
  success: false,
@@ -55015,10 +54979,10 @@ async function executeDeclareScope(args2, fallbackDir) {
55015
54979
  ]
55016
54980
  };
55017
54981
  }
55018
- const resolvedDir = path41.resolve(normalizedDir);
54982
+ const resolvedDir = path40.resolve(normalizedDir);
55019
54983
  try {
55020
54984
  const realPath = fs27.realpathSync(resolvedDir);
55021
- const planPath2 = path41.join(realPath, ".swarm", "plan.json");
54985
+ const planPath2 = path40.join(realPath, ".swarm", "plan.json");
55022
54986
  if (!fs27.existsSync(planPath2)) {
55023
54987
  return {
55024
54988
  success: false,
@@ -55039,7 +55003,7 @@ async function executeDeclareScope(args2, fallbackDir) {
55039
55003
  }
55040
55004
  }
55041
55005
  const directory = normalizedDir ?? fallbackDir ?? process.cwd();
55042
- const planPath = path41.resolve(directory, ".swarm", "plan.json");
55006
+ const planPath = path40.resolve(directory, ".swarm", "plan.json");
55043
55007
  if (!fs27.existsSync(planPath)) {
55044
55008
  return {
55045
55009
  success: false,
@@ -55129,20 +55093,20 @@ function validateBase(base) {
55129
55093
  function validatePaths(paths) {
55130
55094
  if (!paths)
55131
55095
  return null;
55132
- for (const path42 of paths) {
55133
- if (!path42 || path42.length === 0) {
55096
+ for (const path41 of paths) {
55097
+ if (!path41 || path41.length === 0) {
55134
55098
  return "empty path not allowed";
55135
55099
  }
55136
- if (path42.length > MAX_PATH_LENGTH) {
55100
+ if (path41.length > MAX_PATH_LENGTH) {
55137
55101
  return `path exceeds maximum length of ${MAX_PATH_LENGTH}`;
55138
55102
  }
55139
- if (SHELL_METACHARACTERS2.test(path42)) {
55103
+ if (SHELL_METACHARACTERS2.test(path41)) {
55140
55104
  return "path contains shell metacharacters";
55141
55105
  }
55142
- if (path42.startsWith("-")) {
55106
+ if (path41.startsWith("-")) {
55143
55107
  return 'path cannot start with "-" (option-like arguments not allowed)';
55144
55108
  }
55145
- if (CONTROL_CHAR_PATTERN2.test(path42)) {
55109
+ if (CONTROL_CHAR_PATTERN2.test(path41)) {
55146
55110
  return "path contains control characters";
55147
55111
  }
55148
55112
  }
@@ -55222,8 +55186,8 @@ var diff = tool({
55222
55186
  if (parts2.length >= 3) {
55223
55187
  const additions = parseInt(parts2[0], 10) || 0;
55224
55188
  const deletions = parseInt(parts2[1], 10) || 0;
55225
- const path42 = parts2[2];
55226
- files.push({ path: path42, additions, deletions });
55189
+ const path41 = parts2[2];
55190
+ files.push({ path: path41, additions, deletions });
55227
55191
  }
55228
55192
  }
55229
55193
  const contractChanges = [];
@@ -55453,7 +55417,7 @@ Use these as DOMAIN values when delegating to @sme.`;
55453
55417
  init_dist();
55454
55418
  init_create_tool();
55455
55419
  import * as fs28 from "fs";
55456
- import * as path42 from "path";
55420
+ import * as path41 from "path";
55457
55421
  var MAX_FILE_SIZE_BYTES3 = 1024 * 1024;
55458
55422
  var MAX_EVIDENCE_FILES = 1000;
55459
55423
  var EVIDENCE_DIR2 = ".swarm/evidence";
@@ -55483,9 +55447,9 @@ function validateRequiredTypes(input) {
55483
55447
  return null;
55484
55448
  }
55485
55449
  function isPathWithinSwarm2(filePath, cwd) {
55486
- const normalizedCwd = path42.resolve(cwd);
55487
- const swarmPath = path42.join(normalizedCwd, ".swarm");
55488
- const normalizedPath = path42.resolve(filePath);
55450
+ const normalizedCwd = path41.resolve(cwd);
55451
+ const swarmPath = path41.join(normalizedCwd, ".swarm");
55452
+ const normalizedPath = path41.resolve(filePath);
55489
55453
  return normalizedPath.startsWith(swarmPath);
55490
55454
  }
55491
55455
  function parseCompletedTasks(planContent) {
@@ -55515,10 +55479,10 @@ function readEvidenceFiles(evidenceDir, _cwd) {
55515
55479
  if (!VALID_EVIDENCE_FILENAME_REGEX.test(filename)) {
55516
55480
  continue;
55517
55481
  }
55518
- const filePath = path42.join(evidenceDir, filename);
55482
+ const filePath = path41.join(evidenceDir, filename);
55519
55483
  try {
55520
- const resolvedPath = path42.resolve(filePath);
55521
- const evidenceDirResolved = path42.resolve(evidenceDir);
55484
+ const resolvedPath = path41.resolve(filePath);
55485
+ const evidenceDirResolved = path41.resolve(evidenceDir);
55522
55486
  if (!resolvedPath.startsWith(evidenceDirResolved)) {
55523
55487
  continue;
55524
55488
  }
@@ -55636,7 +55600,7 @@ var evidence_check = createSwarmTool({
55636
55600
  return JSON.stringify(errorResult, null, 2);
55637
55601
  }
55638
55602
  const requiredTypes = requiredTypesValue.split(",").map((t) => t.trim()).filter((t) => t.length > 0).map(normalizeEvidenceType);
55639
- const planPath = path42.join(cwd, PLAN_FILE);
55603
+ const planPath = path41.join(cwd, PLAN_FILE);
55640
55604
  if (!isPathWithinSwarm2(planPath, cwd)) {
55641
55605
  const errorResult = {
55642
55606
  error: "plan file path validation failed",
@@ -55668,7 +55632,7 @@ var evidence_check = createSwarmTool({
55668
55632
  };
55669
55633
  return JSON.stringify(result2, null, 2);
55670
55634
  }
55671
- const evidenceDir = path42.join(cwd, EVIDENCE_DIR2);
55635
+ const evidenceDir = path41.join(cwd, EVIDENCE_DIR2);
55672
55636
  const evidence = readEvidenceFiles(evidenceDir, cwd);
55673
55637
  const { tasksWithFullEvidence, gaps } = analyzeGaps(completedTasks, evidence, requiredTypes);
55674
55638
  const completeness = completedTasks.length > 0 ? Math.round(tasksWithFullEvidence.length / completedTasks.length * 100) / 100 : 1;
@@ -55686,7 +55650,7 @@ var evidence_check = createSwarmTool({
55686
55650
  init_tool();
55687
55651
  init_create_tool();
55688
55652
  import * as fs29 from "fs";
55689
- import * as path43 from "path";
55653
+ import * as path42 from "path";
55690
55654
  var EXT_MAP = {
55691
55655
  python: ".py",
55692
55656
  py: ".py",
@@ -55767,12 +55731,12 @@ var extract_code_blocks = createSwarmTool({
55767
55731
  if (prefix) {
55768
55732
  filename = `${prefix}_${filename}`;
55769
55733
  }
55770
- let filepath = path43.join(targetDir, filename);
55771
- const base = path43.basename(filepath, path43.extname(filepath));
55772
- const ext = path43.extname(filepath);
55734
+ let filepath = path42.join(targetDir, filename);
55735
+ const base = path42.basename(filepath, path42.extname(filepath));
55736
+ const ext = path42.extname(filepath);
55773
55737
  let counter = 1;
55774
55738
  while (fs29.existsSync(filepath)) {
55775
- filepath = path43.join(targetDir, `${base}_${counter}${ext}`);
55739
+ filepath = path42.join(targetDir, `${base}_${counter}${ext}`);
55776
55740
  counter++;
55777
55741
  }
55778
55742
  try {
@@ -55890,7 +55854,7 @@ var gitingest = tool({
55890
55854
  // src/tools/imports.ts
55891
55855
  init_dist();
55892
55856
  import * as fs30 from "fs";
55893
- import * as path44 from "path";
55857
+ import * as path43 from "path";
55894
55858
  var MAX_FILE_PATH_LENGTH2 = 500;
55895
55859
  var MAX_SYMBOL_LENGTH = 256;
55896
55860
  var MAX_FILE_SIZE_BYTES4 = 1024 * 1024;
@@ -55944,7 +55908,7 @@ function validateSymbolInput(symbol3) {
55944
55908
  return null;
55945
55909
  }
55946
55910
  function isBinaryFile2(filePath, buffer) {
55947
- const ext = path44.extname(filePath).toLowerCase();
55911
+ const ext = path43.extname(filePath).toLowerCase();
55948
55912
  if (ext === ".json" || ext === ".md" || ext === ".txt") {
55949
55913
  return false;
55950
55914
  }
@@ -55968,15 +55932,15 @@ function parseImports(content, targetFile, targetSymbol) {
55968
55932
  const imports = [];
55969
55933
  let _resolvedTarget;
55970
55934
  try {
55971
- _resolvedTarget = path44.resolve(targetFile);
55935
+ _resolvedTarget = path43.resolve(targetFile);
55972
55936
  } catch {
55973
55937
  _resolvedTarget = targetFile;
55974
55938
  }
55975
- const targetBasename = path44.basename(targetFile, path44.extname(targetFile));
55939
+ const targetBasename = path43.basename(targetFile, path43.extname(targetFile));
55976
55940
  const targetWithExt = targetFile;
55977
55941
  const targetWithoutExt = targetFile.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
55978
- const normalizedTargetWithExt = path44.normalize(targetWithExt).replace(/\\/g, "/");
55979
- const normalizedTargetWithoutExt = path44.normalize(targetWithoutExt).replace(/\\/g, "/");
55942
+ const normalizedTargetWithExt = path43.normalize(targetWithExt).replace(/\\/g, "/");
55943
+ const normalizedTargetWithoutExt = path43.normalize(targetWithoutExt).replace(/\\/g, "/");
55980
55944
  const importRegex = /import\s+(?:\{[\s\S]*?\}|(?:\*\s+as\s+\w+)|\w+)\s+from\s+['"`]([^'"`]+)['"`]|import\s+['"`]([^'"`]+)['"`]|require\s*\(\s*['"`]([^'"`]+)['"`]\s*\)/g;
55981
55945
  for (let match = importRegex.exec(content);match !== null; match = importRegex.exec(content)) {
55982
55946
  const modulePath = match[1] || match[2] || match[3];
@@ -55999,9 +55963,9 @@ function parseImports(content, targetFile, targetSymbol) {
55999
55963
  }
56000
55964
  const _normalizedModule = modulePath.replace(/^\.\//, "").replace(/^\.\.\\/, "../");
56001
55965
  let isMatch = false;
56002
- const _targetDir = path44.dirname(targetFile);
56003
- const targetExt = path44.extname(targetFile);
56004
- const targetBasenameNoExt = path44.basename(targetFile, targetExt);
55966
+ const _targetDir = path43.dirname(targetFile);
55967
+ const targetExt = path43.extname(targetFile);
55968
+ const targetBasenameNoExt = path43.basename(targetFile, targetExt);
56005
55969
  const moduleNormalized = modulePath.replace(/\\/g, "/").replace(/^\.\//, "");
56006
55970
  const moduleName = modulePath.split(/[/\\]/).pop() || "";
56007
55971
  const moduleNameNoExt = moduleName.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/i, "");
@@ -56069,10 +56033,10 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
56069
56033
  entries.sort((a, b) => a.toLowerCase().localeCompare(b.toLowerCase()));
56070
56034
  for (const entry of entries) {
56071
56035
  if (SKIP_DIRECTORIES2.has(entry)) {
56072
- stats.skippedDirs.push(path44.join(dir, entry));
56036
+ stats.skippedDirs.push(path43.join(dir, entry));
56073
56037
  continue;
56074
56038
  }
56075
- const fullPath = path44.join(dir, entry);
56039
+ const fullPath = path43.join(dir, entry);
56076
56040
  let stat2;
56077
56041
  try {
56078
56042
  stat2 = fs30.statSync(fullPath);
@@ -56086,7 +56050,7 @@ function findSourceFiles(dir, files = [], stats = { skippedDirs: [], skippedFile
56086
56050
  if (stat2.isDirectory()) {
56087
56051
  findSourceFiles(fullPath, files, stats);
56088
56052
  } else if (stat2.isFile()) {
56089
- const ext = path44.extname(fullPath).toLowerCase();
56053
+ const ext = path43.extname(fullPath).toLowerCase();
56090
56054
  if (SUPPORTED_EXTENSIONS.includes(ext)) {
56091
56055
  files.push(fullPath);
56092
56056
  }
@@ -56142,7 +56106,7 @@ var imports = tool({
56142
56106
  return JSON.stringify(errorResult, null, 2);
56143
56107
  }
56144
56108
  try {
56145
- const targetFile = path44.resolve(file3);
56109
+ const targetFile = path43.resolve(file3);
56146
56110
  if (!fs30.existsSync(targetFile)) {
56147
56111
  const errorResult = {
56148
56112
  error: `target file not found: ${file3}`,
@@ -56164,7 +56128,7 @@ var imports = tool({
56164
56128
  };
56165
56129
  return JSON.stringify(errorResult, null, 2);
56166
56130
  }
56167
- const baseDir = path44.dirname(targetFile);
56131
+ const baseDir = path43.dirname(targetFile);
56168
56132
  const scanStats = {
56169
56133
  skippedDirs: [],
56170
56134
  skippedFiles: 0,
@@ -56486,7 +56450,7 @@ init_config();
56486
56450
  init_schema();
56487
56451
  init_manager();
56488
56452
  import * as fs31 from "fs";
56489
- import * as path45 from "path";
56453
+ import * as path44 from "path";
56490
56454
  init_utils2();
56491
56455
  init_create_tool();
56492
56456
  function safeWarn(message, error93) {
@@ -56681,7 +56645,7 @@ async function executePhaseComplete(args2, workingDirectory) {
56681
56645
  }
56682
56646
  if (retroFound && retroEntry?.lessons_learned && retroEntry.lessons_learned.length > 0) {
56683
56647
  try {
56684
- const projectName = path45.basename(dir);
56648
+ const projectName = path44.basename(dir);
56685
56649
  const knowledgeConfig = {
56686
56650
  enabled: true,
56687
56651
  swarm_max_entries: 100,
@@ -56853,7 +56817,7 @@ init_discovery();
56853
56817
  init_utils();
56854
56818
  init_create_tool();
56855
56819
  import * as fs32 from "fs";
56856
- import * as path46 from "path";
56820
+ import * as path45 from "path";
56857
56821
  var MAX_OUTPUT_BYTES5 = 52428800;
56858
56822
  var AUDIT_TIMEOUT_MS = 120000;
56859
56823
  function isValidEcosystem(value) {
@@ -56871,16 +56835,16 @@ function validateArgs3(args2) {
56871
56835
  function detectEcosystems(directory) {
56872
56836
  const ecosystems = [];
56873
56837
  const cwd = directory;
56874
- if (fs32.existsSync(path46.join(cwd, "package.json"))) {
56838
+ if (fs32.existsSync(path45.join(cwd, "package.json"))) {
56875
56839
  ecosystems.push("npm");
56876
56840
  }
56877
- if (fs32.existsSync(path46.join(cwd, "pyproject.toml")) || fs32.existsSync(path46.join(cwd, "requirements.txt"))) {
56841
+ if (fs32.existsSync(path45.join(cwd, "pyproject.toml")) || fs32.existsSync(path45.join(cwd, "requirements.txt"))) {
56878
56842
  ecosystems.push("pip");
56879
56843
  }
56880
- if (fs32.existsSync(path46.join(cwd, "Cargo.toml"))) {
56844
+ if (fs32.existsSync(path45.join(cwd, "Cargo.toml"))) {
56881
56845
  ecosystems.push("cargo");
56882
56846
  }
56883
- if (fs32.existsSync(path46.join(cwd, "go.mod"))) {
56847
+ if (fs32.existsSync(path45.join(cwd, "go.mod"))) {
56884
56848
  ecosystems.push("go");
56885
56849
  }
56886
56850
  try {
@@ -56889,10 +56853,10 @@ function detectEcosystems(directory) {
56889
56853
  ecosystems.push("dotnet");
56890
56854
  }
56891
56855
  } catch {}
56892
- if (fs32.existsSync(path46.join(cwd, "Gemfile")) || fs32.existsSync(path46.join(cwd, "Gemfile.lock"))) {
56856
+ if (fs32.existsSync(path45.join(cwd, "Gemfile")) || fs32.existsSync(path45.join(cwd, "Gemfile.lock"))) {
56893
56857
  ecosystems.push("ruby");
56894
56858
  }
56895
- if (fs32.existsSync(path46.join(cwd, "pubspec.yaml"))) {
56859
+ if (fs32.existsSync(path45.join(cwd, "pubspec.yaml"))) {
56896
56860
  ecosystems.push("dart");
56897
56861
  }
56898
56862
  return ecosystems;
@@ -57955,7 +57919,7 @@ var SUPPORTED_PARSER_EXTENSIONS = new Set([
57955
57919
  // src/tools/pre-check-batch.ts
57956
57920
  init_dist();
57957
57921
  import * as fs35 from "fs";
57958
- import * as path49 from "path";
57922
+ import * as path48 from "path";
57959
57923
 
57960
57924
  // node_modules/yocto-queue/index.js
57961
57925
  class Node2 {
@@ -58123,7 +58087,7 @@ init_manager();
58123
58087
 
58124
58088
  // src/quality/metrics.ts
58125
58089
  import * as fs33 from "fs";
58126
- import * as path47 from "path";
58090
+ import * as path46 from "path";
58127
58091
  var MAX_FILE_SIZE_BYTES5 = 256 * 1024;
58128
58092
  var MIN_DUPLICATION_LINES = 10;
58129
58093
  function estimateCyclomaticComplexity(content) {
@@ -58175,7 +58139,7 @@ async function computeComplexityDelta(files, workingDir) {
58175
58139
  let totalComplexity = 0;
58176
58140
  const analyzedFiles = [];
58177
58141
  for (const file3 of files) {
58178
- const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
58142
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58179
58143
  if (!fs33.existsSync(fullPath)) {
58180
58144
  continue;
58181
58145
  }
@@ -58298,7 +58262,7 @@ function countGoExports(content) {
58298
58262
  function getExportCountForFile(filePath) {
58299
58263
  try {
58300
58264
  const content = fs33.readFileSync(filePath, "utf-8");
58301
- const ext = path47.extname(filePath).toLowerCase();
58265
+ const ext = path46.extname(filePath).toLowerCase();
58302
58266
  switch (ext) {
58303
58267
  case ".ts":
58304
58268
  case ".tsx":
@@ -58324,7 +58288,7 @@ async function computePublicApiDelta(files, workingDir) {
58324
58288
  let totalExports = 0;
58325
58289
  const analyzedFiles = [];
58326
58290
  for (const file3 of files) {
58327
- const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
58291
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58328
58292
  if (!fs33.existsSync(fullPath)) {
58329
58293
  continue;
58330
58294
  }
@@ -58358,7 +58322,7 @@ async function computeDuplicationRatio(files, workingDir) {
58358
58322
  let duplicateLines = 0;
58359
58323
  const analyzedFiles = [];
58360
58324
  for (const file3 of files) {
58361
- const fullPath = path47.isAbsolute(file3) ? file3 : path47.join(workingDir, file3);
58325
+ const fullPath = path46.isAbsolute(file3) ? file3 : path46.join(workingDir, file3);
58362
58326
  if (!fs33.existsSync(fullPath)) {
58363
58327
  continue;
58364
58328
  }
@@ -58391,8 +58355,8 @@ function countCodeLines(content) {
58391
58355
  return lines.length;
58392
58356
  }
58393
58357
  function isTestFile(filePath) {
58394
- const basename8 = path47.basename(filePath);
58395
- const _ext = path47.extname(filePath).toLowerCase();
58358
+ const basename8 = path46.basename(filePath);
58359
+ const _ext = path46.extname(filePath).toLowerCase();
58396
58360
  const testPatterns = [
58397
58361
  ".test.",
58398
58362
  ".spec.",
@@ -58473,8 +58437,8 @@ function matchGlobSegment(globSegments, pathSegments) {
58473
58437
  }
58474
58438
  return gIndex === globSegments.length && pIndex === pathSegments.length;
58475
58439
  }
58476
- function matchesGlobSegment(path48, glob) {
58477
- const normalizedPath = path48.replace(/\\/g, "/");
58440
+ function matchesGlobSegment(path47, glob) {
58441
+ const normalizedPath = path47.replace(/\\/g, "/");
58478
58442
  const normalizedGlob = glob.replace(/\\/g, "/");
58479
58443
  if (normalizedPath.includes("//")) {
58480
58444
  return false;
@@ -58505,8 +58469,8 @@ function simpleGlobToRegex2(glob) {
58505
58469
  function hasGlobstar(glob) {
58506
58470
  return glob.includes("**");
58507
58471
  }
58508
- function globMatches(path48, glob) {
58509
- const normalizedPath = path48.replace(/\\/g, "/");
58472
+ function globMatches(path47, glob) {
58473
+ const normalizedPath = path47.replace(/\\/g, "/");
58510
58474
  if (!glob || glob === "") {
58511
58475
  if (normalizedPath.includes("//")) {
58512
58476
  return false;
@@ -58542,7 +58506,7 @@ function shouldExcludeFile(filePath, excludeGlobs) {
58542
58506
  async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
58543
58507
  let testLines = 0;
58544
58508
  let codeLines = 0;
58545
- const srcDir = path47.join(workingDir, "src");
58509
+ const srcDir = path46.join(workingDir, "src");
58546
58510
  if (fs33.existsSync(srcDir)) {
58547
58511
  await scanDirectoryForLines(srcDir, enforceGlobs, excludeGlobs, false, (lines) => {
58548
58512
  codeLines += lines;
@@ -58550,14 +58514,14 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
58550
58514
  }
58551
58515
  const possibleSrcDirs = ["lib", "app", "source", "core"];
58552
58516
  for (const dir of possibleSrcDirs) {
58553
- const dirPath = path47.join(workingDir, dir);
58517
+ const dirPath = path46.join(workingDir, dir);
58554
58518
  if (fs33.existsSync(dirPath)) {
58555
58519
  await scanDirectoryForLines(dirPath, enforceGlobs, excludeGlobs, false, (lines) => {
58556
58520
  codeLines += lines;
58557
58521
  });
58558
58522
  }
58559
58523
  }
58560
- const testsDir = path47.join(workingDir, "tests");
58524
+ const testsDir = path46.join(workingDir, "tests");
58561
58525
  if (fs33.existsSync(testsDir)) {
58562
58526
  await scanDirectoryForLines(testsDir, ["**"], ["node_modules", "dist"], true, (lines) => {
58563
58527
  testLines += lines;
@@ -58565,7 +58529,7 @@ async function computeTestToCodeRatio(workingDir, enforceGlobs, excludeGlobs) {
58565
58529
  }
58566
58530
  const possibleTestDirs = ["test", "__tests__", "specs"];
58567
58531
  for (const dir of possibleTestDirs) {
58568
- const dirPath = path47.join(workingDir, dir);
58532
+ const dirPath = path46.join(workingDir, dir);
58569
58533
  if (fs33.existsSync(dirPath) && dirPath !== testsDir) {
58570
58534
  await scanDirectoryForLines(dirPath, ["**"], ["node_modules", "dist"], true, (lines) => {
58571
58535
  testLines += lines;
@@ -58580,7 +58544,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
58580
58544
  try {
58581
58545
  const entries = fs33.readdirSync(dirPath, { withFileTypes: true });
58582
58546
  for (const entry of entries) {
58583
- const fullPath = path47.join(dirPath, entry.name);
58547
+ const fullPath = path46.join(dirPath, entry.name);
58584
58548
  if (entry.isDirectory()) {
58585
58549
  if (entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === ".git") {
58586
58550
  continue;
@@ -58588,7 +58552,7 @@ async function scanDirectoryForLines(dirPath, includeGlobs, excludeGlobs, isTest
58588
58552
  await scanDirectoryForLines(fullPath, includeGlobs, excludeGlobs, isTestScan, callback);
58589
58553
  } else if (entry.isFile()) {
58590
58554
  const relativePath = fullPath.replace(`${process.cwd()}/`, "");
58591
- const ext = path47.extname(entry.name).toLowerCase();
58555
+ const ext = path46.extname(entry.name).toLowerCase();
58592
58556
  const validExts = [
58593
58557
  ".ts",
58594
58558
  ".tsx",
@@ -58839,7 +58803,7 @@ init_dist();
58839
58803
  init_manager();
58840
58804
  init_detector();
58841
58805
  import * as fs34 from "fs";
58842
- import * as path48 from "path";
58806
+ import * as path47 from "path";
58843
58807
  import { extname as extname9 } from "path";
58844
58808
 
58845
58809
  // src/sast/rules/c.ts
@@ -59802,7 +59766,7 @@ async function sastScan(input, directory, config3) {
59802
59766
  _filesSkipped++;
59803
59767
  continue;
59804
59768
  }
59805
- const resolvedPath = path48.isAbsolute(filePath) ? filePath : path48.resolve(directory, filePath);
59769
+ const resolvedPath = path47.isAbsolute(filePath) ? filePath : path47.resolve(directory, filePath);
59806
59770
  if (!fs34.existsSync(resolvedPath)) {
59807
59771
  _filesSkipped++;
59808
59772
  continue;
@@ -60001,18 +59965,18 @@ function validatePath(inputPath, baseDir, workspaceDir) {
60001
59965
  let resolved;
60002
59966
  const isWinAbs = isWindowsAbsolutePath(inputPath);
60003
59967
  if (isWinAbs) {
60004
- resolved = path49.win32.resolve(inputPath);
60005
- } else if (path49.isAbsolute(inputPath)) {
60006
- resolved = path49.resolve(inputPath);
59968
+ resolved = path48.win32.resolve(inputPath);
59969
+ } else if (path48.isAbsolute(inputPath)) {
59970
+ resolved = path48.resolve(inputPath);
60007
59971
  } else {
60008
- resolved = path49.resolve(baseDir, inputPath);
59972
+ resolved = path48.resolve(baseDir, inputPath);
60009
59973
  }
60010
- const workspaceResolved = path49.resolve(workspaceDir);
59974
+ const workspaceResolved = path48.resolve(workspaceDir);
60011
59975
  let relative5;
60012
59976
  if (isWinAbs) {
60013
- relative5 = path49.win32.relative(workspaceResolved, resolved);
59977
+ relative5 = path48.win32.relative(workspaceResolved, resolved);
60014
59978
  } else {
60015
- relative5 = path49.relative(workspaceResolved, resolved);
59979
+ relative5 = path48.relative(workspaceResolved, resolved);
60016
59980
  }
60017
59981
  if (relative5.startsWith("..")) {
60018
59982
  return "path traversal detected";
@@ -60073,13 +60037,13 @@ async function runLintWrapped(files, directory, _config) {
60073
60037
  }
60074
60038
  async function runLintOnFiles(linter, files, workspaceDir) {
60075
60039
  const isWindows = process.platform === "win32";
60076
- const binDir = path49.join(workspaceDir, "node_modules", ".bin");
60040
+ const binDir = path48.join(workspaceDir, "node_modules", ".bin");
60077
60041
  const validatedFiles = [];
60078
60042
  for (const file3 of files) {
60079
60043
  if (typeof file3 !== "string") {
60080
60044
  continue;
60081
60045
  }
60082
- const resolvedPath = path49.resolve(file3);
60046
+ const resolvedPath = path48.resolve(file3);
60083
60047
  const validationError = validatePath(resolvedPath, workspaceDir, workspaceDir);
60084
60048
  if (validationError) {
60085
60049
  continue;
@@ -60097,10 +60061,10 @@ async function runLintOnFiles(linter, files, workspaceDir) {
60097
60061
  }
60098
60062
  let command;
60099
60063
  if (linter === "biome") {
60100
- const biomeBin = isWindows ? path49.join(binDir, "biome.EXE") : path49.join(binDir, "biome");
60064
+ const biomeBin = isWindows ? path48.join(binDir, "biome.EXE") : path48.join(binDir, "biome");
60101
60065
  command = [biomeBin, "check", ...validatedFiles];
60102
60066
  } else {
60103
- const eslintBin = isWindows ? path49.join(binDir, "eslint.cmd") : path49.join(binDir, "eslint");
60067
+ const eslintBin = isWindows ? path48.join(binDir, "eslint.cmd") : path48.join(binDir, "eslint");
60104
60068
  command = [eslintBin, ...validatedFiles];
60105
60069
  }
60106
60070
  try {
@@ -60237,7 +60201,7 @@ async function runSecretscanWithFiles(files, directory) {
60237
60201
  skippedFiles++;
60238
60202
  continue;
60239
60203
  }
60240
- const resolvedPath = path49.resolve(file3);
60204
+ const resolvedPath = path48.resolve(file3);
60241
60205
  const validationError = validatePath(resolvedPath, directory, directory);
60242
60206
  if (validationError) {
60243
60207
  skippedFiles++;
@@ -60255,7 +60219,7 @@ async function runSecretscanWithFiles(files, directory) {
60255
60219
  };
60256
60220
  }
60257
60221
  for (const file3 of validatedFiles) {
60258
- const ext = path49.extname(file3).toLowerCase();
60222
+ const ext = path48.extname(file3).toLowerCase();
60259
60223
  if (DEFAULT_EXCLUDE_EXTENSIONS2.has(ext)) {
60260
60224
  skippedFiles++;
60261
60225
  continue;
@@ -60414,7 +60378,7 @@ async function runPreCheckBatch(input, workspaceDir) {
60414
60378
  warn(`pre_check_batch: Invalid file path: ${file3}`);
60415
60379
  continue;
60416
60380
  }
60417
- changedFiles.push(path49.resolve(directory, file3));
60381
+ changedFiles.push(path48.resolve(directory, file3));
60418
60382
  }
60419
60383
  if (changedFiles.length === 0) {
60420
60384
  warn("pre_check_batch: No valid files after validation, skipping all tools (fail-closed)");
@@ -60565,7 +60529,7 @@ var pre_check_batch = createSwarmTool({
60565
60529
  };
60566
60530
  return JSON.stringify(errorResult, null, 2);
60567
60531
  }
60568
- const resolvedDirectory = path49.resolve(typedArgs.directory);
60532
+ const resolvedDirectory = path48.resolve(typedArgs.directory);
60569
60533
  const workspaceAnchor = resolvedDirectory;
60570
60534
  const dirError = validateDirectory3(resolvedDirectory, workspaceAnchor);
60571
60535
  if (dirError) {
@@ -60673,7 +60637,7 @@ init_tool();
60673
60637
  init_manager2();
60674
60638
  init_create_tool();
60675
60639
  import * as fs36 from "fs";
60676
- import * as path50 from "path";
60640
+ import * as path49 from "path";
60677
60641
  function detectPlaceholderContent(args2) {
60678
60642
  const issues = [];
60679
60643
  const placeholderPattern = /^\[\w[\w\s]*\]$/;
@@ -60777,7 +60741,7 @@ async function executeSavePlan(args2, fallbackDir) {
60777
60741
  try {
60778
60742
  await savePlan(dir, plan);
60779
60743
  try {
60780
- const markerPath = path50.join(dir, ".swarm", ".plan-write-marker");
60744
+ const markerPath = path49.join(dir, ".swarm", ".plan-write-marker");
60781
60745
  const marker = JSON.stringify({
60782
60746
  source: "save_plan",
60783
60747
  timestamp: new Date().toISOString(),
@@ -60789,7 +60753,7 @@ async function executeSavePlan(args2, fallbackDir) {
60789
60753
  return {
60790
60754
  success: true,
60791
60755
  message: "Plan saved successfully",
60792
- plan_path: path50.join(dir, ".swarm", "plan.json"),
60756
+ plan_path: path49.join(dir, ".swarm", "plan.json"),
60793
60757
  phases_count: plan.phases.length,
60794
60758
  tasks_count: tasksCount
60795
60759
  };
@@ -60828,7 +60792,7 @@ var save_plan = createSwarmTool({
60828
60792
  init_dist();
60829
60793
  init_manager();
60830
60794
  import * as fs37 from "fs";
60831
- import * as path51 from "path";
60795
+ import * as path50 from "path";
60832
60796
 
60833
60797
  // src/sbom/detectors/index.ts
60834
60798
  init_utils();
@@ -61676,7 +61640,7 @@ function findManifestFiles(rootDir) {
61676
61640
  try {
61677
61641
  const entries = fs37.readdirSync(dir, { withFileTypes: true });
61678
61642
  for (const entry of entries) {
61679
- const fullPath = path51.join(dir, entry.name);
61643
+ const fullPath = path50.join(dir, entry.name);
61680
61644
  if (entry.name.startsWith(".") || entry.name === "node_modules" || entry.name === "dist" || entry.name === "build" || entry.name === "target") {
61681
61645
  continue;
61682
61646
  }
@@ -61685,7 +61649,7 @@ function findManifestFiles(rootDir) {
61685
61649
  } else if (entry.isFile()) {
61686
61650
  for (const pattern of patterns) {
61687
61651
  if (simpleGlobToRegex(pattern).test(entry.name)) {
61688
- manifestFiles.push(path51.relative(rootDir, fullPath));
61652
+ manifestFiles.push(path50.relative(rootDir, fullPath));
61689
61653
  break;
61690
61654
  }
61691
61655
  }
@@ -61703,11 +61667,11 @@ function findManifestFilesInDirs(directories, workingDir) {
61703
61667
  try {
61704
61668
  const entries = fs37.readdirSync(dir, { withFileTypes: true });
61705
61669
  for (const entry of entries) {
61706
- const fullPath = path51.join(dir, entry.name);
61670
+ const fullPath = path50.join(dir, entry.name);
61707
61671
  if (entry.isFile()) {
61708
61672
  for (const pattern of patterns) {
61709
61673
  if (simpleGlobToRegex(pattern).test(entry.name)) {
61710
- found.push(path51.relative(workingDir, fullPath));
61674
+ found.push(path50.relative(workingDir, fullPath));
61711
61675
  break;
61712
61676
  }
61713
61677
  }
@@ -61720,11 +61684,11 @@ function findManifestFilesInDirs(directories, workingDir) {
61720
61684
  function getDirectoriesFromChangedFiles(changedFiles, workingDir) {
61721
61685
  const dirs = new Set;
61722
61686
  for (const file3 of changedFiles) {
61723
- let currentDir = path51.dirname(file3);
61687
+ let currentDir = path50.dirname(file3);
61724
61688
  while (true) {
61725
- if (currentDir && currentDir !== "." && currentDir !== path51.sep) {
61726
- dirs.add(path51.join(workingDir, currentDir));
61727
- const parent = path51.dirname(currentDir);
61689
+ if (currentDir && currentDir !== "." && currentDir !== path50.sep) {
61690
+ dirs.add(path50.join(workingDir, currentDir));
61691
+ const parent = path50.dirname(currentDir);
61728
61692
  if (parent === currentDir)
61729
61693
  break;
61730
61694
  currentDir = parent;
@@ -61808,7 +61772,7 @@ var sbom_generate = createSwarmTool({
61808
61772
  const changedFiles = obj.changed_files;
61809
61773
  const relativeOutputDir = obj.output_dir || DEFAULT_OUTPUT_DIR;
61810
61774
  const workingDir = directory;
61811
- const outputDir = path51.isAbsolute(relativeOutputDir) ? relativeOutputDir : path51.join(workingDir, relativeOutputDir);
61775
+ const outputDir = path50.isAbsolute(relativeOutputDir) ? relativeOutputDir : path50.join(workingDir, relativeOutputDir);
61812
61776
  let manifestFiles = [];
61813
61777
  if (scope === "all") {
61814
61778
  manifestFiles = findManifestFiles(workingDir);
@@ -61831,7 +61795,7 @@ var sbom_generate = createSwarmTool({
61831
61795
  const processedFiles = [];
61832
61796
  for (const manifestFile of manifestFiles) {
61833
61797
  try {
61834
- const fullPath = path51.isAbsolute(manifestFile) ? manifestFile : path51.join(workingDir, manifestFile);
61798
+ const fullPath = path50.isAbsolute(manifestFile) ? manifestFile : path50.join(workingDir, manifestFile);
61835
61799
  if (!fs37.existsSync(fullPath)) {
61836
61800
  continue;
61837
61801
  }
@@ -61848,7 +61812,7 @@ var sbom_generate = createSwarmTool({
61848
61812
  const bom = generateCycloneDX(allComponents);
61849
61813
  const bomJson = serializeCycloneDX(bom);
61850
61814
  const filename = generateSbomFilename();
61851
- const outputPath = path51.join(outputDir, filename);
61815
+ const outputPath = path50.join(outputDir, filename);
61852
61816
  fs37.writeFileSync(outputPath, bomJson, "utf-8");
61853
61817
  const verdict = processedFiles.length > 0 ? "pass" : "pass";
61854
61818
  try {
@@ -61892,7 +61856,7 @@ var sbom_generate = createSwarmTool({
61892
61856
  init_dist();
61893
61857
  init_create_tool();
61894
61858
  import * as fs38 from "fs";
61895
- import * as path52 from "path";
61859
+ import * as path51 from "path";
61896
61860
  var SPEC_CANDIDATES = [
61897
61861
  "openapi.json",
61898
61862
  "openapi.yaml",
@@ -61924,12 +61888,12 @@ function normalizePath2(p) {
61924
61888
  }
61925
61889
  function discoverSpecFile(cwd, specFileArg) {
61926
61890
  if (specFileArg) {
61927
- const resolvedPath = path52.resolve(cwd, specFileArg);
61928
- const normalizedCwd = cwd.endsWith(path52.sep) ? cwd : cwd + path52.sep;
61891
+ const resolvedPath = path51.resolve(cwd, specFileArg);
61892
+ const normalizedCwd = cwd.endsWith(path51.sep) ? cwd : cwd + path51.sep;
61929
61893
  if (!resolvedPath.startsWith(normalizedCwd) && resolvedPath !== cwd) {
61930
61894
  throw new Error("Invalid spec_file: path traversal detected");
61931
61895
  }
61932
- const ext = path52.extname(resolvedPath).toLowerCase();
61896
+ const ext = path51.extname(resolvedPath).toLowerCase();
61933
61897
  if (!ALLOWED_EXTENSIONS.includes(ext)) {
61934
61898
  throw new Error(`Invalid spec_file: must end in .json, .yaml, or .yml, got ${ext}`);
61935
61899
  }
@@ -61943,7 +61907,7 @@ function discoverSpecFile(cwd, specFileArg) {
61943
61907
  return resolvedPath;
61944
61908
  }
61945
61909
  for (const candidate of SPEC_CANDIDATES) {
61946
- const candidatePath = path52.resolve(cwd, candidate);
61910
+ const candidatePath = path51.resolve(cwd, candidate);
61947
61911
  if (fs38.existsSync(candidatePath)) {
61948
61912
  const stats = fs38.statSync(candidatePath);
61949
61913
  if (stats.size <= MAX_SPEC_SIZE) {
@@ -61955,7 +61919,7 @@ function discoverSpecFile(cwd, specFileArg) {
61955
61919
  }
61956
61920
  function parseSpec(specFile) {
61957
61921
  const content = fs38.readFileSync(specFile, "utf-8");
61958
- const ext = path52.extname(specFile).toLowerCase();
61922
+ const ext = path51.extname(specFile).toLowerCase();
61959
61923
  if (ext === ".json") {
61960
61924
  return parseJsonSpec(content);
61961
61925
  }
@@ -62031,7 +61995,7 @@ function extractRoutes(cwd) {
62031
61995
  return;
62032
61996
  }
62033
61997
  for (const entry of entries) {
62034
- const fullPath = path52.join(dir, entry.name);
61998
+ const fullPath = path51.join(dir, entry.name);
62035
61999
  if (entry.isSymbolicLink()) {
62036
62000
  continue;
62037
62001
  }
@@ -62041,7 +62005,7 @@ function extractRoutes(cwd) {
62041
62005
  }
62042
62006
  walkDir(fullPath);
62043
62007
  } else if (entry.isFile()) {
62044
- const ext = path52.extname(entry.name).toLowerCase();
62008
+ const ext = path51.extname(entry.name).toLowerCase();
62045
62009
  const baseName = entry.name.toLowerCase();
62046
62010
  if (![".ts", ".js", ".mjs"].includes(ext)) {
62047
62011
  continue;
@@ -62211,7 +62175,7 @@ init_secretscan();
62211
62175
  init_tool();
62212
62176
  init_create_tool();
62213
62177
  import * as fs39 from "fs";
62214
- import * as path53 from "path";
62178
+ import * as path52 from "path";
62215
62179
  var MAX_FILE_SIZE_BYTES7 = 1024 * 1024;
62216
62180
  var WINDOWS_RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(\.|:|$)/i;
62217
62181
  function containsControlCharacters(str) {
@@ -62240,11 +62204,11 @@ function containsWindowsAttacks(str) {
62240
62204
  }
62241
62205
  function isPathInWorkspace(filePath, workspace) {
62242
62206
  try {
62243
- const resolvedPath = path53.resolve(workspace, filePath);
62207
+ const resolvedPath = path52.resolve(workspace, filePath);
62244
62208
  const realWorkspace = fs39.realpathSync(workspace);
62245
62209
  const realResolvedPath = fs39.realpathSync(resolvedPath);
62246
- const relativePath = path53.relative(realWorkspace, realResolvedPath);
62247
- if (relativePath.startsWith("..") || path53.isAbsolute(relativePath)) {
62210
+ const relativePath = path52.relative(realWorkspace, realResolvedPath);
62211
+ if (relativePath.startsWith("..") || path52.isAbsolute(relativePath)) {
62248
62212
  return false;
62249
62213
  }
62250
62214
  return true;
@@ -62256,7 +62220,7 @@ function validatePathForRead(filePath, workspace) {
62256
62220
  return isPathInWorkspace(filePath, workspace);
62257
62221
  }
62258
62222
  function extractTSSymbols(filePath, cwd) {
62259
- const fullPath = path53.join(cwd, filePath);
62223
+ const fullPath = path52.join(cwd, filePath);
62260
62224
  if (!validatePathForRead(fullPath, cwd)) {
62261
62225
  return [];
62262
62226
  }
@@ -62408,7 +62372,7 @@ function extractTSSymbols(filePath, cwd) {
62408
62372
  });
62409
62373
  }
62410
62374
  function extractPythonSymbols(filePath, cwd) {
62411
- const fullPath = path53.join(cwd, filePath);
62375
+ const fullPath = path52.join(cwd, filePath);
62412
62376
  if (!validatePathForRead(fullPath, cwd)) {
62413
62377
  return [];
62414
62378
  }
@@ -62491,7 +62455,7 @@ var symbols = createSwarmTool({
62491
62455
  }, null, 2);
62492
62456
  }
62493
62457
  const cwd = directory;
62494
- const ext = path53.extname(file3);
62458
+ const ext = path52.extname(file3);
62495
62459
  if (containsControlCharacters(file3)) {
62496
62460
  return JSON.stringify({
62497
62461
  file: file3,
@@ -62563,7 +62527,7 @@ init_dist();
62563
62527
  init_utils();
62564
62528
  init_create_tool();
62565
62529
  import * as fs40 from "fs";
62566
- import * as path54 from "path";
62530
+ import * as path53 from "path";
62567
62531
  var MAX_TEXT_LENGTH = 200;
62568
62532
  var MAX_FILE_SIZE_BYTES8 = 1024 * 1024;
62569
62533
  var SUPPORTED_EXTENSIONS2 = new Set([
@@ -62634,9 +62598,9 @@ function validatePathsInput(paths, cwd) {
62634
62598
  return { error: "paths contains path traversal", resolvedPath: null };
62635
62599
  }
62636
62600
  try {
62637
- const resolvedPath = path54.resolve(paths);
62638
- const normalizedCwd = path54.resolve(cwd);
62639
- const normalizedResolved = path54.resolve(resolvedPath);
62601
+ const resolvedPath = path53.resolve(paths);
62602
+ const normalizedCwd = path53.resolve(cwd);
62603
+ const normalizedResolved = path53.resolve(resolvedPath);
62640
62604
  if (!normalizedResolved.startsWith(normalizedCwd)) {
62641
62605
  return {
62642
62606
  error: "paths must be within the current working directory",
@@ -62652,7 +62616,7 @@ function validatePathsInput(paths, cwd) {
62652
62616
  }
62653
62617
  }
62654
62618
  function isSupportedExtension(filePath) {
62655
- const ext = path54.extname(filePath).toLowerCase();
62619
+ const ext = path53.extname(filePath).toLowerCase();
62656
62620
  return SUPPORTED_EXTENSIONS2.has(ext);
62657
62621
  }
62658
62622
  function findSourceFiles2(dir, files = []) {
@@ -62667,7 +62631,7 @@ function findSourceFiles2(dir, files = []) {
62667
62631
  if (SKIP_DIRECTORIES3.has(entry)) {
62668
62632
  continue;
62669
62633
  }
62670
- const fullPath = path54.join(dir, entry);
62634
+ const fullPath = path53.join(dir, entry);
62671
62635
  let stat2;
62672
62636
  try {
62673
62637
  stat2 = fs40.statSync(fullPath);
@@ -62779,7 +62743,7 @@ var todo_extract = createSwarmTool({
62779
62743
  filesToScan.push(scanPath);
62780
62744
  } else {
62781
62745
  const errorResult = {
62782
- error: `unsupported file extension: ${path54.extname(scanPath)}`,
62746
+ error: `unsupported file extension: ${path53.extname(scanPath)}`,
62783
62747
  total: 0,
62784
62748
  byPriority: { high: 0, medium: 0, low: 0 },
62785
62749
  entries: []
@@ -62825,14 +62789,14 @@ var todo_extract = createSwarmTool({
62825
62789
  init_tool();
62826
62790
  init_schema();
62827
62791
  import * as fs42 from "fs";
62828
- import * as path56 from "path";
62792
+ import * as path55 from "path";
62829
62793
 
62830
62794
  // src/hooks/diff-scope.ts
62831
62795
  import * as fs41 from "fs";
62832
- import * as path55 from "path";
62796
+ import * as path54 from "path";
62833
62797
  function getDeclaredScope(taskId, directory) {
62834
62798
  try {
62835
- const planPath = path55.join(directory, ".swarm", "plan.json");
62799
+ const planPath = path54.join(directory, ".swarm", "plan.json");
62836
62800
  if (!fs41.existsSync(planPath))
62837
62801
  return null;
62838
62802
  const raw = fs41.readFileSync(planPath, "utf-8");
@@ -62947,7 +62911,7 @@ var TIER_3_PATTERNS = [
62947
62911
  ];
62948
62912
  function matchesTier3Pattern(files) {
62949
62913
  for (const file3 of files) {
62950
- const fileName = path56.basename(file3);
62914
+ const fileName = path55.basename(file3);
62951
62915
  for (const pattern of TIER_3_PATTERNS) {
62952
62916
  if (pattern.test(fileName)) {
62953
62917
  return true;
@@ -62969,7 +62933,7 @@ function checkReviewerGate(taskId, workingDirectory) {
62969
62933
  if (hasActiveTurboMode2()) {
62970
62934
  const resolvedDir2 = workingDirectory ?? process.cwd();
62971
62935
  try {
62972
- const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
62936
+ const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
62973
62937
  const planRaw = fs42.readFileSync(planPath, "utf-8");
62974
62938
  const plan = JSON.parse(planRaw);
62975
62939
  for (const planPhase of plan.phases ?? []) {
@@ -62989,7 +62953,7 @@ function checkReviewerGate(taskId, workingDirectory) {
62989
62953
  }
62990
62954
  const resolvedDir = workingDirectory ?? process.cwd();
62991
62955
  try {
62992
- const evidencePath = path56.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
62956
+ const evidencePath = path55.join(resolvedDir, ".swarm", "evidence", `${taskId}.json`);
62993
62957
  const raw = fs42.readFileSync(evidencePath, "utf-8");
62994
62958
  const evidence = JSON.parse(raw);
62995
62959
  if (evidence?.required_gates && Array.isArray(evidence.required_gates) && evidence?.gates) {
@@ -63030,7 +62994,7 @@ function checkReviewerGate(taskId, workingDirectory) {
63030
62994
  }
63031
62995
  try {
63032
62996
  const resolvedDir2 = workingDirectory ?? process.cwd();
63033
- const planPath = path56.join(resolvedDir2, ".swarm", "plan.json");
62997
+ const planPath = path55.join(resolvedDir2, ".swarm", "plan.json");
63034
62998
  const planRaw = fs42.readFileSync(planPath, "utf-8");
63035
62999
  const plan = JSON.parse(planRaw);
63036
63000
  for (const planPhase of plan.phases ?? []) {
@@ -63212,8 +63176,8 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
63212
63176
  };
63213
63177
  }
63214
63178
  }
63215
- normalizedDir = path56.normalize(args2.working_directory);
63216
- const pathParts = normalizedDir.split(path56.sep);
63179
+ normalizedDir = path55.normalize(args2.working_directory);
63180
+ const pathParts = normalizedDir.split(path55.sep);
63217
63181
  if (pathParts.includes("..")) {
63218
63182
  return {
63219
63183
  success: false,
@@ -63223,10 +63187,10 @@ async function executeUpdateTaskStatus(args2, fallbackDir) {
63223
63187
  ]
63224
63188
  };
63225
63189
  }
63226
- const resolvedDir = path56.resolve(normalizedDir);
63190
+ const resolvedDir = path55.resolve(normalizedDir);
63227
63191
  try {
63228
63192
  const realPath = fs42.realpathSync(resolvedDir);
63229
- const planPath = path56.join(realPath, ".swarm", "plan.json");
63193
+ const planPath = path55.join(realPath, ".swarm", "plan.json");
63230
63194
  if (!fs42.existsSync(planPath)) {
63231
63195
  return {
63232
63196
  success: false,
@@ -63421,7 +63385,7 @@ var OpenCodeSwarm = async (ctx) => {
63421
63385
  const { PreflightTriggerManager: PTM } = await Promise.resolve().then(() => (init_trigger(), exports_trigger));
63422
63386
  preflightTriggerManager = new PTM(automationConfig);
63423
63387
  const { AutomationStatusArtifact: ASA } = await Promise.resolve().then(() => (init_status_artifact(), exports_status_artifact));
63424
- const swarmDir = path57.resolve(ctx.directory, ".swarm");
63388
+ const swarmDir = path56.resolve(ctx.directory, ".swarm");
63425
63389
  statusArtifact = new ASA(swarmDir);
63426
63390
  statusArtifact.updateConfig(automationConfig.mode, automationConfig.capabilities);
63427
63391
  if (automationConfig.capabilities?.evidence_auto_summaries === true) {
@@ -21,14 +21,6 @@ export declare function readSnapshot(directory: string): Promise<SnapshotData |
21
21
  * Does NOT touch activeToolCalls or pendingEvents (remain at defaults).
22
22
  */
23
23
  export declare function rehydrateState(snapshot: SnapshotData): void;
24
- /**
25
- * Reconcile task workflow states from plan.json for all active sessions.
26
- * Seeds completed plan tasks to 'tests_run' and in_progress tasks to 'coder_delegated'.
27
- * Best-effort: returns silently on any file/parse error. NEVER throws.
28
- *
29
- * @param directory - The project root directory containing .swarm/plan.json
30
- */
31
- export declare function reconcileTaskStatesFromPlan(directory: string): Promise<void>;
32
24
  /**
33
25
  * Load snapshot from disk and rehydrate swarmState.
34
26
  * Called on plugin init to restore state from previous session.
package/dist/state.d.ts CHANGED
@@ -194,7 +194,7 @@ export declare function resetSwarmState(): void;
194
194
  * @param staleDurationMs - Age threshold for stale session eviction (default: 120 min)
195
195
  * @param directory - Optional project directory for rehydrating workflow state from disk
196
196
  */
197
- export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number, directory?: string): void;
197
+ export declare function startAgentSession(sessionId: string, agentName: string, staleDurationMs?: number, _directory?: string): void;
198
198
  /**
199
199
  * End an agent session by removing it from the state.
200
200
  * NOTE: Currently unused in production — no session lifecycle teardown is wired up.
@@ -216,10 +216,9 @@ export declare function getAgentSession(sessionId: string): AgentSessionState |
216
216
  * Always updates lastToolCallTime.
217
217
  * @param sessionId - The session identifier
218
218
  * @param agentName - Optional agent name (if known)
219
- * @param directory - Optional project directory for rehydrating workflow state from disk
220
219
  * @returns The AgentSessionState
221
220
  */
222
- export declare function ensureAgentSession(sessionId: string, agentName?: string, directory?: string): AgentSessionState;
221
+ export declare function ensureAgentSession(sessionId: string, agentName?: string, _directory?: string): AgentSessionState;
223
222
  /**
224
223
  * Update only the agent event timestamp (for stale detection).
225
224
  * Does NOT change agent name or reset guardrail state.
@@ -301,6 +300,25 @@ export declare function getTaskState(session: AgentSessionState, taskId: string)
301
300
  * @param directory - Project root containing .swarm/ subdirectory
302
301
  * @param session - Target AgentSessionState to merge rehydrated state into
303
302
  */
303
+ /**
304
+ * Reads plan.json + evidence/*.json from the project directory and populates the
305
+ * module-level _rehydrationCache. Called once at plugin init by loadSnapshot().
306
+ * Non-fatal: missing/malformed files leave an empty cache.
307
+ */
308
+ export declare function buildRehydrationCache(directory: string): Promise<void>;
309
+ /**
310
+ * Synchronously applies the cached plan+evidence data to a session.
311
+ * Merge rules:
312
+ * - evidence-derived state: always applied (replaces snapshot state, even if lower)
313
+ * - plan-only derived state: only applied if it advances past existing state
314
+ * No-op when the cache has not been built yet.
315
+ */
316
+ export declare function applyRehydrationCache(session: AgentSessionState): void;
317
+ /**
318
+ * Rehydrates session workflow state from durable swarm files.
319
+ * Builds (or refreshes) the rehydration cache from disk, then applies it
320
+ * to the target session.
321
+ */
304
322
  export declare function rehydrateSessionFromDisk(directory: string, session: AgentSessionState): Promise<void>;
305
323
  /**
306
324
  * Check if ANY active session has Turbo Mode enabled.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "6.29.5",
3
+ "version": "6.30.0",
4
4
  "description": "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",