nexus-agents 11.3.0 → 11.4.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.
Files changed (30) hide show
  1. package/dist/{chunk-WDAND5YU.js → chunk-BDP422B2.js} +4 -2
  2. package/dist/{chunk-WDAND5YU.js.map → chunk-BDP422B2.js.map} +1 -1
  3. package/dist/{chunk-QOJPTGQI.js → chunk-C4ZXUDDS.js} +2 -2
  4. package/dist/{chunk-PIBIAVWQ.js → chunk-CVHLQFUX.js} +3 -3
  5. package/dist/{chunk-ZZ2BEXLC.js → chunk-HF36DB2G.js} +3 -3
  6. package/dist/{chunk-A7XDON63.js → chunk-HHOSB6LL.js} +1258 -622
  7. package/dist/chunk-HHOSB6LL.js.map +1 -0
  8. package/dist/{chunk-3OQBXYFS.js → chunk-JEESPQIQ.js} +2 -2
  9. package/dist/{chunk-KS7CAJAC.js → chunk-JYZLBQ7M.js} +2 -2
  10. package/dist/{chunk-BREDDYX4.js → chunk-XXNSAOCH.js} +2 -2
  11. package/dist/cli.js +70 -15
  12. package/dist/cli.js.map +1 -1
  13. package/dist/{consensus-vote-BD5NWZU5.js → consensus-vote-36TUM35R.js} +4 -4
  14. package/dist/{improvement-review-FLF7N7PR.js → improvement-review-NHXRFXMD.js} +4 -4
  15. package/dist/index.d.ts +61 -0
  16. package/dist/index.js +7 -7
  17. package/dist/{pr-reviewer-helpers-HZGPA2OS.js → pr-reviewer-helpers-BB3QNAWD.js} +3 -3
  18. package/dist/{setup-data-dir-A37RQCGA.js → setup-data-dir-UQOVBXCR.js} +3 -3
  19. package/package.json +1 -1
  20. package/dist/chunk-A7XDON63.js.map +0 -1
  21. /package/dist/{chunk-QOJPTGQI.js.map → chunk-C4ZXUDDS.js.map} +0 -0
  22. /package/dist/{chunk-PIBIAVWQ.js.map → chunk-CVHLQFUX.js.map} +0 -0
  23. /package/dist/{chunk-ZZ2BEXLC.js.map → chunk-HF36DB2G.js.map} +0 -0
  24. /package/dist/{chunk-3OQBXYFS.js.map → chunk-JEESPQIQ.js.map} +0 -0
  25. /package/dist/{chunk-KS7CAJAC.js.map → chunk-JYZLBQ7M.js.map} +0 -0
  26. /package/dist/{chunk-BREDDYX4.js.map → chunk-XXNSAOCH.js.map} +0 -0
  27. /package/dist/{consensus-vote-BD5NWZU5.js.map → consensus-vote-36TUM35R.js.map} +0 -0
  28. /package/dist/{improvement-review-FLF7N7PR.js.map → improvement-review-NHXRFXMD.js.map} +0 -0
  29. /package/dist/{pr-reviewer-helpers-HZGPA2OS.js.map → pr-reviewer-helpers-BB3QNAWD.js.map} +0 -0
  30. /package/dist/{setup-data-dir-A37RQCGA.js.map → setup-data-dir-UQOVBXCR.js.map} +0 -0
@@ -2,7 +2,7 @@ import {
2
2
  FINDING_SEVERITY_LEVELS,
3
3
  SARIF_LEVEL_MAP,
4
4
  SEVERITY_ORDER
5
- } from "./chunk-WDAND5YU.js";
5
+ } from "./chunk-BDP422B2.js";
6
6
  import {
7
7
  executeExpert
8
8
  } from "./chunk-XAEGIDWX.js";
@@ -58,7 +58,7 @@ import {
58
58
  updateStage,
59
59
  withFileLock,
60
60
  writeJobCancelled
61
- } from "./chunk-PIBIAVWQ.js";
61
+ } from "./chunk-CVHLQFUX.js";
62
62
  import {
63
63
  normalizeTopicToCanonical,
64
64
  synthesizeResearch
@@ -77,7 +77,7 @@ import {
77
77
  } from "./chunk-HQ2SMW4Y.js";
78
78
  import {
79
79
  withPrerequisite
80
- } from "./chunk-KS7CAJAC.js";
80
+ } from "./chunk-JYZLBQ7M.js";
81
81
  import {
82
82
  NOOP_NOTIFIER,
83
83
  RateLimiter,
@@ -105,7 +105,7 @@ import {
105
105
  toolSuccess,
106
106
  withProgressHeartbeat,
107
107
  wrapToolWithTimeout
108
- } from "./chunk-BREDDYX4.js";
108
+ } from "./chunk-XXNSAOCH.js";
109
109
  import {
110
110
  generateSecurityPlan
111
111
  } from "./chunk-6ZTMMN2N.js";
