opencode-swarm 7.46.2 → 7.46.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -52,7 +52,7 @@ var package_default;
52
52
  var init_package = __esm(() => {
53
53
  package_default = {
54
54
  name: "opencode-swarm",
55
- version: "7.46.2",
55
+ version: "7.46.3",
56
56
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
57
57
  main: "dist/index.js",
58
58
  types: "dist/index.d.ts",
@@ -16,6 +16,7 @@
16
16
  * updates after the initial scan completes.
17
17
  */
18
18
  import { type RepoGraph } from '../tools/repo-graph';
19
+ import { safeRealpathSync } from '../tools/repo-graph/safe-realpath';
19
20
  export interface RepoGraphBuilderHook {
20
21
  init(): Promise<void>;
21
22
  toolAfter(input: {
@@ -40,5 +41,6 @@ export interface RepoGraphDeps {
40
41
  updateGraphForFiles: (workspace: string, files: string[], options?: {
41
42
  forceRebuild?: boolean;
42
43
  }) => Promise<RepoGraph>;
44
+ safeRealpathSync?: typeof safeRealpathSync;
43
45
  }
44
46
  export declare function createRepoGraphBuilderHook(workspaceRoot: string, deps?: Partial<RepoGraphDeps>): RepoGraphBuilderHook;
package/dist/index.js CHANGED
@@ -69,7 +69,7 @@ var package_default;
69
69
  var init_package = __esm(() => {
70
70
  package_default = {
71
71
  name: "opencode-swarm",
72
- version: "7.46.2",
72
+ version: "7.46.3",
73
73
  description: "Architect-centric agentic swarm plugin for OpenCode - hub-and-spoke orchestration with SME consultation, code generation, and QA review",
74
74
  main: "dist/index.js",
75
75
  types: "dist/index.d.ts",
@@ -90663,7 +90663,7 @@ __export(exports_runtime, {
90663
90663
  getSupportedLanguages: () => getSupportedLanguages,
90664
90664
  getInitializedLanguages: () => getInitializedLanguages,
90665
90665
  clearParserCache: () => clearParserCache,
90666
- _internals: () => _internals43
90666
+ _internals: () => _internals45
90667
90667
  });
90668
90668
  import * as path93 from "node:path";
90669
90669
  import { fileURLToPath as fileURLToPath3 } from "node:url";
@@ -90673,10 +90673,10 @@ async function initTreeSitter() {
90673
90673
  const thisDir = path93.dirname(fileURLToPath3(import.meta.url));
90674
90674
  const isSource = thisDir.replace(/\\/g, "/").endsWith("/src/lang");
90675
90675
  if (isSource) {
90676
- await _internals43.parserInit();
90676
+ await _internals45.parserInit();
90677
90677
  } else {
90678
90678
  const grammarsDir = getGrammarsDirAbsolute();
90679
- await _internals43.parserInit({
90679
+ await _internals45.parserInit({
90680
90680
  locateFile(scriptName) {
90681
90681
  return path93.join(grammarsDir, scriptName);
90682
90682
  }
@@ -90778,12 +90778,12 @@ function getInitializedLanguages() {
90778
90778
  function getSupportedLanguages() {
90779
90779
  return Object.keys(LANGUAGE_WASM_MAP);
90780
90780
  }
90781
- var parserCache, initializedLanguages, treeSitterInitPromise = null, _internals43, LANGUAGE_WASM_MAP;
90781
+ var parserCache, initializedLanguages, treeSitterInitPromise = null, _internals45, LANGUAGE_WASM_MAP;
90782
90782
  var init_runtime = __esm(() => {
90783
90783
  init_tree_sitter();
90784
90784
  parserCache = new Map;
90785
90785
  initializedLanguages = new Set;
90786
- _internals43 = {
90786
+ _internals45 = {
90787
90787
  parserInit: Parser.init
90788
90788
  };
90789
90789
  LANGUAGE_WASM_MAP = {
@@ -91670,9 +91670,9 @@ var init_search_knowledge = __esm(() => {
91670
91670
  var exports_knowledge_recall = {};
91671
91671
  __export(exports_knowledge_recall, {
91672
91672
  knowledge_recall: () => knowledge_recall,
91673
- _internals: () => _internals44
91673
+ _internals: () => _internals46
91674
91674
  });
91675
- var knowledge_recall, _internals44;
91675
+ var knowledge_recall, _internals46;
91676
91676
  var init_knowledge_recall = __esm(() => {
91677
91677
  init_zod();
91678
91678
  init_config();
@@ -91753,7 +91753,7 @@ var init_knowledge_recall = __esm(() => {
91753
91753
  return JSON.stringify(result);
91754
91754
  }
91755
91755
  });
91756
- _internals44 = {
91756
+ _internals46 = {
91757
91757
  knowledge_recall
91758
91758
  };
91759
91759
  });
@@ -91808,7 +91808,7 @@ __export(exports_curator_drift, {
91808
91808
  runDeterministicDriftCheck: () => runDeterministicDriftCheck,
91809
91809
  readPriorDriftReports: () => readPriorDriftReports,
91810
91810
  buildDriftInjectionText: () => buildDriftInjectionText,
91811
- _internals: () => _internals47
91811
+ _internals: () => _internals49
91812
91812
  });
91813
91813
  import * as fs65 from "node:fs";
91814
91814
  import * as path102 from "node:path";
@@ -91857,7 +91857,7 @@ async function runDeterministicDriftCheck(directory, phase, curatorResult, confi
91857
91857
  try {
91858
91858
  const planMd = await readSwarmFileAsync(directory, "plan.md");
91859
91859
  const specMd = await readSwarmFileAsync(directory, "spec.md");
91860
- const priorReports = await _internals47.readPriorDriftReports(directory);
91860
+ const priorReports = await _internals49.readPriorDriftReports(directory);
91861
91861
  const complianceCount = curatorResult.compliance.length;
91862
91862
  const warningCompliance = curatorResult.compliance.filter((obs) => obs.severity === "warning");
91863
91863
  let alignment = "ALIGNED";
@@ -91920,7 +91920,7 @@ async function runDeterministicDriftCheck(directory, phase, curatorResult, confi
91920
91920
  scope_additions: [],
91921
91921
  injection_summary: injectionSummary
91922
91922
  };
91923
- const reportPath = await _internals47.writeDriftReport(directory, report);
91923
+ const reportPath = await _internals49.writeDriftReport(directory, report);
91924
91924
  getGlobalEventBus().publish("curator.drift.completed", {
91925
91925
  phase,
91926
91926
  alignment,
@@ -91983,12 +91983,12 @@ function buildDriftInjectionText(report, maxChars) {
91983
91983
  }
91984
91984
  return text.slice(0, maxChars);
91985
91985
  }
91986
- var DRIFT_REPORT_PREFIX = "drift-report-phase-", _internals47;
91986
+ var DRIFT_REPORT_PREFIX = "drift-report-phase-", _internals49;
91987
91987
  var init_curator_drift = __esm(() => {
91988
91988
  init_event_bus();
91989
91989
  init_logger();
91990
91990
  init_utils2();
91991
- _internals47 = {
91991
+ _internals49 = {
91992
91992
  readPriorDriftReports,
91993
91993
  writeDriftReport,
91994
91994
  runDeterministicDriftCheck,
@@ -92000,7 +92000,7 @@ var init_curator_drift = __esm(() => {
92000
92000
  var exports_project_context = {};
92001
92001
  __export(exports_project_context, {
92002
92002
  buildProjectContext: () => buildProjectContext,
92003
- _internals: () => _internals68,
92003
+ _internals: () => _internals70,
92004
92004
  LANG_BACKEND_DETECTION_TIMEOUT_MS: () => LANG_BACKEND_DETECTION_TIMEOUT_MS
92005
92005
  });
92006
92006
  import * as fs117 from "node:fs";
@@ -92084,7 +92084,7 @@ function selectLintCommand(backend, directory) {
92084
92084
  return null;
92085
92085
  }
92086
92086
  async function buildProjectContext(directory) {
92087
- const backend = await _internals68.pickBackend(directory);
92087
+ const backend = await _internals70.pickBackend(directory);
92088
92088
  if (!backend)
92089
92089
  return null;
92090
92090
  const ctx = emptyProjectContext();
@@ -92115,16 +92115,16 @@ async function buildProjectContext(directory) {
92115
92115
  if (backend.prompts.reviewerChecklist.length > 0) {
92116
92116
  ctx.REVIEWER_CHECKLIST = bulletList(backend.prompts.reviewerChecklist);
92117
92117
  }
92118
- const profiles = _internals68.pickedProfiles(directory);
92118
+ const profiles = _internals70.pickedProfiles(directory);
92119
92119
  if (profiles.length > 1) {
92120
92120
  ctx.PROJECT_CONTEXT_SECONDARY_LANGUAGES = profiles.slice(1).map((p) => p.id).join(", ");
92121
92121
  }
92122
92122
  return ctx;
92123
92123
  }
92124
- var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals68;
92124
+ var LANG_BACKEND_DETECTION_TIMEOUT_MS = 300, _internals70;
92125
92125
  var init_project_context = __esm(() => {
92126
92126
  init_dispatch();
92127
- _internals68 = {
92127
+ _internals70 = {
92128
92128
  pickBackend,
92129
92129
  pickedProfiles
92130
92130
  };
@@ -94855,14 +94855,13 @@ ${originalText}`;
94855
94855
  }
94856
94856
  // src/hooks/repo-graph-builder.ts
94857
94857
  init_constants();
94858
- import { realpathSync as realpathSync11 } from "node:fs";
94859
94858
  import * as path86 from "node:path";
94860
94859
 
94861
94860
  // src/tools/repo-graph/builder.ts
94862
94861
  init_logger();
94863
94862
  init_path_security();
94864
94863
  import * as fsSync4 from "node:fs";
94865
- import { existsSync as existsSync48, realpathSync as realpathSync9 } from "node:fs";
94864
+ import { existsSync as existsSync48, realpathSync as realpathSync10 } from "node:fs";
94866
94865
  import * as fsPromises5 from "node:fs/promises";
94867
94866
  import * as os13 from "node:os";
94868
94867
  import * as path82 from "node:path";
@@ -95225,6 +95224,19 @@ var symbols = createSwarmTool({
95225
95224
  }
95226
95225
  });
95227
95226
 
95227
+ // src/tools/repo-graph/safe-realpath.ts
95228
+ import { realpathSync as realpathSync9 } from "node:fs";
95229
+ function safeRealpathSync(targetPath, fallback, realpathResolver = realpathSync9) {
95230
+ try {
95231
+ return realpathResolver(targetPath);
95232
+ } catch (error93) {
95233
+ if (error93 instanceof Error && error93.code === "ENOENT") {
95234
+ return fallback;
95235
+ }
95236
+ return null;
95237
+ }
95238
+ }
95239
+
95228
95240
  // src/tools/repo-graph/types.ts
95229
95241
  import * as path81 from "node:path";
95230
95242
  var REPO_GRAPH_FILENAME = "repo-graph.json";
@@ -95346,6 +95358,9 @@ function validateGraphEdge(edge) {
95346
95358
  }
95347
95359
 
95348
95360
  // src/tools/repo-graph/builder.ts
95361
+ var _internals43 = {
95362
+ safeRealpathSync
95363
+ };
95349
95364
  var SKIP_DIRECTORIES2 = new Set([
95350
95365
  "node_modules",
95351
95366
  ".git",
@@ -95412,17 +95427,14 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
95412
95427
  if (specifier.startsWith(".")) {
95413
95428
  const sourceDir = path82.dirname(sourceFile);
95414
95429
  let resolved = path82.resolve(sourceDir, specifier);
95415
- let realResolved;
95416
- try {
95417
- realResolved = realpathSync9(resolved);
95418
- } catch {
95419
- realResolved = resolved;
95430
+ const initialRealResolved = _internals43.safeRealpathSync(resolved, resolved);
95431
+ if (initialRealResolved === null) {
95432
+ return null;
95420
95433
  }
95421
- let realRoot;
95422
- try {
95423
- realRoot = realpathSync9(workspaceRoot);
95424
- } catch {
95425
- realRoot = path82.normalize(workspaceRoot);
95434
+ let realResolved = initialRealResolved;
95435
+ const realRoot = _internals43.safeRealpathSync(workspaceRoot, path82.normalize(workspaceRoot));
95436
+ if (realRoot === null) {
95437
+ return null;
95426
95438
  }
95427
95439
  if (!existsSync48(resolved)) {
95428
95440
  const EXTENSIONS = [
@@ -95444,11 +95456,11 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
95444
95456
  }
95445
95457
  }
95446
95458
  if (found) {
95447
- try {
95448
- realResolved = realpathSync9(found);
95449
- } catch {
95450
- realResolved = found;
95459
+ const foundRealPath = _internals43.safeRealpathSync(found, found);
95460
+ if (foundRealPath === null) {
95461
+ return null;
95451
95462
  }
95463
+ realResolved = foundRealPath;
95452
95464
  resolved = found;
95453
95465
  } else {
95454
95466
  return null;
@@ -95469,7 +95481,7 @@ function resolveModuleSpecifier(workspaceRoot, sourceFile, specifier) {
95469
95481
  function isRefusedWorkspaceRoot(target) {
95470
95482
  let resolved;
95471
95483
  try {
95472
- resolved = realpathSync9(target);
95484
+ resolved = realpathSync10(target);
95473
95485
  } catch {
95474
95486
  resolved = path82.resolve(target);
95475
95487
  }
@@ -95777,9 +95789,12 @@ import * as path85 from "node:path";
95777
95789
  init_utils2();
95778
95790
  init_logger();
95779
95791
  init_path_security();
95780
- import { constants as constants4, existsSync as existsSync49, realpathSync as realpathSync10 } from "node:fs";
95792
+ import { constants as constants4, existsSync as existsSync49 } from "node:fs";
95781
95793
  import * as fsPromises6 from "node:fs/promises";
95782
95794
  import * as path84 from "node:path";
95795
+ var _internals44 = {
95796
+ safeRealpathSync
95797
+ };
95783
95798
  var WINDOWS_RENAME_MAX_RETRIES2 = 3;
95784
95799
  var WINDOWS_RENAME_RETRY_DELAY_MS2 = 50;
95785
95800
  function getGraphPath(workspace) {
@@ -95885,18 +95900,14 @@ async function saveGraph(workspace, graph, options) {
95885
95900
  throw new Error("Graph must have edges array");
95886
95901
  }
95887
95902
  const normalizedWorkspace = path84.normalize(workspace);
95888
- let realWorkspace;
95889
- try {
95890
- realWorkspace = realpathSync10(workspace);
95891
- } catch {
95892
- realWorkspace = normalizedWorkspace;
95903
+ const realWorkspace = _internals44.safeRealpathSync(workspace, normalizedWorkspace);
95904
+ if (realWorkspace === null) {
95905
+ throw new Error(`Workspace realpath security check failed (non-ENOENT): ${workspace}`);
95893
95906
  }
95894
95907
  const normalizedGraphRoot = path84.normalize(graph.workspaceRoot);
95895
- let realGraphRoot;
95896
- try {
95897
- realGraphRoot = realpathSync10(graph.workspaceRoot);
95898
- } catch {
95899
- realGraphRoot = normalizedGraphRoot;
95908
+ const realGraphRoot = _internals44.safeRealpathSync(graph.workspaceRoot, normalizedGraphRoot);
95909
+ if (realGraphRoot === null) {
95910
+ throw new Error(`Graph workspaceRoot realpath security check failed (non-ENOENT): ${graph.workspaceRoot}`);
95900
95911
  }
95901
95912
  if (path84.normalize(realWorkspace) !== path84.normalize(realGraphRoot)) {
95902
95913
  throw new Error(`Graph workspaceRoot mismatch: graph was built for "${graph.workspaceRoot}" but save was called for "${workspace}"`);
@@ -96072,6 +96083,7 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
96072
96083
  const _buildWorkspaceGraph = deps?.buildWorkspaceGraph ?? buildWorkspaceGraphAsync;
96073
96084
  const _saveGraph = deps?.saveGraph ?? saveGraph;
96074
96085
  const _updateGraphForFiles = deps?.updateGraphForFiles ?? updateGraphForFiles;
96086
+ const _safeRealpathSync = deps?.safeRealpathSync ?? safeRealpathSync;
96075
96087
  let initStarted = false;
96076
96088
  let initPromise = Promise.resolve();
96077
96089
  let consecutiveFailures = 0;
@@ -96112,23 +96124,13 @@ function createRepoGraphBuilderHook(workspaceRoot, deps) {
96112
96124
  if (!isSupportedSourceFile(filePath))
96113
96125
  return;
96114
96126
  const absoluteFilePath = path86.isAbsolute(filePath) ? filePath : path86.resolve(workspaceRoot, filePath);
96115
- let realFilePath;
96116
- try {
96117
- realFilePath = realpathSync11(absoluteFilePath);
96118
- } catch (error93) {
96119
- if (!(error93 instanceof Error) || error93.code !== "ENOENT") {
96120
- return;
96121
- }
96122
- realFilePath = absoluteFilePath;
96127
+ const realFilePath = _safeRealpathSync(absoluteFilePath, absoluteFilePath);
96128
+ if (realFilePath === null) {
96129
+ return;
96123
96130
  }
96124
- let realWorkspace;
96125
- try {
96126
- realWorkspace = realpathSync11(workspaceRoot);
96127
- } catch (error93) {
96128
- if (!(error93 instanceof Error) || error93.code !== "ENOENT") {
96129
- return;
96130
- }
96131
- realWorkspace = workspaceRoot;
96131
+ const realWorkspace = _safeRealpathSync(workspaceRoot, workspaceRoot);
96132
+ if (realWorkspace === null) {
96133
+ return;
96132
96134
  }
96133
96135
  const normalizedAbsolute = realFilePath.replace(/\\/g, "/");
96134
96136
  const normalizedWorkspace = realWorkspace.replace(/\\/g, "/");
@@ -102377,7 +102379,7 @@ async function knowledgeApplicationGateBefore(directory, input, config3) {
102377
102379
  if (config3.mode === "enforce") {
102378
102380
  throw new Error("KNOWLEDGE_ENFORCE_GATE_DENY: missing sessionID on tool.execute.before; refusing to evaluate critical-directive ack state");
102379
102381
  }
102380
- _internals45.writeWarnEvent(directory, {
102382
+ _internals47.writeWarnEvent(directory, {
102381
102383
  timestamp: new Date().toISOString(),
102382
102384
  event: "knowledge_application_gate_warn",
102383
102385
  tool: toolName,
@@ -102460,7 +102462,7 @@ async function knowledgeApplicationTransformScan(directory, output, sessionID) {
102460
102462
  }
102461
102463
  }
102462
102464
  }
102463
- var _internals45 = {
102465
+ var _internals47 = {
102464
102466
  knowledgeApplicationGateBefore,
102465
102467
  knowledgeApplicationTransformScan,
102466
102468
  HIGH_RISK_TOOLS,
@@ -102584,10 +102586,10 @@ async function getRunMemorySummary(directory) {
102584
102586
  if (entries.length === 0) {
102585
102587
  return null;
102586
102588
  }
102587
- const groups = _internals46.groupByTaskId(entries);
102589
+ const groups = _internals48.groupByTaskId(entries);
102588
102590
  const summaries = [];
102589
102591
  for (const [taskId, taskEntries] of groups) {
102590
- const summary = _internals46.summarizeTask(taskId, taskEntries);
102592
+ const summary = _internals48.summarizeTask(taskId, taskEntries);
102591
102593
  if (summary) {
102592
102594
  summaries.push(summary);
102593
102595
  }
@@ -102620,7 +102622,7 @@ Use this data to avoid repeating known failure patterns.`;
102620
102622
  }
102621
102623
  return prefix + summaryText + suffix;
102622
102624
  }
102623
- var _internals46 = {
102625
+ var _internals48 = {
102624
102626
  generateTaskFingerprint,
102625
102627
  recordOutcome,
102626
102628
  getTaskHistory,
@@ -102818,7 +102820,7 @@ function createKnowledgeInjectorHook(directory, config3) {
102818
102820
  projectName,
102819
102821
  currentPhase: phaseDescription
102820
102822
  };
102821
- const searchFn = _internals48.searchKnowledge === defaultSearchKnowledge ? searchKnowledge : _internals48.searchKnowledge;
102823
+ const searchFn = _internals50.searchKnowledge === defaultSearchKnowledge ? searchKnowledge : _internals50.searchKnowledge;
102822
102824
  const search = await searchFn({
102823
102825
  directory,
102824
102826
  config: config3,
@@ -102926,7 +102928,7 @@ ${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
102926
102928
  ranks[id] = idx + 1;
102927
102929
  scores[id] = scoreById.get(id) ?? 0;
102928
102930
  });
102929
- await _internals48.recordKnowledgeEvent(directory, {
102931
+ await _internals50.recordKnowledgeEvent(directory, {
102930
102932
  type: "retrieved",
102931
102933
  trace_id: search.trace_id,
102932
102934
  session_id: systemMsg?.info?.sessionID ?? "unknown",
@@ -102939,7 +102941,7 @@ ${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
102939
102941
  ranks,
102940
102942
  scores
102941
102943
  });
102942
- _internals48.recordKnowledgeShown(directory, cachedShownIds, {
102944
+ _internals50.recordKnowledgeShown(directory, cachedShownIds, {
102943
102945
  phase: phaseLabel,
102944
102946
  tool: retrievalCtx.currentTool,
102945
102947
  action: retrievalCtx.currentAction,
@@ -102949,7 +102951,7 @@ ${freshPreamble}` : `<curator_briefing>${truncatedBriefing}</curator_briefing>`;
102949
102951
  }
102950
102952
  });
102951
102953
  }
102952
- var _internals48 = {
102954
+ var _internals50 = {
102953
102955
  searchKnowledge,
102954
102956
  recordKnowledgeEvent,
102955
102957
  recordKnowledgeShown
@@ -103097,7 +103099,7 @@ var TASK_DIVERSITY_WEIGHT = 0.05;
103097
103099
  var CONTEXT_WEIGHT = 0.2;
103098
103100
  var RECENCY_DECAY_MS = 30 * 24 * 60 * 60 * 1000;
103099
103101
  var SKILL_FRONTMATTER_READ_BYTES = 16 * 1024;
103100
- var _internals49 = {
103102
+ var _internals51 = {
103101
103103
  computeSkillRelevanceScore: null,
103102
103104
  rankSkillsForContext: null,
103103
103105
  getSkillStats: null,
@@ -103316,7 +103318,7 @@ function formatSkillIndexWithContext(skills, directory) {
103316
103318
  } catch {}
103317
103319
  if (!hasHistory) {
103318
103320
  return skills.map((sp) => {
103319
- const meta3 = _internals49.readSkillMetadata(sp, directory);
103321
+ const meta3 = _internals51.readSkillMetadata(sp, directory);
103320
103322
  return ` - file:${meta3.path} - ${meta3.name}: ${meta3.description}`;
103321
103323
  }).join(`
103322
103324
  `);
@@ -103324,7 +103326,7 @@ function formatSkillIndexWithContext(skills, directory) {
103324
103326
  const lines = [];
103325
103327
  for (const skillPath of skills) {
103326
103328
  const stats = getSkillStats(skillPath, directory);
103327
- const meta3 = _internals49.readSkillMetadata(skillPath, directory);
103329
+ const meta3 = _internals51.readSkillMetadata(skillPath, directory);
103328
103330
  const compliancePct = Math.round(stats.complianceRate * 100);
103329
103331
  const topAgentNames = stats.topAgents.slice(0, 3).map((a) => a.agent).join(", ");
103330
103332
  lines.push(` - file:${meta3.path} - ${meta3.name}: ${meta3.description} (used: ${stats.totalUsage}, compliance: ${compliancePct}%)` + (stats.topAgents.length > 0 ? ` → ${topAgentNames}` : ""));
@@ -103332,15 +103334,15 @@ function formatSkillIndexWithContext(skills, directory) {
103332
103334
  return lines.join(`
103333
103335
  `);
103334
103336
  }
103335
- _internals49.computeSkillRelevanceScore = computeSkillRelevanceScore;
103336
- _internals49.rankSkillsForContext = rankSkillsForContext;
103337
- _internals49.getSkillStats = getSkillStats;
103338
- _internals49.formatSkillIndexWithContext = formatSkillIndexWithContext;
103339
- _internals49.parseSkillFrontmatter = parseSkillFrontmatter;
103340
- _internals49.readSkillMetadata = readSkillMetadata;
103341
- _internals49.extractSkillName = extractSkillName;
103342
- _internals49.computeRecencyScore = computeRecencyScore;
103343
- _internals49.computeContextMatchScore = computeContextMatchScore;
103337
+ _internals51.computeSkillRelevanceScore = computeSkillRelevanceScore;
103338
+ _internals51.rankSkillsForContext = rankSkillsForContext;
103339
+ _internals51.getSkillStats = getSkillStats;
103340
+ _internals51.formatSkillIndexWithContext = formatSkillIndexWithContext;
103341
+ _internals51.parseSkillFrontmatter = parseSkillFrontmatter;
103342
+ _internals51.readSkillMetadata = readSkillMetadata;
103343
+ _internals51.extractSkillName = extractSkillName;
103344
+ _internals51.computeRecencyScore = computeRecencyScore;
103345
+ _internals51.computeContextMatchScore = computeContextMatchScore;
103344
103346
 
103345
103347
  // src/hooks/skill-propagation-gate.ts
103346
103348
  init_skill_usage_log();
@@ -103443,10 +103445,10 @@ function parseYamlValue(value) {
103443
103445
  }
103444
103446
  function loadRoutingSkills(directory, targetAgent) {
103445
103447
  const routingPath = path105.join(directory, ".opencode", "skill-routing.yaml");
103446
- if (!_internals50.existsSync(routingPath))
103448
+ if (!_internals52.existsSync(routingPath))
103447
103449
  return [];
103448
103450
  try {
103449
- const content = _internals50.readFileSync(routingPath, "utf-8");
103451
+ const content = _internals52.readFileSync(routingPath, "utf-8");
103450
103452
  const config3 = parseSimpleYaml(content);
103451
103453
  if (!config3?.routing)
103452
103454
  return [];
@@ -103473,7 +103475,7 @@ var SKILL_SEARCH_ROOTS = [
103473
103475
  ".claude/skills"
103474
103476
  ];
103475
103477
  var MAX_SCORING_SESSION_ENTRIES = 500;
103476
- var _internals50 = {
103478
+ var _internals52 = {
103477
103479
  readdirSync: fs67.readdirSync.bind(fs67),
103478
103480
  existsSync: fs67.existsSync.bind(fs67),
103479
103481
  statSync: fs67.statSync.bind(fs67),
@@ -103502,11 +103504,11 @@ function discoverAvailableSkills(directory) {
103502
103504
  const results = [];
103503
103505
  for (const root of SKILL_SEARCH_ROOTS) {
103504
103506
  const rootPath = path105.join(directory, root);
103505
- if (!_internals50.existsSync(rootPath))
103507
+ if (!_internals52.existsSync(rootPath))
103506
103508
  continue;
103507
103509
  let entries;
103508
103510
  try {
103509
- entries = _internals50.readdirSync(rootPath);
103511
+ entries = _internals52.readdirSync(rootPath);
103510
103512
  } catch {
103511
103513
  continue;
103512
103514
  }
@@ -103514,11 +103516,11 @@ function discoverAvailableSkills(directory) {
103514
103516
  if (entry.startsWith("."))
103515
103517
  continue;
103516
103518
  const skillDir = path105.join(rootPath, entry);
103517
- if (_internals50.existsSync(path105.join(skillDir, "retired.marker")))
103519
+ if (_internals52.existsSync(path105.join(skillDir, "retired.marker")))
103518
103520
  continue;
103519
103521
  const skillFile = path105.join(skillDir, "SKILL.md");
103520
103522
  try {
103521
- if (_internals50.statSync(skillDir).isDirectory() && _internals50.existsSync(skillFile)) {
103523
+ if (_internals52.statSync(skillDir).isDirectory() && _internals52.existsSync(skillFile)) {
103522
103524
  results.push(path105.join(root, entry, "SKILL.md").replace(/\\/g, "/"));
103523
103525
  }
103524
103526
  } catch (err2) {
@@ -103550,7 +103552,7 @@ function parseDelegationArgs(args2) {
103550
103552
  }
103551
103553
  if (!targetAgent)
103552
103554
  return null;
103553
- const skillsField = prompt ? _internals50.extractSkillsFieldFromPrompt(prompt) : "";
103555
+ const skillsField = prompt ? _internals52.extractSkillsFieldFromPrompt(prompt) : "";
103554
103556
  return { targetAgent, skillsField };
103555
103557
  }
103556
103558
  function extractSkillsFieldFromPrompt(prompt) {
@@ -103591,10 +103593,10 @@ function writeWarnEvent2(directory, record3) {
103591
103593
  const filePath = path105.join(directory, ".swarm", "events.jsonl");
103592
103594
  try {
103593
103595
  const dir = path105.dirname(filePath);
103594
- if (!_internals50.existsSync(dir)) {
103595
- _internals50.mkdirSync(dir, { recursive: true });
103596
+ if (!_internals52.existsSync(dir)) {
103597
+ _internals52.mkdirSync(dir, { recursive: true });
103596
103598
  }
103597
- _internals50.appendFileSync(filePath, `${JSON.stringify(record3)}
103599
+ _internals52.appendFileSync(filePath, `${JSON.stringify(record3)}
103598
103600
  `, "utf-8");
103599
103601
  } catch (err2) {
103600
103602
  warn(`[skill-propagation-gate] failed to write warning event: ${err2 instanceof Error ? err2.message : String(err2)}`);
@@ -103645,19 +103647,19 @@ async function skillPropagationGateBefore(directory, input, config3) {
103645
103647
  const baseAgent = stripKnownSwarmPrefix(agentRaw);
103646
103648
  if (baseAgent !== "architect")
103647
103649
  return { blocked: false, reason: null, recommendedSkills: undefined };
103648
- const parsed = _internals50.parseDelegationArgs(input.args);
103650
+ const parsed = _internals52.parseDelegationArgs(input.args);
103649
103651
  if (!parsed)
103650
103652
  return { blocked: false, reason: null, recommendedSkills: undefined };
103651
103653
  const targetBase = stripKnownSwarmPrefix(parsed.targetAgent);
103652
- if (!_internals50.SKILL_CAPABLE_AGENTS.has(targetBase))
103654
+ if (!_internals52.SKILL_CAPABLE_AGENTS.has(targetBase))
103653
103655
  return { blocked: false, reason: null, recommendedSkills: undefined };
103654
103656
  const sessionID = typeof input.sessionID === "string" ? input.sessionID : "unknown";
103655
- const availableSkills = _internals50.discoverAvailableSkills(directory);
103657
+ const availableSkills = _internals52.discoverAvailableSkills(directory);
103656
103658
  const skillsValue = parsed.skillsField.trim();
103657
103659
  if (skillsValue && skillsValue.toLowerCase() !== "none") {
103658
103660
  const prompt = typeof input.args?.prompt === "string" ? String(input.args.prompt) : "";
103659
- const taskId = _internals50.extractTaskIdFromPrompt(prompt);
103660
- const skillPaths = _internals50.parseSkillPaths(skillsValue);
103661
+ const taskId = _internals52.extractTaskIdFromPrompt(prompt);
103662
+ const skillPaths = _internals52.parseSkillPaths(skillsValue);
103661
103663
  let coderSkillPaths = [];
103662
103664
  if (prompt) {
103663
103665
  for (const line of prompt.split(`
@@ -103665,7 +103667,7 @@ async function skillPropagationGateBefore(directory, input, config3) {
103665
103667
  const trimmed = line.trim();
103666
103668
  if (trimmed.startsWith("SKILLS_USED_BY_CODER:")) {
103667
103669
  const fieldVal = trimmed.slice("SKILLS_USED_BY_CODER:".length).trim();
103668
- coderSkillPaths = _internals50.parseSkillPaths(fieldVal);
103670
+ coderSkillPaths = _internals52.parseSkillPaths(fieldVal);
103669
103671
  break;
103670
103672
  }
103671
103673
  }
@@ -103673,7 +103675,7 @@ async function skillPropagationGateBefore(directory, input, config3) {
103673
103675
  const allPaths = [...new Set([...skillPaths, ...coderSkillPaths])];
103674
103676
  for (const skillPath of allPaths) {
103675
103677
  try {
103676
- _internals50.appendSkillUsageEntry(directory, {
103678
+ _internals52.appendSkillUsageEntry(directory, {
103677
103679
  skillPath,
103678
103680
  agentName: targetBase,
103679
103681
  taskID: taskId,
@@ -103690,17 +103692,17 @@ async function skillPropagationGateBefore(directory, input, config3) {
103690
103692
  let scored = [];
103691
103693
  if (skillsValue && skillsValue.toLowerCase() !== "none" && availableSkills.length > 0) {
103692
103694
  try {
103693
- const sessionEntries = _internals50.readSkillUsageEntriesTail(directory, {
103695
+ const sessionEntries = _internals52.readSkillUsageEntriesTail(directory, {
103694
103696
  sessionID
103695
103697
  });
103696
- if (sessionEntries.length > _internals50.MAX_SCORING_SESSION_ENTRIES) {
103698
+ if (sessionEntries.length > _internals52.MAX_SCORING_SESSION_ENTRIES) {
103697
103699
  scoringSkipped = true;
103698
- warn(`[skill-propagation-gate] skipping scoring — session has ${sessionEntries.length} entries (limit: ${_internals50.MAX_SCORING_SESSION_ENTRIES})`);
103700
+ warn(`[skill-propagation-gate] skipping scoring — session has ${sessionEntries.length} entries (limit: ${_internals52.MAX_SCORING_SESSION_ENTRIES})`);
103699
103701
  } else {
103700
103702
  const prompt = typeof input.args?.prompt === "string" ? String(input.args.prompt) : "";
103701
103703
  scored = availableSkills.map((skillPath) => {
103702
103704
  const skillEntries = sessionEntries.filter((e) => e.skillPath === skillPath);
103703
- const score = _internals50.computeSkillRelevanceScore(skillPath, prompt, skillEntries);
103705
+ const score = _internals52.computeSkillRelevanceScore(skillPath, prompt, skillEntries);
103704
103706
  return { skillPath, score, usageCount: skillEntries.length };
103705
103707
  }).sort((a, b) => b.score - a.score || b.usageCount - a.usageCount);
103706
103708
  if (scored.length > 0) {
@@ -103714,12 +103716,12 @@ async function skillPropagationGateBefore(directory, input, config3) {
103714
103716
  }
103715
103717
  }
103716
103718
  try {
103717
- const routingPaths = _internals50.loadRoutingSkills(directory, targetBase);
103719
+ const routingPaths = _internals52.loadRoutingSkills(directory, targetBase);
103718
103720
  if (routingPaths.length > 0) {
103719
103721
  const existingPaths = new Set(scored.map((s) => s.skillPath));
103720
103722
  for (const routingPath of routingPaths) {
103721
103723
  const routedSkillDir = path105.dirname(path105.join(directory, routingPath));
103722
- if (_internals50.existsSync(path105.join(routedSkillDir, "retired.marker")))
103724
+ if (_internals52.existsSync(path105.join(routedSkillDir, "retired.marker")))
103723
103725
  continue;
103724
103726
  if (!existingPaths.has(routingPath)) {
103725
103727
  scored.push({
@@ -103745,12 +103747,12 @@ async function skillPropagationGateBefore(directory, input, config3) {
103745
103747
  } else if (typeof scored !== "undefined" && scored.length > 0) {
103746
103748
  skillsForIndex = scored.map((r) => r.skillPath);
103747
103749
  }
103748
- const formattedIndex = _internals50.formatSkillIndexWithContext(skillsForIndex, directory);
103750
+ const formattedIndex = _internals52.formatSkillIndexWithContext(skillsForIndex, directory);
103749
103751
  if (formattedIndex.length > 0) {
103750
103752
  const contextPath = path105.join(directory, ".swarm", "context.md");
103751
103753
  let existingContent = "";
103752
- if (_internals50.existsSync(contextPath)) {
103753
- existingContent = _internals50.readFileSync(contextPath, "utf-8");
103754
+ if (_internals52.existsSync(contextPath)) {
103755
+ existingContent = _internals52.readFileSync(contextPath, "utf-8");
103754
103756
  }
103755
103757
  const sectionHeader = "## Available Skills";
103756
103758
  const newSection = `${sectionHeader}
@@ -103770,10 +103772,10 @@ ${newSection}`;
103770
103772
  }
103771
103773
  }
103772
103774
  const swarmDir = path105.dirname(contextPath);
103773
- if (!_internals50.existsSync(swarmDir)) {
103774
- _internals50.mkdirSync(swarmDir, { recursive: true });
103775
+ if (!_internals52.existsSync(swarmDir)) {
103776
+ _internals52.mkdirSync(swarmDir, { recursive: true });
103775
103777
  }
103776
- _internals50.writeFileSync(contextPath, updatedContent, "utf-8");
103778
+ _internals52.writeFileSync(contextPath, updatedContent, "utf-8");
103777
103779
  }
103778
103780
  } catch (err2) {
103779
103781
  warn(`[skill-propagation-gate] failed to write skill index to context.md: ${err2 instanceof Error ? err2.message : String(err2)}`);
@@ -103799,7 +103801,7 @@ ${newSection}`;
103799
103801
  });
103800
103802
  const warningMsg = `Skill propagation warning: Delegating to ${targetBase} without SKILLS field. ` + `Available skills: ${skillNames.join(", ")}`;
103801
103803
  try {
103802
- _internals50.writeWarnEvent(directory, {
103804
+ _internals52.writeWarnEvent(directory, {
103803
103805
  type: "skill_propagation_warn",
103804
103806
  timestamp: new Date().toISOString(),
103805
103807
  tool: toolName,
@@ -103828,7 +103830,7 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
103828
103830
  let dedupKeys = new Set;
103829
103831
  let existingEntries = [];
103830
103832
  try {
103831
- existingEntries = _internals50.readSkillUsageEntriesTail(directory, {
103833
+ existingEntries = _internals52.readSkillUsageEntriesTail(directory, {
103832
103834
  sessionID
103833
103835
  });
103834
103836
  dedupKeys = new Set(existingEntries.map((e, i2) => {
@@ -103860,7 +103862,7 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
103860
103862
  `)) {
103861
103863
  const coderMatch = line.trim().match(CODER_SKILLS_PATTERN);
103862
103864
  if (coderMatch) {
103863
- const parsed = _internals50.parseSkillPaths(coderMatch[1]);
103865
+ const parsed = _internals52.parseSkillPaths(coderMatch[1]);
103864
103866
  skillPaths.push(...parsed);
103865
103867
  }
103866
103868
  }
@@ -103891,7 +103893,7 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
103891
103893
  if (isDuplicate(skillPath, "reviewer", resolvedTaskID))
103892
103894
  continue;
103893
103895
  try {
103894
- _internals50.appendSkillUsageEntry(directory, {
103896
+ _internals52.appendSkillUsageEntry(directory, {
103895
103897
  skillPath,
103896
103898
  agentName: "reviewer",
103897
103899
  taskID: resolvedTaskID,
@@ -103935,15 +103937,15 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
103935
103937
  skillsField = trimmed.slice("SKILLS:".length).trim();
103936
103938
  }
103937
103939
  if (currentTargetAgent && skillsField && skillsField.toLowerCase() !== "none") {
103938
- const skillPaths = _internals50.parseSkillPaths(skillsField);
103939
- const taskId = _internals50.extractTaskIdFromPrompt(text);
103940
+ const skillPaths = _internals52.parseSkillPaths(skillsField);
103941
+ const taskId = _internals52.extractTaskIdFromPrompt(text);
103940
103942
  for (const skillPath of skillPaths) {
103941
103943
  if (hadRecordingError)
103942
103944
  break;
103943
103945
  if (isDuplicate(skillPath, currentTargetAgent, taskId))
103944
103946
  continue;
103945
103947
  try {
103946
- _internals50.appendSkillUsageEntry(directory, {
103948
+ _internals52.appendSkillUsageEntry(directory, {
103947
103949
  skillPath,
103948
103950
  agentName: currentTargetAgent,
103949
103951
  taskID: taskId,
@@ -103963,16 +103965,16 @@ async function skillPropagationTransformScan(directory, output, sessionID) {
103963
103965
  break;
103964
103966
  }
103965
103967
  }
103966
- _internals50.skillPropagationGateBefore = skillPropagationGateBefore;
103967
- _internals50.skillPropagationTransformScan = skillPropagationTransformScan;
103968
- _internals50.writeWarnEvent = writeWarnEvent2;
103969
- _internals50.discoverAvailableSkills = discoverAvailableSkills;
103970
- _internals50.parseDelegationArgs = parseDelegationArgs;
103971
- _internals50.parseSkillPaths = parseSkillPaths;
103972
- _internals50.extractTaskIdFromPrompt = extractTaskIdFromPrompt;
103973
- _internals50.extractSkillsFieldFromPrompt = extractSkillsFieldFromPrompt;
103974
- _internals50.formatSkillIndexWithContext = formatSkillIndexWithContext;
103975
- _internals50.loadRoutingSkills = loadRoutingSkills;
103968
+ _internals52.skillPropagationGateBefore = skillPropagationGateBefore;
103969
+ _internals52.skillPropagationTransformScan = skillPropagationTransformScan;
103970
+ _internals52.writeWarnEvent = writeWarnEvent2;
103971
+ _internals52.discoverAvailableSkills = discoverAvailableSkills;
103972
+ _internals52.parseDelegationArgs = parseDelegationArgs;
103973
+ _internals52.parseSkillPaths = parseSkillPaths;
103974
+ _internals52.extractTaskIdFromPrompt = extractTaskIdFromPrompt;
103975
+ _internals52.extractSkillsFieldFromPrompt = extractSkillsFieldFromPrompt;
103976
+ _internals52.formatSkillIndexWithContext = formatSkillIndexWithContext;
103977
+ _internals52.loadRoutingSkills = loadRoutingSkills;
103976
103978
 
103977
103979
  // src/index.ts
103978
103980
  init_skill_usage_log();
@@ -107264,7 +107266,7 @@ var EVIDENCE_DIR2 = ".swarm/evidence";
107264
107266
  var VALID_TASK_ID = /^\d+\.\d+(\.\d+)*$/;
107265
107267
  var COUNCIL_GATE_NAME = "council";
107266
107268
  var COUNCIL_AGENT_ID = "architect";
107267
- var _internals51 = {
107269
+ var _internals53 = {
107268
107270
  withTaskEvidenceLock
107269
107271
  };
107270
107272
  var FORBIDDEN_KEYS = new Set(["__proto__", "constructor", "prototype"]);
@@ -107299,7 +107301,7 @@ async function writeCouncilEvidence(workingDir, synthesis) {
107299
107301
  const dir = join95(workingDir, EVIDENCE_DIR2);
107300
107302
  mkdirSync28(dir, { recursive: true });
107301
107303
  const filePath = taskEvidencePath(workingDir, synthesis.taskId);
107302
- await _internals51.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
107304
+ await _internals53.withTaskEvidenceLock(workingDir, synthesis.taskId, COUNCIL_AGENT_ID, async () => {
107303
107305
  const existingRoot = Object.create(null);
107304
107306
  if (existsSync63(filePath)) {
107305
107307
  try {
@@ -111404,7 +111406,7 @@ function listLaneEvidenceSync(directory, phase) {
111404
111406
  }
111405
111407
  return laneIds;
111406
111408
  }
111407
- var _internals52 = {
111409
+ var _internals54 = {
111408
111410
  listActiveLocks,
111409
111411
  readPersisted: readPersisted2,
111410
111412
  readPlanJson: defaultReadPlanJson,
@@ -111465,7 +111467,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
111465
111467
  reason: "Lean Turbo state unreadable or missing"
111466
111468
  };
111467
111469
  }
111468
- const persisted = _internals52.readPersisted(directory);
111470
+ const persisted = _internals54.readPersisted(directory);
111469
111471
  if (!persisted) {
111470
111472
  return {
111471
111473
  ok: false,
@@ -111529,7 +111531,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
111529
111531
  }
111530
111532
  }
111531
111533
  if (runState.lanes.length > 0) {
111532
- const evidenceLaneIds = new Set(_internals52.listLaneEvidenceSync(directory, phase));
111534
+ const evidenceLaneIds = new Set(_internals54.listLaneEvidenceSync(directory, phase));
111533
111535
  for (const lane of runState.lanes) {
111534
111536
  if ((lane.status === "completed" || lane.status === "failed") && !evidenceLaneIds.has(lane.laneId)) {
111535
111537
  return {
@@ -111539,7 +111541,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
111539
111541
  }
111540
111542
  }
111541
111543
  }
111542
- const activeLocks = _internals52.listActiveLocks(directory);
111544
+ const activeLocks = _internals54.listActiveLocks(directory);
111543
111545
  const phaseLaneIds = new Set(laneIds);
111544
111546
  for (const lock of activeLocks) {
111545
111547
  if (lock.laneId && phaseLaneIds.has(lock.laneId)) {
@@ -111559,7 +111561,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
111559
111561
  }
111560
111562
  const serialDegradedTasks = runState.degradedTasks.filter((dt) => !laneTaskIds.has(dt.taskId));
111561
111563
  if (serialDegradedTasks.length > 0) {
111562
- const plan = _internals52.readPlanJson(directory);
111564
+ const plan = _internals54.readPlanJson(directory);
111563
111565
  if (!plan) {
111564
111566
  return {
111565
111567
  ok: false,
@@ -111603,7 +111605,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
111603
111605
  }
111604
111606
  const serializedTasks = runState.serializedTasks;
111605
111607
  if (Array.isArray(serializedTasks) && serializedTasks.length > 0) {
111606
- const plan = _internals52.readPlanJson(directory);
111608
+ const plan = _internals54.readPlanJson(directory);
111607
111609
  if (!plan) {
111608
111610
  return {
111609
111611
  ok: false,
@@ -111662,7 +111664,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
111662
111664
  }
111663
111665
  let reviewerVerdict = runState.lastReviewerVerdict;
111664
111666
  if (!reviewerVerdict) {
111665
- const evidence = _internals52.readReviewerEvidence(directory, phase);
111667
+ const evidence = _internals54.readReviewerEvidence(directory, phase);
111666
111668
  reviewerVerdict = evidence?.verdict ?? undefined;
111667
111669
  }
111668
111670
  if (mergedConfig.phase_reviewer) {
@@ -111675,7 +111677,7 @@ function verifyLeanTurboPhaseReady(directory, phase, sessionIDOrConfig, config3)
111675
111677
  }
111676
111678
  let criticVerdict = runState.lastCriticVerdict;
111677
111679
  if (!criticVerdict) {
111678
- const evidence = _internals52.readCriticEvidence(directory, phase);
111680
+ const evidence = _internals54.readCriticEvidence(directory, phase);
111679
111681
  criticVerdict = evidence?.verdict ?? undefined;
111680
111682
  }
111681
111683
  if (mergedConfig.phase_critic) {
@@ -112653,7 +112655,7 @@ Findings: ${details.join("; ")}` : "";
112653
112655
  phase_critic: leanConfig.phase_critic,
112654
112656
  integrated_diff_required: leanConfig.integrated_diff_required
112655
112657
  } : undefined;
112656
- const leanCheck = _internals52.verifyLeanTurboPhaseReady(dir, phase, sessionID, leanPhaseReadyConfig);
112658
+ const leanCheck = _internals54.verifyLeanTurboPhaseReady(dir, phase, sessionID, leanPhaseReadyConfig);
112657
112659
  if (!leanCheck.ok) {
112658
112660
  return JSON.stringify({
112659
112661
  success: false,
@@ -114871,11 +114873,11 @@ var quality_budget = createSwarmTool({
114871
114873
  }).optional().describe("Quality budget thresholds")
114872
114874
  },
114873
114875
  async execute(args2, directory) {
114874
- const result = await _internals53.qualityBudget(args2, directory);
114876
+ const result = await _internals55.qualityBudget(args2, directory);
114875
114877
  return JSON.stringify(result);
114876
114878
  }
114877
114879
  });
114878
- var _internals53 = {
114880
+ var _internals55 = {
114879
114881
  qualityBudget
114880
114882
  };
114881
114883
 
@@ -115604,7 +115606,7 @@ import * as path129 from "node:path";
115604
115606
  var semgrepAvailableCache = null;
115605
115607
  var DEFAULT_RULES_DIR = ".swarm/semgrep-rules";
115606
115608
  var DEFAULT_TIMEOUT_MS3 = 30000;
115607
- var _internals54 = {
115609
+ var _internals56 = {
115608
115610
  isSemgrepAvailable,
115609
115611
  checkSemgrepAvailable,
115610
115612
  resetSemgrepCache,
@@ -115629,7 +115631,7 @@ function isSemgrepAvailable() {
115629
115631
  }
115630
115632
  }
115631
115633
  async function checkSemgrepAvailable() {
115632
- return _internals54.isSemgrepAvailable();
115634
+ return _internals56.isSemgrepAvailable();
115633
115635
  }
115634
115636
  function resetSemgrepCache() {
115635
115637
  semgrepAvailableCache = null;
@@ -115726,12 +115728,12 @@ async function runSemgrep(options) {
115726
115728
  const timeoutMs = options.timeoutMs || DEFAULT_TIMEOUT_MS3;
115727
115729
  if (files.length === 0) {
115728
115730
  return {
115729
- available: _internals54.isSemgrepAvailable(),
115731
+ available: _internals56.isSemgrepAvailable(),
115730
115732
  findings: [],
115731
115733
  engine: "tier_a"
115732
115734
  };
115733
115735
  }
115734
- if (!_internals54.isSemgrepAvailable()) {
115736
+ if (!_internals56.isSemgrepAvailable()) {
115735
115737
  return {
115736
115738
  available: false,
115737
115739
  findings: [],
@@ -115890,7 +115892,7 @@ function assignOccurrenceIndices(findings, directory) {
115890
115892
  }
115891
115893
  const occIdx = countMap.get(baseKey) ?? 0;
115892
115894
  countMap.set(baseKey, occIdx + 1);
115893
- const fp = _internals55.fingerprintFinding(finding, directory, occIdx);
115895
+ const fp = _internals57.fingerprintFinding(finding, directory, occIdx);
115894
115896
  return {
115895
115897
  finding,
115896
115898
  index: occIdx,
@@ -115959,7 +115961,7 @@ async function captureOrMergeBaseline(directory, phase, findings, engine, scanne
115959
115961
  }
115960
115962
  } catch {}
115961
115963
  const scannedRelFiles = new Set(scannedFiles.map((f) => normalizeFindingPath(directory, f)));
115962
- const indexed = _internals55.assignOccurrenceIndices(findings, directory);
115964
+ const indexed = _internals57.assignOccurrenceIndices(findings, directory);
115963
115965
  if (existing && !opts?.force) {
115964
115966
  const prunedFingerprints = existing.fingerprints.filter((fp) => {
115965
115967
  const relFile = fp.slice(0, fp.indexOf("|"));
@@ -116099,7 +116101,7 @@ function loadBaseline(directory, phase) {
116099
116101
  };
116100
116102
  }
116101
116103
  }
116102
- var _internals55 = {
116104
+ var _internals57 = {
116103
116105
  fingerprintFinding,
116104
116106
  assignOccurrenceIndices,
116105
116107
  captureOrMergeBaseline,
@@ -116509,11 +116511,11 @@ var sast_scan = createSwarmTool({
116509
116511
  capture_baseline: safeArgs.capture_baseline,
116510
116512
  phase: safeArgs.phase
116511
116513
  };
116512
- const result = await _internals56.sastScan(input, directory);
116514
+ const result = await _internals58.sastScan(input, directory);
116513
116515
  return JSON.stringify(result, null, 2);
116514
116516
  }
116515
116517
  });
116516
- var _internals56 = {
116518
+ var _internals58 = {
116517
116519
  sastScan,
116518
116520
  sast_scan
116519
116521
  };
@@ -120930,7 +120932,7 @@ var swarm_memory_propose = createSwarmTool({
120930
120932
  evidenceRefs: exports_external.array(exports_external.string().min(1).max(500)).max(20).optional().describe("Evidence refs such as files, commits, test outputs, or URLs")
120931
120933
  },
120932
120934
  execute: async (args2, directory, ctx) => {
120933
- const { config: config3 } = _internals57.loadPluginConfigWithMeta(directory);
120935
+ const { config: config3 } = _internals59.loadPluginConfigWithMeta(directory);
120934
120936
  if (config3.memory?.enabled !== true) {
120935
120937
  return JSON.stringify({
120936
120938
  success: false,
@@ -120946,7 +120948,7 @@ var swarm_memory_propose = createSwarmTool({
120946
120948
  });
120947
120949
  }
120948
120950
  const agent = getContextAgent2(ctx);
120949
- const gateway = _internals57.createMemoryGateway({
120951
+ const gateway = _internals59.createMemoryGateway({
120950
120952
  directory,
120951
120953
  sessionID: ctx?.sessionID,
120952
120954
  agentRole: agent,
@@ -120971,7 +120973,7 @@ var swarm_memory_propose = createSwarmTool({
120971
120973
  }
120972
120974
  }
120973
120975
  });
120974
- var _internals57 = {
120976
+ var _internals59 = {
120975
120977
  loadPluginConfigWithMeta,
120976
120978
  createMemoryGateway
120977
120979
  };
@@ -121008,7 +121010,7 @@ var swarm_memory_recall = createSwarmTool({
121008
121010
  maxItems: exports_external.number().int().min(1).max(20).optional().describe("Maximum memories to return")
121009
121011
  },
121010
121012
  execute: async (args2, directory, ctx) => {
121011
- const { config: config3 } = _internals58.loadPluginConfigWithMeta(directory);
121013
+ const { config: config3 } = _internals60.loadPluginConfigWithMeta(directory);
121012
121014
  if (config3.memory?.enabled !== true) {
121013
121015
  return JSON.stringify({
121014
121016
  success: false,
@@ -121024,7 +121026,7 @@ var swarm_memory_recall = createSwarmTool({
121024
121026
  });
121025
121027
  }
121026
121028
  const agent = getContextAgent3(ctx);
121027
- const gateway = _internals58.createMemoryGateway({
121029
+ const gateway = _internals60.createMemoryGateway({
121028
121030
  directory,
121029
121031
  sessionID: ctx?.sessionID,
121030
121032
  agentRole: agent,
@@ -121057,7 +121059,7 @@ var RecallArgsSchema = exports_external.object({
121057
121059
  kinds: exports_external.array(exports_external.enum(MEMORY_KINDS2)).optional(),
121058
121060
  maxItems: exports_external.number().int().min(1).max(20).optional()
121059
121061
  });
121060
- var _internals58 = {
121062
+ var _internals60 = {
121061
121063
  loadPluginConfigWithMeta,
121062
121064
  createMemoryGateway
121063
121065
  };
@@ -122302,7 +122304,7 @@ function resolveDefaultReviewerAgent(generatedAgentNames) {
122302
122304
  }
122303
122305
  async function compileReviewPackage(directory, phase, sessionID, requireDiffSummary) {
122304
122306
  const lanes = await listLaneEvidence(directory, phase);
122305
- const persisted = _internals59.readPersisted?.(directory) ?? null;
122307
+ const persisted = _internals61.readPersisted?.(directory) ?? null;
122306
122308
  if (persisted) {
122307
122309
  let matchingRunState = null;
122308
122310
  for (const sessionState of Object.values(persisted.sessions)) {
@@ -122494,7 +122496,7 @@ Be specific and evidence-based. Do not approve a phase with unresolved degraded
122494
122496
  client.session.delete({ path: { id: sessionId } }).catch(() => {});
122495
122497
  }
122496
122498
  }
122497
- var _internals59 = {
122499
+ var _internals61 = {
122498
122500
  compileReviewPackage,
122499
122501
  parseReviewerVerdict,
122500
122502
  writeReviewerEvidence,
@@ -122511,28 +122513,28 @@ async function dispatchPhaseReviewer(directory, phase, sessionID, config3) {
122511
122513
  };
122512
122514
  const generatedAgentNames = swarmState.generatedAgentNames;
122513
122515
  const agentName = mergedConfig.reviewerAgent || resolveDefaultReviewerAgent(generatedAgentNames);
122514
- const pkg = await _internals59.compileReviewPackage(directory, phase, sessionID, mergedConfig.requireDiffSummary);
122516
+ const pkg = await _internals61.compileReviewPackage(directory, phase, sessionID, mergedConfig.requireDiffSummary);
122515
122517
  let responseText;
122516
122518
  try {
122517
- responseText = await _internals59.dispatchReviewerAgent(directory, pkg, agentName, mergedConfig.timeoutMs);
122519
+ responseText = await _internals61.dispatchReviewerAgent(directory, pkg, agentName, mergedConfig.timeoutMs);
122518
122520
  } catch (error93) {
122519
- const evidencePath2 = await _internals59.writeReviewerEvidence(directory, phase, "REJECTED", error93 instanceof Error ? error93.message : String(error93));
122521
+ const evidencePath2 = await _internals61.writeReviewerEvidence(directory, phase, "REJECTED", error93 instanceof Error ? error93.message : String(error93));
122520
122522
  return {
122521
122523
  verdict: "REJECTED",
122522
122524
  reason: `Reviewer dispatch failed: ${error93 instanceof Error ? error93.message : String(error93)}`,
122523
122525
  evidencePath: evidencePath2
122524
122526
  };
122525
122527
  }
122526
- const parsed = _internals59.parseReviewerVerdict(responseText);
122528
+ const parsed = _internals61.parseReviewerVerdict(responseText);
122527
122529
  if (!parsed) {
122528
- const evidencePath2 = await _internals59.writeReviewerEvidence(directory, phase, "REJECTED", "Reviewer response could not be parsed");
122530
+ const evidencePath2 = await _internals61.writeReviewerEvidence(directory, phase, "REJECTED", "Reviewer response could not be parsed");
122529
122531
  return {
122530
122532
  verdict: "REJECTED",
122531
122533
  reason: "Reviewer response could not be parsed",
122532
122534
  evidencePath: evidencePath2
122533
122535
  };
122534
122536
  }
122535
- const evidencePath = await _internals59.writeReviewerEvidence(directory, phase, parsed.verdict, parsed.reason);
122537
+ const evidencePath = await _internals61.writeReviewerEvidence(directory, phase, parsed.verdict, parsed.reason);
122536
122538
  return {
122537
122539
  verdict: parsed.verdict,
122538
122540
  reason: parsed.reason,
@@ -123038,7 +123040,7 @@ ${fileList}
123038
123040
 
123039
123041
  // src/tools/lean-turbo-run-phase.ts
123040
123042
  init_create_tool();
123041
- var _internals60 = {
123043
+ var _internals62 = {
123042
123044
  LeanTurboRunner,
123043
123045
  loadPluginConfigWithMeta
123044
123046
  };
@@ -123048,9 +123050,9 @@ async function executeLeanTurboRunPhase(args2) {
123048
123050
  let runError = null;
123049
123051
  let runner = null;
123050
123052
  try {
123051
- const { config: config3 } = _internals60.loadPluginConfigWithMeta(directory);
123053
+ const { config: config3 } = _internals62.loadPluginConfigWithMeta(directory);
123052
123054
  const leanConfig = config3.turbo?.strategy === "lean" ? config3.turbo.lean : undefined;
123053
- runner = new _internals60.LeanTurboRunner({
123055
+ runner = new _internals62.LeanTurboRunner({
123054
123056
  directory,
123055
123057
  sessionID,
123056
123058
  opencodeClient: swarmState.opencodeClient ?? null,
@@ -123404,7 +123406,7 @@ function isStaticallyEquivalent(originalCode, mutatedCode) {
123404
123406
  const strippedMutated = stripCode(mutatedCode);
123405
123407
  return strippedOriginal === strippedMutated;
123406
123408
  }
123407
- var _internals61 = {
123409
+ var _internals63 = {
123408
123410
  isStaticallyEquivalent,
123409
123411
  checkEquivalence,
123410
123412
  batchCheckEquivalence
@@ -123444,7 +123446,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
123444
123446
  const results = [];
123445
123447
  for (const { patch, originalCode, mutatedCode } of patches) {
123446
123448
  try {
123447
- const result = await _internals61.checkEquivalence(patch, originalCode, mutatedCode, llmJudge);
123449
+ const result = await _internals63.checkEquivalence(patch, originalCode, mutatedCode, llmJudge);
123448
123450
  results.push(result);
123449
123451
  } catch (err3) {
123450
123452
  results.push({
@@ -123463,7 +123465,7 @@ async function batchCheckEquivalence(patches, llmJudge) {
123463
123465
  var MUTATION_TIMEOUT_MS = 30000;
123464
123466
  var TOTAL_BUDGET_MS = 300000;
123465
123467
  var GIT_APPLY_TIMEOUT_MS = 5000;
123466
- var _internals62 = {
123468
+ var _internals64 = {
123467
123469
  executeMutation,
123468
123470
  computeReport,
123469
123471
  executeMutationSuite,
@@ -123495,7 +123497,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
123495
123497
  };
123496
123498
  }
123497
123499
  try {
123498
- const applyResult = _internals62.spawnSync("git", ["apply", "--", patchFile], {
123500
+ const applyResult = _internals64.spawnSync("git", ["apply", "--", patchFile], {
123499
123501
  cwd: workingDir,
123500
123502
  timeout: GIT_APPLY_TIMEOUT_MS,
123501
123503
  stdio: "pipe"
@@ -123524,7 +123526,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
123524
123526
  }
123525
123527
  let testPassed = false;
123526
123528
  try {
123527
- const spawnResult = _internals62.spawnSync(testCommand[0], testCommand.slice(1), {
123529
+ const spawnResult = _internals64.spawnSync(testCommand[0], testCommand.slice(1), {
123528
123530
  cwd: workingDir,
123529
123531
  timeout: MUTATION_TIMEOUT_MS,
123530
123532
  stdio: "pipe"
@@ -123557,7 +123559,7 @@ async function executeMutation(patch, testCommand, _testFiles, workingDir) {
123557
123559
  } finally {
123558
123560
  if (patchFile) {
123559
123561
  try {
123560
- const revertResult = _internals62.spawnSync("git", ["apply", "-R", "--", patchFile], {
123562
+ const revertResult = _internals64.spawnSync("git", ["apply", "-R", "--", patchFile], {
123561
123563
  cwd: workingDir,
123562
123564
  timeout: GIT_APPLY_TIMEOUT_MS,
123563
123565
  stdio: "pipe"
@@ -123750,7 +123752,7 @@ async function executeMutationSuite(patches, testCommand, testFiles, workingDir,
123750
123752
  }
123751
123753
 
123752
123754
  // src/mutation/gate.ts
123753
- var _internals63 = {
123755
+ var _internals65 = {
123754
123756
  evaluateMutationGate,
123755
123757
  buildTestImprovementPrompt,
123756
123758
  buildMessage
@@ -123771,8 +123773,8 @@ function evaluateMutationGate(report, passThreshold = PASS_THRESHOLD, warnThresh
123771
123773
  } else {
123772
123774
  verdict = "fail";
123773
123775
  }
123774
- const testImprovementPrompt = _internals63.buildTestImprovementPrompt(report, passThreshold, verdict);
123775
- const message = _internals63.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
123776
+ const testImprovementPrompt = _internals65.buildTestImprovementPrompt(report, passThreshold, verdict);
123777
+ const message = _internals65.buildMessage(verdict, adjustedKillRate, report.killed, report.totalMutants, report.equivalent, warnThreshold);
123776
123778
  return {
123777
123779
  verdict,
123778
123780
  killRate: report.killRate,
@@ -124399,7 +124401,7 @@ import * as path152 from "node:path";
124399
124401
  init_bun_compat();
124400
124402
  import * as fs109 from "node:fs";
124401
124403
  import * as path151 from "node:path";
124402
- var _internals64 = { bunSpawn };
124404
+ var _internals66 = { bunSpawn };
124403
124405
  var _swarmGitExcludedChecked = false;
124404
124406
  function fileCoversSwarm(content) {
124405
124407
  for (const rawLine of content.split(`
@@ -124432,7 +124434,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
124432
124434
  checkIgnoreExitCode
124433
124435
  ] = await Promise.all([
124434
124436
  (async () => {
124435
- const proc = _internals64.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
124437
+ const proc = _internals66.bunSpawn(["git", "-C", directory, "rev-parse", "--show-toplevel"], GIT_SPAWN_OPTIONS);
124436
124438
  try {
124437
124439
  return await Promise.all([proc.exited, proc.stdout.text()]);
124438
124440
  } finally {
@@ -124442,7 +124444,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
124442
124444
  }
124443
124445
  })(),
124444
124446
  (async () => {
124445
- const proc = _internals64.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
124447
+ const proc = _internals66.bunSpawn(["git", "-C", directory, "rev-parse", "--git-path", "info/exclude"], GIT_SPAWN_OPTIONS);
124446
124448
  try {
124447
124449
  return await Promise.all([proc.exited, proc.stdout.text()]);
124448
124450
  } finally {
@@ -124452,7 +124454,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
124452
124454
  }
124453
124455
  })(),
124454
124456
  (async () => {
124455
- const proc = _internals64.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
124457
+ const proc = _internals66.bunSpawn(["git", "-C", directory, "check-ignore", "-q", ".swarm/.gitkeep"], GIT_SPAWN_OPTIONS);
124456
124458
  try {
124457
124459
  return await proc.exited;
124458
124460
  } finally {
@@ -124491,7 +124493,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
124491
124493
  }
124492
124494
  } catch {}
124493
124495
  }
124494
- const trackedProc = _internals64.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
124496
+ const trackedProc = _internals66.bunSpawn(["git", "-C", directory, "ls-files", "--", ".swarm"], GIT_SPAWN_OPTIONS);
124495
124497
  let trackedExitCode;
124496
124498
  let trackedOutput;
124497
124499
  try {
@@ -124516,7 +124518,7 @@ async function ensureSwarmGitExcluded(directory, options = {}) {
124516
124518
  }
124517
124519
 
124518
124520
  // src/hooks/diff-scope.ts
124519
- var _internals65 = { bunSpawn };
124521
+ var _internals67 = { bunSpawn };
124520
124522
  function getDeclaredScope(taskId, directory) {
124521
124523
  try {
124522
124524
  const planPath = path152.join(directory, ".swarm", "plan.json");
@@ -124551,7 +124553,7 @@ var GIT_DIFF_SPAWN_OPTIONS = {
124551
124553
  };
124552
124554
  async function getChangedFiles(directory) {
124553
124555
  try {
124554
- const proc = _internals65.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
124556
+ const proc = _internals67.bunSpawn(["git", "diff", "--name-only", "HEAD~1"], {
124555
124557
  cwd: directory,
124556
124558
  ...GIT_DIFF_SPAWN_OPTIONS
124557
124559
  });
@@ -124568,7 +124570,7 @@ async function getChangedFiles(directory) {
124568
124570
  return stdout.trim().split(`
124569
124571
  `).map((f) => f.trim()).filter((f) => f.length > 0);
124570
124572
  }
124571
- const proc2 = _internals65.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
124573
+ const proc2 = _internals67.bunSpawn(["git", "diff", "--name-only", "HEAD"], {
124572
124574
  cwd: directory,
124573
124575
  ...GIT_DIFF_SPAWN_OPTIONS
124574
124576
  });
@@ -124626,7 +124628,7 @@ init_telemetry();
124626
124628
  init_file_locks();
124627
124629
  import * as fs111 from "node:fs";
124628
124630
  import * as path153 from "node:path";
124629
- var _internals66 = {
124631
+ var _internals68 = {
124630
124632
  listActiveLocks,
124631
124633
  verifyLeanTurboTaskCompletion
124632
124634
  };
@@ -124768,7 +124770,7 @@ function verifyLeanTurboTaskCompletion(directory, taskId, sessionID) {
124768
124770
  }
124769
124771
  };
124770
124772
  }
124771
- const activeLocks = _internals66.listActiveLocks(directory);
124773
+ const activeLocks = _internals68.listActiveLocks(directory);
124772
124774
  const laneLocks = activeLocks.filter((lock) => lock.laneId === lane.laneId);
124773
124775
  if (laneLocks.length > 0) {
124774
124776
  return {
@@ -125697,7 +125699,7 @@ var web_search = createSwarmTool({
125697
125699
  });
125698
125700
  async function captureSearchEvidence(directory, query, results) {
125699
125701
  try {
125700
- const written = await _internals67.writeEvidenceDocuments(directory, results.map((result) => ({
125702
+ const written = await _internals69.writeEvidenceDocuments(directory, results.map((result) => ({
125701
125703
  sourceType: "web_search",
125702
125704
  query,
125703
125705
  title: result.title,
@@ -125725,7 +125727,7 @@ async function captureSearchEvidence(directory, query, results) {
125725
125727
  };
125726
125728
  }
125727
125729
  }
125728
- var _internals67 = {
125730
+ var _internals69 = {
125729
125731
  writeEvidenceDocuments
125730
125732
  };
125731
125733
  // src/tools/write-drift-evidence.ts
@@ -10,7 +10,17 @@
10
10
  * Also exports upsertNode, addEdge, and resolveModuleSpecifier which are
11
11
  * used by both the builder and the incremental updater.
12
12
  */
13
+ import { safeRealpathSync } from './safe-realpath';
13
14
  import type { BuildWorkspaceGraphOptions, GraphEdge, GraphNode, RepoGraph } from './types';
15
+ /**
16
+ * _internals DI seam for safeRealpathSync.
17
+ * Defaults to the real implementation. Tests can override this to inject
18
+ * mock behavior without calling mock.module(...) which leaks across test files
19
+ * in Bun's shared test-runner process.
20
+ */
21
+ export declare const _internals: {
22
+ safeRealpathSync: typeof safeRealpathSync;
23
+ };
14
24
  /**
15
25
  * Add or update a node in the graph.
16
26
  * @param graph - The graph to modify
@@ -0,0 +1 @@
1
+ export declare function safeRealpathSync(targetPath: string, fallback: string, realpathResolver?: (targetPath: string) => string): string | null;
@@ -5,7 +5,15 @@
5
5
  * writes. Reads validate schema and content before updating the in-memory
6
6
  * cache. Symlink resolution guards against workspace-escape attacks.
7
7
  */
8
+ import { safeRealpathSync } from './safe-realpath';
8
9
  import type { RepoGraph } from './types';
10
+ /**
11
+ * Internal function references for testability.
12
+ * Replace _internals.safeRealpathSync in tests to mock symlink resolution.
13
+ */
14
+ export declare const _internals: {
15
+ safeRealpathSync: typeof safeRealpathSync;
16
+ };
9
17
  /**
10
18
  * Get the validated path for the repo-graph.json file.
11
19
  * Resolves symlinks via realpath before validation to prevent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-swarm",
3
- "version": "7.46.2",
3
+ "version": "7.46.3",
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",