@@ -187,7 +187,7 @@ import {
187
187
  import {
188
188
  DEFAULT_TASK_TTL_MS,
189
189
  clampTaskTtl
190
- } from "./chunk-ZZ2BEXLC.js";
190
+ } from "./chunk-HF36DB2G.js";
191
191
  import {
192
192
  allOf,
193
193
  anyOf
@@ -196,7 +196,7 @@ import {
196
196
  VERSION,
197
197
  createRequestContext,
198
198
  measuredTrustTier
199
- } from "./chunk-3OQBXYFS.js";
199
+ } from "./chunk-JEESPQIQ.js";
200
200
  import {
201
201
  BWRAP_READ_ONLY_ARGS,
202
202
  CliDetectionCache,
@@ -787,19 +787,19 @@ function suggestSimilar(name, known) {
787
787
  function classifyEnvKeys(nexusKeys, env) {
788
788
  const knownRecord = {};
789
789
  const unknownVars = [];
790
- for (const key of nexusKeys) {
791
- if (isDynamicFamilyMember(key)) {
790
+ for (const key2 of nexusKeys) {
791
+ if (isDynamicFamilyMember(key2)) {
792
792
  continue;
793
793
  }
794
- if (KNOWN_NAMES.includes(key)) {
795
- const value = env[key];
794
+ if (KNOWN_NAMES.includes(key2)) {
795
+ const value = env[key2];
796
796
  if (value !== void 0) {
797
- knownRecord[key] = value;
797
+ knownRecord[key2] = value;
798
798
  }
799
799
  } else {
800
800
  unknownVars.push({
801
- name: key,
802
- suggestion: suggestSimilar(key, KNOWN_NAMES)
801
+ name: key2,
802
+ suggestion: suggestSimilar(key2, KNOWN_NAMES)
803
803
  });
804
804
  }
805
805
  }
@@ -963,14 +963,14 @@ var PERSISTENCE_AWARE_FLAGS = /* @__PURE__ */ new Set([
963
963
  function resolveStageFlags(stagesConfig) {
964
964
  const persistenceOn = isPersistenceEnabled();
965
965
  const result = {};
966
- for (const key of STAGE_FLAG_KEYS) {
967
- const explicit = stagesConfig[key];
966
+ for (const key2 of STAGE_FLAG_KEYS) {
967
+ const explicit = stagesConfig[key2];
968
968
  if (explicit !== void 0) {
969
- result[key] = explicit;
970
- } else if (PERSISTENCE_AWARE_FLAGS.has(key) && persistenceOn) {
971
- result[key] = true;
969
+ result[key2] = explicit;
970
+ } else if (PERSISTENCE_AWARE_FLAGS.has(key2) && persistenceOn) {
971
+ result[key2] = true;
972
972
  } else {
973
- result[key] = DEFAULT_COMPOSITE_CONFIG[key];
973
+ result[key2] = DEFAULT_COMPOSITE_CONFIG[key2];
974
974
  }
975
975
  }
976
976
  return result;
@@ -1062,13 +1062,13 @@ var ConfigManager = class _ConfigManager {
1062
1062
  _ConfigManager.instance = null;
1063
1063
  }
1064
1064
  /** Gets the effective value for a configuration key. */
1065
- get(category, key) {
1066
- return this.getWithMeta(category, key).value;
1065
+ get(category, key2) {
1066
+ return this.getWithMeta(category, key2).value;
1067
1067
  }
1068
1068
  /** Gets the effective value with source metadata. */
1069
- getWithMeta(category, key) {
1070
- const fullKey = `${category}.${String(key)}`;
1071
- const defaultValue = DEFAULTS[category][key];
1069
+ getWithMeta(category, key2) {
1070
+ const fullKey = `${category}.${String(key2)}`;
1071
+ const defaultValue = DEFAULTS[category][key2];
1072
1072
  const override = this.overrides.get(fullKey);
1073
1073
  if (override) {
1074
1074
  return {
@@ -1101,9 +1101,9 @@ var ConfigManager = class _ConfigManager {
1101
1101
  * Sets an override for a configuration key.
1102
1102
  * @throws {Error} If value fails type validation
1103
1103
  */
1104
- setOverride(category, key, value, source) {
1105
- const fullKey = `${category}.${String(key)}`;
1106
- const defaultValue = DEFAULTS[category][key];
1104
+ setOverride(category, key2, value, source) {
1105
+ const fullKey = `${category}.${String(key2)}`;
1106
+ const defaultValue = DEFAULTS[category][key2];
1107
1107
  if (!validateValue(value, defaultValue)) {
1108
1108
  throw new Error(
1109
1109
  `Invalid value type for ${fullKey}: expected ${typeof defaultValue}, got ${typeof value}`
@@ -1112,8 +1112,8 @@ var ConfigManager = class _ConfigManager {
1112
1112
  this.overrides.set(fullKey, { value, source, setAt: new Date(getTimeProvider().now()) });
1113
1113
  }
1114
1114
  /** Clears an override. Returns true if it existed. */
1115
- clearOverride(category, key) {
1116
- return this.overrides.delete(`${category}.${String(key)}`);
1115
+ clearOverride(category, key2) {
1116
+ return this.overrides.delete(`${category}.${String(key2)}`);
1117
1117
  }
1118
1118
  /** Clears all overrides. */
1119
1119
  clearAllOverrides() {
@@ -1121,8 +1121,8 @@ var ConfigManager = class _ConfigManager {
1121
1121
  }
1122
1122
  /** Lists all active overrides. */
1123
1123
  listOverrides() {
1124
- return Array.from(this.overrides.entries()).map(([key, override]) => ({
1125
- key,
1124
+ return Array.from(this.overrides.entries()).map(([key2, override]) => ({
1125
+ key: key2,
1126
1126
  value: override.value,
1127
1127
  source: override.source,
1128
1128
  setAt: override.setAt
@@ -1133,12 +1133,12 @@ var ConfigManager = class _ConfigManager {
1133
1133
  const categories = categoryFilter ? [categoryFilter] : Object.keys(DEFAULTS);
1134
1134
  const result = [];
1135
1135
  for (const category of categories) {
1136
- for (const key of Object.keys(DEFAULTS[category])) {
1137
- const fullKey = `${category}.${key}`;
1138
- const meta = this.getWithMeta(category, key);
1136
+ for (const key2 of Object.keys(DEFAULTS[category])) {
1137
+ const fullKey = `${category}.${key2}`;
1138
+ const meta = this.getWithMeta(category, key2);
1139
1139
  result.push({
1140
1140
  category,
1141
- key,
1141
+ key: key2,
1142
1142
  value: meta.value,
1143
1143
  source: meta.source,
1144
1144
  envVar: ENV_VAR_MAP[fullKey]
@@ -1148,12 +1148,12 @@ var ConfigManager = class _ConfigManager {
1148
1148
  return result;
1149
1149
  }
1150
1150
  /** Gets the environment variable name for a config key. */
1151
- getEnvVarName(category, key) {
1152
- return ENV_VAR_MAP[`${category}.${String(key)}`];
1151
+ getEnvVarName(category, key2) {
1152
+ return ENV_VAR_MAP[`${category}.${String(key2)}`];
1153
1153
  }
1154
1154
  /** Checks if a key has an active override. */
1155
- hasOverride(category, key) {
1156
- return this.overrides.has(`${category}.${String(key)}`);
1155
+ hasOverride(category, key2) {
1156
+ return this.overrides.has(`${category}.${String(key2)}`);
1157
1157
  }
1158
1158
  };
1159
1159
  function getConfigManager() {
@@ -1522,7 +1522,7 @@ var RateLimiter2 = class {
1522
1522
  * Sleeps for the specified duration.
1523
1523
  */
1524
1524
  sleep(ms) {
1525
- return new Promise((resolve12) => setTimeout(resolve12, ms));
1525
+ return new Promise((resolve13) => setTimeout(resolve13, ms));
1526
1526
  }
1527
1527
  /**
1528
1528
  * Returns the current number of available tokens.
@@ -1745,14 +1745,14 @@ function notifyRetry(onRetry, info) {
1745
1745
  function sleepUnlessAborted(ms, signal) {
1746
1746
  if (signal === void 0) return sleep(ms).then(() => true);
1747
1747
  if (signal.aborted) return Promise.resolve(false);
1748
- return new Promise((resolve12) => {
1748
+ return new Promise((resolve13) => {
1749
1749
  const onAbort = () => {
1750
1750
  clearTimeout(timer);
1751
- resolve12(false);
1751
+ resolve13(false);
1752
1752
  };
1753
1753
  const timer = setTimeout(() => {
1754
1754
  signal.removeEventListener("abort", onAbort);
1755
- resolve12(true);
1755
+ resolve13(true);
1756
1756
  }, ms);
1757
1757
  signal.addEventListener("abort", onAbort, { once: true });
1758
1758
  });
@@ -4363,7 +4363,7 @@ function getAgentStateKey(agentId) {
4363
4363
 
4364
4364
  // src/agents/memory-operations.ts
4365
4365
  async function persistMemoryState(backend, state, logger58) {
4366
- const key = getAgentStateKey(state.agentId);
4366
+ const key2 = getAgentStateKey(state.agentId);
4367
4367
  const metadata = {
4368
4368
  importance: MemoryImportance.HIGH,
4369
4369
  tags: ["agent-state", state.role]
@@ -4372,7 +4372,7 @@ async function persistMemoryState(backend, state, logger58) {
4372
4372
  ...state,
4373
4373
  persistedAt: new Date(getTimeProvider().now())
4374
4374
  };
4375
- const result = await backend.store(key, updatedState, metadata);
4375
+ const result = await backend.store(key2, updatedState, metadata);
4376
4376
  if (!result.ok) {
4377
4377
  logger58.error("Failed to persist agent memory state", result.error, { agentId: state.agentId });
4378
4378
  return err(
@@ -4388,8 +4388,8 @@ async function persistMemoryState(backend, state, logger58) {
4388
4388
  return ok(void 0);
4389
4389
  }
4390
4390
  async function loadMemoryState(backend, agentId, role, logger58) {
4391
- const key = getAgentStateKey(agentId);
4392
- const result = await backend.retrieve(key);
4391
+ const key2 = getAgentStateKey(agentId);
4392
+ const result = await backend.retrieve(key2);
4393
4393
  if (!result.ok) {
4394
4394
  logger58.debug("No existing memory state found, creating fresh state", { agentId });
4395
4395
  return ok(createInitialMemoryState(agentId, role));
@@ -4741,13 +4741,13 @@ function makeCancelError(taskId) {
4741
4741
  }
4742
4742
  function executeWithTimeout(params) {
4743
4743
  const { task, maxDurationMs, executeTask, transformError, signal } = params;
4744
- return new Promise((resolve12) => {
4744
+ return new Promise((resolve13) => {
4745
4745
  let settled = false;
4746
4746
  const settle = (result) => {
4747
4747
  if (settled) return;
4748
4748
  settled = true;
4749
4749
  clearTimeout(timeoutId);
4750
- resolve12(result);
4750
+ resolve13(result);
4751
4751
  };
4752
4752
  const timeoutId = setTimeout(() => {
4753
4753
  settle(
@@ -6102,9 +6102,9 @@ function mergeArrays(outputs) {
6102
6102
  const merged = [];
6103
6103
  for (const output2 of outputs) {
6104
6104
  for (const item of output2) {
6105
- const key = JSON.stringify(item);
6106
- if (!seen.has(key)) {
6107
- seen.add(key);
6105
+ const key2 = JSON.stringify(item);
6106
+ if (!seen.has(key2)) {
6107
+ seen.add(key2);
6108
6108
  merged.push(item);
6109
6109
  }
6110
6110
  }
@@ -6131,7 +6131,7 @@ function deepEquals(a, b) {
6131
6131
  if (aKeys.length !== bKeys.length) {
6132
6132
  return false;
6133
6133
  }
6134
- return aKeys.every((key) => deepEquals(aObj[key], bObj[key]));
6134
+ return aKeys.every((key2) => deepEquals(aObj[key2], bObj[key2]));
6135
6135
  }
6136
6136
  function handleFieldConflict(ctx) {
6137
6137
  const conflict = {
@@ -6162,25 +6162,25 @@ function mergeObjects(results, outputs, conflictResolver) {
6162
6162
  const output2 = outputs[i];
6163
6163
  const result = results[i];
6164
6164
  if (output2 === void 0 || result === void 0) continue;
6165
- for (const [key, value] of Object.entries(output2)) {
6166
- const existing = keyOwners.get(key);
6165
+ for (const [key2, value] of Object.entries(output2)) {
6166
+ const existing = keyOwners.get(key2);
6167
6167
  if (existing === void 0) {
6168
- keyOwners.set(key, { expertId: result.expertId, value });
6169
- merged[key] = value;
6168
+ keyOwners.set(key2, { expertId: result.expertId, value });
6169
+ merged[key2] = value;
6170
6170
  continue;
6171
6171
  }
6172
6172
  if (deepEquals(existing.value, value)) continue;
6173
6173
  const conflict = handleFieldConflict({
6174
6174
  existing,
6175
6175
  newResult: result,
6176
- key,
6176
+ key: key2,
6177
6177
  value,
6178
6178
  results,
6179
6179
  conflictResolver
6180
6180
  });
6181
6181
  if (conflict.resolution === "expert2") {
6182
- merged[key] = value;
6183
- keyOwners.set(key, { expertId: result.expertId, value });
6182
+ merged[key2] = value;
6183
+ keyOwners.set(key2, { expertId: result.expertId, value });
6184
6184
  }
6185
6185
  conflicts.push(conflict);
6186
6186
  }
@@ -10500,13 +10500,13 @@ var WaveScheduler = class {
10500
10500
  }
10501
10501
  async withTimeout(promise, timeoutMs, taskId) {
10502
10502
  if (timeoutMs <= 0) return promise;
10503
- return new Promise((resolve12, reject) => {
10503
+ return new Promise((resolve13, reject) => {
10504
10504
  const timer = setTimeout(() => {
10505
10505
  reject(new Error(`Task ${taskId} timed out after ${String(timeoutMs)}ms`));
10506
10506
  }, timeoutMs);
10507
10507
  promise.then((result) => {
10508
10508
  clearTimeout(timer);
10509
- resolve12(result);
10509
+ resolve13(result);
10510
10510
  }).catch((error) => {
10511
10511
  clearTimeout(timer);
10512
10512
  reject(error instanceof Error ? error : new Error(String(error)));
@@ -10518,8 +10518,8 @@ function chunkByDirectory(files, basePath) {
10518
10518
  const normalizedBase = basePath.endsWith("/") ? basePath : `${basePath}/`;
10519
10519
  const groups = /* @__PURE__ */ new Map();
10520
10520
  for (const file of files) {
10521
- const relative6 = file.startsWith(normalizedBase) ? file.slice(normalizedBase.length) : file;
10522
- const stripped = relative6.startsWith("/") ? relative6.slice(1) : relative6;
10521
+ const relative7 = file.startsWith(normalizedBase) ? file.slice(normalizedBase.length) : file;
10522
+ const stripped = relative7.startsWith("/") ? relative7.slice(1) : relative7;
10523
10523
  const topDir = stripped.split("/")[0] ?? "root";
10524
10524
  const existing = groups.get(topDir);
10525
10525
  if (existing !== void 0) {
@@ -13500,8 +13500,8 @@ var RecoveryManager = class {
13500
13500
  * Resets the attempt count for a failure archetype.
13501
13501
  */
13502
13502
  resetAttemptCount(failure) {
13503
- const key = this.getAttemptKey(failure);
13504
- this.attemptCounts.delete(key);
13503
+ const key2 = this.getAttemptKey(failure);
13504
+ this.attemptCounts.delete(key2);
13505
13505
  }
13506
13506
  /**
13507
13507
  * Checks if recovery should be attempted.
@@ -13622,8 +13622,8 @@ INDICATORS FOUND: ${ctx.failure.indicators.join("; ")}
13622
13622
  }
13623
13623
  /** Increments the attempt count. */
13624
13624
  incrementAttemptCount(failure) {
13625
- const key = this.getAttemptKey(failure);
13626
- this.attemptCounts.set(key, (this.attemptCounts.get(key) ?? 0) + 1);
13625
+ const key2 = this.getAttemptKey(failure);
13626
+ this.attemptCounts.set(key2, (this.attemptCounts.get(key2) ?? 0) + 1);
13627
13627
  }
13628
13628
  };
13629
13629
 
@@ -13878,12 +13878,12 @@ function categoryToGuidance(category, count) {
13878
13878
  function groupByCategory(outcomes) {
13879
13879
  const groups = /* @__PURE__ */ new Map();
13880
13880
  for (const outcome of outcomes) {
13881
- const key = outcome.failureCategory ?? "unknown";
13882
- const group = groups.get(key);
13881
+ const key2 = outcome.failureCategory ?? "unknown";
13882
+ const group = groups.get(key2);
13883
13883
  if (group !== void 0) {
13884
13884
  group.push(outcome);
13885
13885
  } else {
13886
- groups.set(key, [outcome]);
13886
+ groups.set(key2, [outcome]);
13887
13887
  }
13888
13888
  }
13889
13889
  return groups;
@@ -18121,8 +18121,8 @@ var Semaphore = class {
18121
18121
  this.available -= 1;
18122
18122
  return Promise.resolve();
18123
18123
  }
18124
- return new Promise((resolve12) => {
18125
- this.waiters.push(resolve12);
18124
+ return new Promise((resolve13) => {
18125
+ this.waiters.push(resolve13);
18126
18126
  });
18127
18127
  }
18128
18128
  release() {
@@ -19758,8 +19758,8 @@ function inferLastPattern(recentOutputs) {
19758
19758
  const lastOutput = recentOutputs[recentOutputs.length - 1];
19759
19759
  if (lastOutput === void 0) return void 0;
19760
19760
  const lastAgentId = lastOutput.agentId;
19761
- for (const [key, pattern] of Object.entries(AGENT_PATTERN_MAP)) {
19762
- if (lastAgentId.includes(key)) return pattern;
19761
+ for (const [key2, pattern] of Object.entries(AGENT_PATTERN_MAP)) {
19762
+ if (lastAgentId.includes(key2)) return pattern;
19763
19763
  }
19764
19764
  return void 0;
19765
19765
  }
@@ -20094,8 +20094,8 @@ function extractFeatureValues(features) {
20094
20094
  }
20095
20095
  function computeGradients(trajectory, returns, baseline) {
20096
20096
  const gradients = {};
20097
- for (const key of LEARNABLE_WEIGHTS) {
20098
- gradients[key] = 0;
20097
+ for (const key2 of LEARNABLE_WEIGHTS) {
20098
+ gradients[key2] = 0;
20099
20099
  }
20100
20100
  for (let t = 0; t < trajectory.length; t++) {
20101
20101
  const step = trajectory[t];
@@ -20104,16 +20104,16 @@ function computeGradients(trajectory, returns, baseline) {
20104
20104
  const advantage = returnValue - baseline;
20105
20105
  const features = extractFeatures(step.state);
20106
20106
  const featureValues = extractFeatureValues(features);
20107
- for (const key of LEARNABLE_WEIGHTS) {
20108
- const featureVal = featureValues[key];
20109
- const currentGrad = gradients[key] ?? 0;
20110
- gradients[key] = currentGrad + advantage * featureVal;
20107
+ for (const key2 of LEARNABLE_WEIGHTS) {
20108
+ const featureVal = featureValues[key2];
20109
+ const currentGrad = gradients[key2] ?? 0;
20110
+ gradients[key2] = currentGrad + advantage * featureVal;
20111
20111
  }
20112
20112
  }
20113
20113
  if (trajectory.length > 0) {
20114
- for (const key of LEARNABLE_WEIGHTS) {
20115
- const currentGrad = gradients[key] ?? 0;
20116
- gradients[key] = currentGrad / trajectory.length;
20114
+ for (const key2 of LEARNABLE_WEIGHTS) {
20115
+ const currentGrad = gradients[key2] ?? 0;
20116
+ gradients[key2] = currentGrad / trajectory.length;
20117
20117
  }
20118
20118
  }
20119
20119
  return gradients;
@@ -20122,9 +20122,9 @@ function normalizeWeights(weights) {
20122
20122
  const weightSum = Object.values(weights).reduce((s, w) => s + Math.abs(w), 0);
20123
20123
  if (weightSum === 0) return weights;
20124
20124
  const normalized = { ...weights };
20125
- for (const key of Object.keys(normalized)) {
20126
- const weight = normalized[key] ?? 0;
20127
- normalized[key] = Math.abs(weight) / weightSum;
20125
+ for (const key2 of Object.keys(normalized)) {
20126
+ const weight = normalized[key2] ?? 0;
20127
+ normalized[key2] = Math.abs(weight) / weightSum;
20128
20128
  }
20129
20129
  return normalized;
20130
20130
  }
@@ -20132,10 +20132,10 @@ function applyGradientUpdate(gradients, currentWeights, learningRate, gradientCl
20132
20132
  const gradNorm = Math.sqrt(Object.values(gradients).reduce((sum, g) => sum + g * g, 0));
20133
20133
  const clipRatio = gradNorm > gradientClip ? gradientClip / gradNorm : 1;
20134
20134
  const newWeights = { ...currentWeights };
20135
- for (const key of LEARNABLE_WEIGHTS) {
20136
- const currentWeight = newWeights[key] ?? 0;
20137
- const gradient = gradients[key] ?? 0;
20138
- newWeights[key] = currentWeight + learningRate * gradient * clipRatio;
20135
+ for (const key2 of LEARNABLE_WEIGHTS) {
20136
+ const currentWeight = newWeights[key2] ?? 0;
20137
+ const gradient = gradients[key2] ?? 0;
20138
+ newWeights[key2] = currentWeight + learningRate * gradient * clipRatio;
20139
20139
  }
20140
20140
  return {
20141
20141
  weights: normalizeWeights(newWeights),
@@ -20448,14 +20448,14 @@ var PatternTracker = class {
20448
20448
  const ngramCounts = /* @__PURE__ */ new Map();
20449
20449
  for (let i = 0; i <= sequence2.length - length; i++) {
20450
20450
  const ngram = sequence2.slice(i, i + length);
20451
- const key = ngram.join("|");
20452
- ngramCounts.set(key, (ngramCounts.get(key) ?? 0) + 1);
20451
+ const key2 = ngram.join("|");
20452
+ ngramCounts.set(key2, (ngramCounts.get(key2) ?? 0) + 1);
20453
20453
  }
20454
20454
  const cycles = [];
20455
- for (const [key, count] of ngramCounts) {
20455
+ for (const [key2, count] of ngramCounts) {
20456
20456
  if (count >= 2) {
20457
20457
  cycles.push({
20458
- agents: key.split("|"),
20458
+ agents: key2.split("|"),
20459
20459
  occurrences: count
20460
20460
  });
20461
20461
  }
@@ -20465,14 +20465,14 @@ var PatternTracker = class {
20465
20465
  mergeCycles(cycles) {
20466
20466
  const grouped = /* @__PURE__ */ new Map();
20467
20467
  for (const cycle of cycles) {
20468
- const key = this.normalizeCycleKey(cycle.agents);
20469
- const existing = grouped.get(key);
20468
+ const key2 = this.normalizeCycleKey(cycle.agents);
20469
+ const existing = grouped.get(key2);
20470
20470
  if (existing) {
20471
20471
  if (cycle.occurrences > existing.occurrences) {
20472
- grouped.set(key, cycle);
20472
+ grouped.set(key2, cycle);
20473
20473
  }
20474
20474
  } else {
20475
- grouped.set(key, cycle);
20475
+ grouped.set(key2, cycle);
20476
20476
  }
20477
20477
  }
20478
20478
  return [...grouped.values()].sort((a, b) => b.occurrences - a.occurrences);
@@ -21541,9 +21541,9 @@ var ExpertPool = class {
21541
21541
  if (this.active < this.capacity) {
21542
21542
  return this.issuePermit();
21543
21543
  }
21544
- return new Promise((resolve12, reject) => {
21544
+ return new Promise((resolve13, reject) => {
21545
21545
  const timer = setTimeout(() => {
21546
- const idx = this.queue.findIndex((e) => e.resolve === resolve12);
21546
+ const idx = this.queue.findIndex((e) => e.resolve === resolve13);
21547
21547
  if (idx !== -1) {
21548
21548
  this.queue.splice(idx, 1);
21549
21549
  }
@@ -21553,7 +21553,7 @@ var ExpertPool = class {
21553
21553
  )
21554
21554
  );
21555
21555
  }, this.acquireTimeoutMs);
21556
- this.queue.push({ resolve: resolve12, reject, timer });
21556
+ this.queue.push({ resolve: resolve13, reject, timer });
21557
21557
  });
21558
21558
  }
21559
21559
  /** Release a permit back to the pool. */
@@ -22148,8 +22148,8 @@ var TaskQueue = class {
22148
22148
  if (this.cancelled) {
22149
22149
  return Promise.reject(new Error("Queue has been cancelled"));
22150
22150
  }
22151
- return new Promise((resolve12, reject) => {
22152
- this.queue.push({ task, resolve: resolve12, reject });
22151
+ return new Promise((resolve13, reject) => {
22152
+ this.queue.push({ task, resolve: resolve13, reject });
22153
22153
  this.processNext();
22154
22154
  });
22155
22155
  }
@@ -22425,16 +22425,16 @@ async function executeStepWithTimeout(step, context, stepExecutor, signal) {
22425
22425
  return executeWithTimeout2(step, stepContext, stepExecutor, stepTimeout, startTime);
22426
22426
  }
22427
22427
  function executeWithTimeout2(step, context, executor, timeout, startTime) {
22428
- return new Promise((resolve12) => {
22428
+ return new Promise((resolve13) => {
22429
22429
  const timeoutId = setTimeout(() => {
22430
- resolve12(createTimeoutResult(step.id, getTimeProvider().now() - startTime, timeout));
22430
+ resolve13(createTimeoutResult(step.id, getTimeProvider().now() - startTime, timeout));
22431
22431
  }, timeout);
22432
22432
  executor(step, context).then((result) => {
22433
22433
  clearTimeout(timeoutId);
22434
- resolve12(result);
22434
+ resolve13(result);
22435
22435
  }).catch((error) => {
22436
22436
  clearTimeout(timeoutId);
22437
- resolve12(createErrorResult(step.id, getTimeProvider().now() - startTime, error));
22437
+ resolve13(createErrorResult(step.id, getTimeProvider().now() - startTime, error));
22438
22438
  });
22439
22439
  });
22440
22440
  }
@@ -23235,12 +23235,12 @@ function isCancelled(context) {
23235
23235
  }
23236
23236
  function snapshotContext(context) {
23237
23237
  const stepResults = {};
23238
- for (const [key, value] of context.stepResults) {
23239
- stepResults[key] = value;
23238
+ for (const [key2, value] of context.stepResults) {
23239
+ stepResults[key2] = value;
23240
23240
  }
23241
23241
  const variables = {};
23242
- for (const [key, value] of context.variables) {
23243
- variables[key] = value;
23242
+ for (const [key2, value] of context.variables) {
23243
+ variables[key2] = value;
23244
23244
  }
23245
23245
  return {
23246
23246
  workflowId: context.workflowId,
@@ -23271,14 +23271,14 @@ function validateRequiredInputs(inputs, required) {
23271
23271
  // src/workflows/expression-resolver-helpers.ts
23272
23272
  function getNestedValue(obj, path9) {
23273
23273
  let current = obj;
23274
- for (const key of path9) {
23274
+ for (const key2 of path9) {
23275
23275
  if (current === null || current === void 0) {
23276
23276
  return void 0;
23277
23277
  }
23278
23278
  if (typeof current !== "object") {
23279
23279
  return void 0;
23280
23280
  }
23281
- current = current[key];
23281
+ current = current[key2];
23282
23282
  }
23283
23283
  return current;
23284
23284
  }
@@ -23467,8 +23467,8 @@ function resolveInput(input, context) {
23467
23467
  }
23468
23468
  if (input !== null && typeof input === "object") {
23469
23469
  const resolved = {};
23470
- for (const [key, value] of Object.entries(input)) {
23471
- resolved[key] = resolveInput(value, context);
23470
+ for (const [key2, value] of Object.entries(input)) {
23471
+ resolved[key2] = resolveInput(value, context);
23472
23472
  }
23473
23473
  return resolved;
23474
23474
  }
@@ -23595,7 +23595,7 @@ function formatValue(value) {
23595
23595
  return typeof value === "number" || typeof value === "boolean" ? String(value) : "[complex]";
23596
23596
  }
23597
23597
  function buildTaskDescription(step, inputs) {
23598
- const inputSummary = Object.entries(inputs).map(([key, value]) => `- ${key}: ${formatValue(value)}`).join("\n");
23598
+ const inputSummary = Object.entries(inputs).map(([key2, value]) => `- ${key2}: ${formatValue(value)}`).join("\n");
23599
23599
  return `Execute action: ${step.action}
23600
23600
 
23601
23601
  Inputs:
@@ -26393,8 +26393,8 @@ function buildTopEdges(graph) {
26393
26393
  const edges = graph.getEdges();
26394
26394
  const edgeMap = /* @__PURE__ */ new Map();
26395
26395
  for (const edge of edges) {
26396
- const key = `${edge.from}|${edge.to}`;
26397
- const existing = edgeMap.get(key) ?? { count: 0, successes: 0, totalLatency: 0, timed: 0 };
26396
+ const key2 = `${edge.from}|${edge.to}`;
26397
+ const existing = edgeMap.get(key2) ?? { count: 0, successes: 0, totalLatency: 0, timed: 0 };
26398
26398
  existing.count++;
26399
26399
  if (edge.outcome === "success") {
26400
26400
  existing.successes++;
@@ -26403,10 +26403,10 @@ function buildTopEdges(graph) {
26403
26403
  existing.totalLatency += edge.durationMs;
26404
26404
  existing.timed++;
26405
26405
  }
26406
- edgeMap.set(key, existing);
26406
+ edgeMap.set(key2, existing);
26407
26407
  }
26408
- return Array.from(edgeMap.entries()).map(([key, stats]) => {
26409
- const [from, to] = key.split("|");
26408
+ return Array.from(edgeMap.entries()).map(([key2, stats]) => {
26409
+ const [from, to] = key2.split("|");
26410
26410
  return {
26411
26411
  from: from ?? "",
26412
26412
  to: to ?? "",
@@ -26919,10 +26919,10 @@ function calculateDifferenceCI(p1, p2, total1, total2, confidence) {
26919
26919
  const difference = p1 - p2;
26920
26920
  const measured = total1 > 0 && total2 > 0;
26921
26921
  const seDiff = Math.sqrt(p1 * (1 - p1) / (total1 || 1) + p2 * (1 - p2) / (total2 || 1));
26922
- const z115 = getZScore(confidence);
26922
+ const z116 = getZScore(confidence);
26923
26923
  return {
26924
- lower: difference - z115 * seDiff,
26925
- upper: difference + z115 * seDiff,
26924
+ lower: difference - z116 * seDiff,
26925
+ upper: difference + z116 * seDiff,
26926
26926
  estimate: difference,
26927
26927
  confidence,
26928
26928
  n: total1 + total2,
@@ -26950,11 +26950,11 @@ function proportionConfidenceInterval(successes, total, options = {}) {
26950
26950
  measured: false
26951
26951
  };
26952
26952
  }
26953
- const z115 = getZScore(opts.confidence);
26954
- const z210 = z115 * z115;
26953
+ const z116 = getZScore(opts.confidence);
26954
+ const z210 = z116 * z116;
26955
26955
  const denominator = 1 + z210 / n;
26956
26956
  const center = (p + z210 / (2 * n)) / denominator;
26957
- const margin = z115 / denominator * Math.sqrt(p * (1 - p) / n + z210 / (4 * n * n));
26957
+ const margin = z116 / denominator * Math.sqrt(p * (1 - p) / n + z210 / (4 * n * n));
26958
26958
  const lower = Math.max(0, center - margin);
26959
26959
  const upper = Math.min(1, center + margin);
26960
26960
  const standardError = Math.sqrt(p * (1 - p) / n);
@@ -26992,8 +26992,8 @@ function meanConfidenceInterval(values, options = {}) {
26992
26992
  const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / (n - 1 || 1);
26993
26993
  const stdDev = Math.sqrt(variance);
26994
26994
  const standardError = stdDev / Math.sqrt(n);
26995
- const z115 = getZScore(opts.confidence);
26996
- const margin = z115 * standardError;
26995
+ const z116 = getZScore(opts.confidence);
26996
+ const margin = z116 * standardError;
26997
26997
  return {
26998
26998
  lower: mean - margin,
26999
26999
  upper: mean + margin,
@@ -29085,8 +29085,8 @@ function budgetHaltFailure(context) {
29085
29085
  import { randomUUID as randomUUID8 } from "node:crypto";
29086
29086
  function resolveExecutionEngineOrError(deps, workflowName) {
29087
29087
  try {
29088
- const resolve12 = deps.resolveExecutionEngine ?? (() => deps.workflowEngine);
29089
- return { ok: true, value: resolve12() };
29088
+ const resolve13 = deps.resolveExecutionEngine ?? (() => deps.workflowEngine);
29089
+ return { ok: true, value: resolve13() };
29090
29090
  } catch (error) {
29091
29091
  const message = error instanceof Error ? error.message : String(error);
29092
29092
  deps.logger?.error(
@@ -30053,8 +30053,8 @@ function initializeState(graph, inputs) {
30053
30053
  for (const [field, schema] of Object.entries(graph.stateSchema)) {
30054
30054
  state[field] = schema.defaultValue;
30055
30055
  }
30056
- for (const [key, value] of Object.entries(inputs)) {
30057
- state[key] = value;
30056
+ for (const [key2, value] of Object.entries(inputs)) {
30057
+ state[key2] = value;
30058
30058
  }
30059
30059
  return state;
30060
30060
  }
@@ -30072,9 +30072,9 @@ function applyStateUpdates(graph, state, updates) {
30072
30072
  for (const [field, value] of Object.entries(updates)) {
30073
30073
  const schema = graph.stateSchema[field];
30074
30074
  if (schema === void 0) {
30075
- const key = `${String(Object.keys(graph.stateSchema).length)}:${field}`;
30076
- if (!undeclaredFieldWarned.has(key)) {
30077
- undeclaredFieldWarned.add(key);
30075
+ const key2 = `${String(Object.keys(graph.stateSchema).length)}:${field}`;
30076
+ if (!undeclaredFieldWarned.has(key2)) {
30077
+ undeclaredFieldWarned.add(key2);
30078
30078
  logger17.warn("Node wrote to undeclared state field; defaulting to overwrite reducer", {
30079
30079
  field,
30080
30080
  knownFields: Object.keys(graph.stateSchema)
@@ -30291,13 +30291,13 @@ function dedupe(ids) {
30291
30291
  return [...new Set(ids)];
30292
30292
  }
30293
30293
  async function withTimeout3(promise, ms) {
30294
- return new Promise((resolve12, reject) => {
30294
+ return new Promise((resolve13, reject) => {
30295
30295
  const timer = setTimeout(() => {
30296
30296
  reject(new Error(`Node timed out after ${String(ms)}ms`));
30297
30297
  }, ms);
30298
30298
  promise.then((result) => {
30299
30299
  clearTimeout(timer);
30300
- resolve12(result);
30300
+ resolve13(result);
30301
30301
  }).catch((error) => {
30302
30302
  clearTimeout(timer);
30303
30303
  reject(error instanceof Error ? error : new Error(String(error)));
@@ -32661,12 +32661,12 @@ function computeMetrics2(outcomes, filterPattern) {
32661
32661
  const groups = /* @__PURE__ */ new Map();
32662
32662
  for (const o of outcomes) {
32663
32663
  if (filterPattern !== void 0 && o.pattern !== filterPattern) continue;
32664
- const key = `${o.pattern}:${o.taskType}`;
32665
- const group = groups.get(key);
32664
+ const key2 = `${o.pattern}:${o.taskType}`;
32665
+ const group = groups.get(key2);
32666
32666
  if (group !== void 0) {
32667
32667
  group.push(o);
32668
32668
  } else {
32669
- groups.set(key, [o]);
32669
+ groups.set(key2, [o]);
32670
32670
  }
32671
32671
  }
32672
32672
  const metrics = [];
@@ -32848,11 +32848,11 @@ function createMockOrchestrator() {
32848
32848
  async function raceAgainstDeadline(promise, deadlineMs, onTimeout) {
32849
32849
  const startedAt = Date.now();
32850
32850
  let timer;
32851
- const timeoutP = new Promise((resolve12, reject) => {
32851
+ const timeoutP = new Promise((resolve13, reject) => {
32852
32852
  timer = setTimeout(
32853
32853
  () => {
32854
32854
  try {
32855
- resolve12(onTimeout(Date.now() - startedAt));
32855
+ resolve13(onTimeout(Date.now() - startedAt));
32856
32856
  } catch (err2) {
32857
32857
  reject(err2 instanceof Error ? err2 : new Error(String(err2)));
32858
32858
  }
@@ -34039,11 +34039,11 @@ function createWorkerTask(entry, taskIndex, waveNumber, opts) {
34039
34039
  const staggerSlot = taskIndex % opts.maxConcurrency;
34040
34040
  const staggerMs = staggerSlot * opts.staggerDelayMs;
34041
34041
  if (staggerMs > 0) {
34042
- await new Promise((resolve12) => setTimeout(resolve12, staggerMs));
34042
+ await new Promise((resolve13) => setTimeout(resolve13, staggerMs));
34043
34043
  }
34044
34044
  const spacingDelay = opts.failureTracker.getSpacingDelay(entry.role);
34045
34045
  if (spacingDelay > 0) {
34046
- await new Promise((resolve12) => setTimeout(resolve12, spacingDelay));
34046
+ await new Promise((resolve13) => setTimeout(resolve13, spacingDelay));
34047
34047
  }
34048
34048
  const timeoutMs = opts.options.workerTimeoutMs ?? getExpertTaskTimeout(entry.subTask);
34049
34049
  const result = await executeSafe({
@@ -34096,7 +34096,7 @@ async function maybeDelayForRateLimit(results, waveIdx, totalWaves) {
34096
34096
  );
34097
34097
  if (hasRateLimit) {
34098
34098
  logger27.warn("Rate-limit detected \u2014 delaying next wave", { delayMs: RATE_LIMIT_WAVE_DELAY_MS });
34099
- await new Promise((resolve12) => setTimeout(resolve12, RATE_LIMIT_WAVE_DELAY_MS));
34099
+ await new Promise((resolve13) => setTimeout(resolve13, RATE_LIMIT_WAVE_DELAY_MS));
34100
34100
  }
34101
34101
  }
34102
34102
  function emitWaveStarted(ctx, workerCount, roles) {
@@ -34203,7 +34203,7 @@ async function maybeRetryAfterTriage(opts) {
34203
34203
  }
34204
34204
  const useAltCli = triage.action === "retry_different_cli" && altExecuteWorker !== void 0;
34205
34205
  if (triage.action === "retry_different_cli") {
34206
- await new Promise((resolve12) => setTimeout(resolve12, RATE_LIMIT_SPACING_MS));
34206
+ await new Promise((resolve13) => setTimeout(resolve13, RATE_LIMIT_SPACING_MS));
34207
34207
  }
34208
34208
  if (isCancelled2(opts.signal)) return { ...failedResult2, triageAction: triage.action };
34209
34209
  const retryTimeout = triage.action === "extend_timeout" ? Math.min(timeoutMs * TIMEOUT_EXTENSION_FACTOR, MAX_WORKER_TIMEOUT_MS) : timeoutMs;
@@ -34657,12 +34657,12 @@ function extractFilePaths(output2) {
34657
34657
  FILE_PATH_PATTERN.lastIndex = 0;
34658
34658
  return [...paths];
34659
34659
  }
34660
- function addToOverlapMap(map, key, role) {
34661
- const existing = map.get(key);
34660
+ function addToOverlapMap(map, key2, role) {
34661
+ const existing = map.get(key2);
34662
34662
  if (existing !== void 0) {
34663
34663
  existing.add(role);
34664
34664
  } else {
34665
- map.set(key, /* @__PURE__ */ new Set([role]));
34665
+ map.set(key2, /* @__PURE__ */ new Set([role]));
34666
34666
  }
34667
34667
  }
34668
34668
  function detectConflicts(results) {
@@ -34751,8 +34751,8 @@ var SynthesisHistoryTracker = class {
34751
34751
  if (this.patterns.size <= MAX_PATTERNS) return;
34752
34752
  const sorted = [...this.patterns.entries()].sort((a, b) => a[1].lastUpdated - b[1].lastUpdated);
34753
34753
  const toRemove = sorted.slice(0, this.patterns.size - MAX_PATTERNS);
34754
- for (const [key] of toRemove) {
34755
- this.patterns.delete(key);
34754
+ for (const [key2] of toRemove) {
34755
+ this.patterns.delete(key2);
34756
34756
  }
34757
34757
  }
34758
34758
  };
@@ -35131,18 +35131,18 @@ function createCheckpoint2(role, subTask, partialOutput = "") {
35131
35131
  var WorkerCheckpointStore = class {
35132
35132
  store = /* @__PURE__ */ new Map();
35133
35133
  /** Save a checkpoint, truncating partial output if needed. */
35134
- save(key, checkpoint) {
35134
+ save(key2, checkpoint) {
35135
35135
  const truncated = truncateOutput(checkpoint);
35136
- this.store.set(key, truncated);
35136
+ this.store.set(key2, truncated);
35137
35137
  this.enforceCapacity();
35138
35138
  }
35139
35139
  /** Retrieve a checkpoint by key. */
35140
- get(key) {
35141
- return this.store.get(key);
35140
+ get(key2) {
35141
+ return this.store.get(key2);
35142
35142
  }
35143
35143
  /** Remove a specific checkpoint. Returns true if it existed. */
35144
- remove(key) {
35145
- return this.store.delete(key);
35144
+ remove(key2) {
35145
+ return this.store.delete(key2);
35146
35146
  }
35147
35147
  /** Clear all checkpoints. */
35148
35148
  clear() {
@@ -35705,25 +35705,25 @@ var ReflectionCache = class {
35705
35705
  return query.toLowerCase().trim().replace(/\s+/g, " ");
35706
35706
  }
35707
35707
  get(query) {
35708
- const key = this.normalize(query);
35709
- const entry = this.entries.get(key);
35708
+ const key2 = this.normalize(query);
35709
+ const entry = this.entries.get(key2);
35710
35710
  if (entry === void 0) return void 0;
35711
35711
  if (getTimeProvider().now() - entry.timestamp > this.ttlMs) {
35712
- this.entries.delete(key);
35712
+ this.entries.delete(key2);
35713
35713
  return void 0;
35714
35714
  }
35715
- this.entries.delete(key);
35716
- this.entries.set(key, entry);
35715
+ this.entries.delete(key2);
35716
+ this.entries.set(key2, entry);
35717
35717
  return entry.criteria;
35718
35718
  }
35719
35719
  set(query, criteria) {
35720
- const key = this.normalize(query);
35721
- this.entries.delete(key);
35720
+ const key2 = this.normalize(query);
35721
+ this.entries.delete(key2);
35722
35722
  if (this.entries.size >= this.maxEntries) {
35723
35723
  const oldest = this.entries.keys().next();
35724
35724
  if (oldest.done !== true) this.entries.delete(oldest.value);
35725
35725
  }
35726
- this.entries.set(key, { criteria, timestamp: getTimeProvider().now() });
35726
+ this.entries.set(key2, { criteria, timestamp: getTimeProvider().now() });
35727
35727
  }
35728
35728
  get size() {
35729
35729
  return this.entries.size;
@@ -37060,7 +37060,7 @@ var REASON_MAP = [
37060
37060
  ["needsExploration", "exploration/research task benefits from large context"]
37061
37061
  ];
37062
37062
  function buildReasons(requirements, pref, billingMode = "api", specialization = null, chosenCli) {
37063
- const reasons = REASON_MAP.filter(([key]) => requirements[key] === true).map(([, desc]) => desc);
37063
+ const reasons = REASON_MAP.filter(([key2]) => requirements[key2] === true).map(([, desc]) => desc);
37064
37064
  if (specialization !== null) {
37065
37065
  if (chosenCli !== void 0 && specialization.primaryCli !== chosenCli) {
37066
37066
  reasons.push(
@@ -38146,8 +38146,8 @@ function getSecuritySetupRegistry() {
38146
38146
  }
38147
38147
 
38148
38148
  // src/mcp/tools/run-graph-workflow-templates.ts
38149
- function stateStrings(state, key) {
38150
- const val = state[key];
38149
+ function stateStrings(state, key2) {
38150
+ const val = state[key2];
38151
38151
  return Array.isArray(val) ? val : [];
38152
38152
  }
38153
38153
  var WORKFLOW_METADATA = [
@@ -40211,8 +40211,8 @@ function failureResponse(focus, registry = "techniques") {
40211
40211
  function countByKey(items, keyFn) {
40212
40212
  const counts = {};
40213
40213
  for (const item of items) {
40214
- for (const key of keyFn(item)) {
40215
- counts[key] = (counts[key] ?? 0) + 1;
40214
+ for (const key2 of keyFn(item)) {
40215
+ counts[key2] = (counts[key2] ?? 0) + 1;
40216
40216
  }
40217
40217
  }
40218
40218
  return counts;
@@ -40387,8 +40387,8 @@ function countTechniqueStatuses(techniques, topic) {
40387
40387
  for (const tech of Object.values(techniques)) {
40388
40388
  if (topic !== void 0 && tech.topic !== topic) continue;
40389
40389
  counts.total++;
40390
- const key = statusMap[tech.status];
40391
- if (key !== void 0) counts[key]++;
40390
+ const key2 = statusMap[tech.status];
40391
+ if (key2 !== void 0) counts[key2]++;
40392
40392
  }
40393
40393
  return counts;
40394
40394
  }
@@ -41254,8 +41254,8 @@ function extractSections2(lines) {
41254
41254
  }
41255
41255
  function extractOverview(sections) {
41256
41256
  const keys = ["overview", "goal", "description", "summary"];
41257
- for (const key of keys) {
41258
- const content = sections.get(key);
41257
+ for (const key2 of keys) {
41258
+ const content = sections.get(key2);
41259
41259
  if (content !== void 0 && content.length > 0) {
41260
41260
  return joinNonEmpty(content);
41261
41261
  }
@@ -41266,8 +41266,8 @@ function extractOverview(sections) {
41266
41266
  }
41267
41267
  function extractListItems(sections, keys) {
41268
41268
  const items = [];
41269
- for (const key of keys) {
41270
- const content = sections.get(key);
41269
+ for (const key2 of keys) {
41270
+ const content = sections.get(key2);
41271
41271
  if (content === void 0) continue;
41272
41272
  for (const line of content) {
41273
41273
  const trimmed = line.trim();
@@ -42178,48 +42178,48 @@ var MemoryWriteInputSchema = z73.object({
42178
42178
  metadata: z73.record(z73.string().max(100), z73.string().max(500)).optional().describe("Optional key-value metadata tags"),
42179
42179
  sourceTrustTier: TrustTierSchema.optional().describe(SOURCE_TRUST_TIER_DESCRIPTION)
42180
42180
  });
42181
- function writeToSession(key, content, confidence, trustTier) {
42181
+ function writeToSession(key2, content, confidence, trustTier) {
42182
42182
  const toolMemory = getToolMemory();
42183
42183
  const numericConfidence = confidence === "high" ? 0.9 : confidence === "medium" ? 0.7 : 0.4;
42184
42184
  const outcome = toolMemory.recordLearning({
42185
42185
  pattern: content,
42186
- context: key,
42186
+ context: key2,
42187
42187
  confidence: numericConfidence,
42188
42188
  source: "memory_write_tool",
42189
42189
  ...trustTier !== void 0 ? { trustTier } : {}
42190
42190
  });
42191
42191
  if (!outcome.persisted) {
42192
- return { success: false, backend: "session", key, error: outcome.reason };
42192
+ return { success: false, backend: "session", key: key2, error: outcome.reason };
42193
42193
  }
42194
- return { success: true, backend: "session", key };
42194
+ return { success: true, backend: "session", key: key2 };
42195
42195
  }
42196
- async function writeToBelief(key, content, confidence, trustTier) {
42196
+ async function writeToBelief(key2, content, confidence, trustTier) {
42197
42197
  const toolMemory = getToolMemory();
42198
42198
  const countBefore = toolMemory.getBeliefCount();
42199
42199
  const outcome = await toolMemory.recordBelief(
42200
- key,
42200
+ key2,
42201
42201
  "has_knowledge",
42202
42202
  content,
42203
42203
  confidence,
42204
42204
  trustTier
42205
42205
  );
42206
42206
  if (!outcome.persisted) {
42207
- return { success: false, backend: "belief", key, error: outcome.reason };
42207
+ return { success: false, backend: "belief", key: key2, error: outcome.reason };
42208
42208
  }
42209
42209
  const deduplicated = toolMemory.getBeliefCount() === countBefore;
42210
- return { success: true, backend: "belief", key, ...deduplicated ? { deduplicated: true } : {} };
42210
+ return { success: true, backend: "belief", key: key2, ...deduplicated ? { deduplicated: true } : {} };
42211
42211
  }
42212
- async function writeToAgentic(key, content, confidence, metadata, trustTier) {
42212
+ async function writeToAgentic(key2, content, confidence, metadata, trustTier) {
42213
42213
  const toolMemory = getToolMemory();
42214
42214
  if (!toolMemory.isAgenticMemoryAvailable()) {
42215
42215
  return {
42216
42216
  success: false,
42217
42217
  backend: "agentic",
42218
- key,
42218
+ key: key2,
42219
42219
  error: "Agentic memory backend unavailable (requires SQLite)"
42220
42220
  };
42221
42221
  }
42222
- const outcome = await toolMemory.recordKnowledge(key, content, {
42222
+ const outcome = await toolMemory.recordKnowledge(key2, content, {
42223
42223
  importance: confidence,
42224
42224
  tags: [
42225
42225
  ...metadata !== void 0 ? Object.keys(metadata) : [],
@@ -42227,53 +42227,53 @@ async function writeToAgentic(key, content, confidence, metadata, trustTier) {
42227
42227
  ]
42228
42228
  });
42229
42229
  if (!outcome.persisted) {
42230
- return { success: false, backend: "agentic", key, error: outcome.reason };
42230
+ return { success: false, backend: "agentic", key: key2, error: outcome.reason };
42231
42231
  }
42232
- return { success: true, backend: "agentic", key };
42232
+ return { success: true, backend: "agentic", key: key2 };
42233
42233
  }
42234
- async function writeToAdaptive(key, content, confidence, trustTier) {
42234
+ async function writeToAdaptive(key2, content, confidence, trustTier) {
42235
42235
  const toolMemory = getToolMemory();
42236
42236
  if (!toolMemory.isAdaptiveMemoryAvailable()) {
42237
42237
  return {
42238
42238
  success: false,
42239
42239
  backend: "adaptive",
42240
- key,
42240
+ key: key2,
42241
42241
  error: "Adaptive memory backend unavailable (requires SQLite)"
42242
42242
  };
42243
42243
  }
42244
42244
  const importance = confidence === "high" ? 0.9 : confidence === "medium" ? 0.7 : 0.5;
42245
42245
  const outcome = await toolMemory.storeAdaptive(
42246
- key,
42246
+ key2,
42247
42247
  content,
42248
42248
  importance,
42249
42249
  trustTier
42250
42250
  );
42251
42251
  if (!outcome.persisted) {
42252
- return { success: false, backend: "adaptive", key, error: outcome.reason };
42252
+ return { success: false, backend: "adaptive", key: key2, error: outcome.reason };
42253
42253
  }
42254
- return { success: true, backend: "adaptive", key };
42254
+ return { success: true, backend: "adaptive", key: key2 };
42255
42255
  }
42256
- async function writeToTyped(key, content, confidence, trustTier) {
42256
+ async function writeToTyped(key2, content, confidence, trustTier) {
42257
42257
  const toolMemory = getToolMemory();
42258
42258
  if (!toolMemory.isTypedMemoryAvailable()) {
42259
42259
  return {
42260
42260
  success: false,
42261
42261
  backend: "typed",
42262
- key,
42262
+ key: key2,
42263
42263
  error: "Typed memory backend unavailable (requires SQLite)"
42264
42264
  };
42265
42265
  }
42266
42266
  const importance = confidence === "high" ? "high" : confidence === "medium" ? "medium" : "low";
42267
42267
  const outcome = await toolMemory.storeTyped(
42268
- key,
42268
+ key2,
42269
42269
  content,
42270
42270
  importance,
42271
42271
  trustTier
42272
42272
  );
42273
42273
  if (!outcome.persisted) {
42274
- return { success: false, backend: "typed", key, error: outcome.reason };
42274
+ return { success: false, backend: "typed", key: key2, error: outcome.reason };
42275
42275
  }
42276
- return { success: true, backend: "typed", key };
42276
+ return { success: true, backend: "typed", key: key2 };
42277
42277
  }
42278
42278
  var recentWriteKeys = /* @__PURE__ */ new Map();
42279
42279
  var MAX_DEDUP_CACHE = 200;
@@ -44572,12 +44572,12 @@ var FileAuditStorage = class _FileAuditStorage {
44572
44572
  const data = this.writeBuffer.join("");
44573
44573
  this.writeBuffer = [];
44574
44574
  const stream = this.writeStream;
44575
- return new Promise((resolve12, reject) => {
44575
+ return new Promise((resolve13, reject) => {
44576
44576
  stream.write(data, (err2) => {
44577
44577
  if (err2 !== void 0 && err2 !== null) {
44578
44578
  reject(new AuditError("Failed to flush audit log", { cause: err2 }));
44579
44579
  } else {
44580
- resolve12();
44580
+ resolve13();
44581
44581
  }
44582
44582
  });
44583
44583
  });
@@ -44638,15 +44638,15 @@ var FileAuditStorage = class _FileAuditStorage {
44638
44638
  }
44639
44639
  async close() {
44640
44640
  await this.flush();
44641
- return new Promise((resolve12) => {
44641
+ return new Promise((resolve13) => {
44642
44642
  if (this.writeStream === null) {
44643
- resolve12();
44643
+ resolve13();
44644
44644
  return;
44645
44645
  }
44646
44646
  this.writeStream.end(() => {
44647
44647
  this.writeStream = null;
44648
44648
  this.logger.info("Audit storage closed");
44649
- resolve12();
44649
+ resolve13();
44650
44650
  });
44651
44651
  });
44652
44652
  }
@@ -46077,8 +46077,8 @@ function buildError(templateId, error, startTime) {
46077
46077
  error
46078
46078
  };
46079
46079
  }
46080
- function extractStateValue(state, key) {
46081
- return state[key];
46080
+ function extractStateValue(state, key2) {
46081
+ return state[key2];
46082
46082
  }
46083
46083
 
46084
46084
  // src/pipeline/templates.ts
@@ -46682,7 +46682,7 @@ function buildVotingInput(plan, config) {
46682
46682
  }
46683
46683
  async function executeSingleVote(plan, config, log) {
46684
46684
  try {
46685
- const { executeVoting } = await import("./consensus-vote-BD5NWZU5.js");
46685
+ const { executeVoting } = await import("./consensus-vote-36TUM35R.js");
46686
46686
  const input = buildVotingInput(plan, config);
46687
46687
  const result = await executeVoting(input, log);
46688
46688
  return parseVotingResult(result);
@@ -46839,8 +46839,8 @@ async function recallPriorBeliefContext(bm, task, sessionId) {
46839
46839
  try {
46840
46840
  const records = [];
46841
46841
  const seen = /* @__PURE__ */ new Set();
46842
- for (const key of pipelineHindsightKeys(task, sessionId)) {
46843
- const result = await bm.getHindsightRecords(key);
46842
+ for (const key2 of pipelineHindsightKeys(task, sessionId)) {
46843
+ const result = await bm.getHindsightRecords(key2);
46844
46844
  if (!result.ok) continue;
46845
46845
  for (const rec of result.value) {
46846
46846
  if (seen.has(rec.hindsightId)) continue;
@@ -47192,7 +47192,7 @@ function execFileTree(command, args, options) {
47192
47192
  return Promise.reject(new AbortError(`${command} aborted before it started`));
47193
47193
  }
47194
47194
  const graceMs = options.graceMs ?? SIGKILL_GRACE_MS;
47195
- return new Promise((resolve12, reject) => {
47195
+ return new Promise((resolve13, reject) => {
47196
47196
  const run = {
47197
47197
  settled: false,
47198
47198
  child: void 0
@@ -47220,8 +47220,8 @@ function execFileTree(command, args, options) {
47220
47220
  signal?.addEventListener("abort", onAbort, { once: true });
47221
47221
  run.child = spawnTracked(command, args, options, (error, stdout, stderr) => {
47222
47222
  finish(() => {
47223
- if (error === null) resolve12({ stdout, stderr });
47224
- else reject(error);
47223
+ if (error === null) resolve13({ stdout, stderr });
47224
+ else reject(Object.assign(error, { stdout, stderr }));
47225
47225
  });
47226
47226
  });
47227
47227
  });
@@ -47628,6 +47628,7 @@ async function withDevPipelineWorkspace(stages, run, install = installDependenci
47628
47628
  const dependencies = await provisionDependencies(scratch.path, install, sandbox.wrapper);
47629
47629
  const bound = stages.withWorkspace({
47630
47630
  directory: join13(scratch.path, relative4(repoRoot, directory)),
47631
+ baseline: { sha: baseSha, directory: repoRoot },
47631
47632
  dependencies,
47632
47633
  wrapper: sandbox.wrapper
47633
47634
  });
@@ -47927,6 +47928,7 @@ async function runImplSecurityPhase(planResult, tasks, stages, run) {
47927
47928
  qaIterations: implResult.totalIterations,
47928
47929
  securityPassed: security.passed,
47929
47930
  securityRan: security.verdict !== "skip",
47931
+ ...security.comparison !== void 0 ? { securityComparison: security.comparison } : {},
47930
47932
  taskStatus,
47931
47933
  ...security.verdict === "skip" ? { securityNote: security.feedback } : {},
47932
47934
  ...warnings
@@ -48282,8 +48284,8 @@ function recordRoutingExperience(category, success, durationMs, tokensUsed = 0,
48282
48284
  // #3234: record the run's research-maturity (RECORD + measure; #3815 gates use).
48283
48285
  ...researchMaturity !== void 0 ? { researchMaturity } : {}
48284
48286
  };
48285
- const callRecord = (rm) => {
48286
- rm.recordExperience(category, ["claude"], success, metrics);
48287
+ const callRecord = (rm2) => {
48288
+ rm2.recordExperience(category, ["claude"], success, metrics);
48287
48289
  };
48288
48290
  if (routingMemoryCache !== null) {
48289
48291
  callRecord(routingMemoryCache);
@@ -48298,8 +48300,8 @@ function recordRoutingExperience(category, success, durationMs, tokensUsed = 0,
48298
48300
  logger44.debug("Routing memory init failed; continuing without it", { error: msg });
48299
48301
  return null;
48300
48302
  });
48301
- void routingMemoryInitPromise.then((rm) => {
48302
- if (rm !== null) callRecord(rm);
48303
+ void routingMemoryInitPromise.then((rm2) => {
48304
+ if (rm2 !== null) callRecord(rm2);
48303
48305
  });
48304
48306
  }
48305
48307
 
@@ -48377,6 +48379,14 @@ function accessModeSignals(args) {
48377
48379
  }
48378
48380
  return [];
48379
48381
  }
48382
+ function securityStageResult(result, passed) {
48383
+ return {
48384
+ passed,
48385
+ verdict: result.verdict,
48386
+ feedback: result.details,
48387
+ ...result.comparison !== void 0 ? { comparison: result.comparison } : {}
48388
+ };
48389
+ }
48380
48390
  function throwIfAborted2(signal, expertType) {
48381
48391
  if (signal?.aborted !== true) return;
48382
48392
  const reason = signal.reason;
@@ -48515,7 +48525,7 @@ function createVoteStage({ config, startStage }) {
48515
48525
  const strategy = config.votingStrategy ?? "higher_order";
48516
48526
  await postProgress(config, "Vote", `Running consensus with ${strategy} strategy...`);
48517
48527
  try {
48518
- const { executeVoting } = await import("./consensus-vote-BD5NWZU5.js");
48528
+ const { executeVoting } = await import("./consensus-vote-36TUM35R.js");
48519
48529
  const proposal = buildVoteProposal(plan, research);
48520
48530
  const votingResult = await executeVoting(
48521
48531
  {
@@ -48615,6 +48625,9 @@ Verdict: PASS/NEEDS_WORK/REJECT`;
48615
48625
  };
48616
48626
  }
48617
48627
 
48628
+ // src/mcp/tools/security-scan.ts
48629
+ import { z as z93 } from "zod";
48630
+
48618
48631
  // src/security/sarif-parser.ts
48619
48632
  import { z as z92 } from "zod";
48620
48633
  var SarifLocationSchema = z92.object({
@@ -48623,7 +48636,11 @@ var SarifLocationSchema = z92.object({
48623
48636
  region: z92.object({
48624
48637
  startLine: z92.number().optional().catch(void 0),
48625
48638
  endLine: z92.number().int().min(1).optional().catch(void 0),
48626
- snippet: z92.object({ text: z92.string().optional().catch(void 0) }).optional().catch(void 0)
48639
+ snippet: z92.object({
48640
+ text: z92.string().optional().catch(void 0),
48641
+ // Unknown truncation metadata cannot establish a complete snippet.
48642
+ truncated: z92.boolean().optional().catch(true)
48643
+ }).optional().catch(void 0)
48627
48644
  }).optional()
48628
48645
  }).optional()
48629
48646
  });
@@ -48654,7 +48671,18 @@ var SarifRunSchema = z92.object({
48654
48671
  rules: z92.array(z92.unknown()).optional()
48655
48672
  }).optional()
48656
48673
  }).optional(),
48657
- results: z92.array(z92.unknown()).nullish()
48674
+ results: z92.array(z92.unknown()).nullish(),
48675
+ invocations: z92.array(z92.unknown()).optional()
48676
+ });
48677
+ var SarifNotificationSchema = z92.object({
48678
+ descriptor: z92.object({ id: z92.string().optional() }).optional(),
48679
+ level: z92.string().optional(),
48680
+ message: z92.object({ text: z92.string().optional() }).optional()
48681
+ });
48682
+ var SarifInvocationSchema = z92.object({
48683
+ executionSuccessful: z92.boolean().optional(),
48684
+ toolExecutionNotifications: z92.array(SarifNotificationSchema).optional(),
48685
+ toolConfigurationNotifications: z92.array(SarifNotificationSchema).optional()
48658
48686
  });
48659
48687
  var SarifLogSchema = z92.object({
48660
48688
  version: z92.string().optional(),
@@ -48685,7 +48713,7 @@ function parseSarif(sarifJson, maxFindings = 100) {
48685
48713
  const errors = [];
48686
48714
  const envelope = parseEnvelope(sarifJson);
48687
48715
  if (!envelope.ok) {
48688
- return { scanner: "unknown", totalFindings: 0, findings: [], errors: [envelope.error] };
48716
+ return emptyResult(envelope.error);
48689
48717
  }
48690
48718
  return parseLog(envelope.log, maxFindings, errors);
48691
48719
  }
@@ -48694,25 +48722,91 @@ function describeDriver(run) {
48694
48722
  return { scanner: driver?.name ?? "unknown", rules: driver?.rules ?? [] };
48695
48723
  }
48696
48724
  function emptyResult(error) {
48697
- return { scanner: "unknown", totalFindings: 0, findings: [], errors: [error] };
48725
+ return {
48726
+ scanner: "unknown",
48727
+ totalFindings: 0,
48728
+ findings: [],
48729
+ errors: [error],
48730
+ coverageComplete: false
48731
+ };
48698
48732
  }
48699
48733
  function parseLog(log, maxFindings, errors) {
48700
48734
  const runs = log.runs;
48701
48735
  if (runs === void 0 || runs.length === 0) return emptyResult("No runs in SARIF");
48702
- const parsedRun = SarifRunSchema.safeParse(runs[0]);
48703
- if (!parsedRun.success) {
48704
- return emptyResult(`Malformed SARIF run: ${describeZodError(parsedRun.error)}`);
48736
+ let scanner = "unknown";
48737
+ const parseDiagnostics = [];
48738
+ const findings = [];
48739
+ for (const [index, raw] of runs.entries()) {
48740
+ const parsedRun = SarifRunSchema.safeParse(raw);
48741
+ if (!parsedRun.success) {
48742
+ errors.push(`Malformed SARIF run ${String(index)}: ${describeZodError(parsedRun.error)}`);
48743
+ continue;
48744
+ }
48745
+ const driver = describeDriver(parsedRun.data);
48746
+ checkRunCoverage(parsedRun.data, errors);
48747
+ if (index === 0) scanner = driver.scanner;
48748
+ checkInvocations(parsedRun.data.invocations ?? [], errors, parseDiagnostics);
48749
+ const ruleMap = buildRuleMap(driver.rules, errors);
48750
+ findings.push(
48751
+ ...collectFindings(parsedRun.data.results ?? [], driver.scanner, ruleMap, errors)
48752
+ );
48753
+ }
48754
+ findings.sort((a, b) => SEVERITY_ORDER[a.severity] - SEVERITY_ORDER[b.severity]);
48755
+ if (findings.length > maxFindings) {
48756
+ errors.push(
48757
+ `Truncated findings: returned ${String(maxFindings)} of ${String(findings.length)}`
48758
+ );
48705
48759
  }
48706
- const { scanner, rules } = describeDriver(parsedRun.data);
48707
- const ruleMap = buildRuleMap(rules, errors);
48708
- const findings = collectFindings(parsedRun.data.results ?? [], scanner, ruleMap, errors);
48709
48760
  return {
48710
48761
  scanner,
48711
48762
  totalFindings: findings.length,
48712
48763
  findings: findings.slice(0, maxFindings),
48713
- errors
48764
+ errors,
48765
+ coverageComplete: errors.length === 0,
48766
+ ...parseDiagnostics.length > 0 ? { parseDiagnostics } : {}
48714
48767
  };
48715
48768
  }
48769
+ function checkRunCoverage(run, errors) {
48770
+ if (run.tool?.driver?.name === void 0 || run.tool.driver.name.length === 0) {
48771
+ errors.push("SARIF run missing scanner identity");
48772
+ }
48773
+ if (run.results === void 0 || run.results === null) {
48774
+ errors.push("SARIF run missing measured results");
48775
+ }
48776
+ }
48777
+ function checkInvocations(invocations, errors, parseDiagnostics) {
48778
+ for (const raw of invocations) {
48779
+ const parsed = SarifInvocationSchema.safeParse(raw);
48780
+ if (!parsed.success) {
48781
+ errors.push(`Malformed SARIF invocation: ${describeZodError(parsed.error)}`);
48782
+ continue;
48783
+ }
48784
+ if (parsed.data.executionSuccessful === false) errors.push("Scanner invocation failed");
48785
+ const notifications = [
48786
+ ...parsed.data.toolExecutionNotifications ?? [],
48787
+ ...parsed.data.toolConfigurationNotifications ?? []
48788
+ ];
48789
+ checkNotifications(notifications, errors, parseDiagnostics);
48790
+ }
48791
+ }
48792
+ function checkNotifications(notifications, errors, parseDiagnostics) {
48793
+ for (const notification of notifications ?? []) {
48794
+ const diagnostic = parseNotification(notification);
48795
+ if (diagnostic !== void 0) parseDiagnostics.push(diagnostic);
48796
+ else if (notification.level !== "note" && notification.level !== "none")
48797
+ errors.push(`Scanner notification: ${notification.message?.text ?? "unknown scanner error"}`);
48798
+ }
48799
+ }
48800
+ function parseNotification(notification) {
48801
+ if (!/^(?:Syntax error|Other syntax error)$/.test(notification.descriptor?.id ?? ""))
48802
+ return void 0;
48803
+ const message = notification.message?.text;
48804
+ if (message === void 0) return void 0;
48805
+ const file = /^(?:Syntax error|Other syntax error) at line (.+):(\d+):(?:\n|$| )/.exec(
48806
+ message
48807
+ )?.[1];
48808
+ return file === void 0 ? void 0 : { file, kind: "parse", message };
48809
+ }
48716
48810
  function collectFindings(results, scanner, ruleMap, errors) {
48717
48811
  const findings = [];
48718
48812
  for (const [index, raw] of results.entries()) {
@@ -48751,7 +48845,8 @@ function buildLocation(file, startLine, phys) {
48751
48845
  const endLine = phys.region?.endLine;
48752
48846
  const snippetText = phys.region?.snippet?.text;
48753
48847
  if (endLine !== void 0) loc.endLine = endLine;
48754
- if (snippetText !== void 0) loc.snippet = snippetText.slice(0, 500);
48848
+ if (snippetText !== void 0) loc.snippet = snippetText;
48849
+ if (phys.region?.snippet?.truncated === true) loc.snippetTruncated = true;
48755
48850
  return loc;
48756
48851
  }
48757
48852
  function extractLocation(result, ruleId, errors) {
@@ -48807,6 +48902,7 @@ function parseResult(result, scanner, ruleMap, errors) {
48807
48902
  cweIds: extractCweIds(rule),
48808
48903
  confidence: resolveConfidence(rule),
48809
48904
  snippet: loc.snippet,
48905
+ snippetTruncated: loc.snippetTruncated,
48810
48906
  helpUrl: rule?.helpUri
48811
48907
  };
48812
48908
  }
@@ -48857,25 +48953,46 @@ function resolveConfidence(rule) {
48857
48953
  }
48858
48954
 
48859
48955
  // src/mcp/tools/security-scan.ts
48956
+ import { access, constants as constants2 } from "node:fs/promises";
48957
+ import { readFile as readFile5, realpath as realpath2, writeFile as writeFile2 } from "node:fs/promises";
48958
+ import { delimiter as delimiter2, isAbsolute as isAbsolute6, join as join14, parse as parse4, resolve as resolve8 } from "node:path";
48860
48959
  var logger47 = createLogger({ component: "security-scan" });
48861
48960
  var SCAN_TIMEOUT_MS = 3e5;
48862
- async function isSemgrepAvailable(signal, env, wrapper) {
48961
+ async function isSemgrepAvailable(signal, env, wrapper, binary = "semgrep", cwd) {
48863
48962
  try {
48864
- await execFileTree("semgrep", ["--version"], { timeoutMs: 1e4, signal, env, wrapper });
48865
- return true;
48963
+ const { stdout } = await execFileTree(binary, ["--version"], {
48964
+ timeoutMs: 1e4,
48965
+ signal,
48966
+ env,
48967
+ wrapper,
48968
+ cwd
48969
+ });
48970
+ return stdout.trim() || void 0;
48866
48971
  } catch {
48867
- return false;
48972
+ return void 0;
48868
48973
  }
48869
48974
  }
48870
- async function runSemgrep(targetDir, rulesets, signal, env, wrapper) {
48871
- const args = ["--sarif", "--quiet", ...rulesets.flatMap((r) => ["--config", r]), targetDir];
48872
- const { stdout } = await execFileTree("semgrep", args, {
48975
+ async function runSemgrep(targetDir, rulesets, signal, env, options) {
48976
+ const prepared = options.preparedScan;
48977
+ const flags = prepared?.flags ?? (options.completeResults === true ? COMPLETE_SCAN_FLAGS : []);
48978
+ const configs = prepared?.rulesets ?? rulesets.map(
48979
+ (ruleset) => /^(?:[pr]\/|https?:\/\/|auto$)/.test(ruleset) ? ruleset : resolve8(ruleset)
48980
+ );
48981
+ const args = [
48982
+ "--sarif",
48983
+ "--quiet",
48984
+ ...flags,
48985
+ ...configs.flatMap((r) => ["--config", r]),
48986
+ targetDir
48987
+ ];
48988
+ const { stdout } = await execFileTree(prepared?.binary ?? "semgrep", args, {
48989
+ cwd: parse4(targetDir).root,
48873
48990
  timeoutMs: SCAN_TIMEOUT_MS,
48874
48991
  maxBuffer: 10 * 1024 * 1024,
48875
48992
  // 10MB for large SARIF output
48876
48993
  signal,
48877
48994
  env,
48878
- wrapper
48995
+ wrapper: options.wrapper
48879
48996
  });
48880
48997
  return stdout;
48881
48998
  }
@@ -48886,6 +49003,105 @@ function validateTargetPath(target, root = process.cwd()) {
48886
49003
  }
48887
49004
  return resolved;
48888
49005
  }
49006
+ var COMPLETE_SCAN_FLAGS = [
49007
+ "--no-git-ignore",
49008
+ "--max-target-bytes=0",
49009
+ "--metrics=off",
49010
+ "--disable-nosem",
49011
+ "--no-rewrite-rule-ids",
49012
+ // Avoid mutable ignore files and hidden-ancestor skips in scratch worktrees.
49013
+ // Unsupported scanner versions fail closed on this explicitly pinned flag.
49014
+ "--x-ignore-semgrepignore-files",
49015
+ "--exclude=node_modules",
49016
+ "--exclude=.git"
49017
+ ];
49018
+ async function resolveSemgrep(env) {
49019
+ for (const directory of (env["PATH"] ?? "").split(delimiter2)) {
49020
+ if (!isAbsolute6(directory)) continue;
49021
+ const binary = join14(directory, process.platform === "win32" ? "semgrep.exe" : "semgrep");
49022
+ try {
49023
+ await access(binary, constants2.X_OK);
49024
+ return await realpath2(binary);
49025
+ } catch {
49026
+ }
49027
+ }
49028
+ throw new Error("semgrep is not installed. Install with: pip install semgrep");
49029
+ }
49030
+ async function readRuleset(ruleset, signal) {
49031
+ const url = /^[pr]\//.test(ruleset) ? `https://semgrep.dev/c/${ruleset}` : ruleset;
49032
+ if (!/^https?:\/\//.test(url)) return await readFile5(resolve8(ruleset), "utf8");
49033
+ const timeout = AbortSignal.timeout(3e4);
49034
+ const response = await fetch(url, {
49035
+ headers: { Accept: "application/json" },
49036
+ signal: signal === void 0 ? timeout : AbortSignal.any([signal, timeout])
49037
+ });
49038
+ if (!response.ok) throw new Error(`Ruleset download failed: HTTP ${String(response.status)}`);
49039
+ const text = await response.text();
49040
+ if (text.length > 10 * 1024 * 1024) throw new Error("Ruleset download exceeds 10MB");
49041
+ return unwrapRuleset(text);
49042
+ }
49043
+ function unwrapRuleset(text) {
49044
+ let raw;
49045
+ try {
49046
+ raw = JSON.parse(text);
49047
+ } catch {
49048
+ return text;
49049
+ }
49050
+ if (typeof raw === "object" && raw !== null && "rule_config" in raw) {
49051
+ const config = raw.rule_config;
49052
+ return typeof config === "string" ? config : JSON.stringify(config);
49053
+ }
49054
+ return text;
49055
+ }
49056
+ async function measureScannerVersion(options, targetDir) {
49057
+ const version = await isSemgrepAvailable(
49058
+ options.signal,
49059
+ options.env,
49060
+ options.wrapper,
49061
+ options.preparedScan?.binary,
49062
+ parse4(targetDir).root
49063
+ );
49064
+ if (options.signal?.aborted === true) return { error: "Scan aborted before semgrep ran" };
49065
+ if (version === void 0)
49066
+ return { error: "semgrep is not installed. Install with: pip install semgrep" };
49067
+ if (options.preparedScan !== void 0 && options.preparedScan.version !== version) {
49068
+ return {
49069
+ error: `Scanner version changed: expected ${options.preparedScan.version}, got ${version}`
49070
+ };
49071
+ }
49072
+ return version;
49073
+ }
49074
+ async function prepareSecurityScan(rulesets, options) {
49075
+ try {
49076
+ if (rulesets.length === 0) throw new Error("No security rulesets configured");
49077
+ const binary = await resolveSemgrep(options.env ?? process.env);
49078
+ const version = await isSemgrepAvailable(
49079
+ options.signal,
49080
+ options.env,
49081
+ options.wrapper,
49082
+ binary,
49083
+ parse4(resolve8(options.directory)).root
49084
+ );
49085
+ if (version === void 0) throw new Error("Cannot measure semgrep version");
49086
+ const configs = [];
49087
+ for (const [index, ruleset] of rulesets.entries()) {
49088
+ const contents = await readRuleset(ruleset, options.signal);
49089
+ const file = join14(options.directory, `security-rules-${String(index)}.yaml`);
49090
+ await writeFile2(file, contents, { mode: 256, flag: "wx" });
49091
+ configs.push(file);
49092
+ }
49093
+ return Object.freeze({
49094
+ binary,
49095
+ version,
49096
+ rulesets: Object.freeze(configs),
49097
+ flags: COMPLETE_SCAN_FLAGS
49098
+ });
49099
+ } catch (error) {
49100
+ return {
49101
+ error: `Security scan preparation failed: ${error instanceof Error ? error.message : String(error)}`
49102
+ };
49103
+ }
49104
+ }
48889
49105
  async function executeSecurityScan(input, options = {}) {
48890
49106
  const { signal, env } = options;
48891
49107
  let targetDir;
@@ -48899,42 +49115,104 @@ async function executeSecurityScan(input, options = {}) {
48899
49115
  scanner: input.scanner,
48900
49116
  rulesets: input.rulesets
48901
49117
  });
48902
- const available = await isSemgrepAvailable(signal, env, options.wrapper);
48903
- if (signal?.aborted === true) return { error: "Scan aborted before semgrep ran" };
48904
- if (!available) {
48905
- return {
48906
- error: "semgrep is not installed. Install with: pip install semgrep"
48907
- };
48908
- }
49118
+ const version = await measureScannerVersion(options, targetDir);
49119
+ if (typeof version !== "string") return version;
48909
49120
  try {
48910
- const sarifOutput = await runSemgrep(targetDir, input.rulesets, signal, env, options.wrapper);
48911
- const result = parseSarif(sarifOutput, input.maxFindings);
49121
+ const sarifOutput = await runSemgrep(targetDir, input.rulesets, signal, env, options);
49122
+ const result = parseSarif(
49123
+ sarifOutput,
49124
+ options.completeResults === true ? Infinity : input.maxFindings
49125
+ );
48912
49126
  logger47.info("Security scan completed", {
48913
49127
  scanner: result.scanner,
48914
49128
  findings: result.totalFindings,
48915
49129
  errors: result.errors.length
48916
49130
  });
48917
- return result;
49131
+ return { ...result, scannerVersion: version };
48918
49132
  } catch (error) {
48919
- const msg = error instanceof Error ? error.message : String(error);
48920
- logger47.warn("Security scan failed", { error: msg });
48921
- return { error: `Scan failed: ${msg.slice(0, 500)}` };
49133
+ return handleScanFailure(
49134
+ error,
49135
+ version,
49136
+ options.completeResults === true ? Infinity : input.maxFindings
49137
+ );
48922
49138
  }
48923
49139
  }
49140
+ var InvocationSuccessSchema = z93.object({
49141
+ runs: z93.array(
49142
+ z93.object({
49143
+ invocations: z93.array(z93.object({ executionSuccessful: z93.literal(true) })).min(1)
49144
+ })
49145
+ ).min(1)
49146
+ });
49147
+ function failureCode(error) {
49148
+ return typeof error === "object" && error !== null && "code" in error ? error.code : "unknown";
49149
+ }
49150
+ function failureOutput(error) {
49151
+ if (typeof error !== "object" || error === null || !("stdout" in error)) return void 0;
49152
+ return typeof error.stdout === "string" && error.stdout.length > 0 ? error.stdout : void 0;
49153
+ }
49154
+ function scannerInvocationsSuccessful(output2) {
49155
+ try {
49156
+ return InvocationSuccessSchema.safeParse(JSON.parse(output2)).success;
49157
+ } catch {
49158
+ return false;
49159
+ }
49160
+ }
49161
+ function handleScanFailure(error, version, maxFindings) {
49162
+ const output2 = failureOutput(error);
49163
+ const result = output2 === void 0 ? void 0 : parseSarif(output2, maxFindings);
49164
+ if (result !== void 0 && output2 !== void 0 && failureCode(error) === 3) {
49165
+ if (result.coverageComplete === true && (result.parseDiagnostics?.length ?? 0) > 0 && scannerInvocationsSuccessful(output2)) {
49166
+ return { ...result, scannerVersion: version };
49167
+ }
49168
+ }
49169
+ const message = `${summarizeScanFailure(error)}${failedOutputDetails(result)}`;
49170
+ logger47.warn("Security scan failed", { error: message });
49171
+ return { error: message };
49172
+ }
49173
+ function failedOutputDetails(result) {
49174
+ if (result === void 0) return "";
49175
+ const files = result.parseDiagnostics?.map((diagnostic) => diagnostic.file) ?? [];
49176
+ const diagnostics = files.length > 0 ? `; affected files: ${[...new Set(files)].join(", ")}` : "";
49177
+ const errors = result.errors.length > 0 ? `; ${result.errors.join("; ")}` : "";
49178
+ return diagnostics + errors;
49179
+ }
49180
+ function summarizeScanFailure(error) {
49181
+ const code = String(failureCode(error));
49182
+ const message = error instanceof Error ? error.message : String(error);
49183
+ const commandFailure = message.startsWith("Command failed:");
49184
+ const newline = message.indexOf("\n");
49185
+ const rawDiagnostic = commandFailure && newline >= 0 ? message.slice(newline + 1) : message;
49186
+ const diagnostic = rawDiagnostic.split("\n").filter((line) => !isScannerNoise(line)).join("\n");
49187
+ const detail = diagnostic.length > 500 ? `[diagnostic truncated] ${diagnostic.slice(-500)}` : diagnostic;
49188
+ const files = [
49189
+ ...new Set(
49190
+ [...diagnostic.matchAll(/^(?:Syntax error|Other syntax error) at line (.+):\d+:/gm)].map(
49191
+ (match) => match[1]
49192
+ )
49193
+ )
49194
+ ];
49195
+ const affected = files.length > 0 ? `; affected files: ${files.join(", ")}` : "";
49196
+ const unavailable = commandFailure && failureOutput(error) === void 0 ? "; scanner stdout unavailable" : "";
49197
+ return `Scan failed (exit ${code}${unavailable}${affected}): ${detail}`;
49198
+ }
49199
+ function isScannerNoise(line) {
49200
+ return /opentelemetry\/instrumentation\/dependencies\.py.*UserWarning: pkg_resources/.test(line) || /^\s*from pkg_resources import \(/.test(line) || /^pyenv: (?:cannot rehash|warning:)/.test(line) || /^.*WARNING.*(?:experimental|--x-).*$/i.test(line) || /^.*These options are not part of the semgrep API.*$/.test(line);
49201
+ }
48924
49202
 
48925
49203
  // src/security/osv-lookup.ts
48926
- import { z as z93 } from "zod";
49204
+ import { z as z94 } from "zod";
48927
49205
  var logger48 = createLogger({ component: "osv-lookup" });
48928
49206
  var OSV_API_URL = "https://api.osv.dev/v1/query";
48929
49207
  var DEFAULT_TIMEOUT_MS4 = NETWORK_FETCH_TIMEOUT_MS;
48930
- var OsvVulnerabilitySchema = z93.object({
48931
- id: z93.string(),
48932
- summary: z93.string().optional(),
48933
- severity: z93.enum(["CRITICAL", "HIGH", "MODERATE", "LOW", "UNKNOWN"]).optional(),
48934
- aliases: z93.array(z93.string()).default([]),
48935
- affectedVersions: z93.string().optional(),
48936
- fixedVersion: z93.string().optional(),
48937
- url: z93.string().optional()
49208
+ var OsvVulnerabilitySchema = z94.object({
49209
+ id: z94.string(),
49210
+ summary: z94.string().optional(),
49211
+ severity: z94.enum(["CRITICAL", "HIGH", "MODERATE", "LOW", "UNKNOWN"]).optional(),
49212
+ aliases: z94.array(z94.string()).default([]),
49213
+ affectedVersions: z94.string().optional(),
49214
+ fixedVersion: z94.string().optional(),
49215
+ url: z94.string().optional()
48938
49216
  });
48939
49217
  var DEFAULT_OSV_CONFIG = {
48940
49218
  timeoutMs: DEFAULT_TIMEOUT_MS4
@@ -49026,11 +49304,343 @@ async function queryOsvBatch(packages, config = DEFAULT_OSV_CONFIG, signal) {
49026
49304
  return results;
49027
49305
  }
49028
49306
 
49307
+ // src/pipeline/security-baseline.ts
49308
+ import { createHash as createHash4 } from "node:crypto";
49309
+ import { mkdtemp, rm, readFile as readFile7, readlink } from "node:fs/promises";
49310
+ import { tmpdir as tmpdir2 } from "node:os";
49311
+ import { isAbsolute as isAbsolute8, join as join16 } from "node:path";
49312
+
49313
+ // src/pipeline/security-baseline-coverage.ts
49314
+ import { readFile as readFile6 } from "node:fs/promises";
49315
+ import { isAbsolute as isAbsolute7, join as join15, relative as relative6 } from "node:path";
49316
+ function scanErrors(scan, side) {
49317
+ if ("error" in scan) return [`${side}: ${scan.error}`];
49318
+ const errors = scan.errors.map((error) => `${side}: ${error}`);
49319
+ if (scan.coverageComplete !== true || scan.totalFindings !== scan.findings.length)
49320
+ errors.push(`${side}: scan coverage is incomplete`);
49321
+ for (const finding of scan.findings) {
49322
+ if (isAbsolute7(finding.file) || finding.file.split("/").includes("..") || /^[a-z]+:/i.test(finding.file))
49323
+ errors.push(`${side}: finding path outside scanned tree: ${finding.file}`);
49324
+ if (ambiguousSnippet(finding))
49325
+ errors.push(
49326
+ `${side}: missing or truncated snippet: ${finding.rule} ${finding.file}:${String(finding.startLine)}`
49327
+ );
49328
+ }
49329
+ return errors;
49330
+ }
49331
+ function normalizedScan(scan, directory) {
49332
+ if ("error" in scan) return scan;
49333
+ return {
49334
+ ...scan,
49335
+ parseDiagnostics: (scan.parseDiagnostics ?? []).map((diagnostic) => ({
49336
+ ...diagnostic,
49337
+ file: isAbsolute7(diagnostic.file) ? relative6(directory, diagnostic.file) : diagnostic.file.replace(/^\.\//, ""),
49338
+ message: diagnostic.message.split(join15(directory, "/")).join("")
49339
+ })),
49340
+ findings: scan.findings.map((finding) => ({
49341
+ ...finding,
49342
+ file: isAbsolute7(finding.file) ? relative6(directory, finding.file) : finding.file.replace(/^\.\//, "")
49343
+ }))
49344
+ };
49345
+ }
49346
+ function ambiguousSnippet(finding) {
49347
+ return finding.snippet === void 0 || finding.snippet.trim() === "" || finding.snippetTruncated === true;
49348
+ }
49349
+ async function compareParseCoverage(input) {
49350
+ const base = input.base.parseDiagnostics ?? [];
49351
+ const worktree = input.worktree.parseDiagnostics ?? [];
49352
+ const files = [...new Set([...base, ...worktree].map((diagnostic) => diagnostic.file))].sort();
49353
+ const errors = [];
49354
+ const unscannedCoverage = [];
49355
+ for (const file of files) {
49356
+ if (outsideTree(file)) {
49357
+ errors.push(`Parse diagnostic path outside scanned tree: ${file}`);
49358
+ continue;
49359
+ }
49360
+ const identities = (diagnostics) => JSON.stringify(
49361
+ diagnostics.filter((d) => d.file === file).map(({ kind, message }) => JSON.stringify([kind, message])).sort()
49362
+ );
49363
+ if (identities(base) !== identities(worktree)) {
49364
+ errors.push(`New or changed parse diagnostics: ${file}`);
49365
+ continue;
49366
+ }
49367
+ try {
49368
+ const [oldBytes, newBytes, diff] = await Promise.all([
49369
+ readFile6(join15(input.baseDirectory, file)),
49370
+ readFile6(join15(input.target, file)),
49371
+ input.diff(file)
49372
+ ]);
49373
+ if (!oldBytes.equals(newBytes) || diff !== "") {
49374
+ errors.push(`Change touches partially parsed file: ${file}`);
49375
+ } else unscannedCoverage.push(file);
49376
+ } catch (error) {
49377
+ errors.push(
49378
+ `Cannot verify partially parsed file ${file}: ${error instanceof Error ? error.message : String(error)}`
49379
+ );
49380
+ }
49381
+ }
49382
+ return { errors, unscannedCoverage };
49383
+ }
49384
+ function outsideTree(file) {
49385
+ return isAbsolute7(file) || file.split("/").includes("..") || /^[a-z]+:/i.test(file);
49386
+ }
49387
+
49388
+ // src/pipeline/security-baseline.ts
49389
+ var blocking = (finding) => finding.severity === "critical" || finding.severity === "high";
49390
+ function key(finding) {
49391
+ return JSON.stringify([finding.rule, finding.file, finding.snippet?.replace(/\s+/g, " ").trim()]);
49392
+ }
49393
+ function preservedLine(finding, diff) {
49394
+ let offset = 0;
49395
+ for (const match of diff.matchAll(/^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/gm)) {
49396
+ const oldStart = Number(match[1]);
49397
+ const oldCount = Number(match[2] ?? 1);
49398
+ const newCount = Number(match[4] ?? 1);
49399
+ const oldEnd = oldStart + oldCount - 1;
49400
+ if (oldCount > 0 && finding.startLine <= oldEnd && (finding.endLine ?? finding.startLine) >= oldStart)
49401
+ return void 0;
49402
+ if ((oldCount === 0 ? oldStart : oldEnd) < finding.startLine) offset += newCount - oldCount;
49403
+ }
49404
+ return finding.startLine + offset;
49405
+ }
49406
+ async function introducedFindings(base, worktree, git2, target, sha) {
49407
+ const diffs = /* @__PURE__ */ new Map();
49408
+ for (const file of new Set(base.map((finding) => finding.file))) {
49409
+ if (isAbsolute8(file) || file.split("/").includes(".."))
49410
+ throw new Error("Finding path outside scanned tree");
49411
+ diffs.set(
49412
+ file,
49413
+ await git2(target, [
49414
+ "diff",
49415
+ "--text",
49416
+ "--no-color",
49417
+ "--no-ext-diff",
49418
+ "--no-textconv",
49419
+ "--no-renames",
49420
+ "--unified=0",
49421
+ sha,
49422
+ "--",
49423
+ file
49424
+ ])
49425
+ );
49426
+ }
49427
+ const remaining = [...base];
49428
+ const result = [];
49429
+ for (const finding of worktree) {
49430
+ const index = remaining.findIndex(
49431
+ (old) => key(old) === key(finding) && preservedLine(old, diffs.get(old.file) ?? "") === finding.startLine && SEVERITY_ORDER[finding.severity] >= SEVERITY_ORDER[old.severity]
49432
+ );
49433
+ if (index >= 0) remaining.splice(index, 1);
49434
+ else if (blocking(finding) || remaining.some(
49435
+ (old) => key(old) === key(finding) && SEVERITY_ORDER[finding.severity] < SEVERITY_ORDER[old.severity]
49436
+ ))
49437
+ result.push(finding);
49438
+ }
49439
+ return result;
49440
+ }
49441
+ async function compareSecurityBaseline(target, rulesets, config, signal) {
49442
+ const baseline = config.baseline;
49443
+ if (baseline === void 0) throw new Error("Security baseline required");
49444
+ let directory;
49445
+ let base = { error: "base scan did not run" };
49446
+ let worktree = { error: "worktree scan did not run" };
49447
+ let sha = baseline.sha;
49448
+ const execOptions = comparisonExecOptions(config, signal);
49449
+ const git2 = comparisonGit(execOptions);
49450
+ try {
49451
+ sha = (await git2(baseline.directory, ["rev-parse", "--verify", `${baseline.sha}^{commit}`])).trim();
49452
+ if (!/^[a-f0-9]{40,64}$/.test(sha)) throw new Error("Base did not resolve to a commit SHA");
49453
+ directory = await allocateComparisonDirectory(config, execOptions);
49454
+ const archive = await archiveBaseline({ target, directory, baseline, sha, git: git2, execOptions });
49455
+ ({ base, worktree } = await scanTrees({
49456
+ target,
49457
+ rulesets,
49458
+ config,
49459
+ signal,
49460
+ directory,
49461
+ archive
49462
+ }));
49463
+ throwIfAborted(signal, "Security baseline scan aborted");
49464
+ return await assessComparison({
49465
+ sha,
49466
+ base,
49467
+ worktree,
49468
+ git: git2,
49469
+ target,
49470
+ baseDirectory: archive.target
49471
+ });
49472
+ } catch (error) {
49473
+ throwIfAborted(signal, "Security baseline scan aborted");
49474
+ return incomplete(sha, base, worktree, [
49475
+ error instanceof Error ? error.message : String(error)
49476
+ ]);
49477
+ } finally {
49478
+ if (directory !== void 0) await rm(directory, { recursive: true, force: true });
49479
+ }
49480
+ }
49481
+ function incomplete(sha, base, worktree, errors, unscannedCoverage = []) {
49482
+ return {
49483
+ baseSha: sha,
49484
+ baseCount: "error" in base ? null : base.totalFindings,
49485
+ worktreeCount: "error" in worktree ? null : worktree.totalFindings,
49486
+ introducedBlockingCount: null,
49487
+ blockingFindings: [],
49488
+ unscannedCoverage,
49489
+ ...scannerVersion(base, worktree),
49490
+ complete: false,
49491
+ errors
49492
+ };
49493
+ }
49494
+ async function allocateComparisonDirectory(config, options) {
49495
+ if (config.wrapper === void 0) return mkdtemp(join16(tmpdir2(), "security-baseline-"));
49496
+ const path9 = (await execFileTree("mktemp", ["-d"], options)).stdout.trim();
49497
+ if (!isAbsolute8(path9)) throw new Error("Sandbox did not allocate a comparison directory");
49498
+ return path9;
49499
+ }
49500
+ async function assessComparison(input) {
49501
+ const { sha, base, worktree, git: git2, target } = input;
49502
+ const errors = [...scanErrors(base, "base"), ...scanErrors(worktree, "worktree")];
49503
+ if ("error" in base || "error" in worktree) return incomplete(sha, base, worktree, errors);
49504
+ const coverage = await compareParseCoverage({
49505
+ base,
49506
+ worktree,
49507
+ baseDirectory: input.baseDirectory,
49508
+ target,
49509
+ diff: async (file) => git2(target, [
49510
+ "diff",
49511
+ "--text",
49512
+ "--no-color",
49513
+ "--no-ext-diff",
49514
+ "--no-textconv",
49515
+ "--no-renames",
49516
+ "--unified=0",
49517
+ sha,
49518
+ "--",
49519
+ file
49520
+ ])
49521
+ });
49522
+ errors.push(...coverage.errors);
49523
+ if (errors.length > 0) return incomplete(sha, base, worktree, errors, coverage.unscannedCoverage);
49524
+ const findings = await introducedFindings(base.findings, worktree.findings, git2, target, sha);
49525
+ return {
49526
+ baseSha: sha,
49527
+ baseCount: base.totalFindings,
49528
+ worktreeCount: worktree.totalFindings,
49529
+ introducedBlockingCount: findings.length,
49530
+ blockingFindings: actionableFindings(findings),
49531
+ complete: true,
49532
+ errors: [],
49533
+ unscannedCoverage: coverage.unscannedCoverage,
49534
+ ...scannerVersion(base, worktree)
49535
+ };
49536
+ }
49537
+ async function verifyArchive(directory, tree) {
49538
+ if (tree === "") return;
49539
+ for (const entry of tree.split("\0").filter((record) => record !== "")) {
49540
+ const { mode, hash, file } = parseTreeEntry(entry);
49541
+ const contents = mode === "120000" ? Buffer.from(await readlink(join16(directory, file))) : await readFile7(join16(directory, file));
49542
+ const digest = createHash4(hash.length === 64 ? "sha256" : "sha1").update(`blob ${String(contents.length)}\0`).update(contents).digest("hex");
49543
+ if (digest !== hash) throw new Error(`Pinned archive content differs: ${file}`);
49544
+ }
49545
+ }
49546
+ function parseTreeEntry(entry) {
49547
+ const match = /^(\d+) (\w+) ([a-f0-9]+)\t([\s\S]+)$/.exec(entry);
49548
+ if (match === null) throw new Error("Unreadable pinned Git tree");
49549
+ const [, mode, type, hash, file] = match;
49550
+ if (mode === void 0 || type !== "blob" || hash === void 0 || file === void 0 || isAbsolute8(file) || file.split("/").includes(".."))
49551
+ throw new Error("Pinned tree coverage incomplete: unsupported tree entry");
49552
+ return { mode, hash, file };
49553
+ }
49554
+ function comparisonExecOptions(config, signal) {
49555
+ return {
49556
+ signal,
49557
+ env: hermeticGitEnv(config.env),
49558
+ wrapper: config.wrapper,
49559
+ timeoutMs: 3e4,
49560
+ maxBuffer: 16 * 1024 * 1024
49561
+ };
49562
+ }
49563
+ function comparisonGit(options) {
49564
+ return async (cwd, args) => (await execFileTree(
49565
+ "git",
49566
+ [
49567
+ "--literal-pathspecs",
49568
+ "-c",
49569
+ "core.hooksPath=/dev/null",
49570
+ "-c",
49571
+ "core.fsmonitor=false",
49572
+ ...args
49573
+ ],
49574
+ { ...options, cwd }
49575
+ )).stdout;
49576
+ }
49577
+ async function archiveBaseline(input) {
49578
+ const { target, directory, baseline, sha, git: git2, execOptions } = input;
49579
+ const baseDir = join16(directory, "base");
49580
+ const prefix = (await git2(target, ["rev-parse", "--show-prefix"])).trim();
49581
+ if (isAbsolute8(prefix) || prefix.split("/").includes(".."))
49582
+ throw new Error("Invalid scan subtree");
49583
+ const { mkdir: mkdir2 } = await import("node:fs/promises");
49584
+ await mkdir2(baseDir);
49585
+ const archive = join16(directory, "base.tar");
49586
+ await git2(baseline.directory, ["archive", "--format=tar", `--output=${archive}`, sha]);
49587
+ await execFileTree("tar", ["-xf", archive, "-C", baseDir], execOptions);
49588
+ await verifyArchive(baseDir, await git2(baseline.directory, ["ls-tree", "-r", "-z", sha]));
49589
+ return { root: baseDir, target: join16(baseDir, prefix) };
49590
+ }
49591
+ async function scanTrees(input) {
49592
+ const { target, rulesets, config, signal, directory, archive } = input;
49593
+ const prepared = await prepareSecurityScan(rulesets, {
49594
+ ...comparisonExecOptions(config, signal),
49595
+ directory
49596
+ });
49597
+ if ("error" in prepared) throw new Error(prepared.error);
49598
+ const scanInput = {
49599
+ scanner: "semgrep",
49600
+ rulesets: [...rulesets],
49601
+ maxFindings: Number.MAX_SAFE_INTEGER
49602
+ };
49603
+ const options = {
49604
+ signal,
49605
+ env: config.env,
49606
+ wrapper: config.wrapper,
49607
+ completeResults: true,
49608
+ preparedScan: prepared
49609
+ };
49610
+ const base = normalizedScan(
49611
+ await executeSecurityScan(
49612
+ { ...scanInput, target: archive.target },
49613
+ { ...options, root: archive.root }
49614
+ ),
49615
+ archive.target
49616
+ );
49617
+ const worktree = normalizedScan(
49618
+ await executeSecurityScan({ ...scanInput, target }, { ...options, root: config.root }),
49619
+ target
49620
+ );
49621
+ return { base, worktree };
49622
+ }
49623
+ function actionableFindings(findings) {
49624
+ return findings.map(({ rule, file, startLine, severity }) => ({
49625
+ rule,
49626
+ file,
49627
+ startLine,
49628
+ severity
49629
+ }));
49630
+ }
49631
+ function scannerVersion(base, worktree) {
49632
+ const version = "error" in base ? void 0 : base.scannerVersion;
49633
+ const other = "error" in worktree ? void 0 : worktree.scannerVersion;
49634
+ const measured = version ?? other;
49635
+ return measured === void 0 ? {} : { scannerVersion: measured };
49636
+ }
49637
+
49029
49638
  // src/pipeline/security-gate.ts
49030
49639
  var logger49 = createLogger({ component: "security-gate" });
49031
49640
  var BLOCKING_SEVERITIES = /* @__PURE__ */ new Set(["critical", "high"]);
49032
49641
  function checkSecurityScan(targetDir, rulesets = ["p/default"], config = {}) {
49033
49642
  return async (signal) => {
49643
+ if (config.baseline !== void 0) return runBaselineGate(targetDir, rulesets, config, signal);
49034
49644
  const start = Date.now();
49035
49645
  const result = await executeSecurityScan(
49036
49646
  {
@@ -49051,33 +49661,59 @@ function checkSecurityScan(targetDir, rulesets = ["p/default"], config = {}) {
49051
49661
  durationMs: Date.now() - start
49052
49662
  };
49053
49663
  }
49054
- return runSecurityPipeline(result, targetDir, config, start, signal);
49664
+ const gateResult = await runSecurityPipeline(result, targetDir, config, start, signal);
49665
+ if (gateResult.verdict === "fail") return gateResult;
49666
+ if (result.parseDiagnostics !== void 0 && result.parseDiagnostics.length > 0) {
49667
+ return {
49668
+ ...gateResult,
49669
+ verdict: "skip",
49670
+ details: `Security scan incomplete: unparsed files ${result.parseDiagnostics.map((d) => d.file).join(", ")}`,
49671
+ durationMs: Date.now() - start
49672
+ };
49673
+ }
49674
+ return gateResult;
49675
+ };
49676
+ }
49677
+ async function runBaselineGate(target, rulesets, config, signal) {
49678
+ const start = Date.now();
49679
+ const comparison = await compareSecurityBaseline(target, rulesets, config, signal);
49680
+ const osv = comparison.complete ? await runOsvCheck(target, config.enableOsv ?? true, signal) : OSV_EMPTY;
49681
+ throwIfAborted(signal, "Security baseline scan aborted");
49682
+ const osvFailed = osv.vulnerabilities.some((v) => v.severity === "CRITICAL");
49683
+ const details = comparison.complete ? `Base ${String(comparison.baseCount)}, worktree ${String(comparison.worktreeCount)} findings; ${String(comparison.introducedBlockingCount)} introduced blocking; ${buildScanSummary(comparison.worktreeCount ?? 0, comparison.introducedBlockingCount ?? 0, osv.vulnerabilities.length, osv)}` : `Security comparison incomplete: ${comparison.errors.join("; ")}`;
49684
+ return {
49685
+ name: "security_scan",
49686
+ verdict: !comparison.complete ? "skip" : comparison.introducedBlockingCount === 0 && !osvFailed ? "pass" : "fail",
49687
+ details: details.slice(0, 500),
49688
+ comparison,
49689
+ durationMs: Date.now() - start
49055
49690
  };
49056
49691
  }
49057
49692
  async function runSecurityPipeline(sarifResult, targetDir, config, start, signal) {
49058
49693
  const osv = await runOsvCheck(targetDir, config.enableOsv ?? true, signal);
49059
49694
  throwIfAborted(signal, "Security scan aborted");
49060
49695
  const osvVulns = osv.vulnerabilities;
49061
- const blocking = getBlockingFindings(sarifResult.findings);
49696
+ const blocking2 = getBlockingFindings(sarifResult.findings);
49062
49697
  const details = buildScanSummary(
49063
49698
  sarifResult.totalFindings,
49064
- blocking.length,
49699
+ blocking2.length,
49065
49700
  osvVulns.length,
49066
49701
  osv,
49067
49702
  sarifResult.errors.length
49068
49703
  );
49069
49704
  logger49.info("Security gate complete", {
49070
49705
  total: sarifResult.totalFindings,
49071
- blocking: blocking.length,
49706
+ blocking: blocking2.length,
49072
49707
  osvVulns: osvVulns.length,
49073
49708
  osvFailedLookups: osv.failedLookups,
49074
49709
  sarifParseErrors: sarifResult.errors.length
49075
49710
  });
49076
- const failed = blocking.length > 0 || osvVulns.some((v) => v.severity === "CRITICAL");
49711
+ const failed = blocking2.length > 0 || osvVulns.some((v) => v.severity === "CRITICAL");
49077
49712
  return {
49078
49713
  name: "security_scan",
49079
49714
  verdict: failed ? "fail" : "pass",
49080
49715
  details,
49716
+ blockingFindings: blocking2,
49081
49717
  durationMs: Date.now() - start
49082
49718
  };
49083
49719
  }
@@ -49124,26 +49760,26 @@ async function runOsvCheck(targetDir, enabled, signal) {
49124
49760
  function getBlockingFindings(findings) {
49125
49761
  return findings.filter((f) => BLOCKING_SEVERITIES.has(f.severity));
49126
49762
  }
49127
- function osvCoverageNote(blocking, osvCount, osv) {
49763
+ function osvCoverageNote(blocking2, osvCount, osv) {
49128
49764
  if (osv?.checkFailed === true) {
49129
49765
  return "OSV check did not run (error) \u2014 dependency vulnerabilities unknown";
49130
49766
  }
49131
49767
  if (osv !== void 0 && osv.failedLookups > 0) {
49132
49768
  return `OSV not checked for ${String(osv.failedLookups)} of ${String(osv.queried)} dependencies (lookup failed)`;
49133
49769
  }
49134
- if (blocking === 0 && osvCount === 0) return "none blocking";
49770
+ if (blocking2 === 0 && osvCount === 0) return "none blocking";
49135
49771
  return "";
49136
49772
  }
49137
- function buildScanSummary(total, blocking, osvCount, osv, sarifParseErrors = 0) {
49773
+ function buildScanSummary(total, blocking2, osvCount, osv, sarifParseErrors = 0) {
49138
49774
  const parts = [`${String(total)} SAST findings`];
49139
49775
  if (sarifParseErrors > 0) {
49140
49776
  parts.push(
49141
49777
  `${String(sarifParseErrors)} scanner output line(s) unreadable \u2014 SAST coverage is partial`
49142
49778
  );
49143
49779
  }
49144
- if (blocking > 0) parts.push(`${String(blocking)} blocking`);
49780
+ if (blocking2 > 0) parts.push(`${String(blocking2)} blocking`);
49145
49781
  if (osvCount > 0) parts.push(`${String(osvCount)} OSV dependency vulnerabilities`);
49146
- parts.push(osvCoverageNote(blocking, osvCount, osv));
49782
+ parts.push(osvCoverageNote(blocking2, osvCount, osv));
49147
49783
  if (osv !== void 0 && osv.declared > osv.queried) {
49148
49784
  parts.push(
49149
49785
  `OSV covered ${String(osv.queried)} of ${String(osv.declared)} declared dependencies`
@@ -49154,7 +49790,7 @@ function buildScanSummary(total, blocking, osvCount, osv, sarifParseErrors = 0)
49154
49790
 
49155
49791
  // src/security/quality-gate-commands.ts
49156
49792
  import { existsSync as existsSync11, readFileSync as readFileSync9 } from "node:fs";
49157
- import { join as join14 } from "node:path";
49793
+ import { join as join17 } from "node:path";
49158
49794
  var LOCKFILES = [
49159
49795
  { file: "pnpm-lock.yaml", manager: "pnpm" },
49160
49796
  { file: "yarn.lock", manager: "yarn" },
@@ -49169,12 +49805,12 @@ var SCRIPT_CANDIDATES = {
49169
49805
  };
49170
49806
  function detectPackageManager(projectDir) {
49171
49807
  for (const { file, manager } of LOCKFILES) {
49172
- if (existsSync11(join14(projectDir, file))) return manager;
49808
+ if (existsSync11(join17(projectDir, file))) return manager;
49173
49809
  }
49174
49810
  return "npm";
49175
49811
  }
49176
49812
  function readScripts(projectDir) {
49177
- const manifest = join14(projectDir, "package.json");
49813
+ const manifest = join17(projectDir, "package.json");
49178
49814
  if (!existsSync11(manifest)) return void 0;
49179
49815
  try {
49180
49816
  const parsed = JSON.parse(readFileSync9(manifest, "utf-8"));
@@ -49376,8 +50012,8 @@ function getTrendContext() {
49376
50012
 
49377
50013
  // src/pipeline/agent-executor-parsers.ts
49378
50014
  var logger50 = createLogger({ component: "agent-executor" });
49379
- function stringField(record, key, fallback) {
49380
- const value = record[key];
50015
+ function stringField(record, key2, fallback) {
50016
+ const value = record[key2];
49381
50017
  if (typeof value === "string") return value;
49382
50018
  if (typeof value === "number") return String(value);
49383
50019
  return fallback;
@@ -49765,12 +50401,8 @@ function createQualityGateStage({
49765
50401
  return { passed, verdict: result.verdict, feedback };
49766
50402
  };
49767
50403
  }
49768
- function createSecurityScanStage({
49769
- config,
49770
- startStage,
49771
- workspaceDependencies,
49772
- wrapper
49773
- }) {
50404
+ function createSecurityScanStage(deps) {
50405
+ const { config, startStage, workspaceDependencies, wrapper } = deps;
49774
50406
  return async (signal) => {
49775
50407
  startStage("security");
49776
50408
  const start = getTimeProvider().now();
@@ -49778,6 +50410,7 @@ function createSecurityScanStage({
49778
50410
  await postProgress(config, "Security", `Scanning ${target}...`);
49779
50411
  const scratchBound = workspaceDependencies !== void 0;
49780
50412
  const check = checkSecurityScan(target, void 0, {
50413
+ baseline: config.securityBaseline,
49781
50414
  env: scratchBound ? hermeticGitEnv() : void 0,
49782
50415
  root: scratchBound ? target : void 0,
49783
50416
  wrapper
@@ -49801,7 +50434,7 @@ function createSecurityScanStage({
49801
50434
  const securityNote = result.verdict === "skip" ? `Security scan did not run: ${result.details}. Install the scanner, or use qualityGate 'advisory' to proceed without security evidence.` : `BLOCKED: ${result.details}`;
49802
50435
  await postProgress(config, "Security", passed ? "Passed" : securityNote);
49803
50436
  flushPipelineMemory();
49804
- return { passed, verdict: result.verdict, feedback: result.details };
50437
+ return securityStageResult(result, passed);
49805
50438
  };
49806
50439
  }
49807
50440
 
@@ -49826,12 +50459,12 @@ function createAgentStages(config = {}) {
49826
50459
  decompose: createDecomposeStage(deps),
49827
50460
  ...createExecutionStages(deps),
49828
50461
  // #6794: execution closures share the same guard and scratch directory.
49829
- withWorkspace: ({ directory, dependencies: workspaceDependencies, wrapper }) => {
50462
+ withWorkspace: ({ directory, dependencies: workspaceDependencies, wrapper, baseline }) => {
49830
50463
  const bound = {
49831
50464
  ...deps,
49832
50465
  workspaceDependencies,
49833
50466
  wrapper,
49834
- config: { ...config, scanTarget: directory }
50467
+ config: { ...config, scanTarget: directory, securityBaseline: baseline }
49835
50468
  };
49836
50469
  return {
49837
50470
  ...createExecutionStages(bound),
@@ -49857,11 +50490,11 @@ function createExecutionStages(deps) {
49857
50490
  }
49858
50491
 
49859
50492
  // src/pipeline/stage-wrappers.ts
49860
- function output(key, value, durationMs, success) {
49861
- return { stateKey: key, value, durationMs, success };
50493
+ function output(key2, value, durationMs, success) {
50494
+ return { stateKey: key2, value, durationMs, success };
49862
50495
  }
49863
- function failOutput(key, error, durationMs) {
49864
- return { stateKey: key, value: null, durationMs, success: false, error };
50496
+ function failOutput(key2, error, durationMs) {
50497
+ return { stateKey: key2, value: null, durationMs, success: false, error };
49865
50498
  }
49866
50499
  function createParseSpecStageWrapper() {
49867
50500
  return {
@@ -50401,7 +51034,7 @@ ${FINDINGS_FORMAT_INSTRUCTIONS}
50401
51034
  }
50402
51035
 
50403
51036
  // src/mcp/tools/pr-review-tool.ts
50404
- import { z as z94 } from "zod";
51037
+ import { z as z95 } from "zod";
50405
51038
  import { randomUUID as randomUUID14 } from "node:crypto";
50406
51039
 
50407
51040
  // src/audit/reviewed-diff-hash.ts
@@ -50952,19 +51585,19 @@ var MAX_REPO_CONTEXT_LENGTH = 2e3;
50952
51585
  var MAX_TITLE_LENGTH = 500;
50953
51586
  var MAX_DESCRIPTION_LENGTH = 1e4;
50954
51587
  var PR_REVIEW_ASYNC_HINT = "A pr_review run fans out to 5 live LLM voters and can exceed the synchronous MCP request timeout. Retry with `dispatch: 'async'` to get a jobId immediately, then poll get_job_result({ jobId }) for the result.";
50955
- var PrReviewInputSchema = z94.object({
50956
- prTitle: z94.string().min(1).max(MAX_TITLE_LENGTH).describe("PR title"),
50957
- prDescription: z94.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("PR body / description"),
50958
- prDiff: z94.string().min(1).max(MAX_DIFF_INPUT_LENGTH).refine(looksLikeUnifiedDiff, {
51588
+ var PrReviewInputSchema = z95.object({
51589
+ prTitle: z95.string().min(1).max(MAX_TITLE_LENGTH).describe("PR title"),
51590
+ prDescription: z95.string().max(MAX_DESCRIPTION_LENGTH).optional().describe("PR body / description"),
51591
+ prDiff: z95.string().min(1).max(MAX_DIFF_INPUT_LENGTH).refine(looksLikeUnifiedDiff, {
50959
51592
  message: "prDiff must be a unified diff (expected a `diff --git`, `---`/`+++`, or `@@ \u2026 @@` line). Prose descriptions of a change are rejected: a review of a summary is not a review of the code, and would be recorded as though it were (#4451)."
50960
51593
  }).describe(
50961
51594
  `Unified diff text (max ${String(MAX_DIFF_INPUT_LENGTH)} chars). REQUIRED SHAPE (#4451): must contain a \`diff --git\` header, an \`@@ \u2026 @@\` hunk header backed by +/- lines, or a \`---\`/\`+++\` header pair \u2014 a prose summary of the change is REJECTED, because reviewing a summary is not reviewing the code and would be recorded as though it were. (Stated here because Zod refinements do not survive JSON-schema generation, so this constraint is otherwise invisible to clients.) No need to truncate before calling: the panel reads the whole diff whenever it fits the voters' context windows (#6003); a diff larger than that is security-prioritized and PARTIALLY reviewed (lowest-priority whole files dropped; a partial panel read can block but never verified-approve). Separately, the audit record's hash binds only the first ${String(MAX_DIFF_LENGTH)} UTF-8 bytes; the response \`coverage\` and the record summary state both what the panel read and what the hash binds.`
50962
51595
  ),
50963
- repoContext: z94.string().max(MAX_REPO_CONTEXT_LENGTH).optional().describe(
51596
+ repoContext: z95.string().max(MAX_REPO_CONTEXT_LENGTH).optional().describe(
50964
51597
  `Optional one-paragraph repo context (architecture, conventions; max ${String(MAX_REPO_CONTEXT_LENGTH)} chars; trim before calling)`
50965
51598
  ),
50966
- baseRef: z94.string().max(200).optional().describe("Base branch ref (e.g. main)"),
50967
- headRef: z94.string().max(200).optional().describe("Head branch ref"),
51599
+ baseRef: z95.string().max(200).optional().describe("Base branch ref (e.g. main)"),
51600
+ headRef: z95.string().max(200).optional().describe("Head branch ref"),
50968
51601
  /**
50969
51602
  * Option-C audit binding (#4031). When BOTH `prNumber` and `baseSha` are
50970
51603
  * supplied AND the review is live (not simulated), pr_review persists an
@@ -50980,14 +51613,14 @@ var PrReviewInputSchema = z94.object({
50980
51613
  * the PR opened and drifts as main advances), so pass the merge-base as
50981
51614
  * `baseSha` or the record will not match on an aged branch (#5692).
50982
51615
  */
50983
- prNumber: z94.number().int().positive().optional().describe("PR number \u2014 with baseSha, enables Option-C audit-record persistence (#4031)"),
50984
- baseSha: z94.string().regex(/^[0-9a-f]{40}$/, "baseSha must be a 40-char lowercase hex commit sha").optional().describe(
51616
+ prNumber: z95.number().int().positive().optional().describe("PR number \u2014 with baseSha, enables Option-C audit-record persistence (#4031)"),
51617
+ baseSha: z95.string().regex(/^[0-9a-f]{40}$/, "baseSha must be a 40-char lowercase hex commit sha").optional().describe(
50985
51618
  "40-hex base commit sha the reviewed diff was computed from \u2014 pass `git merge-base origin/<base> <head>`, the base the gate recomputes (Option-C binding, #4031, #5692)"
50986
51619
  ),
50987
- repoPath: z94.string().max(1024).optional().describe(
51620
+ repoPath: z95.string().max(1024).optional().describe(
50988
51621
  "Repo root path for persisting the governance pr-review record (overrides cwd auto-detection). Must contain a .git ancestor \u2014 relative paths are resolved against cwd; ignored (falls back to cwd auto-detection) if it is not a real repo root. Env NEXUS_PR_REVIEW_RECORDS_PATH still takes precedence and is unrestricted."
50989
51622
  ),
50990
- simulate: z94.boolean().default(false).describe("Use simulated voters (testing only; never ship live with this true)"),
51623
+ simulate: z95.boolean().default(false).describe("Use simulated voters (testing only; never ship live with this true)"),
50991
51624
  /**
50992
51625
  * Error policy (#4132). `standard` (default) excludes absent voters but
50993
51626
  * requires a majority of the requested panel to approve. `absolute_quorum` gates
@@ -50999,7 +51632,7 @@ var PrReviewInputSchema = z94.object({
50999
51632
  * verified approve. A genuine `request_changes` blocker still wins (Tiers 1-2
51000
51633
  * run first).
51001
51634
  */
51002
- errorPolicy: z94.enum(["standard", "absolute_quorum"]).default("standard").describe(
51635
+ errorPolicy: z95.enum(["standard", "absolute_quorum"]).default("standard").describe(
51003
51636
  "Error policy (#4132). 'standard' (default): absent voters excluded; approval requires a majority of the requested panel. 'absolute_quorum': any errored voter \u2014 esp. the contrarian \u2014 degrades a would-be approve to a recoverable abstain (verified:false); never manufactures a verified approve from an induced error."
51004
51637
  ),
51005
51638
  // #6123: same field as consensus_vote — the panel judges the caller's project.
@@ -51355,27 +51988,27 @@ function absoluteQuorumApprove(reviews, valid) {
51355
51988
  }
51356
51989
 
51357
51990
  // src/mcp/tools/survey-oss-landscape.ts
51358
- import { z as z95 } from "zod";
51359
- var SurveyOssLandscapeInputSchema = z95.object({
51360
- query: z95.string().min(1).max(200).describe('Free-text search query, e.g. "cargo nextest replacement" or "OSS SBOM tools"'),
51361
- maxResults: z95.number().int().min(1).max(50).optional().default(10).describe("Maximum candidates to return (1-50; default 10)"),
51362
- minStars: z95.number().int().min(0).optional().default(0).describe("Minimum star count to include (default 0; useful for filtering noise)"),
51363
- language: z95.string().max(50).optional().describe('GitHub language filter, e.g. "rust" or "typescript"')
51991
+ import { z as z96 } from "zod";
51992
+ var SurveyOssLandscapeInputSchema = z96.object({
51993
+ query: z96.string().min(1).max(200).describe('Free-text search query, e.g. "cargo nextest replacement" or "OSS SBOM tools"'),
51994
+ maxResults: z96.number().int().min(1).max(50).optional().default(10).describe("Maximum candidates to return (1-50; default 10)"),
51995
+ minStars: z96.number().int().min(0).optional().default(0).describe("Minimum star count to include (default 0; useful for filtering noise)"),
51996
+ language: z96.string().max(50).optional().describe('GitHub language filter, e.g. "rust" or "typescript"')
51364
51997
  });
51365
- var GitHubRepoSchema = z95.object({
51366
- full_name: z95.string().optional(),
51367
- html_url: z95.string().optional(),
51368
- description: z95.string().nullable().optional(),
51369
- stargazers_count: z95.number().optional(),
51370
- pushed_at: z95.string().nullable().optional(),
51371
- language: z95.string().nullable().optional(),
51372
- license: z95.object({
51373
- spdx_id: z95.string().nullable().optional()
51998
+ var GitHubRepoSchema = z96.object({
51999
+ full_name: z96.string().optional(),
52000
+ html_url: z96.string().optional(),
52001
+ description: z96.string().nullable().optional(),
52002
+ stargazers_count: z96.number().optional(),
52003
+ pushed_at: z96.string().nullable().optional(),
52004
+ language: z96.string().nullable().optional(),
52005
+ license: z96.object({
52006
+ spdx_id: z96.string().nullable().optional()
51374
52007
  }).nullable().optional()
51375
52008
  });
51376
- var GitHubSearchResponseSchema = z95.object({
51377
- total_count: z95.number().optional(),
51378
- items: z95.array(GitHubRepoSchema).optional()
52009
+ var GitHubSearchResponseSchema = z96.object({
52010
+ total_count: z96.number().optional(),
52011
+ items: z96.array(GitHubRepoSchema).optional()
51379
52012
  });
51380
52013
  var GITHUB_SEARCH_BASE = "https://api.github.com/search/repositories";
51381
52014
  function buildGithubQuery(input) {
@@ -51497,16 +52130,16 @@ function createSurveyHandler(deps) {
51497
52130
  });
51498
52131
  return withToolError("Survey failed", logger58, async () => {
51499
52132
  const result = await executeSurvey(validation.data, logger58);
51500
- return structuredToolSuccess(z95.object(SURVEY_OUTPUT_SCHEMA), result);
52133
+ return structuredToolSuccess(z96.object(SURVEY_OUTPUT_SCHEMA), result);
51501
52134
  });
51502
52135
  };
51503
52136
  }
51504
52137
  var SURVEY_OUTPUT_SCHEMA = {
51505
- query: z95.string(),
51506
- totalFound: z95.number(),
51507
- candidates: z95.array(z95.unknown()),
51508
- sourcesQueried: z95.array(z95.string()),
51509
- sourcesFailed: z95.array(z95.string())
52138
+ query: z96.string(),
52139
+ totalFound: z96.number(),
52140
+ candidates: z96.array(z96.unknown()),
52141
+ sourcesQueried: z96.array(z96.string()),
52142
+ sourcesFailed: z96.array(z96.string())
51510
52143
  };
51511
52144
  var SURVEY_DESCRIPTION = 'Transient OSS project search. Returns a ranked list of GitHub repositories with license, last-commit, star-count, and one-line description. Does NOT persist to the research registry \u2014 use `research_add_source` for that. Best for one-off engineering decisions like "what tools exist in this space?".';
51512
52145
  function registerSurveyOssLandscapeTool(server, deps) {
@@ -51536,7 +52169,7 @@ function registerSurveyOssLandscapeTool(server, deps) {
51536
52169
  }
51537
52170
 
51538
52171
  // src/mcp/tools/vendor-publishing-audit.ts
51539
- import { z as z96 } from "zod";
52172
+ import { z as z97 } from "zod";
51540
52173
 
51541
52174
  // src/mcp/tools/vendor-publishing-seed.ts
51542
52175
  var VENDOR_PUBLISHING_SEED = {
@@ -51609,8 +52242,8 @@ function listKnownVendors() {
51609
52242
  }
51610
52243
 
51611
52244
  // src/mcp/tools/vendor-publishing-audit.ts
51612
- var VendorPublishingAuditInputSchema = z96.object({
51613
- vendor: z96.string().min(1).max(50).toLowerCase().describe('Vendor identifier, lowercase. e.g. "ubuntu", "debian", "fedora"')
52245
+ var VendorPublishingAuditInputSchema = z97.object({
52246
+ vendor: z97.string().min(1).max(50).toLowerCase().describe('Vendor identifier, lowercase. e.g. "ubuntu", "debian", "fedora"')
51614
52247
  });
51615
52248
  function lookupVendor(vendor) {
51616
52249
  if (isKnownVendor(vendor)) {
@@ -51638,26 +52271,26 @@ function createVendorPublishingAuditHandler(deps) {
51638
52271
  return withToolError("Vendor publishing audit failed", logger58, () => {
51639
52272
  const result = lookupVendor(validation.data.vendor);
51640
52273
  return Promise.resolve(
51641
- structuredToolSuccess(z96.object(VENDOR_PUBLISHING_OUTPUT_SCHEMA), result)
52274
+ structuredToolSuccess(z97.object(VENDOR_PUBLISHING_OUTPUT_SCHEMA), result)
51642
52275
  );
51643
52276
  });
51644
52277
  };
51645
52278
  }
51646
52279
  var VENDOR_PUBLISHING_OUTPUT_SCHEMA = {
51647
- vendor: z96.string(),
51648
- known: z96.boolean(),
52280
+ vendor: z97.string(),
52281
+ known: z97.boolean(),
51649
52282
  // Fields below populate when known=true; permissive optional for known=false.
51650
- sha256SumsUrlPattern: z96.string().optional(),
51651
- sha256SumsSignatureUrlPattern: z96.string().optional(),
51652
- signaturePattern: z96.string().optional(),
51653
- gpgKeys: z96.array(z96.unknown()).optional(),
51654
- releaseCadence: z96.string().optional(),
51655
- keyRotationNotes: z96.string().optional(),
51656
- vendorDocUrl: z96.string().optional(),
51657
- citedAt: z96.string().optional(),
52283
+ sha256SumsUrlPattern: z97.string().optional(),
52284
+ sha256SumsSignatureUrlPattern: z97.string().optional(),
52285
+ signaturePattern: z97.string().optional(),
52286
+ gpgKeys: z97.array(z97.unknown()).optional(),
52287
+ releaseCadence: z97.string().optional(),
52288
+ keyRotationNotes: z97.string().optional(),
52289
+ vendorDocUrl: z97.string().optional(),
52290
+ citedAt: z97.string().optional(),
51658
52291
  // Fields below populate when known=false.
51659
- message: z96.string().optional(),
51660
- knownVendors: z96.array(z96.string()).optional()
52292
+ message: z97.string().optional(),
52293
+ knownVendors: z97.array(z97.string()).optional()
51661
52294
  };
51662
52295
  var VENDOR_PUBLISHING_DESCRIPTION = "Look up a vendor's published-artifact signing infrastructure: GPG key fingerprints, SHA256SUMS URL pattern, signature shape (clearsigned / detached / detached-on-iso), release cadence, key rotation notes, and the vendor doc citation. Static lookup against a curated seed dataset; the vendor doc URL is the authoritative source. Returns `{known: false, knownVendors: [...]}` for vendors without a seed entry. v1 covers ubuntu, debian, fedora.";
51663
52296
  function registerVendorPublishingAuditTool(server, deps) {
@@ -51687,17 +52320,17 @@ function registerVendorPublishingAuditTool(server, deps) {
51687
52320
  }
51688
52321
 
51689
52322
  // src/mcp/tools/compare-data-feeds.ts
51690
- import { z as z97 } from "zod";
52323
+ import { z as z98 } from "zod";
51691
52324
  import * as path6 from "node:path";
51692
52325
  import * as fs7 from "node:fs";
51693
52326
  import * as yaml3 from "yaml";
51694
- var CompareDataFeedsInputSchema = z97.object({
51695
- feedAPath: z97.string().min(1).max(1e3).describe("Filesystem path to feed A (YAML or JSON, auto-detected by extension)"),
51696
- feedBPath: z97.string().min(1).max(1e3).describe("Filesystem path to feed B"),
51697
- keyPath: z97.string().min(1).max(200).describe(
52327
+ var CompareDataFeedsInputSchema = z98.object({
52328
+ feedAPath: z98.string().min(1).max(1e3).describe("Filesystem path to feed A (YAML or JSON, auto-detected by extension)"),
52329
+ feedBPath: z98.string().min(1).max(1e3).describe("Filesystem path to feed B"),
52330
+ keyPath: z98.string().min(1).max(200).describe(
51698
52331
  'Dotted path to the entry key, e.g. "id" or "name". Each entry must have this field.'
51699
52332
  ),
51700
- compareFields: z97.array(z97.string().min(1).max(200)).max(20).optional().describe(
52333
+ compareFields: z98.array(z98.string().min(1).max(200)).max(20).optional().describe(
51701
52334
  'Optional dotted field paths to compare across matched entries (e.g. ["license", "sha256"])'
51702
52335
  )
51703
52336
  });
@@ -51737,16 +52370,16 @@ function indexByKey(entries, keyPath) {
51737
52370
  const missingKeyAt = [];
51738
52371
  for (let i = 0; i < entries.length; i++) {
51739
52372
  const entry = entries[i];
51740
- const key = readDottedPath(entry, keyPath);
51741
- if (key === void 0 || key === null) {
52373
+ const key2 = readDottedPath(entry, keyPath);
52374
+ if (key2 === void 0 || key2 === null) {
51742
52375
  missingKeyAt.push(i);
51743
52376
  continue;
51744
52377
  }
51745
- if (typeof key === "object") {
52378
+ if (typeof key2 === "object") {
51746
52379
  missingKeyAt.push(i);
51747
52380
  continue;
51748
52381
  }
51749
- const keyStr = typeof key === "string" ? key : typeof key === "number" ? String(key) : typeof key === "bigint" ? key.toString() : typeof key === "boolean" ? String(key) : "";
52382
+ const keyStr = typeof key2 === "string" ? key2 : typeof key2 === "number" ? String(key2) : typeof key2 === "bigint" ? key2.toString() : typeof key2 === "boolean" ? String(key2) : "";
51750
52383
  if (keyStr === "") {
51751
52384
  missingKeyAt.push(i);
51752
52385
  continue;
@@ -51759,12 +52392,12 @@ function membershipDiff(indexA, indexB) {
51759
52392
  const onlyInA = [];
51760
52393
  const onlyInB = [];
51761
52394
  const inBoth = [];
51762
- for (const key of indexA.keys()) {
51763
- if (indexB.has(key)) inBoth.push(key);
51764
- else onlyInA.push(key);
52395
+ for (const key2 of indexA.keys()) {
52396
+ if (indexB.has(key2)) inBoth.push(key2);
52397
+ else onlyInA.push(key2);
51765
52398
  }
51766
- for (const key of indexB.keys()) {
51767
- if (!indexA.has(key)) onlyInB.push(key);
52399
+ for (const key2 of indexB.keys()) {
52400
+ if (!indexA.has(key2)) onlyInB.push(key2);
51768
52401
  }
51769
52402
  onlyInA.sort();
51770
52403
  onlyInB.sort();
@@ -51773,14 +52406,14 @@ function membershipDiff(indexA, indexB) {
51773
52406
  }
51774
52407
  function compareFields(inBothKeys, indexA, indexB, fields) {
51775
52408
  const out = [];
51776
- for (const key of inBothKeys) {
51777
- const a = indexA.get(key);
51778
- const b = indexB.get(key);
52409
+ for (const key2 of inBothKeys) {
52410
+ const a = indexA.get(key2);
52411
+ const b = indexB.get(key2);
51779
52412
  for (const field of fields) {
51780
52413
  const valueA = readDottedPath(a, field);
51781
52414
  const valueB = readDottedPath(b, field);
51782
52415
  if (!deepEqual(valueA, valueB)) {
51783
- out.push({ key, field, valueA, valueB });
52416
+ out.push({ key: key2, field, valueA, valueB });
51784
52417
  }
51785
52418
  }
51786
52419
  }
@@ -51875,29 +52508,29 @@ function createCompareDataFeedsHandler(deps) {
51875
52508
  });
51876
52509
  return withToolError("Compare data feeds failed", logger58, () => {
51877
52510
  const result = executeCompare(validation.data);
51878
- return Promise.resolve(structuredToolSuccess(z97.object(COMPARE_OUTPUT_SCHEMA), result));
52511
+ return Promise.resolve(structuredToolSuccess(z98.object(COMPARE_OUTPUT_SCHEMA), result));
51879
52512
  });
51880
52513
  };
51881
52514
  }
51882
52515
  var COMPARE_OUTPUT_SCHEMA = {
51883
- feedAPath: z97.string(),
51884
- feedBPath: z97.string(),
51885
- keyPath: z97.string(),
51886
- counts: z97.object({
51887
- entriesInA: z97.number(),
51888
- entriesInB: z97.number(),
51889
- onlyInA: z97.number(),
51890
- onlyInB: z97.number(),
51891
- inBoth: z97.number(),
51892
- fieldDifferences: z97.number()
52516
+ feedAPath: z98.string(),
52517
+ feedBPath: z98.string(),
52518
+ keyPath: z98.string(),
52519
+ counts: z98.object({
52520
+ entriesInA: z98.number(),
52521
+ entriesInB: z98.number(),
52522
+ onlyInA: z98.number(),
52523
+ onlyInB: z98.number(),
52524
+ inBoth: z98.number(),
52525
+ fieldDifferences: z98.number()
51893
52526
  }),
51894
- coverage: z97.object({
51895
- onlyInA: z97.array(z97.string()),
51896
- onlyInB: z97.array(z97.string()),
51897
- inBoth: z97.array(z97.string())
52527
+ coverage: z98.object({
52528
+ onlyInA: z98.array(z98.string()),
52529
+ onlyInB: z98.array(z98.string()),
52530
+ inBoth: z98.array(z98.string())
51898
52531
  }),
51899
- fieldDifferences: z97.array(z97.unknown()),
51900
- summary: z97.string()
52532
+ fieldDifferences: z98.array(z98.unknown()),
52533
+ summary: z98.string()
51901
52534
  };
51902
52535
  var COMPARE_DESCRIPTION = "Diff two upstream data feeds (YAML or JSON files) along coverage and per-field axes. Returns which entries exist in A, B, both, plus optional field-level diffs across matched entries. v1 takes file paths only (no URL fetch \u2014 that needs an SSRF design pass). Both feeds must be a top-level array OR a top-level object with exactly one array field.";
51903
52536
  function registerCompareDataFeedsTool(server, deps) {
@@ -51927,9 +52560,9 @@ function registerCompareDataFeedsTool(server, deps) {
51927
52560
  }
51928
52561
 
51929
52562
  // src/mcp/tools/query-task-state-tool.ts
51930
- import { z as z98 } from "zod";
51931
- var QueryTaskStateInputSchema = z98.object({
51932
- taskId: z98.string().min(1).max(128).describe("Task ID whose structured state log should be read")
52563
+ import { z as z99 } from "zod";
52564
+ var QueryTaskStateInputSchema = z99.object({
52565
+ taskId: z99.string().min(1).max(128).describe("Task ID whose structured state log should be read")
51933
52566
  });
51934
52567
  function queryTaskStateHandler(args, ctx) {
51935
52568
  const parsed = QueryTaskStateInputSchema.safeParse(args);
@@ -51964,7 +52597,7 @@ function queryTaskStateHandler(args, ctx) {
51964
52597
  function registerQueryTaskStateTool(server, deps) {
51965
52598
  const logger58 = deps.logger ?? createLogger({ tool: "query_task_state" });
51966
52599
  const toolSchema = {
51967
- taskId: z98.string().min(1).max(128).describe("Task ID whose structured state log should be read")
52600
+ taskId: z99.string().min(1).max(128).describe("Task ID whose structured state log should be read")
51968
52601
  };
51969
52602
  const description = "Read the structured state log for a task ID and return the current snapshot. Includes Magentic-One Task Ledger (facts/guesses/openQuestions) and Progress Ledger (per-step reflections with suggestedAction) when orchestrators have written them. Structured state is only written when NEXUS_TASK_STATE_ENABLED=1 was set during the orchestrate invocation.";
51970
52603
  const secureHandler = createSecureHandler(queryTaskStateHandler, {
@@ -51986,28 +52619,28 @@ function registerQueryTaskStateTool(server, deps) {
51986
52619
  }
51987
52620
 
51988
52621
  // src/mcp/tools/ci-health-check-tool.ts
51989
- import { z as z101 } from "zod";
52622
+ import { z as z102 } from "zod";
51990
52623
 
51991
52624
  // src/mcp/tools/ci-health-log.ts
51992
52625
  import { appendFileSync as appendFileSync5, existsSync as existsSync13, readFileSync as readFileSync11, statSync as statSync2, writeFileSync as writeFileSync3 } from "node:fs";
51993
- import { z as z100 } from "zod";
52626
+ import { z as z101 } from "zod";
51994
52627
 
51995
52628
  // src/mcp/tools/ci-health-types.ts
51996
- import { z as z99 } from "zod";
51997
- var CiHealthStatusSchema = z99.enum(["healthy", "degraded", "outage", "unknown"]);
52629
+ import { z as z100 } from "zod";
52630
+ var CiHealthStatusSchema = z100.enum(["healthy", "degraded", "outage", "unknown"]);
51998
52631
 
51999
52632
  // src/mcp/tools/ci-health-log.ts
52000
52633
  var logger52 = createLogger({ component: "ci-health-log" });
52001
- var CiHealthEventSchema = z100.object({
52002
- v: z100.literal(1),
52003
- ts: z100.iso.datetime(),
52634
+ var CiHealthEventSchema = z101.object({
52635
+ v: z101.literal(1),
52636
+ ts: z101.iso.datetime(),
52004
52637
  status: CiHealthStatusSchema,
52005
- repo: z100.string().optional(),
52006
- signals: z100.array(
52007
- z100.object({
52008
- source: z100.enum(["github-status", "repo-activity-window"]),
52638
+ repo: z101.string().optional(),
52639
+ signals: z101.array(
52640
+ z101.object({
52641
+ source: z101.enum(["github-status", "repo-activity-window"]),
52009
52642
  status: CiHealthStatusSchema,
52010
- evidence: z100.string()
52643
+ evidence: z101.string()
52011
52644
  })
52012
52645
  )
52013
52646
  });
@@ -52087,17 +52720,17 @@ function eventFromCheck(params) {
52087
52720
  }
52088
52721
 
52089
52722
  // src/mcp/tools/ci-health-check-tool.ts
52090
- var CiHealthCheckInputSchema = z101.object({
52723
+ var CiHealthCheckInputSchema = z102.object({
52091
52724
  /**
52092
52725
  * Repo to check for the recent-runs activity signal (in `owner/repo` form).
52093
52726
  * Optional — when omitted, only the status-page signal is consulted.
52094
52727
  */
52095
- repo: z101.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/, "Must be owner/repo form").optional().describe("GitHub repo (owner/repo) to check for recent CI activity. Optional."),
52728
+ repo: z102.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/, "Must be owner/repo form").optional().describe("GitHub repo (owner/repo) to check for recent CI activity. Optional."),
52096
52729
  /**
52097
52730
  * How far back to look for recent-runs activity (minutes). Default 30 —
52098
52731
  * matches the typical wedge-detection window from the #3070 / #3076 outages.
52099
52732
  */
52100
- activityWindowMinutes: z101.number().int().min(5).max(180).default(30).describe("Recent-runs lookback window in minutes (5-180; default 30).")
52733
+ activityWindowMinutes: z102.number().int().min(5).max(180).default(30).describe("Recent-runs lookback window in minutes (5-180; default 30).")
52101
52734
  });
52102
52735
  var STATUS_PAGE_URL = "https://www.githubstatus.com/api/v2/components.json";
52103
52736
  function mapStatusPageStatus(raw) {
@@ -52256,8 +52889,8 @@ var DESCRIPTION = "Check CI infrastructure health before triggering / polling ru
52256
52889
  function registerCiHealthCheckTool(server, deps) {
52257
52890
  const logger58 = deps.logger ?? createLogger({ tool: "ci_health_check" });
52258
52891
  const toolSchema = {
52259
- repo: z101.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/, "Must be owner/repo form").optional().describe("GitHub repo (owner/repo) to check for recent CI activity. Optional."),
52260
- activityWindowMinutes: z101.number().int().min(5).max(180).optional().describe("Recent-runs lookback window in minutes (5-180; default 30).")
52892
+ repo: z102.string().regex(/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/, "Must be owner/repo form").optional().describe("GitHub repo (owner/repo) to check for recent CI activity. Optional."),
52893
+ activityWindowMinutes: z102.number().int().min(5).max(180).optional().describe("Recent-runs lookback window in minutes (5-180; default 30).")
52261
52894
  };
52262
52895
  const secureHandler = createSecureHandler((args) => ciHealthCheckHandler(args, logger58), {
52263
52896
  toolName: "ci_health_check",
@@ -52283,18 +52916,18 @@ function registerCiHealthCheckTool(server, deps) {
52283
52916
 
52284
52917
  // src/mcp/tools/quality-gate-tool.ts
52285
52918
  import { statSync as statSync3 } from "node:fs";
52286
- import { z as z102 } from "zod";
52287
- var QualityCheckSchema = z102.enum(["typecheck", "lint", "tests", "build", "security"]);
52919
+ import { z as z103 } from "zod";
52920
+ var QualityCheckSchema = z103.enum(["typecheck", "lint", "tests", "build", "security"]);
52288
52921
  var DEFAULT_CHECKS = ["typecheck", "lint", "tests"];
52289
- var RunQualityGateInputSchema = z102.object({
52922
+ var RunQualityGateInputSchema = z103.object({
52290
52923
  /** Project directory to run checks against. Must resolve inside the repo/cwd root. */
52291
- projectDir: z102.string().optional().describe(
52924
+ projectDir: z103.string().optional().describe(
52292
52925
  "Project directory to run checks against (default: cwd). Must stay inside the repo root."
52293
52926
  ),
52294
52927
  /** Which allowlisted checks to run. */
52295
- checks: z102.array(QualityCheckSchema).nonempty().default([...DEFAULT_CHECKS]).describe("Allowlisted checks to run (default: ['typecheck','lint','tests'])."),
52928
+ checks: z103.array(QualityCheckSchema).nonempty().default([...DEFAULT_CHECKS]).describe("Allowlisted checks to run (default: ['typecheck','lint','tests'])."),
52296
52929
  /** 1-based iteration counter, forwarded to the engine for feedback context. */
52297
- iteration: z102.number().int().min(1).default(1).describe("1-based iteration number (default 1).")
52930
+ iteration: z103.number().int().min(1).default(1).describe("1-based iteration number (default 1).")
52298
52931
  });
52299
52932
  function validateProjectDir(raw) {
52300
52933
  const candidate = raw ?? process.cwd();
@@ -52369,11 +53002,11 @@ var DESCRIPTION2 = "Run the QA quality gate (#1684 engine) against a project dir
52369
53002
  function registerRunQualityGateTool(server, deps) {
52370
53003
  const logger58 = deps.logger ?? createLogger({ tool: "run_quality_gate" });
52371
53004
  const toolSchema = {
52372
- projectDir: z102.string().optional().describe(
53005
+ projectDir: z103.string().optional().describe(
52373
53006
  "Project directory to run checks against (default: cwd). Must stay inside the repo root."
52374
53007
  ),
52375
- checks: z102.array(QualityCheckSchema).nonempty().optional().describe("Allowlisted checks to run (default: ['typecheck','lint','tests'])."),
52376
- iteration: z102.number().int().min(1).optional().describe("1-based iteration number (default 1).")
53008
+ checks: z103.array(QualityCheckSchema).nonempty().optional().describe("Allowlisted checks to run (default: ['typecheck','lint','tests'])."),
53009
+ iteration: z103.number().int().min(1).optional().describe("1-based iteration number (default 1).")
52377
53010
  };
52378
53011
  const secureHandler = createSecureHandler(
52379
53012
  (args) => runQualityGateHandler(args, logger58),
@@ -52403,7 +53036,7 @@ function registerRunQualityGateTool(server, deps) {
52403
53036
  // src/mcp/tools/verify-audit-chain-tool.ts
52404
53037
  import * as fs8 from "node:fs/promises";
52405
53038
  import * as path7 from "node:path";
52406
- import { z as z103 } from "zod";
53039
+ import { z as z104 } from "zod";
52407
53040
 
52408
53041
  // src/cli-server-auth.ts
52409
53042
  function resolveAuthEnabled(config) {
@@ -52577,11 +53210,11 @@ function logSecurityConfig(logger58, config) {
52577
53210
  }
52578
53211
 
52579
53212
  // src/mcp/tools/verify-audit-chain-tool.ts
52580
- var VerifyAuditChainInputSchema = z103.object({
52581
- logDir: z103.string().min(1).max(512).describe(
53213
+ var VerifyAuditChainInputSchema = z104.object({
53214
+ logDir: z104.string().min(1).max(512).describe(
52582
53215
  "Filesystem path to the FileAuditStorage log directory. Must lie inside the nexus data dir, a repo-local `.nexus-agents/`, or the configured `security.audit.logDir`. Tool reads all `audit-*.jsonl` files in lexicographic order and verifies the combined chain."
52583
53216
  ),
52584
- filePrefix: z103.string().min(1).max(64).optional().default(DEFAULT_AUDIT_FILE_PREFIX).describe(
53217
+ filePrefix: z104.string().min(1).max(64).optional().default(DEFAULT_AUDIT_FILE_PREFIX).describe(
52585
53218
  'Filename prefix for audit log files (defaults to "audit"). Files matching `${filePrefix}-*.jsonl` will be verified.'
52586
53219
  )
52587
53220
  });
@@ -52710,10 +53343,10 @@ async function handler2(args, ctx, security) {
52710
53343
  function registerVerifyAuditChainTool(server, deps) {
52711
53344
  const logger58 = deps.logger ?? createLogger({ tool: "verify_audit_chain" });
52712
53345
  const toolSchema = {
52713
- logDir: z103.string().min(1).max(512).describe(
53346
+ logDir: z104.string().min(1).max(512).describe(
52714
53347
  "Filesystem path to the FileAuditStorage log directory. Must lie inside the nexus data dir, a repo-local `.nexus-agents/`, or the configured `security.audit.logDir`. Tool reads all `audit-*.jsonl` files and verifies the combined hash chain."
52715
53348
  ),
52716
- filePrefix: z103.string().min(1).max(64).optional().describe(
53349
+ filePrefix: z104.string().min(1).max(64).optional().describe(
52717
53350
  'Filename prefix for audit log files (defaults to "audit"). Files matching `${filePrefix}-*.jsonl` will be verified.'
52718
53351
  )
52719
53352
  };
@@ -52737,15 +53370,15 @@ function registerVerifyAuditChainTool(server, deps) {
52737
53370
  }
52738
53371
 
52739
53372
  // src/mcp/tools/suggest-research-tasks-tool.ts
52740
- import { z as z104 } from "zod";
53373
+ import { z as z105 } from "zod";
52741
53374
  var SUGGEST_RESEARCH_TASKS_NOTE = "Suggestions derived from external research (untrusted); review before acting \u2014 nothing was executed or filed.";
52742
53375
  var RESEARCH_BUDGET_MS = 2e4;
52743
53376
  var RESEARCH_TIMED_OUT = /* @__PURE__ */ Symbol("research-budget-exceeded");
52744
53377
  async function withResearchBudget(p, ms) {
52745
53378
  let timer;
52746
- const budget = new Promise((resolve12) => {
53379
+ const budget = new Promise((resolve13) => {
52747
53380
  timer = setTimeout(() => {
52748
- resolve12(RESEARCH_TIMED_OUT);
53381
+ resolve13(RESEARCH_TIMED_OUT);
52749
53382
  }, ms);
52750
53383
  });
52751
53384
  try {
@@ -52754,11 +53387,11 @@ async function withResearchBudget(p, ms) {
52754
53387
  if (timer !== void 0) clearTimeout(timer);
52755
53388
  }
52756
53389
  }
52757
- var SuggestResearchTasksInputSchema = z104.object({
52758
- topic: z104.string().optional().describe("Topic filter passed to research_discover. Optional."),
52759
- qualityThreshold: z104.number().min(0).max(10).optional().describe("Minimum quality score (0-10) a discovery must meet to be suggested. Optional."),
52760
- maxTriggers: z104.number().int().min(1).optional().describe("Max number of candidate tasks to return (>=1). Optional."),
52761
- existingTaskIds: z104.array(z104.string()).optional().describe("Known task IDs to skip (dedup). Optional.")
53390
+ var SuggestResearchTasksInputSchema = z105.object({
53391
+ topic: z105.string().optional().describe("Topic filter passed to research_discover. Optional."),
53392
+ qualityThreshold: z105.number().min(0).max(10).optional().describe("Minimum quality score (0-10) a discovery must meet to be suggested. Optional."),
53393
+ maxTriggers: z105.number().int().min(1).optional().describe("Max number of candidate tasks to return (>=1). Optional."),
53394
+ existingTaskIds: z105.array(z105.string()).optional().describe("Known task IDs to skip (dedup). Optional.")
52762
53395
  });
52763
53396
  function toTriggerConfig(input) {
52764
53397
  return {
@@ -52815,10 +53448,10 @@ var DESCRIPTION3 = "SUGGEST-ONLY: surface candidate pipeline tasks for human/orc
52815
53448
  function registerSuggestResearchTasksTool(server, deps) {
52816
53449
  const logger58 = deps.logger ?? createLogger({ tool: "suggest_research_tasks" });
52817
53450
  const toolSchema = {
52818
- topic: z104.string().optional().describe("Topic filter passed to research_discover. Optional."),
52819
- qualityThreshold: z104.number().min(0).max(10).optional().describe("Minimum quality score (0-10) a discovery must meet to be suggested. Optional."),
52820
- maxTriggers: z104.number().int().min(1).optional().describe("Max number of candidate tasks to return (>=1). Optional."),
52821
- existingTaskIds: z104.array(z104.string()).optional().describe("Known task IDs to skip (dedup). Optional.")
53451
+ topic: z105.string().optional().describe("Topic filter passed to research_discover. Optional."),
53452
+ qualityThreshold: z105.number().min(0).max(10).optional().describe("Minimum quality score (0-10) a discovery must meet to be suggested. Optional."),
53453
+ maxTriggers: z105.number().int().min(1).optional().describe("Max number of candidate tasks to return (>=1). Optional."),
53454
+ existingTaskIds: z105.array(z105.string()).optional().describe("Known task IDs to skip (dedup). Optional.")
52822
53455
  };
52823
53456
  const secureHandler = createSecureHandler(
52824
53457
  (args) => suggestResearchTasksHandler(args, logger58),
@@ -52846,7 +53479,7 @@ function registerSuggestResearchTasksTool(server, deps) {
52846
53479
  }
52847
53480
 
52848
53481
  // src/mcp/tools/run-tool.ts
52849
- import { z as z108 } from "zod";
53482
+ import { z as z109 } from "zod";
52850
53483
  import { randomUUID as randomUUID19 } from "node:crypto";
52851
53484
 
52852
53485
  // src/orchestration/consensus-enforcement-mode.ts
@@ -53468,7 +54101,7 @@ function createMetaOrchestrator(options) {
53468
54101
 
53469
54102
  // src/orchestration/meta-shadow-selector.ts
53470
54103
  import { appendFileSync as appendFileSync6, existsSync as existsSync14, readFileSync as readFileSync12 } from "node:fs";
53471
- import { z as z105 } from "zod";
54104
+ import { z as z106 } from "zod";
53472
54105
  var SHADOW_STRATEGY_ARMS = [
53473
54106
  "single-shot",
53474
54107
  "dev-pipeline",
@@ -53557,19 +54190,19 @@ function createHydratableSelector() {
53557
54190
  var META_OUTCOME_SCHEMA_VERSION = 1;
53558
54191
  var HYDRATE_LOOKBACK_DAYS = 30;
53559
54192
  var HYDRATE_LOOKBACK_MS = HYDRATE_LOOKBACK_DAYS * 24 * 60 * 60 * 1e3;
53560
- var PersistedContextSchema = z105.object({
53561
- taskComplexity: z105.number(),
53562
- contextLengthNormalized: z105.number(),
53563
- isCodeTask: z105.number(),
53564
- isReasoningTask: z105.number(),
53565
- budgetUtilization: z105.number(),
53566
- timePressure: z105.number()
54193
+ var PersistedContextSchema = z106.object({
54194
+ taskComplexity: z106.number(),
54195
+ contextLengthNormalized: z106.number(),
54196
+ isCodeTask: z106.number(),
54197
+ isReasoningTask: z106.number(),
54198
+ budgetUtilization: z106.number(),
54199
+ timePressure: z106.number()
53567
54200
  });
53568
- var PersistedMetaOutcomeSchema = z105.object({
53569
- schema: z105.literal(META_OUTCOME_SCHEMA_VERSION),
53570
- timestamp: z105.string(),
53571
- strategy: z105.enum(SHADOW_STRATEGY_ARMS),
53572
- success: z105.boolean(),
54201
+ var PersistedMetaOutcomeSchema = z106.object({
54202
+ schema: z106.literal(META_OUTCOME_SCHEMA_VERSION),
54203
+ timestamp: z106.string(),
54204
+ strategy: z106.enum(SHADOW_STRATEGY_ARMS),
54205
+ success: z106.boolean(),
53573
54206
  context: PersistedContextSchema
53574
54207
  });
53575
54208
  var persistLogger = createLogger({ component: "MetaShadowSelector" });
@@ -53962,7 +54595,7 @@ function evaluateMetaStrategyReadiness(result, config = DEFAULT_META_STRATEGY_RE
53962
54595
  }
53963
54596
 
53964
54597
  // src/mcp/tools/dev-pipeline-tool.ts
53965
- import { z as z106 } from "zod";
54598
+ import { z as z107 } from "zod";
53966
54599
  import * as fs10 from "node:fs";
53967
54600
  import { randomUUID as randomUUID17 } from "node:crypto";
53968
54601
 
@@ -54016,8 +54649,11 @@ function warningsField(result) {
54016
54649
  return result.warnings !== void 0 ? { warnings: result.warnings } : {};
54017
54650
  }
54018
54651
  function securityStatus(result) {
54019
- if (result.securityRan !== true) return { status: "unmeasured" };
54020
- return { status: result.securityPassed ? "passed" : "failed" };
54652
+ const comparison = result.securityComparison ?? {};
54653
+ if (result.securityRan !== true || result.securityComparison?.complete === false) {
54654
+ return { status: "unmeasured", ...comparison };
54655
+ }
54656
+ return { status: result.securityPassed ? "passed" : "failed", ...comparison };
54021
54657
  }
54022
54658
  function planVoteVerdictFields(result) {
54023
54659
  return {
@@ -54030,7 +54666,7 @@ function planVoteVerdictFields(result) {
54030
54666
  }
54031
54667
 
54032
54668
  // src/mcp/tools/dev-pipeline-tool.ts
54033
- import { resolve as resolve10 } from "node:path";
54669
+ import { resolve as resolve11 } from "node:path";
54034
54670
 
54035
54671
  // src/mcp/tools/dev-pipeline-options.ts
54036
54672
  function buildPipelineOptions(input, trustTier, auditLogger) {
@@ -54223,48 +54859,48 @@ var DEV_PIPELINE_DRY_RUN_NOTE = "This was a dry run (plan+vote), which always ru
54223
54859
  function dispatchNoteFor(dryRun) {
54224
54860
  return dryRun ? DEV_PIPELINE_DRY_RUN_NOTE : DEV_PIPELINE_ASYNC_HINT;
54225
54861
  }
54226
- var DevPipelineInputSchema = z106.object({
54862
+ var DevPipelineInputSchema = z107.object({
54227
54863
  /** Direct task instructions. */
54228
- task: z106.string().max(1e4).optional().describe("Direct task instructions (what to build)"),
54864
+ task: z107.string().max(1e4).optional().describe("Direct task instructions (what to build)"),
54229
54865
  /** Declared provenance of the task text (#6795); omitted means '3'. */
54230
54866
  sourceTrustTier: TaskSourceTrustTierSchema,
54231
54867
  /** Path to a plan file (.md, .yaml, .txt) to use as input. */
54232
- planFile: z106.string().max(500).optional().describe("Path to a plan/spec file to use as input"),
54868
+ planFile: z107.string().max(500).optional().describe("Path to a plan/spec file to use as input"),
54233
54869
  /** Whether to run in dry-run mode (plan+vote only, no implementation). */
54234
- dryRun: z106.boolean().default(false).describe("If true, stop after plan+vote (no implementation)"),
54870
+ dryRun: z107.boolean().default(false).describe("If true, stop after plan+vote (no implementation)"),
54235
54871
  /** Maximum vote iterations before proceeding (default: 3). */
54236
- maxVoteIterations: z106.number().int().min(1).max(5).default(3).describe("Max plan\u2192vote iterations"),
54872
+ maxVoteIterations: z107.number().int().min(1).max(5).default(3).describe("Max plan\u2192vote iterations"),
54237
54873
  /** Maximum QA iterations per task (default: 3). */
54238
- maxQaIterations: z106.number().int().min(1).max(5).default(3).describe("Max QA review iterations per task"),
54874
+ maxQaIterations: z107.number().int().min(1).max(5).default(3).describe("Max QA review iterations per task"),
54239
54875
  /** Working directory for the pipeline (default: cwd). Used for security scan and context. */
54240
- workingDir: z106.string().max(500).optional().describe("Working directory (default: cwd)"),
54876
+ workingDir: z107.string().max(500).optional().describe("Working directory (default: cwd)"),
54241
54877
  /** GitHub issue number to track progress on. Updates posted as comments. */
54242
- issueNumber: z106.number().int().positive().optional().describe("GitHub issue to post progress to"),
54878
+ issueNumber: z107.number().int().positive().optional().describe("GitHub issue to post progress to"),
54243
54879
  /** GitHub repo (owner/name) for issue tracking. */
54244
- repo: z106.string().max(200).optional().describe("GitHub repo for issue tracking (e.g., owner/repo)"),
54880
+ repo: z107.string().max(200).optional().describe("GitHub repo for issue tracking (e.g., owner/repo)"),
54245
54881
  /** Task tracking backend: github, gitlab, or json (default: json). */
54246
- trackerBackend: z106.enum(["github", "gitlab", "json"]).default("json").describe("Task tracking backend for issue creation"),
54882
+ trackerBackend: z107.enum(["github", "gitlab", "json"]).default("json").describe("Task tracking backend for issue creation"),
54247
54883
  /** Labels to apply to created issues. */
54248
- labels: z106.array(z106.string()).optional().describe("Labels for created issues"),
54884
+ labels: z107.array(z107.string()).optional().describe("Labels for created issues"),
54249
54885
  /** Session ID for checkpoint/resume. Enables crash recovery. */
54250
- sessionId: z106.string().max(128).regex(/^[a-zA-Z0-9_-]+$/).optional().describe("Session ID for checkpoint/resume (crash recovery)"),
54886
+ sessionId: z107.string().max(128).regex(/^[a-zA-Z0-9_-]+$/).optional().describe("Session ID for checkpoint/resume (crash recovery)"),
54251
54887
  /**
54252
54888
  * TESTS ONLY — when true, voters return random decisions. Must not be used as
54253
54889
  * a fallback when adapters are unavailable; configure an adapter instead. (#2319)
54254
54890
  */
54255
- simulateVotes: z106.boolean().default(false).describe("TESTS ONLY \u2014 random output, must not be used for real decisions (#2319)"),
54891
+ simulateVotes: z107.boolean().default(false).describe("TESTS ONLY \u2014 random output, must not be used for real decisions (#2319)"),
54256
54892
  /** Voting strategy for consensus stages. */
54257
54893
  votingStrategy: VotingStrategySchema.optional().describe(
54258
54894
  "Voting strategy for plan approval (default: higher_order)"
54259
54895
  ),
54260
54896
  /** Use 3 agents instead of 6 for faster voting. */
54261
- quickMode: z106.boolean().default(false).describe("Use 3 agents instead of 6 for faster consensus voting"),
54897
+ quickMode: z107.boolean().default(false).describe("Use 3 agents instead of 6 for faster consensus voting"),
54262
54898
  /**
54263
54899
  * Deadline for EACH stage call in milliseconds (min 30s, max 600s), not a
54264
54900
  * budget for the whole run (#6736). Replaces every stage's default, the
54265
54901
  * vote's included; clamped to the `pipeline` class guard.
54266
54902
  */
54267
- timeoutMs: z106.number().int().min(3e4).max(6e5).optional().describe(
54903
+ timeoutMs: z107.number().int().min(3e4).max(6e5).optional().describe(
54268
54904
  "Max time for EACH stage call in ms (30000-600000), not for the whole run; applies to every stage, the vote included, and to each plan/vote and implement/QA iteration. A stage past it fails with a timeout and its model calls are aborted. Default: the vote stage gets the multi-LLM panel guard (900000 unless overridden), other stages the pipeline guard (1800000 unless overridden)"
54269
54905
  ),
54270
54906
  /**
@@ -54272,7 +54908,7 @@ var DevPipelineInputSchema = z106.object({
54272
54908
  * dispatch. A caller who learned `mode: 'async'` elsewhere gets an error
54273
54909
  * naming `dispatch` rather than the bare enum message (#4968).
54274
54910
  */
54275
- mode: z106.enum(["autonomous", "harness"], { error: modeEnumErrorNamingDispatch }).default("autonomous").describe(
54911
+ mode: z107.enum(["autonomous", "harness"], { error: modeEnumErrorNamingDispatch }).default("autonomous").describe(
54276
54912
  "'autonomous': full pipeline. 'harness': stops after decompose, returns tasks for caller to implement. (Not the async switch \u2014 that is `dispatch`.)"
54277
54913
  ),
54278
54914
  /**
@@ -54286,11 +54922,11 @@ var DevPipelineInputSchema = z106.object({
54286
54922
  */
54287
54923
  dispatch: dispatchFieldDefaultSync("Ignored for dryRun."),
54288
54924
  /** Local pre-ship quality gate (typecheck/lint/tests) mode (#3356). */
54289
- qualityGate: z106.enum(["off", "advisory", "blocking"]).default("off").describe(
54925
+ qualityGate: z107.enum(["off", "advisory", "blocking"]).default("off").describe(
54290
54926
  "Pre-ship local quality gate. 'off' (default): skip. 'advisory': run + record feedback, never fail. 'blocking': a red gate fails the pipeline."
54291
54927
  ),
54292
54928
  /** Opt-in per-run token budget — a safety cap for unattended runs (#3395). */
54293
- maxBudgetTokens: z106.number().int().positive().optional().describe(
54929
+ maxBudgetTokens: z107.number().int().positive().optional().describe(
54294
54930
  "Per-run token ceiling (#3395). When set, expert calls stop (returning failures) once cumulative usage crosses it \u2014 a hard-stop safety cap for unattended/multi-day runs. Omit to disable (default)."
54295
54931
  )
54296
54932
  });
@@ -54319,7 +54955,7 @@ function containWorkingDir(workingDir) {
54319
54955
  const roots = [process.cwd()];
54320
54956
  const workspaceRoot = getActiveWorkspaceRoot();
54321
54957
  if (workspaceRoot !== void 0) roots.push(workspaceRoot);
54322
- const absolute = resolve10(workingDir);
54958
+ const absolute = resolve11(workingDir);
54323
54959
  for (const root of roots) {
54324
54960
  const contained = resolveInsideRoot(absolute, root);
54325
54961
  if (contained !== null) return contained;
@@ -54377,7 +55013,7 @@ async function executeDevPipelineBody(taskText, stages, pipelineOptions, simulat
54377
55013
  detail: output2
54378
55014
  });
54379
55015
  }
54380
- return structuredToolSuccess(z106.record(z106.string(), z106.unknown()), output2);
55016
+ return structuredToolSuccess(z107.record(z107.string(), z107.unknown()), output2);
54381
55017
  }
54382
55018
  function describeIncompleteRun(result) {
54383
55019
  if (result.planStatus !== void 0) {
@@ -54509,33 +55145,33 @@ function registerDevPipelineTool(server, deps) {
54509
55145
  }
54510
55146
 
54511
55147
  // src/mcp/tools/pipeline-tool.ts
54512
- import { z as z107 } from "zod";
55148
+ import { z as z108 } from "zod";
54513
55149
  import * as fs11 from "node:fs";
54514
55150
  import { randomUUID as randomUUID18 } from "node:crypto";
54515
55151
  var PIPELINE_ASYNC_HINT = "A full run_pipeline run can exceed the synchronous MCP request timeout. Retry with `dispatch: 'async'` to get a jobId immediately, then poll get_job_result({ jobId }) for the result.";
54516
- var PipelineInputSchema = z107.object({
55152
+ var PipelineInputSchema = z108.object({
54517
55153
  /** The task to execute. */
54518
- task: z107.string().min(5).max(1e4).describe("Task description \u2014 pipeline template auto-selected based on content"),
55154
+ task: z108.string().min(5).max(1e4).describe("Task description \u2014 pipeline template auto-selected based on content"),
54519
55155
  /** Path to a spec file (.md, .yaml) to use as task input. */
54520
- specFile: z107.string().max(500).optional().describe("Path to a spec file \u2014 content prepended to task for greenfield projects"),
55156
+ specFile: z108.string().max(500).optional().describe("Path to a spec file \u2014 content prepended to task for greenfield projects"),
54521
55157
  /** Override template — see `listTemplateIds()` for the canonical list (#2728). Auto-detected if omitted. */
54522
- template: z107.string().max(50).optional().describe(`Pipeline template override. Available: ${listTemplateIds().join(", ")}`),
55158
+ template: z108.string().max(50).optional().describe(`Pipeline template override. Available: ${listTemplateIds().join(", ")}`),
54523
55159
  /** Voting strategy for consensus stages. */
54524
55160
  votingStrategy: VotingStrategySchema.optional().describe(
54525
55161
  "Voting strategy for plan approval. simple_majority (default), supermajority (67%), unanimous, higher_order (Bayesian), opinion_wise"
54526
55162
  ),
54527
55163
  /** Use 3 agents instead of 7 for faster voting. */
54528
- quickMode: z107.boolean().default(false).describe("Use 3 agents instead of 7 for faster consensus voting"),
55164
+ quickMode: z108.boolean().default(false).describe("Use 3 agents instead of 7 for faster consensus voting"),
54529
55165
  /**
54530
55166
  * Deadline for EACH stage in milliseconds (min 30s, max 600s), not a budget
54531
55167
  * for the whole run (#6730). Replaces every stage's default, the vote's
54532
55168
  * included; clamped to the `pipeline` class guard.
54533
55169
  */
54534
- timeoutMs: z107.number().int().min(3e4).max(6e5).optional().describe(
55170
+ timeoutMs: z108.number().int().min(3e4).max(6e5).optional().describe(
54535
55171
  "Max time for EACH stage in ms (30000-600000), not for the whole run; applies to every stage, the vote included. Default: the vote stage gets the multi-LLM panel guard (900000 unless overridden), other stages 120000"
54536
55172
  ),
54537
55173
  /** Stop after planning/voting (no implementation). */
54538
- dryRun: z107.boolean().default(false).describe("Stop after vote stage (no implementation)"),
55174
+ dryRun: z108.boolean().default(false).describe("Stop after vote stage (no implementation)"),
54539
55175
  /**
54540
55176
  * Dispatch mode (#3730). `sync` (default) runs the pipeline inline and
54541
55177
  * returns the result — but a real multi-stage adaptive run can exceed the
@@ -54546,7 +55182,7 @@ var PipelineInputSchema = z107.object({
54546
55182
  */
54547
55183
  ...asyncDispatchInputDefaultSync("Ignored for dryRun."),
54548
55184
  /** TESTS ONLY — random output, must not be used for real decisions. (#2319) */
54549
- simulateVotes: z107.boolean().default(false).describe("TESTS ONLY \u2014 random output, must not be used for real decisions (#2319)")
55185
+ simulateVotes: z108.boolean().default(false).describe("TESTS ONLY \u2014 random output, must not be used for real decisions (#2319)")
54550
55186
  });
54551
55187
  function buildOutput3(result, simulated) {
54552
55188
  return {
@@ -54572,14 +55208,14 @@ function buildOutput3(result, simulated) {
54572
55208
  rateLimitHint: result.error?.toLowerCase().includes("rate limit") === true ? "Consider using quickMode or increasing delay between pipeline runs" : void 0
54573
55209
  };
54574
55210
  }
54575
- var VoteEvidenceSchema = z107.object({
54576
- approvalPercentage: z107.number(),
54577
- voteRecordId: z107.string().optional()
55211
+ var VoteEvidenceSchema = z108.object({
55212
+ approvalPercentage: z108.number(),
55213
+ voteRecordId: z108.string().optional()
54578
55214
  });
54579
- var VoteResultSchema = z107.discriminatedUnion("kind", [
54580
- VoteEvidenceSchema.extend({ kind: z107.literal("approved") }),
54581
- VoteEvidenceSchema.extend({ kind: z107.literal("rejected"), feedback: z107.string() }),
54582
- VoteEvidenceSchema.extend({ kind: z107.literal("no_quorum"), reason: z107.string() })
55215
+ var VoteResultSchema = z108.discriminatedUnion("kind", [
55216
+ VoteEvidenceSchema.extend({ kind: z108.literal("approved") }),
55217
+ VoteEvidenceSchema.extend({ kind: z108.literal("rejected"), feedback: z108.string() }),
55218
+ VoteEvidenceSchema.extend({ kind: z108.literal("no_quorum"), reason: z108.string() })
54583
55219
  ]);
54584
55220
  function isVoteResult(value) {
54585
55221
  return VoteResultSchema.safeParse(value).success;
@@ -54681,7 +55317,7 @@ async function executePipelineBody(task, stages, run) {
54681
55317
  detail: output2
54682
55318
  });
54683
55319
  }
54684
- return structuredToolSuccess(z107.record(z107.string(), z107.unknown()), output2);
55320
+ return structuredToolSuccess(z108.record(z108.string(), z108.unknown()), output2);
54685
55321
  }
54686
55322
  function createPipelineAgentStages(input, config) {
54687
55323
  return createAgentStages({
@@ -54832,9 +55468,9 @@ function cancellableExecutor(strategy, executor, signal) {
54832
55468
  }
54833
55469
 
54834
55470
  // src/mcp/tools/run-tool.ts
54835
- var RunInputSchema = z108.object({
54836
- goal: z108.string().min(1).describe("Natural-language goal. nexus-agents selects how to execute it."),
54837
- forceStrategy: z108.enum([
55471
+ var RunInputSchema = z109.object({
55472
+ goal: z109.string().min(1).describe("Natural-language goal. nexus-agents selects how to execute it."),
55473
+ forceStrategy: z109.enum([
54838
55474
  "single-shot",
54839
55475
  "dev-pipeline",
54840
55476
  "pipeline",
@@ -54846,10 +55482,10 @@ var RunInputSchema = z108.object({
54846
55482
  ]).optional().describe(
54847
55483
  "Power-user override: force a specific strategy instead of letting the router choose."
54848
55484
  ),
54849
- requiresConsensus: z108.boolean().optional().describe("Hint: the task needs a multi-perspective consensus decision."),
54850
- dependencyStructure: z108.enum(["linear", "dag", "independent", "unknown"]).optional().describe("Hint: the dependency structure of the work."),
54851
- isNovel: z108.boolean().optional().describe("Hint: this kind of task has not been seen before."),
54852
- execute: z108.boolean().optional().describe(
55485
+ requiresConsensus: z109.boolean().optional().describe("Hint: the task needs a multi-perspective consensus decision."),
55486
+ dependencyStructure: z109.enum(["linear", "dag", "independent", "unknown"]).optional().describe("Hint: the dependency structure of the work."),
55487
+ isNovel: z109.boolean().optional().describe("Hint: this kind of task has not been seen before."),
55488
+ execute: z109.boolean().optional().describe(
54853
55489
  "When true, actually run the selected strategy (if an executor is wired) and return its result; otherwise return the routing decision only (default false, read-only)."
54854
55490
  ),
54855
55491
  /**
@@ -54864,7 +55500,7 @@ var RunInputSchema = z108.object({
54864
55500
  * other, the call is REFUSED rather than executed: silently ignoring a
54865
55501
  * do-not-act flag is the one outcome a governance substrate cannot allow.
54866
55502
  */
54867
- dryRun: z108.boolean().optional().describe(
55503
+ dryRun: z109.boolean().optional().describe(
54868
55504
  "Plan and vote only, no implementation (#4806). Requires the dev-pipeline strategy \u2014 refused (never silently executed) when the router selects another."
54869
55505
  ),
54870
55506
  /**
@@ -55100,12 +55736,12 @@ function registerRunTool(server, deps) {
55100
55736
  }
55101
55737
 
55102
55738
  // src/mcp/tools/list-available-models-tool.ts
55103
- import { z as z109 } from "zod";
55739
+ import { z as z110 } from "zod";
55104
55740
  var DESCRIPTION5 = "Probe every model-discovery transport (OpenRouter API, the configured gateway, and the opencode/claude/codex/gemini CLIs) and report a per-transport health summary: probe ok/failed, model count, and a sample of usable ids. Models with open route breakers are excluded; each CLI reports whether its default-route breaker is open. Use it to validate the CLIs and APIs are wired and reachable. Read-only; does not change routing.";
55105
55741
  var PROBE_TIMEOUT_MS = 12e3;
55106
- var ListAvailableModelsInputSchema = z109.object({
55107
- includeModelIds: z109.boolean().optional().describe("Include the full model-id list per transport (default false \u2192 sample of 5 only)."),
55108
- includeOpenRouter: z109.boolean().optional().describe("Probe the OpenRouter live catalog (default true).")
55742
+ var ListAvailableModelsInputSchema = z110.object({
55743
+ includeModelIds: z110.boolean().optional().describe("Include the full model-id list per transport (default false \u2192 sample of 5 only)."),
55744
+ includeOpenRouter: z110.boolean().optional().describe("Probe the OpenRouter live catalog (default true).")
55109
55745
  });
55110
55746
  async function probeSource(source, includeModelIds) {
55111
55747
  let timer;
@@ -55214,8 +55850,8 @@ async function listAvailableModelsHandler(args, deps, logger58) {
55214
55850
  function registerListAvailableModelsTool(server, deps) {
55215
55851
  const logger58 = deps.logger ?? createLogger({ tool: "list_available_models" });
55216
55852
  const toolSchema = {
55217
- includeModelIds: z109.boolean().optional().describe("Include the full model-id list per transport (default false \u2192 sample of 5 only)."),
55218
- includeOpenRouter: z109.boolean().optional().describe("Probe the OpenRouter live catalog (default true).")
55853
+ includeModelIds: z110.boolean().optional().describe("Include the full model-id list per transport (default false \u2192 sample of 5 only)."),
55854
+ includeOpenRouter: z110.boolean().optional().describe("Probe the OpenRouter live catalog (default true).")
55219
55855
  };
55220
55856
  const secureHandler = createSecureHandler(
55221
55857
  (args) => listAvailableModelsHandler(args, deps, logger58),
@@ -55239,9 +55875,9 @@ function registerListAvailableModelsTool(server, deps) {
55239
55875
  }
55240
55876
 
55241
55877
  // src/mcp/tools/pr-review-eval-types.ts
55242
- import { z as z110 } from "zod";
55878
+ import { z as z111 } from "zod";
55243
55879
  var MAX_EVAL_FINDINGS = 100;
55244
- var VoterEvalFindingSchema = z110.object({
55880
+ var VoterEvalFindingSchema = z111.object({
55245
55881
  summary: RawFindingSchema.shape.summary,
55246
55882
  location: RawFindingSchema.shape.location,
55247
55883
  severity: RawFindingSchema.shape.severity.unwrap(),
@@ -55249,14 +55885,14 @@ var VoterEvalFindingSchema = z110.object({
55249
55885
  gate: RawFindingSchema.shape.gate.extend({
55250
55886
  named_assertion: RawFindingSchema.shape.claim.min(0)
55251
55887
  }).optional(),
55252
- verified: z110.boolean().optional(),
55253
- classification: z110.enum(["TP", "FP", "FN", "excluded"]),
55254
- source: z110.enum(["voter", "ground_truth"]),
55888
+ verified: z111.boolean().optional(),
55889
+ classification: z111.enum(["TP", "FP", "FN", "excluded"]),
55890
+ source: z111.enum(["voter", "ground_truth"]),
55255
55891
  /** Original index in the voter's raw findings; repeated TP evidence shares it. */
55256
- findingIndex: z110.number().int().nonnegative().optional(),
55257
- knownBugIndex: z110.number().int().nonnegative().optional(),
55892
+ findingIndex: z111.number().int().nonnegative().optional(),
55893
+ knownBugIndex: z111.number().int().nonnegative().optional(),
55258
55894
  /** String fields shortened by the producer, never silently truncated. */
55259
- truncatedFields: z110.array(z110.enum(["summary", "location", "rationale", "gate.named_assertion"])).max(4).optional()
55895
+ truncatedFields: z111.array(z111.enum(["summary", "location", "rationale", "gate.named_assertion"])).max(4).optional()
55260
55896
  });
55261
55897
  var PR_REVIEW_EVAL_ROLES = [
55262
55898
  "architect",
@@ -55265,47 +55901,47 @@ var PR_REVIEW_EVAL_ROLES = [
55265
55901
  "catfish",
55266
55902
  "scope_steward"
55267
55903
  ];
55268
- var PrReviewEvalRoleSchema = z110.enum(PR_REVIEW_EVAL_ROLES);
55269
- var PrReviewCaseClassSchema = z110.enum(["buggy", "clean", "borderline"]);
55270
- var VoterEvalVerdictSchema = z110.object({
55904
+ var PrReviewEvalRoleSchema = z111.enum(PR_REVIEW_EVAL_ROLES);
55905
+ var PrReviewCaseClassSchema = z111.enum(["buggy", "clean", "borderline"]);
55906
+ var VoterEvalVerdictSchema = z111.object({
55271
55907
  /** Stable record id (e.g. `${runId}:${caseNumber}:${role}`). */
55272
- id: z110.string().min(1).max(160),
55908
+ id: z111.string().min(1).max(160),
55273
55909
  /** The pr_review run / batch this verdict belongs to. */
55274
- runId: z110.string().min(1).max(64),
55910
+ runId: z111.string().min(1).max(64),
55275
55911
  /** Dataset case identifier (the dataset's `number` field). */
55276
- caseNumber: z110.string().min(1).max(80),
55912
+ caseNumber: z111.string().min(1).max(80),
55277
55913
  /** Rubric class of the case (ground-truth label). */
55278
55914
  caseClass: PrReviewCaseClassSchema,
55279
55915
  /** The voter role being scored. */
55280
55916
  role: PrReviewEvalRoleSchema,
55281
55917
  /** Verified findings that matched a known bug. */
55282
- truePositives: z110.number().int().nonnegative(),
55918
+ truePositives: z111.number().int().nonnegative(),
55283
55919
  /** Verified findings on clean code that matched no known bug. */
55284
- falsePositives: z110.number().int().nonnegative(),
55920
+ falsePositives: z111.number().int().nonnegative(),
55285
55921
  /** Known bugs this voter failed to flag. */
55286
- falseNegatives: z110.number().int().nonnegative(),
55922
+ falseNegatives: z111.number().int().nonnegative(),
55287
55923
  /** Optional for legacy records/count-only callers; [] means measured, no evidence. */
55288
- findings: z110.array(VoterEvalFindingSchema).max(MAX_EVAL_FINDINGS).optional(),
55924
+ findings: z111.array(VoterEvalFindingSchema).max(MAX_EVAL_FINDINGS).optional(),
55289
55925
  /** Number of evidence entries omitted at the cap; full tallies are unchanged. */
55290
- findingsTruncated: z110.number().int().nonnegative().optional(),
55926
+ findingsTruncated: z111.number().int().nonnegative().optional(),
55291
55927
  /** Rubric version the ground truth was adjudicated under. */
55292
- rubricVersion: z110.string().min(1).max(32),
55928
+ rubricVersion: z111.string().min(1).max(32),
55293
55929
  /** ISO-8601 timestamp the verdict was recorded. */
55294
- timestamp: z110.string().min(1).max(40)
55930
+ timestamp: z111.string().min(1).max(40)
55295
55931
  });
55296
- var VoterEvalVerdictQuerySchema = z110.object({
55932
+ var VoterEvalVerdictQuerySchema = z111.object({
55297
55933
  role: PrReviewEvalRoleSchema.optional(),
55298
- runId: z110.string().min(1).max(64).optional(),
55934
+ runId: z111.string().min(1).max(64).optional(),
55299
55935
  caseClass: PrReviewCaseClassSchema.optional(),
55300
- rubricVersion: z110.string().min(1).max(32).optional(),
55936
+ rubricVersion: z111.string().min(1).max(32).optional(),
55301
55937
  /** ISO-8601 lower bound (inclusive) on `timestamp`. */
55302
- since: z110.string().optional(),
55938
+ since: z111.string().optional(),
55303
55939
  /** Most-recent-N cap. */
55304
- limit: z110.number().int().positive().optional()
55940
+ limit: z111.number().int().positive().optional()
55305
55941
  });
55306
55942
 
55307
55943
  // src/mcp/tools/supply-chain-tradeoff-panel.ts
55308
- import { z as z111 } from "zod";
55944
+ import { z as z112 } from "zod";
55309
55945
  import { randomUUID as randomUUID20 } from "node:crypto";
55310
55946
  var DEFAULT_AXES = [
55311
55947
  "build_time_determinism",
@@ -55327,16 +55963,16 @@ var FULL_PANEL = [
55327
55963
  "scope_steward"
55328
55964
  ];
55329
55965
  var QUICK_PANEL = ["architect", "security", "scope_steward"];
55330
- var SupplyChainTradeoffPanelInputSchema = z111.object({
55331
- proposal: z111.string().min(1).max(MAX_PROPOSAL_LENGTH).describe('The proposal under tradeoff review (e.g. "Should aegis-boot adopt cargo-nextest?")'),
55332
- axes: z111.array(z111.string().min(1).max(MAX_AXIS_NAME_LENGTH)).min(1).max(MAX_AXES).optional().describe(
55966
+ var SupplyChainTradeoffPanelInputSchema = z112.object({
55967
+ proposal: z112.string().min(1).max(MAX_PROPOSAL_LENGTH).describe('The proposal under tradeoff review (e.g. "Should aegis-boot adopt cargo-nextest?")'),
55968
+ axes: z112.array(z112.string().min(1).max(MAX_AXIS_NAME_LENGTH)).min(1).max(MAX_AXES).optional().describe(
55333
55969
  `Tradeoff axes to evaluate. Default: ${DEFAULT_AXES.join(", ")}. Custom axes accepted; max ${String(MAX_AXES)}.`
55334
55970
  ),
55335
- context: z111.string().max(MAX_CONTEXT_LENGTH).optional().describe(
55971
+ context: z112.string().max(MAX_CONTEXT_LENGTH).optional().describe(
55336
55972
  "Optional context: relevant repo state, dependency tree, vendor publishing patterns, etc."
55337
55973
  ),
55338
- quickMode: z111.boolean().optional().default(false).describe("Use 3 voters (architect, security, scope_steward) instead of 7"),
55339
- simulate: z111.boolean().optional().default(false).describe("Use simulated voters (testing only)"),
55974
+ quickMode: z112.boolean().optional().default(false).describe("Use 3 voters (architect, security, scope_steward) instead of 7"),
55975
+ simulate: z112.boolean().optional().default(false).describe("Use simulated voters (testing only)"),
55340
55976
  // #6123: same field as consensus_vote — the panel judges the caller's project.
55341
55977
  project: VoterProjectInputSchema,
55342
55978
  /**
@@ -55636,7 +56272,7 @@ function createAnnotationsProxy(server) {
55636
56272
 
55637
56273
  // src/mcp/workspace-roots.ts
55638
56274
  import { existsSync as existsSync15, realpathSync as realpathSync6, statSync as statSync4 } from "node:fs";
55639
- import { isAbsolute as isAbsolute6, join as join16 } from "node:path";
56275
+ import { isAbsolute as isAbsolute9, join as join19 } from "node:path";
55640
56276
  import { homedir as homedir3 } from "node:os";
55641
56277
  import { fileURLToPath as fileURLToPath2 } from "node:url";
55642
56278
  function deriveWorkspaceRootFromRoots(roots) {
@@ -55651,7 +56287,7 @@ function deriveWorkspaceRootFromRoots(roots) {
55651
56287
  continue;
55652
56288
  }
55653
56289
  first ??= path9;
55654
- if (gitRoot === null && existsSync15(join16(path9, ".git"))) gitRoot = path9;
56290
+ if (gitRoot === null && existsSync15(join19(path9, ".git"))) gitRoot = path9;
55655
56291
  }
55656
56292
  return gitRoot ?? first;
55657
56293
  }
@@ -55662,7 +56298,7 @@ function resolveClaudeProjectRoot(logger58) {
55662
56298
  const candidate = process.env["CLAUDE_PROJECT_DIR"];
55663
56299
  if (candidate === void 0) return null;
55664
56300
  try {
55665
- if (isAbsolute6(candidate)) {
56301
+ if (isAbsolute9(candidate)) {
55666
56302
  const canonical = realpathSync6(candidate);
55667
56303
  const root = statSync4(canonical).isDirectory() ? findRepoRoot(canonical) : null;
55668
56304
  if (root !== null && setActiveWorkspaceRoot(root)) return root;
@@ -55675,8 +56311,8 @@ function resolveClaudeProjectRoot(logger58) {
55675
56311
  function beginWorkspaceRootResolution(logger58) {
55676
56312
  if (resolution?.timer !== void 0) clearTimeout(resolution.timer);
55677
56313
  let resolveReady;
55678
- workspaceRootReady = new Promise((resolve12) => {
55679
- resolveReady = resolve12;
56314
+ workspaceRootReady = new Promise((resolve13) => {
56315
+ resolveReady = resolve13;
55680
56316
  });
55681
56317
  const root = resolveClaudeProjectRoot(logger58);
55682
56318
  resolution = {
@@ -55958,40 +56594,40 @@ var RiskLevel = /* @__PURE__ */ ((RiskLevel2) => {
55958
56594
  })(RiskLevel || {});
55959
56595
 
55960
56596
  // src/mcp/safety/stpa-schemas.ts
55961
- import { z as z112 } from "zod";
55962
- var HazardCategorySchema = z112.enum(HazardCategory);
55963
- var HazardSeveritySchema = z112.enum(HazardSeverity);
55964
- var ConstraintPrioritySchema = z112.enum(ConstraintPriority);
55965
- var RiskLevelSchema = z112.enum(RiskLevel);
55966
- var TriggerPatternSchema = z112.object({
55967
- parameter: z112.string().min(1),
55968
- matchType: z112.enum(["contains", "regex", "equals", "startsWith", "endsWith"]),
55969
- pattern: z112.string(),
55970
- reason: z112.string()
56597
+ import { z as z113 } from "zod";
56598
+ var HazardCategorySchema = z113.enum(HazardCategory);
56599
+ var HazardSeveritySchema = z113.enum(HazardSeverity);
56600
+ var ConstraintPrioritySchema = z113.enum(ConstraintPriority);
56601
+ var RiskLevelSchema = z113.enum(RiskLevel);
56602
+ var TriggerPatternSchema = z113.object({
56603
+ parameter: z113.string().min(1),
56604
+ matchType: z113.enum(["contains", "regex", "equals", "startsWith", "endsWith"]),
56605
+ pattern: z113.string(),
56606
+ reason: z113.string()
55971
56607
  });
55972
- var HazardSchema = z112.object({
55973
- id: z112.string().min(1),
55974
- description: z112.string(),
56608
+ var HazardSchema = z113.object({
56609
+ id: z113.string().min(1),
56610
+ description: z113.string(),
55975
56611
  category: HazardCategorySchema,
55976
56612
  severity: HazardSeveritySchema,
55977
- likelihood: z112.enum(["almost_certain", "likely", "possible", "unlikely", "rare"]),
55978
- triggerConditions: z112.array(z112.string()),
55979
- consequences: z112.array(z112.string())
56613
+ likelihood: z113.enum(["almost_certain", "likely", "possible", "unlikely", "rare"]),
56614
+ triggerConditions: z113.array(z113.string()),
56615
+ consequences: z113.array(z113.string())
55980
56616
  });
55981
- var UnsafeControlActionSchema = z112.object({
55982
- id: z112.string().min(1),
55983
- toolName: z112.string().min(1),
55984
- type: z112.enum(["not_provided", "provided_causes_hazard", "wrong_timing", "wrong_duration"]),
55985
- description: z112.string(),
55986
- unsafeContext: z112.string(),
55987
- relatedHazards: z112.array(z112.string()),
55988
- triggerPatterns: z112.array(TriggerPatternSchema).optional()
56617
+ var UnsafeControlActionSchema = z113.object({
56618
+ id: z113.string().min(1),
56619
+ toolName: z113.string().min(1),
56620
+ type: z113.enum(["not_provided", "provided_causes_hazard", "wrong_timing", "wrong_duration"]),
56621
+ description: z113.string(),
56622
+ unsafeContext: z113.string(),
56623
+ relatedHazards: z113.array(z113.string()),
56624
+ triggerPatterns: z113.array(TriggerPatternSchema).optional()
55989
56625
  });
55990
- var SafetyConstraintSchema = z112.object({
55991
- id: z112.string().min(1),
55992
- description: z112.string(),
55993
- mitigates: z112.array(z112.string()),
55994
- enforcement: z112.enum([
56626
+ var SafetyConstraintSchema = z113.object({
56627
+ id: z113.string().min(1),
56628
+ description: z113.string(),
56629
+ mitigates: z113.array(z113.string()),
56630
+ enforcement: z113.enum([
55995
56631
  "prevent",
55996
56632
  "require_confirmation",
55997
56633
  "alert",
@@ -55999,52 +56635,52 @@ var SafetyConstraintSchema = z112.object({
55999
56635
  "rate_limit",
56000
56636
  "require_privilege"
56001
56637
  ]),
56002
- validationFunction: z112.string().optional(),
56638
+ validationFunction: z113.string().optional(),
56003
56639
  priority: ConstraintPrioritySchema
56004
56640
  });
56005
- var PropertySchemaSchema = z112.object({
56006
- type: z112.string(),
56007
- description: z112.string().optional(),
56008
- enum: z112.array(z112.unknown()).optional(),
56009
- pattern: z112.string().optional(),
56010
- minimum: z112.number().optional(),
56011
- maximum: z112.number().optional()
56641
+ var PropertySchemaSchema = z113.object({
56642
+ type: z113.string(),
56643
+ description: z113.string().optional(),
56644
+ enum: z113.array(z113.unknown()).optional(),
56645
+ pattern: z113.string().optional(),
56646
+ minimum: z113.number().optional(),
56647
+ maximum: z113.number().optional()
56012
56648
  });
56013
- var ToolInputSchemaSchema = z112.object({
56014
- type: z112.string(),
56015
- properties: z112.record(z112.string(), PropertySchemaSchema).optional(),
56016
- required: z112.array(z112.string()).optional(),
56017
- additionalProperties: z112.boolean().optional()
56649
+ var ToolInputSchemaSchema = z113.object({
56650
+ type: z113.string(),
56651
+ properties: z113.record(z113.string(), PropertySchemaSchema).optional(),
56652
+ required: z113.array(z113.string()).optional(),
56653
+ additionalProperties: z113.boolean().optional()
56018
56654
  });
56019
- var ToolDefinitionSchema = z112.object({
56020
- name: z112.string().min(1),
56021
- description: z112.string(),
56655
+ var ToolDefinitionSchema = z113.object({
56656
+ name: z113.string().min(1),
56657
+ description: z113.string(),
56022
56658
  inputSchema: ToolInputSchemaSchema
56023
56659
  });
56024
- var AnalysisConfigurationSchema = z112.object({
56025
- includeLowSeverity: z112.boolean().default(true),
56026
- generateAllConstraints: z112.boolean().default(true),
56027
- checkInteractions: z112.boolean().default(true),
56028
- maxHazardsPerTool: z112.number().int().min(1).max(100).default(50),
56029
- categories: z112.array(HazardCategorySchema).default([])
56660
+ var AnalysisConfigurationSchema = z113.object({
56661
+ includeLowSeverity: z113.boolean().default(true),
56662
+ generateAllConstraints: z113.boolean().default(true),
56663
+ checkInteractions: z113.boolean().default(true),
56664
+ maxHazardsPerTool: z113.number().int().min(1).max(100).default(50),
56665
+ categories: z113.array(HazardCategorySchema).default([])
56030
56666
  });
56031
- var ConstraintViolationSchema = z112.object({
56032
- constraintId: z112.string().min(1),
56033
- constraintDescription: z112.string(),
56667
+ var ConstraintViolationSchema = z113.object({
56668
+ constraintId: z113.string().min(1),
56669
+ constraintDescription: z113.string(),
56034
56670
  severity: HazardSeveritySchema,
56035
- details: z112.string(),
56036
- remediation: z112.string()
56671
+ details: z113.string(),
56672
+ remediation: z113.string()
56037
56673
  });
56038
- var ValidationWarningSchema = z112.object({
56039
- code: z112.string().min(1),
56040
- message: z112.string(),
56041
- affected: z112.string()
56674
+ var ValidationWarningSchema = z113.object({
56675
+ code: z113.string().min(1),
56676
+ message: z113.string(),
56677
+ affected: z113.string()
56042
56678
  });
56043
- var ValidationResultSchema = z112.object({
56044
- valid: z112.boolean(),
56045
- toolName: z112.string().min(1),
56046
- violations: z112.array(ConstraintViolationSchema),
56047
- passed: z112.array(z112.string()),
56679
+ var ValidationResultSchema = z113.object({
56680
+ valid: z113.boolean(),
56681
+ toolName: z113.string().min(1),
56682
+ violations: z113.array(ConstraintViolationSchema),
56683
+ passed: z113.array(z113.string()),
56048
56684
  // Optional rather than required, deliberately. `ValidationResult` declares
56049
56685
  // both fields required because every result this package produces has them;
56050
56686
  // the schema is the lenient inbound edge for a result that arrived from
@@ -56055,10 +56691,10 @@ var ValidationResultSchema = z112.object({
56055
56691
  // "nothing was evaluated". The strict/lenient split is safe because nothing
56056
56692
  // bridges the two with `z.infer`: a parsed result will not typecheck as a
56057
56693
  // `ValidationResult` without handling the absent fields.
56058
- evaluated: z112.array(z112.string()).optional(),
56059
- notApplicable: z112.array(z112.string()).optional(),
56060
- warnings: z112.array(ValidationWarningSchema),
56061
- validatedAt: z112.date()
56694
+ evaluated: z113.array(z113.string()).optional(),
56695
+ notApplicable: z113.array(z113.string()).optional(),
56696
+ warnings: z113.array(ValidationWarningSchema),
56697
+ validatedAt: z113.date()
56062
56698
  });
56063
56699
 
56064
56700
  // src/mcp/safety/stpa-types.ts
@@ -57143,18 +57779,18 @@ var GeminiResponseParser = class {
57143
57779
  };
57144
57780
 
57145
57781
  // src/cli-adapters/router-types.ts
57146
- import { z as z113 } from "zod";
57147
- var RouterConfigSchema = z113.object({
57148
- preferCostEfficient: z113.boolean().default(false)
57782
+ import { z as z114 } from "zod";
57783
+ var RouterConfigSchema = z114.object({
57784
+ preferCostEfficient: z114.boolean().default(false)
57149
57785
  });
57150
57786
 
57151
57787
  // src/cli-adapters/task-classifier.ts
57152
- import { z as z114 } from "zod";
57153
- var ClassificationPatternsSchema = z114.object({
57154
- code: z114.array(z114.string()).readonly(),
57155
- research: z114.array(z114.string()).readonly(),
57156
- documentation: z114.array(z114.string()).readonly(),
57157
- analysis: z114.array(z114.string()).readonly()
57788
+ import { z as z115 } from "zod";
57789
+ var ClassificationPatternsSchema = z115.object({
57790
+ code: z115.array(z115.string()).readonly(),
57791
+ research: z115.array(z115.string()).readonly(),
57792
+ documentation: z115.array(z115.string()).readonly(),
57793
+ analysis: z115.array(z115.string()).readonly()
57158
57794
  });
57159
57795
 
57160
57796
  // src/security/sandbox/sandbox-types.ts
@@ -57389,25 +58025,25 @@ function sanitizeEnvironment(sourceEnv, allowedVars, additionalEnv) {
57389
58025
  const blocked = [];
57390
58026
  const violations = [];
57391
58027
  const effectiveAllowlist = allowedVars.length > 0 ? allowedVars : SAFE_ENV_VARS;
57392
- for (const [key, value] of Object.entries(sourceEnv)) {
58028
+ for (const [key2, value] of Object.entries(sourceEnv)) {
57393
58029
  if (value === void 0) continue;
57394
- const validation = validateEnvVar(key, effectiveAllowlist);
58030
+ const validation = validateEnvVar(key2, effectiveAllowlist);
57395
58031
  if (validation !== null) {
57396
- blocked.push(key);
58032
+ blocked.push(key2);
57397
58033
  violations.push(validation);
57398
58034
  continue;
57399
58035
  }
57400
- result[key] = value;
58036
+ result[key2] = value;
57401
58037
  }
57402
58038
  if (additionalEnv !== void 0) {
57403
- for (const [key, value] of Object.entries(additionalEnv)) {
57404
- const denyCheck = isDeniedEnvVar(key);
58039
+ for (const [key2, value] of Object.entries(additionalEnv)) {
58040
+ const denyCheck = isDeniedEnvVar(key2);
57405
58041
  if (denyCheck !== null) {
57406
- blocked.push(key);
58042
+ blocked.push(key2);
57407
58043
  violations.push(denyCheck);
57408
58044
  continue;
57409
58045
  }
57410
- result[key] = value;
58046
+ result[key2] = value;
57411
58047
  }
57412
58048
  }
57413
58049
  return { env: result, blocked, violations };
@@ -57583,7 +58219,7 @@ function getPolicy(id) {
57583
58219
  // src/security/sandbox/sandbox-executor.ts
57584
58220
  import { execFile as execFile2 } from "node:child_process";
57585
58221
  import { promisify } from "node:util";
57586
- import { resolve as resolve11 } from "node:path";
58222
+ import { resolve as resolve12 } from "node:path";
57587
58223
  var execFileAsync = promisify(execFile2);
57588
58224
  var logger55 = createLogger({ component: "sandbox-executor" });
57589
58225
  function parseExecError(error) {
@@ -57675,7 +58311,7 @@ var PolicySandboxExecutor = class {
57675
58311
  * following symlinks, else `null`. No rules means no allowed directory.
57676
58312
  */
57677
58313
  resolveAllowedCwd(cwd, policy) {
57678
- const absolute = resolve11(cwd);
58314
+ const absolute = resolve12(cwd);
57679
58315
  for (const rule of policy.pathRules) {
57680
58316
  if (rule.access === "none") continue;
57681
58317
  const contained = resolveInsideRoot(absolute, rule.path);
@@ -58532,4 +59168,4 @@ export {
58532
59168
  initializeSandbox,
58533
59169
  getSandboxMode
58534
59170
  };
58535
- //# sourceMappingURL=chunk-A7XDON63.js.map
59171
+ //# sourceMappingURL=chunk-HHOSB6LL.js.map