@kyo-so/cli 0.15.1 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/kyoso.js CHANGED
@@ -183964,7 +183964,7 @@ var JUDGE_MAX_OUTPUT_TOKENS = 4096;
183964
183964
  var RAW_OUTPUT_MAX_CHARS = 16384;
183965
183965
  var TRACE_DIR = ".kyoso/traces";
183966
183966
  var KYOSO_CHILD_AGENT = "KYOSO_CHILD_AGENT";
183967
- var KYOSO_VERSION = "0.15.1";
183967
+ var KYOSO_VERSION = "0.16.0";
183968
183968
 
183969
183969
  // src/utils/pathContainment.ts
183970
183970
  import { resolve, sep as sep2 } from "node:path";
@@ -184269,7 +184269,7 @@ var defaultConfig = {
184269
184269
  enabled: true,
184270
184270
  type: "acp",
184271
184271
  command: "npx",
184272
- args: ["-y", "@agentclientprotocol/codex-acp@1.1.5"],
184272
+ args: ["-y", "@agentclientprotocol/codex-acp@1.1.7"],
184273
184273
  role: "implementation_reviewer",
184274
184274
  timeoutMs: DEFAULT_AGENT_TIMEOUT_MS,
184275
184275
  allowProjectProvider: [],
@@ -184294,7 +184294,7 @@ var defaultConfig = {
184294
184294
  enabled: true,
184295
184295
  type: "acp",
184296
184296
  command: "npx",
184297
- args: ["-y", "@agentclientprotocol/claude-agent-acp@0.60.0"],
184297
+ args: ["-y", "@agentclientprotocol/claude-agent-acp@0.61.0"],
184298
184298
  role: "architecture_security_reviewer",
184299
184299
  timeoutMs: DEFAULT_AGENT_TIMEOUT_MS,
184300
184300
  env: {
@@ -184405,22 +184405,27 @@ var kyosoConfigOverridePaths = [
184405
184405
  "agents.codex.model",
184406
184406
  "agents.codex.provider",
184407
184407
  "agents.codex.openRouter.streamIdleTimeoutMs",
184408
+ "agents.codex.openRouter.streamIdleTimeoutS",
184408
184409
  "agents.codex.openRouter.streamMaxRetries",
184409
184410
  "agents.codex.openRouter.requestMaxRetries",
184410
184411
  "agents.codex.effort",
184411
184412
  "agents.codex.role",
184412
184413
  "agents.codex.timeoutMs",
184414
+ "agents.codex.timeoutS",
184413
184415
  "agents.claude.enabled",
184414
184416
  "agents.claude.model",
184415
184417
  "agents.claude.effort",
184416
184418
  "agents.claude.role",
184417
184419
  "agents.claude.timeoutMs",
184420
+ "agents.claude.timeoutS",
184418
184421
  "verification.enabled",
184419
184422
  "verification.maxFindings",
184420
184423
  "verification.timeoutMs",
184424
+ "verification.timeoutS",
184421
184425
  "judge.mode",
184422
184426
  "judge.provider",
184423
- "judge.timeoutMs"
184427
+ "judge.timeoutMs",
184428
+ "judge.timeoutS"
184424
184429
  ];
184425
184430
  var CONFIG_OVERRIDE_PATHS = new Set(kyosoConfigOverridePaths);
184426
184431
  function isAllowedConfigOverridePath(path) {
@@ -184893,6 +184898,7 @@ function agentConfigLeafPaths(agent) {
184893
184898
  `agents.${agent}.effort`,
184894
184899
  `agents.${agent}.role`,
184895
184900
  `agents.${agent}.timeoutMs`,
184901
+ `agents.${agent}.timeoutS`,
184896
184902
  `agents.${agent}.env`,
184897
184903
  `agents.${agent}.auth.mode`,
184898
184904
  `agents.${agent}.auth.preferExistingLogin`,
@@ -184901,7 +184907,7 @@ function agentConfigLeafPaths(agent) {
184901
184907
  `agents.${agent}.auth.envWhitelist`
184902
184908
  ];
184903
184909
  if (agent === "codex") {
184904
- paths.push("agents.codex.provider", "agents.codex.allowProjectProvider", "agents.codex.openRouter.streamIdleTimeoutMs", "agents.codex.openRouter.streamMaxRetries", "agents.codex.openRouter.requestMaxRetries");
184910
+ paths.push("agents.codex.provider", "agents.codex.allowProjectProvider", "agents.codex.openRouter.streamIdleTimeoutMs", "agents.codex.openRouter.streamIdleTimeoutS", "agents.codex.openRouter.streamMaxRetries", "agents.codex.openRouter.requestMaxRetries");
184905
184911
  }
184906
184912
  return paths;
184907
184913
  }
@@ -184938,12 +184944,15 @@ var kyosoConfigKnownLeafPaths = [
184938
184944
  "judge.mode",
184939
184945
  "judge.provider",
184940
184946
  "judge.timeoutMs",
184947
+ "judge.timeoutS",
184941
184948
  "verification.enabled",
184942
184949
  "verification.maxFindings",
184943
184950
  "verification.timeoutMs",
184951
+ "verification.timeoutS",
184944
184952
  "verification.allowDemotion",
184945
184953
  "reviewBudget.maxModelCalls",
184946
184954
  "reviewBudget.maxTotalWallTimeMs",
184955
+ "reviewBudget.maxTotalWallTimeS",
184947
184956
  "reviewBudget.warnAgentOutputBytes",
184948
184957
  "reviewBudget.maxAgentOutputBytes",
184949
184958
  "reviewBudget.maxFindingsPerAgent",
@@ -186039,6 +186048,146 @@ function isMissingPathError2(error51) {
186039
186048
  return typeof error51 === "object" && error51 !== null && "code" in error51 && error51.code === "ENOENT";
186040
186049
  }
186041
186050
 
186051
+ // src/utils/timeUnits.ts
186052
+ class TimeUnitValidationError extends Error {
186053
+ field;
186054
+ constructor(field, message) {
186055
+ super(`${field} ${message}`);
186056
+ this.name = "TimeUnitValidationError";
186057
+ this.field = field;
186058
+ }
186059
+ }
186060
+ function validateMilliseconds(value, field, constraints = {}) {
186061
+ assertFiniteNumber(value, field);
186062
+ if (!Number.isSafeInteger(value)) {
186063
+ throw new TimeUnitValidationError(field, "must be a safe integer number of milliseconds.");
186064
+ }
186065
+ assertMinimumMilliseconds(value, field, constraints);
186066
+ return value;
186067
+ }
186068
+ function secondsToMilliseconds(value, field, constraints = {}) {
186069
+ assertFiniteNumber(value, field);
186070
+ const milliseconds = value * 1000;
186071
+ if (!Number.isSafeInteger(milliseconds)) {
186072
+ throw new TimeUnitValidationError(field, "must convert to a safe integer number of milliseconds.");
186073
+ }
186074
+ assertMinimumMilliseconds(milliseconds, field, constraints);
186075
+ return milliseconds;
186076
+ }
186077
+ function resolveTimeUnitPair(input2, fields, constraints = {}) {
186078
+ const hasMilliseconds = input2.milliseconds !== undefined;
186079
+ const hasSeconds = input2.seconds !== undefined;
186080
+ if (!hasMilliseconds && !hasSeconds)
186081
+ return;
186082
+ const milliseconds = hasMilliseconds ? validateMilliseconds(input2.milliseconds, fields.milliseconds, constraints) : undefined;
186083
+ const secondsMilliseconds = hasSeconds ? secondsToMilliseconds(input2.seconds, fields.seconds, constraints) : undefined;
186084
+ if (secondsMilliseconds !== undefined) {
186085
+ return {
186086
+ milliseconds: secondsMilliseconds,
186087
+ source: "seconds",
186088
+ sourceField: fields.seconds
186089
+ };
186090
+ }
186091
+ return {
186092
+ milliseconds,
186093
+ source: "milliseconds",
186094
+ sourceField: fields.milliseconds
186095
+ };
186096
+ }
186097
+ function assertFiniteNumber(value, field) {
186098
+ if (typeof value !== "number" || !Number.isFinite(value)) {
186099
+ throw new TimeUnitValidationError(field, "must be a finite number.");
186100
+ }
186101
+ }
186102
+ function assertMinimumMilliseconds(value, field, constraints) {
186103
+ if (constraints.allowZero && value === 0)
186104
+ return;
186105
+ const minimumMilliseconds = constraints.minimumMilliseconds ?? 1;
186106
+ if (value < minimumMilliseconds) {
186107
+ throw new TimeUnitValidationError(field, `must be at least ${minimumMilliseconds} milliseconds.`);
186108
+ }
186109
+ }
186110
+
186111
+ // src/config/timeUnits.ts
186112
+ var configTimeUnitPairs = [
186113
+ {
186114
+ parentPath: ["agents", "codex"],
186115
+ millisecondsKey: "timeoutMs",
186116
+ secondsKey: "timeoutS"
186117
+ },
186118
+ {
186119
+ parentPath: ["agents", "claude"],
186120
+ millisecondsKey: "timeoutMs",
186121
+ secondsKey: "timeoutS"
186122
+ },
186123
+ {
186124
+ parentPath: ["agents", "codex", "openRouter"],
186125
+ millisecondsKey: "streamIdleTimeoutMs",
186126
+ secondsKey: "streamIdleTimeoutS",
186127
+ constraints: { minimumMilliseconds: 1000 }
186128
+ },
186129
+ {
186130
+ parentPath: ["judge"],
186131
+ millisecondsKey: "timeoutMs",
186132
+ secondsKey: "timeoutS"
186133
+ },
186134
+ {
186135
+ parentPath: ["verification"],
186136
+ millisecondsKey: "timeoutMs",
186137
+ secondsKey: "timeoutS"
186138
+ },
186139
+ {
186140
+ parentPath: ["reviewBudget"],
186141
+ millisecondsKey: "maxTotalWallTimeMs",
186142
+ secondsKey: "maxTotalWallTimeS"
186143
+ }
186144
+ ];
186145
+ function normalizeConfigTimeUnits(input2) {
186146
+ let normalized = input2;
186147
+ for (const pair of configTimeUnitPairs) {
186148
+ normalized = updateRecordAtPath(normalized, pair.parentPath, (parent) => normalizePair(parent, pair));
186149
+ }
186150
+ return normalized;
186151
+ }
186152
+ function normalizePair(parent, pair) {
186153
+ const hasSecondsProperty = Object.hasOwn(parent, pair.secondsKey);
186154
+ if (!hasSecondsProperty)
186155
+ return parent;
186156
+ const normalized = { ...parent };
186157
+ if (parent[pair.secondsKey] === undefined) {
186158
+ delete normalized[pair.secondsKey];
186159
+ return normalized;
186160
+ }
186161
+ const parentPath = pair.parentPath.join(".");
186162
+ const resolved = resolveTimeUnitPair({
186163
+ milliseconds: parent[pair.millisecondsKey],
186164
+ seconds: parent[pair.secondsKey]
186165
+ }, {
186166
+ milliseconds: `${parentPath}.${pair.millisecondsKey}`,
186167
+ seconds: `${parentPath}.${pair.secondsKey}`
186168
+ }, pair.constraints);
186169
+ if (resolved)
186170
+ normalized[pair.millisecondsKey] = resolved.milliseconds;
186171
+ delete normalized[pair.secondsKey];
186172
+ return normalized;
186173
+ }
186174
+ function updateRecordAtPath(input2, path, update) {
186175
+ if (path.length === 0) {
186176
+ return isRecord3(input2) ? update(input2) : input2;
186177
+ }
186178
+ if (!isRecord3(input2))
186179
+ return input2;
186180
+ const [key, ...rest] = path;
186181
+ if (key === undefined)
186182
+ return input2;
186183
+ const current = input2[key];
186184
+ const updated = updateRecordAtPath(current, rest, update);
186185
+ return updated === current ? input2 : { ...input2, [key]: updated };
186186
+ }
186187
+ function isRecord3(value) {
186188
+ return typeof value === "object" && value !== null && !Array.isArray(value);
186189
+ }
186190
+
186042
186191
  // src/config/loadConfig.ts
186043
186192
  var configValidationContexts = new WeakMap;
186044
186193
  function getConfigValidationContext(error51) {
@@ -186078,7 +186227,7 @@ async function loadConfig(options = {}) {
186078
186227
  let configTrustStatus = options.ignoreConfig ? "ignored" : "not_found";
186079
186228
  if (!options.ignoreConfig) {
186080
186229
  if (await exists2(globalConfigPath)) {
186081
- const globalConfig2 = await loadTomlConfigFile(globalConfigPath);
186230
+ const globalConfig2 = normalizeConfigTimeUnits(await loadTomlConfigFile(globalConfigPath));
186082
186231
  validateExplicitReviewBudgetThresholds(globalConfig2, defaultConfig);
186083
186232
  const globalConfigWarnings = collectGlobalConfigWarnings(globalConfigPath, globalConfig2);
186084
186233
  const securitySensitiveWarnings = globalConfigWarnings.filter((warning) => warning.startsWith("security-sensitive unknown settings "));
@@ -186205,7 +186354,7 @@ async function loadProjectConfig(input2) {
186205
186354
  const { canonicalDirectory, canonicalPath, requestedPath } = input2.projectConfig;
186206
186355
  const extension = extname3(requestedPath);
186207
186356
  if (extension === ".toml") {
186208
- const projectTomlConfig = await loadTomlConfigFile(canonicalPath);
186357
+ const projectTomlConfig = normalizeConfigTimeUnits(await loadTomlConfigFile(canonicalPath));
186209
186358
  const projectChangesOpenRouterPolicy = projectConfigChangesOpenRouterPolicy(projectTomlConfig, input2.baseConfig);
186210
186359
  await assertProjectOpenRouterAuthorization({
186211
186360
  projectConfig: projectTomlConfig,
@@ -186251,7 +186400,7 @@ function configSelectsOpenRouter(config2) {
186251
186400
  return flattenLeaves(config2).some((leaf) => leaf.path.join(".") === "agents.codex.provider" && leaf.value === CODEX_OPENROUTER_PROVIDER);
186252
186401
  }
186253
186402
  function applyProjectCodexProviderReset(baseConfig, projectConfig, mergedConfig) {
186254
- if (!projectConfigSelectsDefaultProvider(projectConfig) || !configSelectsOpenRouter(baseConfig) || !isRecord3(mergedConfig) || !isRecord3(mergedConfig.agents) || !isRecord3(mergedConfig.agents.codex)) {
186403
+ if (!projectConfigSelectsDefaultProvider(projectConfig) || !configSelectsOpenRouter(baseConfig) || !isRecord4(mergedConfig) || !isRecord4(mergedConfig.agents) || !isRecord4(mergedConfig.agents.codex)) {
186255
186404
  return mergedConfig;
186256
186405
  }
186257
186406
  const shouldClearInheritedModel = !projectConfigSuppliesCodexModel(projectConfig);
@@ -186283,13 +186432,13 @@ async function assertProjectOpenRouterAuthorization(input2) {
186283
186432
  });
186284
186433
  }
186285
186434
  async function projectProviderIsAuthorized(config2, projectDirectory) {
186286
- if (!isRecord3(config2))
186435
+ if (!isRecord4(config2))
186287
186436
  return false;
186288
186437
  const agents = config2.agents;
186289
- if (!isRecord3(agents))
186438
+ if (!isRecord4(agents))
186290
186439
  return false;
186291
186440
  const codex = agents.codex;
186292
- if (!isRecord3(codex) || !Array.isArray(codex.allowProjectProvider)) {
186441
+ if (!isRecord4(codex) || !Array.isArray(codex.allowProjectProvider)) {
186293
186442
  return false;
186294
186443
  }
186295
186444
  for (const directory of codex.allowProjectProvider) {
@@ -186332,7 +186481,7 @@ async function loadProjectTsConfig(input2) {
186332
186481
  options: input2.options
186333
186482
  });
186334
186483
  if (trustDecision.execute) {
186335
- const userConfig = await loadUserConfig(canonicalPath, source);
186484
+ const userConfig = normalizeConfigTimeUnits(await loadUserConfig(canonicalPath, source));
186336
186485
  validateExplicitReviewBudgetThresholds(userConfig, input2.baseConfig);
186337
186486
  const projectChangesOpenRouterPolicy = projectConfigChangesOpenRouterPolicy(userConfig, input2.baseConfig);
186338
186487
  await assertProjectOpenRouterAuthorization({
@@ -186419,7 +186568,7 @@ async function promptForConfigTrust(configPath, configHash) {
186419
186568
  }
186420
186569
  }
186421
186570
  function deepMerge2(base, override) {
186422
- if (!isRecord3(base) || !isRecord3(override))
186571
+ if (!isRecord4(base) || !isRecord4(override))
186423
186572
  return override ?? base;
186424
186573
  const result = { ...base };
186425
186574
  for (const [key, value] of Object.entries(override)) {
@@ -186439,12 +186588,12 @@ function validateExplicitReviewBudgetThresholds(config2, baseConfig) {
186439
186588
  }
186440
186589
  }
186441
186590
  function readRecord(value, key) {
186442
- if (!isRecord3(value))
186591
+ if (!isRecord4(value))
186443
186592
  return;
186444
186593
  const nested = value[key];
186445
- return isRecord3(nested) ? nested : undefined;
186594
+ return isRecord4(nested) ? nested : undefined;
186446
186595
  }
186447
- function isRecord3(value) {
186596
+ function isRecord4(value) {
186448
186597
  return typeof value === "object" && value !== null && !Array.isArray(value);
186449
186598
  }
186450
186599
  async function exists2(path) {
@@ -186479,7 +186628,7 @@ function createModelExecutionIdentity(input2) {
186479
186628
  };
186480
186629
  }
186481
186630
  function normalizeModelExecutionIdentity(value) {
186482
- if (!isRecord4(value) || !isModelProviderRoute(value.providerRoute)) {
186631
+ if (!isRecord5(value) || !isModelProviderRoute(value.providerRoute)) {
186483
186632
  return;
186484
186633
  }
186485
186634
  return createModelExecutionIdentity({
@@ -186501,7 +186650,7 @@ function sanitizeIdentityValue(value) {
186501
186650
  function isModelProviderRoute(value) {
186502
186651
  return typeof value === "string" && MODEL_PROVIDER_ROUTES.has(value);
186503
186652
  }
186504
- function isRecord4(value) {
186653
+ function isRecord5(value) {
186505
186654
  return value !== null && typeof value === "object" && !Array.isArray(value);
186506
186655
  }
186507
186656
 
@@ -186515,7 +186664,7 @@ var TOKEN_USAGE_KEYS = [
186515
186664
  "cachedWriteTokens"
186516
186665
  ];
186517
186666
  function normalizeModelTokenUsage(usage) {
186518
- if (!isRecord5(usage))
186667
+ if (!isRecord6(usage))
186519
186668
  return;
186520
186669
  const normalized = {};
186521
186670
  for (const key of TOKEN_USAGE_KEYS) {
@@ -186528,7 +186677,7 @@ function normalizeModelTokenUsage(usage) {
186528
186677
  function isTokenCount(value) {
186529
186678
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
186530
186679
  }
186531
- function isRecord5(value) {
186680
+ function isRecord6(value) {
186532
186681
  return typeof value === "object" && value !== null && !Array.isArray(value);
186533
186682
  }
186534
186683
 
@@ -186580,7 +186729,7 @@ function parseJudgeOutput(text, fallbackSummaryText) {
186580
186729
  const parsed = JSON.parse(json2);
186581
186730
  const summaryText = typeof parsed.summaryText === "string" && parsed.summaryText.trim().length > 0 ? sanitizeText(parsed.summaryText) : fallbackSummaryText;
186582
186731
  const disagreementComments = Array.isArray(parsed.disagreementComments) ? parsed.disagreementComments.flatMap((item) => {
186583
- if (!isRecord6(item) || typeof item.topic !== "string" || typeof item.judgeComment !== "string") {
186732
+ if (!isRecord7(item) || typeof item.topic !== "string" || typeof item.judgeComment !== "string") {
186584
186733
  return [];
186585
186734
  }
186586
186735
  return [
@@ -186596,7 +186745,7 @@ function parseJudgeOutput(text, fallbackSummaryText) {
186596
186745
  return { summaryText, disagreementComments, analysis };
186597
186746
  }
186598
186747
  function parseAnalysis(value) {
186599
- if (!isRecord6(value))
186748
+ if (!isRecord7(value))
186600
186749
  return;
186601
186750
  if (!Array.isArray(value.blindSpots) || !Array.isArray(value.contradictions) || !Array.isArray(value.partialCoverage)) {
186602
186751
  return;
@@ -186604,7 +186753,7 @@ function parseAnalysis(value) {
186604
186753
  return {
186605
186754
  blindSpots: value.blindSpots.slice(0, ANALYSIS_MAX_ITEMS).flatMap((item) => typeof item === "string" ? [sanitizeAnalysisText(item)] : []),
186606
186755
  contradictions: value.contradictions.slice(0, ANALYSIS_MAX_ITEMS).flatMap((item) => {
186607
- if (!isRecord6(item) || typeof item.topic !== "string" || typeof item.detail !== "string") {
186756
+ if (!isRecord7(item) || typeof item.topic !== "string" || typeof item.detail !== "string") {
186608
186757
  return [];
186609
186758
  }
186610
186759
  return [
@@ -186615,7 +186764,7 @@ function parseAnalysis(value) {
186615
186764
  ];
186616
186765
  }),
186617
186766
  partialCoverage: value.partialCoverage.slice(0, ANALYSIS_MAX_ITEMS).flatMap((item) => {
186618
- if (!isRecord6(item) || typeof item.note !== "string")
186767
+ if (!isRecord7(item) || typeof item.note !== "string")
186619
186768
  return [];
186620
186769
  const findingId = typeof item.findingId === "string" ? sanitizeAnalysisText(item.findingId) : undefined;
186621
186770
  return [
@@ -186662,7 +186811,7 @@ function extractFirstJsonObject(text) {
186662
186811
  }
186663
186812
  return;
186664
186813
  }
186665
- function isRecord6(value) {
186814
+ function isRecord7(value) {
186666
186815
  return typeof value === "object" && value !== null && !Array.isArray(value);
186667
186816
  }
186668
186817
 
@@ -187156,9 +187305,9 @@ var PLUGIN_RUNTIME_COMPATIBILITY_SCHEMA_VERSION = 2;
187156
187305
  var MINIMUM_SUPPORTED_CODEX_VERSION = "0.144.0-alpha.4";
187157
187306
  var PLUGIN_RUNTIME_EXPECTED_CONTRACT = {
187158
187307
  distribution: {
187159
- pluginVersion: "0.7.5",
187308
+ pluginVersion: "0.7.7",
187160
187309
  mcpCommand: "npx",
187161
- mcpPackagePin: "@kyo-so/cli@0.15.0",
187310
+ mcpPackagePin: "@kyo-so/cli@0.15.2",
187162
187311
  mcpExecutable: "kyoso"
187163
187312
  },
187164
187313
  marketplace: {
@@ -187404,7 +187553,7 @@ function parseJson(value) {
187404
187553
  }
187405
187554
  }
187406
187555
  function parsePluginList(value) {
187407
- if (!isRecord7(value))
187556
+ if (!isRecord8(value))
187408
187557
  return;
187409
187558
  const allowedKeys = new Set(PLUGIN_LIST_JSON_SCHEMA.collections);
187410
187559
  if (Object.keys(value).some((key) => !allowedKeys.has(key))) {
@@ -187432,7 +187581,7 @@ function parsePluginEntries(value) {
187432
187581
  return;
187433
187582
  const entries = [];
187434
187583
  for (const item of value) {
187435
- if (!isRecord7(item))
187584
+ if (!isRecord8(item))
187436
187585
  return;
187437
187586
  if (typeof item.pluginId !== "string" || typeof item.installed !== "boolean" || typeof item.enabled !== "boolean") {
187438
187587
  return;
@@ -187458,7 +187607,7 @@ function parseMcpList(value) {
187458
187607
  return;
187459
187608
  const matches = [];
187460
187609
  for (const item of value) {
187461
- if (!isRecord7(item) || typeof item.name !== "string")
187610
+ if (!isRecord8(item) || typeof item.name !== "string")
187462
187611
  return "unknown";
187463
187612
  if (item.name !== "kyoso")
187464
187613
  continue;
@@ -187540,7 +187689,7 @@ function comparePrerelease(left, right) {
187540
187689
  }
187541
187690
  return 0;
187542
187691
  }
187543
- function isRecord7(value) {
187692
+ function isRecord8(value) {
187544
187693
  return typeof value === "object" && value !== null && !Array.isArray(value);
187545
187694
  }
187546
187695
 
@@ -187701,7 +187850,7 @@ function findKyosoPackage(executable) {
187701
187850
  if (existsSync(packagePath)) {
187702
187851
  try {
187703
187852
  const parsed = JSON.parse(readFileSync(packagePath, "utf8"));
187704
- if (isRecord8(parsed) && parsed.name === "@kyo-so/cli" && typeof parsed.version === "string" && parsed.version.trim().length > 0) {
187853
+ if (isRecord9(parsed) && parsed.name === "@kyo-so/cli" && typeof parsed.version === "string" && parsed.version.trim().length > 0) {
187705
187854
  return { directory, version: parsed.version };
187706
187855
  }
187707
187856
  } catch {}
@@ -187870,7 +188019,7 @@ function isWithin(path, parent) {
187870
188019
  const relativePath = relative(resolve5(parent), resolve5(path));
187871
188020
  return relativePath === "" || !relativePath.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) && relativePath !== ".." && !isAbsolute4(relativePath);
187872
188021
  }
187873
- function isRecord8(value) {
188022
+ function isRecord9(value) {
187874
188023
  return typeof value === "object" && value !== null && !Array.isArray(value);
187875
188024
  }
187876
188025
 
@@ -187915,7 +188064,7 @@ var GENERATED_MCP_ENV_VAR_NAMES = new Set([
187915
188064
  "CLAUDE_CODE_OAUTH_TOKEN"
187916
188065
  ]);
187917
188066
  function inspectManualMcpInvocation(value) {
187918
- if (!isRecord9(value)) {
188067
+ if (!isRecord10(value)) {
187919
188068
  return { kind: "unknown", reason: "MCP entry is not an object." };
187920
188069
  }
187921
188070
  if (typeof value.command !== "string" || value.command.length === 0) {
@@ -187961,7 +188110,7 @@ function applyEnvironmentSafety(invocation, environment) {
187961
188110
  return environment ?? invocation;
187962
188111
  }
187963
188112
  function isGeneratedMcpEnvironment(value) {
187964
- if (!isRecord9(value))
188113
+ if (!isRecord10(value))
187965
188114
  return false;
187966
188115
  return Object.entries(value).every(([name, placeholder]) => GENERATED_MCP_ENV_VALUE_NAMES.has(name) && placeholder === `\${${name}}`);
187967
188116
  }
@@ -188069,7 +188218,7 @@ function versionFromKnownPackageSpec(packageSpec) {
188069
188218
  const version2 = packageSpec.slice(prefix.length);
188070
188219
  return isCompleteSemVer(version2) ? version2 : undefined;
188071
188220
  }
188072
- function isRecord9(value) {
188221
+ function isRecord10(value) {
188073
188222
  return typeof value === "object" && value !== null && !Array.isArray(value);
188074
188223
  }
188075
188224
  function isString(value) {
@@ -188102,8 +188251,14 @@ import {
188102
188251
  } from "node:path";
188103
188252
 
188104
188253
  // src/cli/knownSkillDigests.ts
188105
- var CURRENT_SKILL_DIGEST = "sha256:d28acaadf490df9e58e12f195804f181a683d0d33344275d7989efbee26a4504";
188254
+ var CURRENT_SKILL_DIGEST = "sha256:1ea8914f4657741fcd544822326f80e82033078f8e2b11b1f5aad420072dcb39";
188106
188255
  var KNOWN_SKILL_DIGESTS_BY_VERSION = {
188256
+ "0.15.2": [
188257
+ {
188258
+ digest: "sha256:d28acaadf490df9e58e12f195804f181a683d0d33344275d7989efbee26a4504",
188259
+ kind: "historical"
188260
+ }
188261
+ ],
188107
188262
  "0.13.1": [
188108
188263
  {
188109
188264
  digest: "sha256:8654e68ea61f2acea29027056802bf627ad737f084c9a86ab052946943538409",
@@ -189366,7 +189521,7 @@ function parseJsonObject(path, content) {
189366
189521
  if (content.trim().length === 0)
189367
189522
  return {};
189368
189523
  const parsed = JSON.parse(content);
189369
- if (!isRecord10(parsed))
189524
+ if (!isRecord11(parsed))
189370
189525
  throw new Error(`${path} must contain a JSON object`);
189371
189526
  return parsed;
189372
189527
  }
@@ -189375,7 +189530,7 @@ function inspectCodexAppendSafety(content, cwd, home) {
189375
189530
  return { ok: true };
189376
189531
  try {
189377
189532
  const parsed = parse5(content);
189378
- if (!isRecord10(parsed)) {
189533
+ if (!isRecord11(parsed)) {
189379
189534
  return {
189380
189535
  ok: false,
189381
189536
  detail: "Codex config is not a TOML object and was left unchanged."
@@ -189387,13 +189542,13 @@ function inspectCodexAppendSafety(content, cwd, home) {
189387
189542
  detail: "Codex has a project-scoped MCP or Plugin override; the global config was left unchanged."
189388
189543
  };
189389
189544
  }
189390
- if ("mcp_servers" in parsed && !isRecord10(parsed.mcp_servers)) {
189545
+ if ("mcp_servers" in parsed && !isRecord11(parsed.mcp_servers)) {
189391
189546
  return {
189392
189547
  ok: false,
189393
189548
  detail: "Codex mcp_servers is malformed and was left unchanged."
189394
189549
  };
189395
189550
  }
189396
- if (isRecord10(parsed.mcp_servers) && "kyoso" in parsed.mcp_servers) {
189551
+ if (isRecord11(parsed.mcp_servers) && "kyoso" in parsed.mcp_servers) {
189397
189552
  return {
189398
189553
  ok: false,
189399
189554
  detail: "Codex already defines mcp_servers.kyoso in a form setup cannot safely extend; migrate it manually."
@@ -189429,7 +189584,7 @@ function inspectCodexMcpContent(content, path, cwd, home) {
189429
189584
  value: undefined
189430
189585
  });
189431
189586
  }
189432
- if (!isRecord10(parsed) || !isRecord10(parsed.mcp_servers)) {
189587
+ if (!isRecord11(parsed) || !isRecord11(parsed.mcp_servers)) {
189433
189588
  return manualMcpRegistration({
189434
189589
  path,
189435
189590
  scope: "codex-global",
@@ -189457,7 +189612,7 @@ function inspectCodexMcpContent(content, path, cwd, home) {
189457
189612
  function inspectClaudeProjectMcp(current, path) {
189458
189613
  if (!("mcpServers" in current))
189459
189614
  return;
189460
- if (!isRecord10(current.mcpServers)) {
189615
+ if (!isRecord11(current.mcpServers)) {
189461
189616
  return manualMcpRegistration({
189462
189617
  path,
189463
189618
  scope: "claude-project",
@@ -190087,7 +190242,7 @@ function detectCodexMcp(path, cwd, home) {
190087
190242
  value: undefined
190088
190243
  }));
190089
190244
  }
190090
- if (!isRecord10(parsed)) {
190245
+ if (!isRecord11(parsed)) {
190091
190246
  return singleMcpDetection(manualMcpRegistration({
190092
190247
  path,
190093
190248
  scope: "codex-global",
@@ -190097,7 +190252,7 @@ function detectCodexMcp(path, cwd, home) {
190097
190252
  }
190098
190253
  if (!("mcp_servers" in parsed))
190099
190254
  return missingMcpDetection();
190100
- if (!isRecord10(parsed.mcp_servers)) {
190255
+ if (!isRecord11(parsed.mcp_servers)) {
190101
190256
  return singleMcpDetection(manualMcpRegistration({
190102
190257
  path,
190103
190258
  scope: "codex-global",
@@ -190147,7 +190302,7 @@ function detectClaudeMcp(path, cwd, home) {
190147
190302
  }
190148
190303
  function jsonMcpRegistrations(value, path, cwd, home) {
190149
190304
  const directScope = path.endsWith(".mcp.json") ? "claude-project" : "claude-global";
190150
- if (!isRecord10(value)) {
190305
+ if (!isRecord11(value)) {
190151
190306
  return [
190152
190307
  manualMcpRegistration({
190153
190308
  path,
@@ -190160,7 +190315,7 @@ function jsonMcpRegistrations(value, path, cwd, home) {
190160
190315
  const registrations = directMcpRegistrations(value, path, directScope);
190161
190316
  if (!("projects" in value))
190162
190317
  return registrations;
190163
- if (!isRecord10(value.projects)) {
190318
+ if (!isRecord11(value.projects)) {
190164
190319
  return [
190165
190320
  ...registrations,
190166
190321
  manualMcpRegistration({
@@ -190175,7 +190330,7 @@ function jsonMcpRegistrations(value, path, cwd, home) {
190175
190330
  for (const [projectPath, projectConfig] of Object.entries(value.projects)) {
190176
190331
  if (normalizeProjectPath(projectPath, home) !== currentProject)
190177
190332
  continue;
190178
- if (!isRecord10(projectConfig)) {
190333
+ if (!isRecord11(projectConfig)) {
190179
190334
  registrations.push(manualMcpRegistration({
190180
190335
  path,
190181
190336
  scope: "claude-global-project",
@@ -190191,7 +190346,7 @@ function jsonMcpRegistrations(value, path, cwd, home) {
190191
190346
  function directMcpRegistrations(value, path, scope) {
190192
190347
  if (!("mcpServers" in value))
190193
190348
  return [];
190194
- if (!isRecord10(value.mcpServers)) {
190349
+ if (!isRecord11(value.mcpServers)) {
190195
190350
  return [
190196
190351
  manualMcpRegistration({
190197
190352
  path,
@@ -190215,7 +190370,7 @@ function directMcpRegistrations(value, path, scope) {
190215
190370
  function nestedMcpEntryStatus(value, path) {
190216
190371
  let current = value;
190217
190372
  for (const key of path) {
190218
- if (!isRecord10(current))
190373
+ if (!isRecord11(current))
190219
190374
  return "unknown";
190220
190375
  if (!(key in current))
190221
190376
  return "missing";
@@ -190224,11 +190379,11 @@ function nestedMcpEntryStatus(value, path) {
190224
190379
  return mcpEntryStatus(current);
190225
190380
  }
190226
190381
  function hasUnprobedProjectIntegrationOverride(value, cwd, home) {
190227
- if (!isRecord10(value) || !isRecord10(value.projects))
190382
+ if (!isRecord11(value) || !isRecord11(value.projects))
190228
190383
  return false;
190229
190384
  const currentProject = normalizeProjectPath(cwd, home);
190230
190385
  for (const [projectPath, projectConfig] of Object.entries(value.projects)) {
190231
- if (normalizeProjectPath(projectPath, home) !== currentProject || !isRecord10(projectConfig)) {
190386
+ if (normalizeProjectPath(projectPath, home) !== currentProject || !isRecord11(projectConfig)) {
190232
190387
  continue;
190233
190388
  }
190234
190389
  if ("mcp_servers" in projectConfig || "plugins" in projectConfig) {
@@ -190251,7 +190406,7 @@ function normalizeProjectPath(path, home) {
190251
190406
  return process.platform === "win32" ? normalized.toLowerCase() : normalized;
190252
190407
  }
190253
190408
  function mcpEntryStatus(value) {
190254
- if (!isRecord10(value))
190409
+ if (!isRecord11(value))
190255
190410
  return "unknown";
190256
190411
  if (!("enabled" in value))
190257
190412
  return "enabled";
@@ -190302,7 +190457,7 @@ function readTextSync(path) {
190302
190457
  function recordValue(value) {
190303
190458
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
190304
190459
  }
190305
- function isRecord10(value) {
190460
+ function isRecord11(value) {
190306
190461
  return typeof value === "object" && value !== null && !Array.isArray(value);
190307
190462
  }
190308
190463
  function diffForAppend(path, snippet) {
@@ -190506,12 +190661,13 @@ async function runDoctor(options) {
190506
190661
  }
190507
190662
  const judgeRoute = resolveJudgeCallRoute(loaded.config.judge.mode, loaded.config.judge.provider, env);
190508
190663
  const reviewTiming = calculateReviewTiming(loaded.config, judgeRoute.llmAvailable);
190664
+ const recommendedReviewWallTimeS = Math.ceil(reviewTiming.recommendedReviewWallTimeMs / 1000);
190509
190665
  lines.push("", "Review timing");
190510
190666
  lines.push(` review-wide deadline: ${loaded.config.reviewBudget.maxTotalWallTimeMs} ms`, ` sequential phases: primary ${reviewTiming.primaryPhaseMs} + verification ${reviewTiming.verificationPhaseMs} + LLM judge ${reviewTiming.judgePhaseMs} = ${reviewTiming.sequentialPhaseMs} ms`, ` recommended review-wide deadline: ${reviewTiming.recommendedReviewWallTimeMs} ms`);
190511
190667
  if (loaded.config.reviewBudget.maxTotalWallTimeMs < reviewTiming.sequentialPhaseMs) {
190512
- lines.push(` warning: review-wide deadline is insufficient: ${loaded.config.reviewBudget.maxTotalWallTimeMs} ms is below the configured sequential phase time of ${reviewTiming.sequentialPhaseMs} ms; later phases cannot receive their configured timeout.`, ` hint: set user-global reviewBudget.maxTotalWallTimeMs to at least ${reviewTiming.recommendedReviewWallTimeMs}.`);
190668
+ lines.push(` warning: review-wide deadline is insufficient: ${loaded.config.reviewBudget.maxTotalWallTimeMs} ms is below the configured sequential phase time of ${reviewTiming.sequentialPhaseMs} ms; later phases cannot receive their configured timeout.`, ` hint: set user-global reviewBudget.maxTotalWallTimeS to at least ${recommendedReviewWallTimeS}.`);
190513
190669
  } else if (loaded.config.reviewBudget.maxTotalWallTimeMs < reviewTiming.recommendedReviewWallTimeMs) {
190514
- lines.push(` warning: review-wide deadline has low margin: ${loaded.config.reviewBudget.maxTotalWallTimeMs} ms is below the recommended ${reviewTiming.recommendedReviewWallTimeMs} ms; scheduling and finalization margin is reduced.`, ` hint: set user-global reviewBudget.maxTotalWallTimeMs to at least ${reviewTiming.recommendedReviewWallTimeMs}.`);
190670
+ lines.push(` warning: review-wide deadline has low margin: ${loaded.config.reviewBudget.maxTotalWallTimeMs} ms is below the recommended ${reviewTiming.recommendedReviewWallTimeMs} ms; scheduling and finalization margin is reduced.`, ` hint: set user-global reviewBudget.maxTotalWallTimeS to at least ${recommendedReviewWallTimeS}.`);
190515
190671
  }
190516
190672
  const judgeProvider = judgeRoute.llmAvailable ? judgeRoute.provider : "deterministic_fallback";
190517
190673
  lines.push("", "Judge");
@@ -191322,6 +191478,9 @@ var zToolCallUpdate = object({
191322
191478
  title: defaultOnError(string2().nullish(), () => {
191323
191479
  return;
191324
191480
  }),
191481
+ name: defaultOnError(string2().nullish(), () => {
191482
+ return;
191483
+ }),
191325
191484
  content: defaultOnError(vecSkipError(zToolCallContent).nullish(), () => {
191326
191485
  return;
191327
191486
  }),
@@ -192433,6 +192592,9 @@ var zContentChunk = object({
192433
192592
  var zToolCall = object({
192434
192593
  toolCallId: zToolCallId,
192435
192594
  title: string2(),
192595
+ name: defaultOnError(string2().nullish(), () => {
192596
+ return;
192597
+ }),
192436
192598
  kind: defaultOnError(zToolKind.optional(), () => {
192437
192599
  return;
192438
192600
  }),
@@ -193356,37 +193518,71 @@ var zCancelRequestNotification = object({
193356
193518
  })
193357
193519
  });
193358
193520
 
193359
- // node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js
193360
- var zGuardCreateElicitationRequestForm = zElicitationFormMode.and(object({ mode: literal("form") })).and(object({ message: string2() }));
193361
- var zGuardCreateElicitationRequestUrl = zElicitationUrlMode.and(object({ mode: literal("url") })).and(object({ message: string2() }));
193362
- var zGuardCreateElicitationRequestCustom = union([zElicitationSessionScope, zElicitationRequestScope]).and(object({ message: string2() }));
193363
- var zGuardElicitationPropertySchemaString = zStringPropertySchema.and(object({ type: literal("string") }));
193364
- var zGuardElicitationPropertySchemaNumber = zNumberPropertySchema.and(object({ type: literal("number") }));
193365
- var zGuardElicitationPropertySchemaInteger = zIntegerPropertySchema.and(object({ type: literal("integer") }));
193366
- var zGuardElicitationPropertySchemaBoolean = zBooleanPropertySchema.and(object({ type: literal("boolean") }));
193367
- var zGuardElicitationPropertySchemaArray = zMultiSelectPropertySchema.and(object({ type: literal("array") }));
193368
- var zGuardMultiSelectItemsString = zStringMultiSelectItems.and(object({ type: literal("string") }));
193369
- var zGuardCreateElicitationResponseAccept = zElicitationAcceptAction.and(object({ action: literal("accept") }));
193370
- var zGuardCreateElicitationResponseDecline = object({
193371
- action: literal("decline")
193372
- });
193373
- var zGuardCreateElicitationResponseCancel = object({
193374
- action: literal("cancel")
193375
- });
193376
193521
  // node_modules/@agentclientprotocol/sdk/dist/jsonrpc.js
193377
193522
  var CANCEL_REQUEST_METHOD = "$/cancel_request";
193378
- function isRecord11(value) {
193523
+ function isRequestMessage(value) {
193524
+ return isJsonRpcEnvelope(value) && "id" in value && typeof value["method"] === "string" && isJsonRpcId(value["id"]);
193525
+ }
193526
+ function isResponseMessage(value) {
193527
+ if (!isJsonRpcEnvelope(value) || "method" in value) {
193528
+ return false;
193529
+ }
193530
+ if (!("id" in value) || !isJsonRpcId(value["id"])) {
193531
+ return false;
193532
+ }
193533
+ const hasResult = Object.hasOwn(value, "result");
193534
+ const hasError = Object.hasOwn(value, "error");
193535
+ if (hasResult === hasError) {
193536
+ return false;
193537
+ }
193538
+ return !hasError || isErrorResponse(value["error"]);
193539
+ }
193540
+ function isNotificationMessage(value) {
193541
+ return isJsonRpcEnvelope(value) && !("id" in value) && typeof value["method"] === "string";
193542
+ }
193543
+ function isRecord12(value) {
193379
193544
  return typeof value === "object" && value !== null;
193380
193545
  }
193546
+ function isJsonRpcEnvelope(value) {
193547
+ return isRecord12(value) && value["jsonrpc"] === "2.0";
193548
+ }
193381
193549
  function isJsonRpcId(value) {
193382
193550
  return value === null || typeof value === "string" || typeof value === "number" && Number.isFinite(value);
193383
193551
  }
193552
+ function isResponseShapedMessage(value) {
193553
+ return isRecord12(value) && !("method" in value) && (("id" in value) || ("result" in value) || ("error" in value));
193554
+ }
193555
+ function isResponseBatch(batch) {
193556
+ let hasValidCall = false;
193557
+ let hasValidResponse = false;
193558
+ let hasCallShape = false;
193559
+ let hasResponseShape = false;
193560
+ for (const entry of batch) {
193561
+ hasValidCall ||= isRequestMessage(entry) || isNotificationMessage(entry);
193562
+ hasValidResponse ||= isResponseMessage(entry);
193563
+ if (!isRecord12(entry)) {
193564
+ continue;
193565
+ }
193566
+ hasCallShape ||= "method" in entry;
193567
+ hasResponseShape ||= "result" in entry || "error" in entry;
193568
+ }
193569
+ if (hasValidCall) {
193570
+ return false;
193571
+ }
193572
+ if (hasValidResponse) {
193573
+ return true;
193574
+ }
193575
+ return hasResponseShape && !hasCallShape;
193576
+ }
193384
193577
  function cancelRequestId(params) {
193385
- if (!isRecord11(params) || !isJsonRpcId(params["requestId"])) {
193578
+ if (!isRecord12(params) || !isJsonRpcId(params["requestId"])) {
193386
193579
  return;
193387
193580
  }
193388
193581
  return params["requestId"];
193389
193582
  }
193583
+ function isErrorResponse(value) {
193584
+ return isRecord12(value) && typeof value["code"] === "number" && Number.isInteger(value["code"]) && typeof value["message"] === "string";
193585
+ }
193390
193586
  var Handled = {
193391
193587
  yes() {
193392
193588
  return { handled: true };
@@ -193515,6 +193711,9 @@ class ConnectionContext {
193515
193711
  sendNotification(method, params) {
193516
193712
  return this.connection.sendNotification(method, params);
193517
193713
  }
193714
+ sendBatch(entries) {
193715
+ return this.connection.sendBatch(entries);
193716
+ }
193518
193717
  sendCancelRequest(requestId) {
193519
193718
  return this.connection.sendCancelRequest(requestId);
193520
193719
  }
@@ -193542,6 +193741,7 @@ class Connection {
193542
193741
  retryQueue = [];
193543
193742
  context = new ConnectionContext(this);
193544
193743
  receiveReader;
193744
+ allowBatches = true;
193545
193745
  constructor(requestHandlerOrStream, notificationHandlerOrHandlers, streamOrOptions, options) {
193546
193746
  if (typeof requestHandlerOrStream === "function") {
193547
193747
  const requestHandler = requestHandlerOrStream;
@@ -193550,16 +193750,13 @@ class Connection {
193550
193750
  this.initialize(stream2, [
193551
193751
  ...options?.handlers ?? [],
193552
193752
  this.legacyHandler(requestHandler, notificationHandler)
193553
- ]);
193753
+ ], options);
193554
193754
  return;
193555
193755
  }
193556
193756
  const stream = requestHandlerOrStream;
193557
193757
  const handlers = notificationHandlerOrHandlers;
193558
193758
  const connectionOptions = streamOrOptions;
193559
- this.initialize(stream, [
193560
- ...connectionOptions?.handlers ?? [],
193561
- ...handlers
193562
- ]);
193759
+ this.initialize(stream, [...connectionOptions?.handlers ?? [], ...handlers], connectionOptions);
193563
193760
  }
193564
193761
  static builder() {
193565
193762
  return new ConnectionBuilder;
@@ -193604,14 +193801,73 @@ class Connection {
193604
193801
  if (this.abortController.signal.aborted) {
193605
193802
  return rejectedPromise(this.closedReason());
193606
193803
  }
193804
+ const request = this.prepareRequest(method, params, mapResponse, options);
193805
+ const requestSent = this.sendWireMessage(request.message);
193806
+ requestSent.catch(() => {});
193807
+ if (options.cancellationSignal?.aborted) {
193808
+ request.cancel();
193809
+ }
193810
+ return request.response;
193811
+ }
193812
+ sendBatch(entries) {
193813
+ if (this.abortController.signal.aborted) {
193814
+ return rejectedPromise(this.closedReason());
193815
+ }
193816
+ if (!this.allowBatches) {
193817
+ return rejectedPromise(new TypeError("JSON-RPC batches are not supported on this connection"));
193818
+ }
193819
+ if (entries.length === 0) {
193820
+ return rejectedPromise(new TypeError("JSON-RPC batch must contain at least one entry"));
193821
+ }
193822
+ const messages = [];
193823
+ const cancellations = [];
193824
+ const outputs = [];
193825
+ for (const entry of entries) {
193826
+ if (entry.kind === "notification") {
193827
+ messages.push({
193828
+ jsonrpc: "2.0",
193829
+ method: entry.method,
193830
+ params: entry.params
193831
+ });
193832
+ outputs.push(Promise.resolve(undefined));
193833
+ continue;
193834
+ }
193835
+ const request = this.prepareRequest(entry.method, entry.params, entry.mapResponse, entry.options);
193836
+ messages.push(request.message);
193837
+ outputs.push(request.response);
193838
+ cancellations.push({
193839
+ signal: entry.options?.cancellationSignal,
193840
+ cancel: request.cancel
193841
+ });
193842
+ }
193843
+ const batch = messages;
193844
+ const batchSent = this.sendWireMessage(batch);
193845
+ for (const cancellation of cancellations) {
193846
+ if (cancellation.signal?.aborted) {
193847
+ cancellation.cancel();
193848
+ }
193849
+ }
193850
+ const response = Promise.all([batchSent, ...outputs]).then(([, ...resolved]) => resolved);
193851
+ response.catch(() => {});
193852
+ return response;
193853
+ }
193854
+ sendCancelRequest(requestId) {
193855
+ return this.sendNotification(CANCEL_REQUEST_METHOD, { requestId });
193856
+ }
193857
+ sendNotification(method, params) {
193858
+ if (this.abortController.signal.aborted) {
193859
+ return rejectedPromise(this.closedReason());
193860
+ }
193861
+ return this.sendWireMessage({ jsonrpc: "2.0", method, params });
193862
+ }
193863
+ prepareRequest(method, params, mapResponse, options = {}) {
193607
193864
  const id = this.nextRequestId++;
193608
193865
  let cancel = () => {};
193609
- const responsePromise = new Promise((resolve9, reject) => {
193866
+ const response = new Promise((resolve9, reject) => {
193610
193867
  const pendingResponse = {
193611
- resolve: (response) => {
193868
+ resolve: (value) => {
193612
193869
  try {
193613
- const value = mapResponse ? mapResponse(response) : response;
193614
- resolve9(value);
193870
+ resolve9(mapResponse ? mapResponse(value) : value);
193615
193871
  } catch (error51) {
193616
193872
  reject(error51);
193617
193873
  }
@@ -193634,27 +193890,12 @@ class Connection {
193634
193890
  };
193635
193891
  this.pendingResponses.set(id, pendingResponse);
193636
193892
  });
193637
- responsePromise.catch(() => {});
193638
- const requestSent = this.sendMessage({
193639
- jsonrpc: "2.0",
193640
- id,
193641
- method,
193642
- params
193643
- });
193644
- requestSent.catch(() => {});
193645
- if (options.cancellationSignal?.aborted) {
193646
- cancel();
193647
- }
193648
- return responsePromise;
193649
- }
193650
- sendCancelRequest(requestId) {
193651
- return this.sendNotification(CANCEL_REQUEST_METHOD, { requestId });
193652
- }
193653
- sendNotification(method, params) {
193654
- if (this.abortController.signal.aborted) {
193655
- return rejectedPromise(this.closedReason());
193656
- }
193657
- return this.sendMessage({ jsonrpc: "2.0", method, params });
193893
+ response.catch(() => {});
193894
+ return {
193895
+ message: { jsonrpc: "2.0", id, method, params },
193896
+ response,
193897
+ cancel: () => cancel()
193898
+ };
193658
193899
  }
193659
193900
  close(error51) {
193660
193901
  if (this.abortController.signal.aborted) {
@@ -193673,9 +193914,10 @@ class Connection {
193673
193914
  this.incomingRequests.clear();
193674
193915
  this.receiveReader?.cancel(closeError).catch(() => {});
193675
193916
  }
193676
- initialize(stream, handlers) {
193917
+ initialize(stream, handlers, options) {
193677
193918
  this.stream = stream;
193678
193919
  this.staticHandlers = handlers;
193920
+ this.allowBatches = options?.allowBatches ?? true;
193679
193921
  this.closedPromise = new Promise((resolve9) => {
193680
193922
  this.abortController.signal.addEventListener("abort", () => resolve9());
193681
193923
  });
@@ -193711,7 +193953,7 @@ class Connection {
193711
193953
  if (!message) {
193712
193954
  continue;
193713
193955
  }
193714
- this.receiveMessage(message);
193956
+ this.receiveWireMessage(message);
193715
193957
  }
193716
193958
  } finally {
193717
193959
  if (this.receiveReader === reader) {
@@ -193725,24 +193967,91 @@ class Connection {
193725
193967
  this.close(closeError);
193726
193968
  }
193727
193969
  }
193728
- receiveMessage(message) {
193729
- if (this.abortController.signal.aborted) {
193970
+ receiveWireMessage(message) {
193971
+ if (Array.isArray(message)) {
193972
+ if (!this.allowBatches) {
193973
+ this.close(new TypeError("JSON-RPC batches are not supported on this connection"));
193974
+ return;
193975
+ }
193976
+ this.receiveBatch(message);
193730
193977
  return;
193731
193978
  }
193732
- if (!isRecord11(message)) {
193979
+ if (!isRecord12(message)) {
193733
193980
  console.error("Invalid message", { message });
193734
193981
  return;
193735
193982
  }
193983
+ this.receiveMessage(message);
193984
+ }
193985
+ receiveBatch(batch) {
193986
+ if (batch.length === 0) {
193987
+ this.sendWireMessage({
193988
+ jsonrpc: "2.0",
193989
+ id: null,
193990
+ error: RequestError.invalidRequest(batch).toErrorResponse()
193991
+ }).catch(() => {});
193992
+ return;
193993
+ }
193994
+ const responseBatch = isResponseBatch(batch);
193995
+ const responseCount = responseBatch ? 0 : batch.reduce((count, message) => count + (isNotificationMessage(message) ? 0 : 1), 0);
193996
+ let remaining = responseCount;
193997
+ let remainingNotifications = batch.reduce((count, message) => count + (isNotificationMessage(message) ? 1 : 0), 0);
193998
+ let responseSent = false;
193999
+ const responses = [];
194000
+ const sendResponsesIfReady = async () => {
194001
+ if (responseSent || remaining !== 0 || remainingNotifications !== 0 || responses.length === 0) {
194002
+ return;
194003
+ }
194004
+ responseSent = true;
194005
+ await this.sendWireMessage(responses);
194006
+ };
194007
+ const collectResponse = async (response) => {
194008
+ responses.push(response);
194009
+ remaining -= 1;
194010
+ await sendResponsesIfReady();
194011
+ };
194012
+ for (const message of batch) {
194013
+ if (responseBatch) {
194014
+ if (isResponseShapedMessage(message)) {
194015
+ this.receiveMessage(message);
194016
+ }
194017
+ continue;
194018
+ }
194019
+ if (!isRequestMessage(message) && !isNotificationMessage(message)) {
194020
+ collectResponse({
194021
+ jsonrpc: "2.0",
194022
+ id: null,
194023
+ error: RequestError.invalidRequest(message).toErrorResponse()
194024
+ }).catch(() => {});
194025
+ continue;
194026
+ }
194027
+ const processing = this.receiveMessage(message, isRequestMessage(message) ? collectResponse : undefined);
194028
+ if (isNotificationMessage(message)) {
194029
+ processing.finally(() => {
194030
+ remainingNotifications -= 1;
194031
+ sendResponsesIfReady().catch((error51) => this.close(error51));
194032
+ });
194033
+ }
194034
+ }
194035
+ }
194036
+ receiveMessage(message, sendResponse) {
194037
+ if (this.abortController.signal.aborted) {
194038
+ return Promise.resolve();
194039
+ }
194040
+ if (!isRecord12(message)) {
194041
+ console.error("Invalid message", { message });
194042
+ return Promise.resolve();
194043
+ }
193736
194044
  if ("method" in message) {
193737
194045
  if (!("id" in message)) {
193738
194046
  this.handleProtocolNotification(message);
193739
194047
  }
193740
- this.processIncomingMessage(this.toIncomingMessage(message)).catch((error51) => this.close(error51));
194048
+ return this.processIncomingMessage(this.toIncomingMessage(message, sendResponse)).catch((error51) => this.close(error51));
193741
194049
  } else if ("id" in message) {
193742
194050
  this.handleResponse(message);
193743
194051
  } else {
193744
194052
  console.error("Invalid message", { message });
193745
194053
  }
194054
+ return Promise.resolve();
193746
194055
  }
193747
194056
  async processIncomingMessage(message) {
193748
194057
  if (this.abortController.signal.aborted) {
@@ -193786,7 +194095,7 @@ class Connection {
193786
194095
  }
193787
194096
  }
193788
194097
  }
193789
- toIncomingMessage(message) {
194098
+ toIncomingMessage(message, sendResponse) {
193790
194099
  if ("id" in message) {
193791
194100
  const abortController = new AbortController;
193792
194101
  this.incomingRequests.set(message.id, abortController);
@@ -193801,11 +194110,14 @@ class Connection {
193801
194110
  params: message.params,
193802
194111
  raw: message,
193803
194112
  signal: abortController.signal,
193804
- responder: new RequestResponder(message.id, (result) => this.sendMessage({
193805
- jsonrpc: "2.0",
193806
- id: message.id,
193807
- ...result
193808
- }), abortController.signal, finishRequest)
194113
+ responder: new RequestResponder(message.id, (result) => {
194114
+ const response = {
194115
+ jsonrpc: "2.0",
194116
+ id: message.id,
194117
+ ...result
194118
+ };
194119
+ return sendResponse ? sendResponse(response) : this.sendWireMessage(response);
194120
+ }, abortController.signal, finishRequest)
193809
194121
  };
193810
194122
  }
193811
194123
  return {
@@ -193820,13 +194132,13 @@ class Connection {
193820
194132
  if (pendingResponse) {
193821
194133
  this.pendingResponses.delete(response.id);
193822
194134
  pendingResponse.cleanup?.();
193823
- if ("result" in response) {
194135
+ if (!isResponseMessage(response)) {
194136
+ pendingResponse.reject(RequestError.invalidRequest(response));
194137
+ } else if ("result" in response) {
193824
194138
  pendingResponse.resolve(response.result);
193825
- } else if ("error" in response && isRecord11(response.error)) {
194139
+ } else {
193826
194140
  const { code, message, data } = response.error;
193827
194141
  pendingResponse.reject(new RequestError(code, message, data));
193828
- } else {
193829
- pendingResponse.reject(RequestError.invalidRequest(response));
193830
194142
  }
193831
194143
  } else {
193832
194144
  console.error("Got response to unknown request", response.id);
@@ -193849,7 +194161,7 @@ class Connection {
193849
194161
  closedReason() {
193850
194162
  return this.abortController.signal.reason ?? new Error("ACP connection closed");
193851
194163
  }
193852
- async sendMessage(message) {
194164
+ async sendWireMessage(message) {
193853
194165
  if (this.abortController.signal.aborted) {
193854
194166
  return rejectedPromise(this.closedReason());
193855
194167
  }
@@ -194032,7 +194344,7 @@ function ndJsonStream(output2, input2) {
194032
194344
  if (trimmedLine) {
194033
194345
  try {
194034
194346
  const message = JSON.parse(trimmedLine);
194035
- if (isRecord11(message)) {
194347
+ if (isRecord12(message) || Array.isArray(message)) {
194036
194348
  controller.enqueue(message);
194037
194349
  } else {
194038
194350
  console.warn("Skipping JSON line that is not an object:", trimmedLine);
@@ -194106,7 +194418,28 @@ function ndJsonStream(output2, input2) {
194106
194418
  });
194107
194419
  return { readable, writable };
194108
194420
  }
194421
+
194422
+ // node_modules/@agentclientprotocol/sdk/dist/schema/guards.gen.js
194423
+ var zGuardCreateElicitationRequestForm = zElicitationFormMode.and(object({ mode: literal("form") })).and(object({ message: string2() }));
194424
+ var zGuardCreateElicitationRequestUrl = zElicitationUrlMode.and(object({ mode: literal("url") })).and(object({ message: string2() }));
194425
+ var zGuardCreateElicitationRequestCustom = union([zElicitationSessionScope, zElicitationRequestScope]).and(object({ message: string2() }));
194426
+ var zGuardElicitationPropertySchemaString = zStringPropertySchema.and(object({ type: literal("string") }));
194427
+ var zGuardElicitationPropertySchemaNumber = zNumberPropertySchema.and(object({ type: literal("number") }));
194428
+ var zGuardElicitationPropertySchemaInteger = zIntegerPropertySchema.and(object({ type: literal("integer") }));
194429
+ var zGuardElicitationPropertySchemaBoolean = zBooleanPropertySchema.and(object({ type: literal("boolean") }));
194430
+ var zGuardElicitationPropertySchemaArray = zMultiSelectPropertySchema.and(object({ type: literal("array") }));
194431
+ var zGuardMultiSelectItemsString = zStringMultiSelectItems.and(object({ type: literal("string") }));
194432
+ var zGuardCreateElicitationResponseAccept = zElicitationAcceptAction.and(object({ action: literal("accept") }));
194433
+ var zGuardCreateElicitationResponseDecline = object({
194434
+ action: literal("decline")
194435
+ });
194436
+ var zGuardCreateElicitationResponseCancel = object({
194437
+ action: literal("cancel")
194438
+ });
194109
194439
  // node_modules/@agentclientprotocol/sdk/dist/acp.js
194440
+ function ndJsonStream2(output2, input2) {
194441
+ return ndJsonStream(output2, input2);
194442
+ }
194110
194443
  function emptyObjectResponse(response) {
194111
194444
  return response ?? {};
194112
194445
  }
@@ -194691,6 +195024,7 @@ function runConnectHandlers(connection, handlers) {
194691
195024
  var appBuilder = Symbol("appBuilder");
194692
195025
  var runAgentConnectHandlers = Symbol("runAgentConnectHandlers");
194693
195026
  var runClientConnectHandlers = Symbol("runClientConnectHandlers");
195027
+ var stableConnectionOptions = { allowBatches: false };
194694
195028
  class AgentApp {
194695
195029
  builder = Connection.builder();
194696
195030
  connectHandlers = [];
@@ -194753,7 +195087,7 @@ class AgentApp {
194753
195087
  return state2;
194754
195088
  }
194755
195089
  const [thisStream, peerStream] = memoryStreamPair();
194756
- const peerRawConnection = target[appBuilder]().connect(peerStream);
195090
+ const peerRawConnection = target[appBuilder]().connect(peerStream, stableConnectionOptions);
194757
195091
  const peerConnection = clientConnection(peerRawConnection);
194758
195092
  const state = this.openStreamConnection(thisStream);
194759
195093
  state.rawConnection.closed.then(() => peerConnection.close());
@@ -194768,8 +195102,8 @@ class AgentApp {
194768
195102
  }
194769
195103
  return state;
194770
195104
  }
194771
- openStreamConnection(stream2) {
194772
- const rawConnection = this.builder.connect(stream2);
195105
+ openStreamConnection(stream) {
195106
+ const rawConnection = this.builder.connect(stream, stableConnectionOptions);
194773
195107
  return {
194774
195108
  rawConnection,
194775
195109
  connection: agentConnection(rawConnection, this.connectHandlers)
@@ -194844,7 +195178,7 @@ class ClientApp {
194844
195178
  return state2;
194845
195179
  }
194846
195180
  const [thisStream, peerStream] = memoryStreamPair();
194847
- const peerRawConnection = target[appBuilder]().connect(peerStream);
195181
+ const peerRawConnection = target[appBuilder]().connect(peerStream, stableConnectionOptions);
194848
195182
  const peerConnection = agentConnection(peerRawConnection);
194849
195183
  const state = this.openStreamConnection(thisStream);
194850
195184
  state.rawConnection.closed.then(() => peerConnection.close());
@@ -194859,8 +195193,8 @@ class ClientApp {
194859
195193
  }
194860
195194
  return state;
194861
195195
  }
194862
- openStreamConnection(stream2) {
194863
- const rawConnection = this.builder.connect(stream2);
195196
+ openStreamConnection(stream) {
195197
+ const rawConnection = this.builder.connect(stream, stableConnectionOptions);
194864
195198
  return {
194865
195199
  rawConnection,
194866
195200
  connection: clientConnection(rawConnection, this.connectHandlers)
@@ -195042,12 +195376,12 @@ class AgentOutputAccumulator {
195042
195376
  var RETRY_ATTEMPT_PATTERN = /Reconnecting\.\.\.\s*(\d+)\/(\d+)/;
195043
195377
  var DISPLAY_MESSAGE_FIELDS = ["title", "text", "message", "description"];
195044
195378
  function parseCodexRetryUpdate(update) {
195045
- if (!isRecord12(update) || update.sessionUpdate !== "session_info_update") {
195379
+ if (!isRecord13(update) || update.sessionUpdate !== "session_info_update") {
195046
195380
  return;
195047
195381
  }
195048
- const meta3 = isRecord12(update._meta) ? update._meta : undefined;
195049
- const codex = meta3 && isRecord12(meta3.codex) ? meta3.codex : undefined;
195050
- const error51 = codex && isRecord12(codex.error) ? codex.error : undefined;
195382
+ const meta3 = isRecord13(update._meta) ? update._meta : undefined;
195383
+ const codex = meta3 && isRecord13(meta3.codex) ? meta3.codex : undefined;
195384
+ const error51 = codex && isRecord13(codex.error) ? codex.error : undefined;
195051
195385
  if (error51?.willRetry !== true)
195052
195386
  return;
195053
195387
  const rawMessage = typeof error51.message === "string" ? error51.message : findDisplayMessage(update) ?? "model stream retry";
@@ -195067,7 +195401,7 @@ function findDisplayMessage(update) {
195067
195401
  }
195068
195402
  return;
195069
195403
  }
195070
- function isRecord12(value) {
195404
+ function isRecord13(value) {
195071
195405
  return value !== null && typeof value === "object" && !Array.isArray(value);
195072
195406
  }
195073
195407
 
@@ -195552,7 +195886,7 @@ function isSeverity(value) {
195552
195886
  return typeof value === "string" && severities.includes(value);
195553
195887
  }
195554
195888
  function normalizeCisaSecureByDesign(value) {
195555
- if (!isRecord13(value))
195889
+ if (!isRecord14(value))
195556
195890
  return;
195557
195891
  const normalized = {};
195558
195892
  const customerSecurityOutcomes = normalizeGateStatus(value.customerSecurityOutcomes);
@@ -195593,7 +195927,7 @@ function isEvidenceQuality(value) {
195593
195927
  return typeof value === "string" && evidenceQualities.includes(value);
195594
195928
  }
195595
195929
  function isStrictAgentOpinion(value) {
195596
- if (!isRecord13(value) || !hasOnlyKeys(value, STRICT_ROOT_KEYS))
195930
+ if (!isRecord14(value) || !hasOnlyKeys(value, STRICT_ROOT_KEYS))
195597
195931
  return false;
195598
195932
  if (typeof value.summary !== "string")
195599
195933
  return false;
@@ -195603,7 +195937,7 @@ function isStrictAgentOpinion(value) {
195603
195937
  return value.cisaSecureByDesign === undefined || isStrictCisaSecureByDesign(value.cisaSecureByDesign);
195604
195938
  }
195605
195939
  function isStrictFinding(value) {
195606
- if (!isRecord13(value) || !hasOnlyKeys(value, STRICT_FINDING_KEYS)) {
195940
+ if (!isRecord14(value) || !hasOnlyKeys(value, STRICT_FINDING_KEYS)) {
195607
195941
  return false;
195608
195942
  }
195609
195943
  if (!isSeverity(value.severity) || !isCategory(value.category) || !isNonEmptyString(value.title) || !isNonEmptyString(value.evidence) || !isNonEmptyString(value.recommendation) || !isConfidence(value.confidence)) {
@@ -195615,11 +195949,11 @@ function isStrictFinding(value) {
195615
195949
  return true;
195616
195950
  }
195617
195951
  function isStrictFindingFiles(value) {
195618
- return Array.isArray(value) && value.every((item) => isRecord13(item) && hasOnlyKeys(item, STRICT_FILE_KEYS) && isNonEmptyString(item.path) && isOptionalLineNumber(item.lineStart) && isOptionalLineNumber(item.lineEnd));
195952
+ return Array.isArray(value) && value.every((item) => isRecord14(item) && hasOnlyKeys(item, STRICT_FILE_KEYS) && isNonEmptyString(item.path) && isOptionalLineNumber(item.lineStart) && isOptionalLineNumber(item.lineEnd));
195619
195953
  }
195620
195954
  function isStrictEvidenceRefs(value) {
195621
195955
  return Array.isArray(value) && value.length <= MAX_EVIDENCE_REFS2 && value.every((item) => {
195622
- if (!isRecord13(item) || !hasOnlyKeys(item, STRICT_EVIDENCE_REF_KEYS)) {
195956
+ if (!isRecord14(item) || !hasOnlyKeys(item, STRICT_EVIDENCE_REF_KEYS)) {
195623
195957
  return false;
195624
195958
  }
195625
195959
  if (item.kind !== "file" && item.kind !== "diff_hunk" && item.kind !== "plan_clause") {
@@ -195635,7 +195969,7 @@ function isStrictEvidenceRefs(value) {
195635
195969
  });
195636
195970
  }
195637
195971
  function isStrictCisaSecureByDesign(value) {
195638
- if (!isRecord13(value) || !hasOnlyKeys(value, STRICT_CISA_KEYS))
195972
+ if (!isRecord14(value) || !hasOnlyKeys(value, STRICT_CISA_KEYS))
195639
195973
  return false;
195640
195974
  for (const key of [
195641
195975
  "customerSecurityOutcomes",
@@ -195674,7 +196008,7 @@ function normalizeFindingFiles(value) {
195674
196008
  if (!Array.isArray(value))
195675
196009
  return;
195676
196010
  const files = value.flatMap((item) => {
195677
- if (!isRecord13(item) || typeof item.path !== "string" || item.path.trim().length === 0) {
196011
+ if (!isRecord14(item) || typeof item.path !== "string" || item.path.trim().length === 0) {
195678
196012
  return [];
195679
196013
  }
195680
196014
  const file2 = {
@@ -195694,7 +196028,7 @@ function normalizeEvidenceRefs2(value) {
195694
196028
  if (!Array.isArray(value))
195695
196029
  return;
195696
196030
  const references = value.slice(0, MAX_EVIDENCE_REFS2).flatMap((item) => {
195697
- if (!isRecord13(item) || item.kind !== "file" && item.kind !== "diff_hunk" && item.kind !== "plan_clause") {
196031
+ if (!isRecord14(item) || item.kind !== "file" && item.kind !== "diff_hunk" && item.kind !== "plan_clause") {
195698
196032
  return [];
195699
196033
  }
195700
196034
  const reference = { kind: item.kind };
@@ -195717,7 +196051,7 @@ function normalizeEvidenceRefs2(value) {
195717
196051
  function normalizeLineNumber(value) {
195718
196052
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 && value <= MAX_EVIDENCE_LINE2 ? value : undefined;
195719
196053
  }
195720
- function isRecord13(value) {
196054
+ function isRecord14(value) {
195721
196055
  return typeof value === "object" && value !== null && !Array.isArray(value);
195722
196056
  }
195723
196057
 
@@ -196057,7 +196391,7 @@ async function runAcpClientWorkflow(child, input2, abortController, configOption
196057
196391
  }
196058
196392
  const output2 = Writable.toWeb(child.stdin);
196059
196393
  const inputStream = Readable.toWeb(child.stdout);
196060
- const stream2 = ndJsonStream(output2, limitAcpNdJsonLineBytes(inputStream));
196394
+ const stream = ndJsonStream2(output2, limitAcpNdJsonLineBytes(inputStream));
196061
196395
  const app = client({ name: "kyoso" }).onRequest(methods.client.session.requestPermission, () => ({
196062
196396
  outcome: { outcome: "cancelled" }
196063
196397
  })).onRequest(methods.client.fs.readTextFile, async (ctx) => ({
@@ -196079,7 +196413,7 @@ async function runAcpClientWorkflow(child, input2, abortController, configOption
196079
196413
  policy: "Kyoso does not create terminals."
196080
196414
  });
196081
196415
  }).onRequest(methods.client.terminal.kill, () => ({}));
196082
- return app.connectWith(stream2, async (ctx) => {
196416
+ return app.connectWith(stream, async (ctx) => {
196083
196417
  await ctx.request(methods.agent.initialize, {
196084
196418
  protocolVersion: PROTOCOL_VERSION,
196085
196419
  clientCapabilities: {
@@ -196342,7 +196676,7 @@ function normalizeUsage3(usage) {
196342
196676
  return normalizeModelTokenUsage(usage);
196343
196677
  }
196344
196678
  function withReportedExecutionIdentity(identity, metadata) {
196345
- const record2 = isRecord14(metadata) ? metadata : {};
196679
+ const record2 = isRecord15(metadata) ? metadata : {};
196346
196680
  return createModelExecutionIdentity({
196347
196681
  providerRoute: identity.providerRoute,
196348
196682
  requestedModel: identity.requestedModel,
@@ -196351,9 +196685,9 @@ function withReportedExecutionIdentity(identity, metadata) {
196351
196685
  });
196352
196686
  }
196353
196687
  function readChunkMeta(update) {
196354
- const record2 = isRecord14(update) ? update : {};
196355
- const metadata = isRecord14(record2._meta) ? record2._meta : {};
196356
- const codex = isRecord14(metadata.codex) ? metadata.codex : {};
196688
+ const record2 = isRecord15(update) ? update : {};
196689
+ const metadata = isRecord15(record2._meta) ? record2._meta : {};
196690
+ const codex = isRecord15(metadata.codex) ? metadata.codex : {};
196357
196691
  const phase = codex.phase === "commentary" || codex.phase === "final_answer" ? codex.phase : "unknown";
196358
196692
  return {
196359
196693
  ...typeof record2.messageId === "string" ? { messageId: record2.messageId } : {},
@@ -196361,15 +196695,15 @@ function readChunkMeta(update) {
196361
196695
  };
196362
196696
  }
196363
196697
  function readCodexThreadStatus(update) {
196364
- const record2 = isRecord14(update) ? update : {};
196698
+ const record2 = isRecord15(update) ? update : {};
196365
196699
  if (record2.sessionUpdate !== "session_info_update")
196366
196700
  return;
196367
- const metadata = isRecord14(record2._meta) ? record2._meta : {};
196368
- const codex = isRecord14(metadata.codex) ? metadata.codex : {};
196369
- const threadStatus = isRecord14(codex.threadStatus) ? codex.threadStatus : {};
196701
+ const metadata = isRecord15(record2._meta) ? record2._meta : {};
196702
+ const codex = isRecord15(metadata.codex) ? metadata.codex : {};
196703
+ const threadStatus = isRecord15(codex.threadStatus) ? codex.threadStatus : {};
196370
196704
  return typeof threadStatus.type === "string" ? threadStatus.type : undefined;
196371
196705
  }
196372
- function isRecord14(value) {
196706
+ function isRecord15(value) {
196373
196707
  return value !== null && typeof value === "object" && !Array.isArray(value);
196374
196708
  }
196375
196709
  function resolveEffortConfigOption(agent, effort) {
@@ -196814,7 +197148,7 @@ var __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__
196814
197148
  enumerable: true
196815
197149
  }) : target, mod));
196816
197150
 
196817
- // node_modules/@modelcontextprotocol/core/dist/auth-DFgbUATV.mjs
197151
+ // node_modules/@modelcontextprotocol/core/dist/auth-CUe6YdwF.mjs
196818
197152
  var LATEST_PROTOCOL_VERSION = "2025-11-25";
196819
197153
  var SUPPORTED_PROTOCOL_VERSIONS = [
196820
197154
  LATEST_PROTOCOL_VERSION,
@@ -196826,6 +197160,7 @@ var SUPPORTED_PROTOCOL_VERSIONS = [
196826
197160
  var RELATED_TASK_META_KEY = "io.modelcontextprotocol/related-task";
196827
197161
  var PROTOCOL_VERSION_META_KEY = "io.modelcontextprotocol/protocolVersion";
196828
197162
  var CLIENT_INFO_META_KEY = "io.modelcontextprotocol/clientInfo";
197163
+ var SERVER_INFO_META_KEY = "io.modelcontextprotocol/serverInfo";
196829
197164
  var CLIENT_CAPABILITIES_META_KEY = "io.modelcontextprotocol/clientCapabilities";
196830
197165
  var SUBSCRIPTION_ID_META_KEY = "io.modelcontextprotocol/subscriptionId";
196831
197166
  var LOG_LEVEL_META_KEY = "io.modelcontextprotocol/logLevel";
@@ -196859,7 +197194,10 @@ var NotificationSchema = object({
196859
197194
  method: string2(),
196860
197195
  params: NotificationsParamsSchema.loose().optional()
196861
197196
  });
196862
- var ResultSchema = looseObject({ _meta: RequestMetaSchema.optional() });
197197
+ var ResultMetaObjectSchema = looseObject({ get [SERVER_INFO_META_KEY]() {
197198
+ return ImplementationSchema.optional().catch(undefined);
197199
+ } });
197200
+ var ResultSchema = looseObject({ _meta: ResultMetaObjectSchema.optional() });
196863
197201
  var RequestIdSchema = union([string2(), number2().int()]);
196864
197202
  var JSONRPCRequestSchema = object({
196865
197203
  jsonrpc: literal(JSONRPC_VERSION),
@@ -196990,7 +197328,6 @@ var DiscoverRequestSchema = RequestSchema.extend({
196990
197328
  var DiscoverResultSchema = ResultSchema.extend({
196991
197329
  supportedVersions: array(string2()),
196992
197330
  capabilities: ServerCapabilitiesSchema,
196993
- serverInfo: ImplementationSchema,
196994
197331
  instructions: string2().optional()
196995
197332
  });
196996
197333
  var PingRequestSchema = RequestSchema.extend({
@@ -197095,7 +197432,7 @@ var SubscriptionsAcknowledgedNotificationSchema = NotificationSchema.extend({
197095
197432
  method: literal("notifications/subscriptions/acknowledged"),
197096
197433
  params: SubscriptionsAcknowledgedNotificationParamsSchema
197097
197434
  });
197098
- var SubscriptionsListenResultMetaSchema = looseObject({ [SUBSCRIPTION_ID_META_KEY]: RequestIdSchema });
197435
+ var SubscriptionsListenResultMetaSchema = ResultMetaObjectSchema.extend({ [SUBSCRIPTION_ID_META_KEY]: RequestIdSchema });
197099
197436
  var SubscriptionsListenResultSchema = ResultSchema.extend({ _meta: SubscriptionsListenResultMetaSchema });
197100
197437
  var ResourceUpdatedNotificationParamsSchema = NotificationsParamsSchema.extend({ uri: string2() });
197101
197438
  var ResourceUpdatedNotificationSchema = NotificationSchema.extend({
@@ -197752,7 +198089,7 @@ var OAuthTokenRevocationRequestSchema = object({
197752
198089
  token_type_hint: string2().optional()
197753
198090
  }).strip();
197754
198091
 
197755
- // node_modules/@modelcontextprotocol/server/dist/src-D5Nfqtoz.mjs
198092
+ // node_modules/@modelcontextprotocol/server/dist/src-D86MbS1I.mjs
197756
198093
  var BRANDS = Symbol.for("mcp.sdk.errorBrands");
197757
198094
  function stampErrorBrands(instance, ctor) {
197758
198095
  const brands = /* @__PURE__ */ new Set;
@@ -197870,7 +198207,7 @@ var SdkHttpError = class extends SdkError {
197870
198207
  return this.data.statusText;
197871
198208
  }
197872
198209
  };
197873
- function isPlainObject$6(value) {
198210
+ function isPlainObject$7(value) {
197874
198211
  return value !== null && typeof value === "object" && !Array.isArray(value);
197875
198212
  }
197876
198213
  function isImpliedCapabilityMember(capability, member, declaredValue) {
@@ -197904,7 +198241,7 @@ function missingClientCapabilities(required2, declared) {
197904
198241
  missing[capability] = requirement;
197905
198242
  continue;
197906
198243
  }
197907
- if (isPlainObject$6(requirement) && isPlainObject$6(declaredValue)) {
198244
+ if (isPlainObject$7(requirement) && isPlainObject$7(declaredValue)) {
197908
198245
  const missingMembers = {};
197909
198246
  for (const [member, memberRequirement] of Object.entries(requirement))
197910
198247
  if (memberRequirement !== undefined && declaredValue[member] === undefined && !isImpliedCapabilityMember(capability, member, declaredValue))
@@ -199023,7 +199360,7 @@ function getNotificationSchema(method) {
199023
199360
  }
199024
199361
  var rev2025RequestMethods = Object.keys(requestMethodKeys$1);
199025
199362
  var rev2025NotificationMethods = Object.keys(notificationMethodKeys$1);
199026
- function isPlainObject$5(value) {
199363
+ function isPlainObject$6(value) {
199027
199364
  return value !== null && typeof value === "object" && !Array.isArray(value);
199028
199365
  }
199029
199366
  function triState$1(schema, raw) {
@@ -199047,7 +199384,7 @@ var NOT_IN_ERA$1 = {
199047
199384
  reason: "not-in-era"
199048
199385
  };
199049
199386
  function toolNeedsLegacyWrap(t) {
199050
- return isPlainObject$5(t) && isPlainObject$5(t["outputSchema"]) && isNonObjectJsonSchemaRoot(t["outputSchema"]);
199387
+ return isPlainObject$6(t) && isPlainObject$6(t["outputSchema"]) && isNonObjectJsonSchemaRoot(t["outputSchema"]);
199051
199388
  }
199052
199389
  function toNeutralResult(value) {
199053
199390
  return value;
@@ -199085,7 +199422,7 @@ var rev2025Codec = {
199085
199422
  };
199086
199423
  },
199087
199424
  decodeResult(_method, raw) {
199088
- if (isPlainObject$5(raw) && "resultType" in raw) {
199425
+ if (isPlainObject$6(raw) && "resultType" in raw) {
199089
199426
  const stripped = { ...raw };
199090
199427
  delete stripped["resultType"];
199091
199428
  return {
@@ -199506,7 +199843,7 @@ function build() {
199506
199843
  const RequestMetaEnvelopeSchema = looseObject({
199507
199844
  progressToken: ProgressTokenSchema$1.optional(),
199508
199845
  [PROTOCOL_VERSION_META_KEY]: string2(),
199509
- [CLIENT_INFO_META_KEY]: ImplementationSchema$1,
199846
+ [CLIENT_INFO_META_KEY]: ImplementationSchema$1.optional(),
199510
199847
  [CLIENT_CAPABILITIES_META_KEY]: ClientCapabilities2026Schema,
199511
199848
  [LOG_LEVEL_META_KEY]: LoggingLevelSchema$1.optional()
199512
199849
  });
@@ -199543,7 +199880,8 @@ function build() {
199543
199880
  _meta: record(string2(), unknown()).optional()
199544
199881
  });
199545
199882
  const ResultTypeSchema = string2();
199546
- const wireMeta = record(string2(), unknown()).optional();
199883
+ const ResultMetaSchema = looseObject({ [SERVER_INFO_META_KEY]: ImplementationSchema$1.optional().catch(undefined) });
199884
+ const wireMeta = ResultMetaSchema.optional();
199547
199885
  function wireResult(shape) {
199548
199886
  return looseObject({
199549
199887
  _meta: wireMeta,
@@ -199605,7 +199943,6 @@ function build() {
199605
199943
  cacheScope: _enum2(["public", "private"]).catch("private"),
199606
199944
  supportedVersions: array(string2()),
199607
199945
  capabilities: ServerCapabilities2026Schema,
199608
- serverInfo: ImplementationSchema$1,
199609
199946
  instructions: string2().optional()
199610
199947
  });
199611
199948
  const CreateMessageRequestParamsSchema$1 = object({
@@ -199742,7 +200079,7 @@ function build() {
199742
200079
  });
199743
200080
  const subscriptionsListenParamsShape = { notifications: SubscriptionFilterSchema$1 };
199744
200081
  const SubscriptionsListenRequestSchema$1 = wireRequest("subscriptions/listen", subscriptionsListenParamsShape);
199745
- const SubscriptionsListenResultMetaSchema$1 = looseObject({ "io.modelcontextprotocol/subscriptionId": RequestIdSchema$1 });
200082
+ const SubscriptionsListenResultMetaSchema$1 = ResultMetaSchema.extend({ "io.modelcontextprotocol/subscriptionId": RequestIdSchema$1 });
199746
200083
  const SubscriptionsListenResultSchema$1 = looseObject({
199747
200084
  _meta: SubscriptionsListenResultMetaSchema$1,
199748
200085
  resultType: ResultTypeSchema.default("complete")
@@ -199817,7 +200154,6 @@ function build() {
199817
200154
  cacheScope: _enum2(["public", "private"]).catch("private"),
199818
200155
  supportedVersions: array(string2()),
199819
200156
  capabilities: ServerCapabilities2026Schema,
199820
- serverInfo: ImplementationSchema$1,
199821
200157
  instructions: string2().optional()
199822
200158
  }),
199823
200159
  "subscriptions/listen": liftedResult({})
@@ -199931,6 +200267,7 @@ function build() {
199931
200267
  SamplingMessageContentBlockSchema: SamplingMessageContentBlockSchema$1,
199932
200268
  SamplingMessageSchema: SamplingMessageSchema$1,
199933
200269
  ResultTypeSchema,
200270
+ ResultMetaSchema,
199934
200271
  ResultSchema: ResultSchema$1,
199935
200272
  PaginatedResultSchema: PaginatedResultSchema$1,
199936
200273
  CallToolResultSchema: CallToolResultSchema$1,
@@ -200182,6 +200519,30 @@ function fillCacheFields(method, result) {
200182
200519
  delete filled[RESULT_CACHE_HINT_FALLBACK];
200183
200520
  return filled;
200184
200521
  }
200522
+ function isPlainObject$5(value) {
200523
+ return value !== null && typeof value === "object" && !Array.isArray(value);
200524
+ }
200525
+ function stampServerInfoMeta(result, serverInfo) {
200526
+ if (serverInfo === undefined)
200527
+ return result;
200528
+ const meta3 = result["_meta"];
200529
+ if (meta3 === undefined)
200530
+ return {
200531
+ ...result,
200532
+ _meta: { [SERVER_INFO_META_KEY]: serverInfo }
200533
+ };
200534
+ if (!isPlainObject$5(meta3))
200535
+ return result;
200536
+ if (meta3[SERVER_INFO_META_KEY] !== undefined)
200537
+ return result;
200538
+ return {
200539
+ ...result,
200540
+ _meta: {
200541
+ ...meta3,
200542
+ [SERVER_INFO_META_KEY]: serverInfo
200543
+ }
200544
+ };
200545
+ }
200185
200546
  function resolveTtlMs(fallback) {
200186
200547
  return fallback !== undefined && isValidCacheTtlMs(fallback.ttlMs) ? fallback.ttlMs : DEFAULT_CACHE_TTL_MS;
200187
200548
  }
@@ -200300,11 +200661,7 @@ var NOT_IN_ERA = {
200300
200661
  ok: false,
200301
200662
  reason: "not-in-era"
200302
200663
  };
200303
- var REQUIRED_ENVELOPE_KEYS = [
200304
- PROTOCOL_VERSION_META_KEY,
200305
- CLIENT_INFO_META_KEY,
200306
- CLIENT_CAPABILITIES_META_KEY
200307
- ];
200664
+ var REQUIRED_ENVELOPE_KEYS = [PROTOCOL_VERSION_META_KEY, CLIENT_CAPABILITIES_META_KEY];
200308
200665
  function enforceDeletedFields(method, result) {
200309
200666
  let next = result;
200310
200667
  let copied = false;
@@ -200441,13 +200798,13 @@ var rev2026Codec = {
200441
200798
  result: lifted
200442
200799
  };
200443
200800
  },
200444
- encodeResult(method, result) {
200445
- return fillCacheFields(method, stampResultType(method, enforceDeletedFields(method, result)));
200801
+ encodeResult(method, result, serverInfo) {
200802
+ return stampServerInfoMeta(fillCacheFields(method, stampResultType(method, enforceDeletedFields(method, result))), serverInfo);
200446
200803
  },
200447
200804
  encodeErrorCode: (code) => code === -32002 ? -32602 : code,
200448
200805
  checkInboundEnvelope(material) {
200449
200806
  if (material.envelope === undefined)
200450
- return "Request is missing the required _meta envelope for protocol revision 2026-07-28 (io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientInfo, io.modelcontextprotocol/clientCapabilities)";
200807
+ return "Request is missing the required _meta envelope for protocol revision 2026-07-28 (io.modelcontextprotocol/protocolVersion, io.modelcontextprotocol/clientCapabilities)";
200451
200808
  const parsed = buildSchemas2026().RequestMetaEnvelopeSchema.safeParse(material.envelope);
200452
200809
  if (!parsed.success)
200453
200810
  return `Invalid _meta envelope for protocol revision 2026-07-28: ${parsed.error.issues.map((issue2) => issue2.message).join("; ")}`;
@@ -200606,6 +200963,7 @@ var schemas_exports = /* @__PURE__ */ __exportAll({
200606
200963
  ResourceTemplateSchema: () => ResourceTemplateSchema,
200607
200964
  ResourceUpdatedNotificationParamsSchema: () => ResourceUpdatedNotificationParamsSchema,
200608
200965
  ResourceUpdatedNotificationSchema: () => ResourceUpdatedNotificationSchema,
200966
+ ResultMetaObjectSchema: () => ResultMetaObjectSchema,
200609
200967
  ResultSchema: () => ResultSchema,
200610
200968
  RoleSchema: () => RoleSchema,
200611
200969
  RootSchema: () => RootSchema,
@@ -201287,6 +201645,7 @@ var SPEC_SCHEMA_KEYS = [
201287
201645
  "ResourceTemplateReferenceSchema",
201288
201646
  "ResourceUpdatedNotificationSchema",
201289
201647
  "ResourceUpdatedNotificationParamsSchema",
201648
+ "ResultMetaObjectSchema",
201290
201649
  "ResultSchema",
201291
201650
  "RoleSchema",
201292
201651
  "RootSchema",
@@ -201713,7 +202072,7 @@ var Protocol = class {
201713
202072
  return;
201714
202073
  let encoded;
201715
202074
  try {
201716
- encoded = codec2.encodeResult(request.method, result);
202075
+ encoded = codec2.encodeResult(request.method, result, this._outboundServerInfo());
201717
202076
  } catch (error51) {
201718
202077
  this._onerror(/* @__PURE__ */ new Error(`Failed to encode result for ${request.method}: ${error51}`));
201719
202078
  sendErrorResponse(ProtocolErrorCode.InternalError, "Internal error");
@@ -202012,6 +202371,7 @@ var Protocol = class {
202012
202371
  _wrapHandler(_method, handler) {
202013
202372
  return handler;
202014
202373
  }
202374
+ _outboundServerInfo() {}
202015
202375
  removeRequestHandler(method) {
202016
202376
  this._requestHandlers.delete(method);
202017
202377
  }
@@ -209439,7 +209799,7 @@ var Ajv = import_ajv.Ajv;
209439
209799
  // node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs
209440
209800
  import process3 from "node:process";
209441
209801
 
209442
- // node_modules/@modelcontextprotocol/server/dist/mcp-Ctiu4nBa.mjs
209802
+ // node_modules/@modelcontextprotocol/server/dist/mcp-IJurDZVN.mjs
209443
209803
  var COMPLETABLE_SYMBOL = Symbol.for("mcp.completable");
209444
209804
  function isCompletable(schema) {
209445
209805
  return !!schema && typeof schema === "object" && COMPLETABLE_SYMBOL in schema;
@@ -209602,6 +209962,7 @@ var INPUT_REQUIRED_CAPABLE_METHODS = new Set([
209602
209962
  ]);
209603
209963
  var writeClientIdentity;
209604
209964
  var installDiscoverHandler;
209965
+ var readServerIdentity;
209605
209966
  var Server = class extends Protocol {
209606
209967
  _clientCapabilities;
209607
209968
  _clientVersion;
@@ -209618,6 +209979,7 @@ var Server = class extends Protocol {
209618
209979
  server2._supportedProtocolVersions = [...server2._supportedProtocolVersions, ...missing];
209619
209980
  server2.setRequestHandler("server/discover", () => server2._ondiscover());
209620
209981
  };
209982
+ readServerIdentity = (server2) => server2._serverInfo;
209621
209983
  }
209622
209984
  _capabilities;
209623
209985
  _instructions;
@@ -209922,10 +210284,12 @@ var Server = class extends Protocol {
209922
210284
  return {
209923
210285
  supportedVersions: modernProtocolVersions(this._supportedProtocolVersions),
209924
210286
  capabilities: discoverAdvertisedCapabilities(this.getCapabilities()),
209925
- serverInfo: this._serverInfo,
209926
210287
  ...this._instructions && { instructions: this._instructions }
209927
210288
  };
209928
210289
  }
210290
+ _outboundServerInfo() {
210291
+ return this._serverInfo;
210292
+ }
209929
210293
  getClientCapabilities() {
209930
210294
  return this._clientCapabilities;
209931
210295
  }
@@ -210742,9 +211106,14 @@ import { resolve as resolve10 } from "node:path";
210742
211106
  // src/config/configOverrides.ts
210743
211107
  var NUMBER_VALUE = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i;
210744
211108
  var UNSET_NUMBER_OVERRIDE_PATHS = new Set([
211109
+ "agents.codex.timeoutS",
211110
+ "agents.claude.timeoutS",
210745
211111
  "agents.codex.openRouter.streamIdleTimeoutMs",
211112
+ "agents.codex.openRouter.streamIdleTimeoutS",
210746
211113
  "agents.codex.openRouter.streamMaxRetries",
210747
- "agents.codex.openRouter.requestMaxRetries"
211114
+ "agents.codex.openRouter.requestMaxRetries",
211115
+ "judge.timeoutS",
211116
+ "verification.timeoutS"
210748
211117
  ]);
210749
211118
  function applyConfigOverrides(config2, assignments) {
210750
211119
  if (assignments.length === 0)
@@ -210755,9 +211124,21 @@ function applyConfigOverrides(config2, assignments) {
210755
211124
  for (const override of overrides) {
210756
211125
  writePath2(overridden, override.path, parseConfigOverrideValue(override.value, readPath2(baseConfig, override.path), override.path));
210757
211126
  }
210758
- clearInheritedOpenRouterConfigForProviderReset(baseConfig, overridden, overrides);
210759
- assertOpenRouterProviderOverrideIncludesModel(baseConfig, overridden, overrides);
210760
- const parsed = kyosoConfigSchema.safeParse(overridden);
211127
+ let normalized;
211128
+ try {
211129
+ normalized = normalizeConfigTimeUnits(overridden);
211130
+ } catch (error51) {
211131
+ if (!(error51 instanceof TimeUnitValidationError))
211132
+ throw error51;
211133
+ const assignment2 = findAssignmentForPath(overrides, error51.field);
211134
+ if (!assignment2) {
211135
+ throw new Error(`Invalid config time value: ${error51.message}`);
211136
+ }
211137
+ throw new Error(`Invalid --set value ${JSON.stringify(assignment2)}: ${error51.message}`);
211138
+ }
211139
+ clearInheritedOpenRouterConfigForProviderReset(baseConfig, normalized, overrides);
211140
+ assertOpenRouterProviderOverrideIncludesModel(baseConfig, normalized, overrides);
211141
+ const parsed = kyosoConfigSchema.safeParse(normalized);
210761
211142
  if (parsed.success)
210762
211143
  return parsed.data;
210763
211144
  const issue2 = parsed.error.issues[0];
@@ -210787,7 +211168,7 @@ function clearInheritedOpenRouterConfigForProviderReset(baseConfig, overridden,
210787
211168
  return;
210788
211169
  }
210789
211170
  const codex = readPath2(overridden, ["agents", "codex"]);
210790
- if (!isRecord15(codex))
211171
+ if (!isRecord16(codex))
210791
211172
  return;
210792
211173
  if (!suppliesModel)
210793
211174
  delete codex.model;
@@ -210836,7 +211217,7 @@ function parseConfigOverrideValue(value, currentValue, path) {
210836
211217
  function readPath2(target, path) {
210837
211218
  let current = target;
210838
211219
  for (const key of path) {
210839
- if (!isRecord15(current))
211220
+ if (!isRecord16(current))
210840
211221
  return;
210841
211222
  current = current[key];
210842
211223
  }
@@ -210846,7 +211227,7 @@ function writePath2(target, path, value) {
210846
211227
  let current = target;
210847
211228
  for (const key of path.slice(0, -1)) {
210848
211229
  const child = current[key];
210849
- if (!isRecord15(child)) {
211230
+ if (!isRecord16(child)) {
210850
211231
  throw new Error(`Cannot apply --set key ${JSON.stringify(path.join("."))}.`);
210851
211232
  }
210852
211233
  current = child;
@@ -210855,7 +211236,7 @@ function writePath2(target, path, value) {
210855
211236
  if (leaf)
210856
211237
  current[leaf] = value;
210857
211238
  }
210858
- function isRecord15(value) {
211239
+ function isRecord16(value) {
210859
211240
  return typeof value === "object" && value !== null && !Array.isArray(value);
210860
211241
  }
210861
211242
 
@@ -212093,7 +212474,7 @@ function validateReviewContract(request) {
212093
212474
  const contract = request.reviewContract;
212094
212475
  if (contract === undefined)
212095
212476
  return;
212096
- if (!isRecord16(contract)) {
212477
+ if (!isRecord17(contract)) {
212097
212478
  throw new KyosoRequestError("reviewContract must be an object", "VALIDATION_ERROR");
212098
212479
  }
212099
212480
  const allowedKeys = new Set(["focus", "nonGoals", "acceptedRisks"]);
@@ -212110,7 +212491,7 @@ function validateReviewContract(request) {
212110
212491
  throw new KyosoRequestError("reviewContract.nonGoals must contain at most 20 non-empty strings of 500 characters or fewer", "VALIDATION_ERROR");
212111
212492
  }
212112
212493
  const acceptedRisks = contract.acceptedRisks;
212113
- if (acceptedRisks !== undefined && (!Array.isArray(acceptedRisks) || acceptedRisks.length > 20 || acceptedRisks.some((risk) => !isRecord16(risk) || typeof risk.findingFingerprint !== "string" || !/^sha256:[0-9a-f]{64}$/.test(risk.findingFingerprint) || typeof risk.rationale !== "string" || risk.rationale.trim().length === 0 || risk.rationale.length > 500))) {
212494
+ if (acceptedRisks !== undefined && (!Array.isArray(acceptedRisks) || acceptedRisks.length > 20 || acceptedRisks.some((risk) => !isRecord17(risk) || typeof risk.findingFingerprint !== "string" || !/^sha256:[0-9a-f]{64}$/.test(risk.findingFingerprint) || typeof risk.rationale !== "string" || risk.rationale.trim().length === 0 || risk.rationale.length > 500))) {
212114
212495
  throw new KyosoRequestError("reviewContract.acceptedRisks must contain valid finding fingerprints and bounded rationales", "VALIDATION_ERROR");
212115
212496
  }
212116
212497
  }
@@ -212122,13 +212503,13 @@ function validateSelectedFiles(request) {
212122
212503
  throw new KyosoRequestError("selectedFiles must be an array", "VALIDATION_ERROR");
212123
212504
  }
212124
212505
  for (const file2 of selectedFiles) {
212125
- if (!isRecord16(file2) || typeof file2.path !== "string" || file2.path.trim().length === 0 || typeof file2.content !== "string" || file2.language !== undefined && typeof file2.language !== "string" || file2.truncated !== undefined && typeof file2.truncated !== "boolean") {
212506
+ if (!isRecord17(file2) || typeof file2.path !== "string" || file2.path.trim().length === 0 || typeof file2.content !== "string" || file2.language !== undefined && typeof file2.language !== "string" || file2.truncated !== undefined && typeof file2.truncated !== "boolean") {
212126
212507
  throw new KyosoRequestError("selectedFiles entries require string path/content and valid optional metadata", "VALIDATION_ERROR");
212127
212508
  }
212128
212509
  normalizeRelativePath(file2.path);
212129
212510
  }
212130
212511
  }
212131
- function isRecord16(value) {
212512
+ function isRecord17(value) {
212132
212513
  return typeof value === "object" && value !== null && !Array.isArray(value);
212133
212514
  }
212134
212515
 
@@ -212659,11 +213040,11 @@ function canonicalJson(value) {
212659
213040
  function canonicalize(value) {
212660
213041
  if (Array.isArray(value))
212661
213042
  return value.map(canonicalize);
212662
- if (!isRecord17(value))
213043
+ if (!isRecord18(value))
212663
213044
  return value;
212664
213045
  return Object.fromEntries(Object.entries(value).filter(([, child]) => child !== undefined).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, child]) => [key, canonicalize(child)]));
212665
213046
  }
212666
- function isRecord17(value) {
213047
+ function isRecord18(value) {
212667
213048
  return typeof value === "object" && value !== null && !Array.isArray(value);
212668
213049
  }
212669
213050
 
@@ -212671,19 +213052,24 @@ function isRecord17(value) {
212671
213052
  var REVIEW_BUDGET_KEYS = new Set([
212672
213053
  "maxModelCalls",
212673
213054
  "maxTotalWallTimeMs",
213055
+ "maxTotalWallTimeS",
212674
213056
  "maxAgentOutputBytes",
212675
213057
  "maxFindingsPerAgent",
212676
213058
  "skipOptionalPhasesWhenTokenUsageUnknown"
212677
213059
  ]);
212678
213060
  var MODEL_CALL_KINDS = ["primary", "verifier", "judge"];
212679
213061
  function resolveReviewBudget(ceiling, requested) {
212680
- if (requested !== undefined && !isRecord18(requested)) {
213062
+ if (requested !== undefined && !isRecord19(requested)) {
212681
213063
  throw new KyosoRequestError("options.reviewBudget must be an object.", "REVIEW_BUDGET_INVALID");
212682
213064
  }
213065
+ const hasWallTimeSeconds = requested?.maxTotalWallTimeS !== undefined;
212683
213066
  for (const [key, value] of Object.entries(requested ?? {})) {
212684
213067
  if (!REVIEW_BUDGET_KEYS.has(key)) {
212685
213068
  throw new KyosoRequestError(`options.reviewBudget.${key} is not supported.`, "REVIEW_BUDGET_INVALID");
212686
213069
  }
213070
+ if (key === "maxTotalWallTimeS" || key === "maxTotalWallTimeMs" && hasWallTimeSeconds) {
213071
+ continue;
213072
+ }
212687
213073
  if (key === "skipOptionalPhasesWhenTokenUsageUnknown") {
212688
213074
  if (typeof value !== "boolean") {
212689
213075
  throw new KyosoRequestError(`options.reviewBudget.${key} must be a boolean.`, "REVIEW_BUDGET_INVALID");
@@ -212694,12 +213080,26 @@ function resolveReviewBudget(ceiling, requested) {
212694
213080
  throw new KyosoRequestError(`options.reviewBudget.${key} must be a positive integer.`, "REVIEW_BUDGET_INVALID");
212695
213081
  }
212696
213082
  }
212697
- const numericKeys = [
212698
- "maxModelCalls",
212699
- "maxTotalWallTimeMs",
212700
- "maxAgentOutputBytes",
212701
- "maxFindingsPerAgent"
212702
- ];
213083
+ let requestedWallTime;
213084
+ if (hasWallTimeSeconds) {
213085
+ try {
213086
+ requestedWallTime = resolveTimeUnitPair({
213087
+ milliseconds: requested?.maxTotalWallTimeMs,
213088
+ seconds: requested?.maxTotalWallTimeS
213089
+ }, {
213090
+ milliseconds: "options.reviewBudget.maxTotalWallTimeMs",
213091
+ seconds: "options.reviewBudget.maxTotalWallTimeS"
213092
+ });
213093
+ } catch (error51) {
213094
+ if (error51 instanceof TimeUnitValidationError) {
213095
+ throw new KyosoRequestError(error51.message, "REVIEW_BUDGET_INVALID");
213096
+ }
213097
+ throw error51;
213098
+ }
213099
+ }
213100
+ const numericKeys = ["maxModelCalls", "maxAgentOutputBytes", "maxFindingsPerAgent"];
213101
+ if (!hasWallTimeSeconds)
213102
+ numericKeys.push("maxTotalWallTimeMs");
212703
213103
  for (const key of numericKeys) {
212704
213104
  const value = requested?.[key];
212705
213105
  if (value === undefined)
@@ -212708,13 +213108,19 @@ function resolveReviewBudget(ceiling, requested) {
212708
213108
  throw new KyosoRequestError(`options.reviewBudget.${key} cannot exceed the user-global ceiling.`, "REVIEW_BUDGET_EXCEEDS_CEILING");
212709
213109
  }
212710
213110
  }
213111
+ if (hasWallTimeSeconds && requested?.maxTotalWallTimeMs !== undefined && requested.maxTotalWallTimeMs > ceiling.maxTotalWallTimeMs) {
213112
+ throw new KyosoRequestError("options.reviewBudget.maxTotalWallTimeMs cannot exceed the user-global ceiling.", "REVIEW_BUDGET_EXCEEDS_CEILING");
213113
+ }
213114
+ if (requestedWallTime && requestedWallTime.milliseconds > ceiling.maxTotalWallTimeMs) {
213115
+ throw new KyosoRequestError(`${requestedWallTime.sourceField} cannot exceed the user-global ceiling.`, "REVIEW_BUDGET_EXCEEDS_CEILING");
213116
+ }
212711
213117
  if (ceiling.skipOptionalPhasesWhenTokenUsageUnknown && requested?.skipOptionalPhasesWhenTokenUsageUnknown === false) {
212712
213118
  throw new KyosoRequestError("options.reviewBudget.skipOptionalPhasesWhenTokenUsageUnknown cannot relax the user-global ceiling.", "REVIEW_BUDGET_EXCEEDS_CEILING");
212713
213119
  }
212714
213120
  const maxAgentOutputBytes = requested?.maxAgentOutputBytes ?? ceiling.maxAgentOutputBytes;
212715
213121
  return {
212716
213122
  maxModelCalls: requested?.maxModelCalls ?? ceiling.maxModelCalls,
212717
- maxTotalWallTimeMs: requested?.maxTotalWallTimeMs ?? ceiling.maxTotalWallTimeMs,
213123
+ maxTotalWallTimeMs: requestedWallTime?.milliseconds ?? requested?.maxTotalWallTimeMs ?? ceiling.maxTotalWallTimeMs,
212718
213124
  warnAgentOutputBytes: ceiling.warnAgentOutputBytes,
212719
213125
  maxAgentOutputBytes,
212720
213126
  maxFindingsPerAgent: requested?.maxFindingsPerAgent ?? ceiling.maxFindingsPerAgent,
@@ -213031,10 +213437,63 @@ function emptyReviewModelCallPlan() {
213031
213437
  ceilingEffects: []
213032
213438
  };
213033
213439
  }
213034
- function isRecord18(value) {
213440
+ function isRecord19(value) {
213035
213441
  return typeof value === "object" && value !== null && !Array.isArray(value);
213036
213442
  }
213037
213443
 
213444
+ // src/core/requestTimeUnits.ts
213445
+ function normalizeRequestTimeUnits(request) {
213446
+ if (!request.options)
213447
+ return request;
213448
+ const options = { ...request.options };
213449
+ normalizeRequestTimeUnitField(options, "maxAgentTimeoutMs", "maxAgentTimeoutS", {
213450
+ milliseconds: "options.maxAgentTimeoutMs",
213451
+ seconds: "options.maxAgentTimeoutS"
213452
+ });
213453
+ if (options.reviewBudget) {
213454
+ const reviewBudget = { ...options.reviewBudget };
213455
+ normalizeRequestTimeUnitField(reviewBudget, "maxTotalWallTimeMs", "maxTotalWallTimeS", {
213456
+ milliseconds: "options.reviewBudget.maxTotalWallTimeMs",
213457
+ seconds: "options.reviewBudget.maxTotalWallTimeS"
213458
+ });
213459
+ options.reviewBudget = reviewBudget;
213460
+ }
213461
+ return { ...request, options };
213462
+ }
213463
+ function resolveProgressHeartbeatMs(input2) {
213464
+ if (input2.progressHeartbeatS === undefined) {
213465
+ return input2.progressHeartbeatMs;
213466
+ }
213467
+ return resolveRequestTimeUnit({
213468
+ milliseconds: input2.progressHeartbeatMs,
213469
+ seconds: input2.progressHeartbeatS
213470
+ }, {
213471
+ milliseconds: "progressHeartbeatMs",
213472
+ seconds: "progressHeartbeatS"
213473
+ }, { allowZero: true })?.milliseconds;
213474
+ }
213475
+ function normalizeRequestTimeUnitField(target, millisecondsKey, secondsKey, fields) {
213476
+ if (target[secondsKey] !== undefined) {
213477
+ const resolved = resolveRequestTimeUnit({
213478
+ milliseconds: target[millisecondsKey],
213479
+ seconds: target[secondsKey]
213480
+ }, fields);
213481
+ if (resolved)
213482
+ target[millisecondsKey] = resolved.milliseconds;
213483
+ }
213484
+ delete target[secondsKey];
213485
+ }
213486
+ function resolveRequestTimeUnit(input2, fields, constraints) {
213487
+ try {
213488
+ return resolveTimeUnitPair(input2, fields, constraints);
213489
+ } catch (error51) {
213490
+ if (error51 instanceof TimeUnitValidationError) {
213491
+ throw new KyosoRequestError(error51.message, "VALIDATION_ERROR");
213492
+ }
213493
+ throw error51;
213494
+ }
213495
+ }
213496
+
213038
213497
  // src/core/verification.ts
213039
213498
  var REAL_AGENTS = ["codex", "claude"];
213040
213499
  var VERIFIABLE_SEVERITIES = new Set(["critical", "high"]);
@@ -213093,7 +213552,7 @@ function parseVerificationVerdicts(rawText) {
213093
213552
  if (!Array.isArray(parsed.verdicts))
213094
213553
  return;
213095
213554
  return parsed.verdicts.flatMap((item) => {
213096
- if (!isRecord19(item))
213555
+ if (!isRecord20(item))
213097
213556
  return [];
213098
213557
  if (typeof item.findingId !== "string")
213099
213558
  return [];
@@ -213171,7 +213630,7 @@ function verificationNote(reasoning) {
213171
213630
  function isVerdict(value) {
213172
213631
  return value === "confirmed" || value === "refuted" || value === "uncertain";
213173
213632
  }
213174
- function isRecord19(value) {
213633
+ function isRecord20(value) {
213175
213634
  return typeof value === "object" && value !== null && !Array.isArray(value);
213176
213635
  }
213177
213636
 
@@ -213179,7 +213638,7 @@ function isRecord19(value) {
213179
213638
  var MAX_AGENT_RETRY_PROGRESS_EVENTS = 100;
213180
213639
  function requestForRecursionFingerprint(request) {
213181
213640
  try {
213182
- return scanAndRedactSecrets(request).redactedRequest;
213641
+ return scanAndRedactSecrets(normalizeRequestTimeUnits(request)).redactedRequest;
213183
213642
  } catch {
213184
213643
  return { goal: "" };
213185
213644
  }
@@ -213439,15 +213898,17 @@ async function runReview(tool, request, options = {}) {
213439
213898
  });
213440
213899
  validateReviewRequest(tool, request);
213441
213900
  const reviewBudget = resolveReviewBudget(loaded.config.reviewBudget, request.options?.reviewBudget);
213442
- const budgetTracker = new ReviewBudgetTracker(reviewBudget, startedAtEpochMs, configuredReviewModelCallPlan(loaded.config, reviewBudget, options.env ?? process.env, request.options?.judgeProvider));
213443
- assertTrustedWorkspaceRoot(request.workspace?.root, loaded.config.workspace.root, cwd);
213444
- const networkMode = resolveNetworkMode(request.options?.network, loaded.config.network.defaultMode, options.mcpNetworkMode);
213901
+ const normalizedRequest = normalizeRequestTimeUnits(request);
213902
+ const progressHeartbeatMs = resolveProgressHeartbeatMs(options);
213903
+ const budgetTracker = new ReviewBudgetTracker(reviewBudget, startedAtEpochMs, configuredReviewModelCallPlan(loaded.config, reviewBudget, options.env ?? process.env, normalizedRequest.options?.judgeProvider));
213904
+ assertTrustedWorkspaceRoot(normalizedRequest.workspace?.root, loaded.config.workspace.root, cwd);
213905
+ const networkMode = resolveNetworkMode(normalizedRequest.options?.network, loaded.config.network.defaultMode, options.mcpNetworkMode);
213445
213906
  if (networkMode === "unrestricted" && !loaded.config.network.allowUnrestricted) {
213446
213907
  throw new KyosoRequestError("unrestricted network mode is disabled by config", "NETWORK_MODE_DISABLED");
213447
213908
  }
213448
213909
  const disabledPolicy = disabledReviewPolicy(tool, loaded.config, options.entrypoint);
213449
213910
  if (disabledPolicy) {
213450
- const redactedRequest = requestForRecursionFingerprint(request);
213911
+ const redactedRequest = requestForRecursionFingerprint(normalizedRequest);
213451
213912
  const requestFingerprint2 = createRequestFingerprint({
213452
213913
  tool,
213453
213914
  request: redactedRequest,
@@ -213498,7 +213959,7 @@ async function runReview(tool, request, options = {}) {
213498
213959
  warnings.push("Network mode is unrestricted; write policy remains denied.");
213499
213960
  }
213500
213961
  startPhase("context");
213501
- const secretScan = scanAndRedactSecrets(request);
213962
+ const secretScan = scanAndRedactSecrets(normalizedRequest);
213502
213963
  await trace.write({
213503
213964
  type: "secret_scan_completed",
213504
213965
  traceId,
@@ -213506,7 +213967,7 @@ async function runReview(tool, request, options = {}) {
213506
213967
  redactions: secretScan.redactions,
213507
213968
  timestamp: new Date().toISOString()
213508
213969
  });
213509
- const allowSecretOverride = loaded.config.secrets.allowOverride && request.options?.allowSecretRedaction === true;
213970
+ const allowSecretOverride = loaded.config.secrets.allowOverride && normalizedRequest.options?.allowSecretRedaction === true;
213510
213971
  if (secretScan.detected && loaded.config.secrets.blockOnDetectedSecret && !allowSecretOverride) {
213511
213972
  const requestFingerprint2 = createRequestFingerprint({
213512
213973
  tool,
@@ -213593,7 +214054,7 @@ async function runReview(tool, request, options = {}) {
213593
214054
  budgetTracker,
213594
214055
  progressDispatcher: dispatcher,
213595
214056
  signal: options.signal,
213596
- progressHeartbeatMs: options.progressHeartbeatMs
214057
+ progressHeartbeatMs
213597
214058
  });
213598
214059
  completePhase("primary");
213599
214060
  warnings.push(...agentResults.flatMap((result) => (result.warnings ?? []).map((warning) => `Agent ${result.agent} ${warning}`)));
@@ -215141,9 +215602,11 @@ var kyosoReviewRequestSchema = object({
215141
215602
  options: object({
215142
215603
  network: _enum2(["model_only", "unrestricted"]).optional(),
215143
215604
  maxAgentTimeoutMs: number2().int().positive().optional(),
215605
+ maxAgentTimeoutS: secondsSchema("options.maxAgentTimeoutS").optional(),
215144
215606
  reviewBudget: object({
215145
215607
  maxModelCalls: number2().int().positive().optional(),
215146
215608
  maxTotalWallTimeMs: number2().int().positive().optional(),
215609
+ maxTotalWallTimeS: secondsSchema("options.reviewBudget.maxTotalWallTimeS").optional(),
215147
215610
  maxAgentOutputBytes: number2().int().positive().optional(),
215148
215611
  maxFindingsPerAgent: number2().int().positive().optional(),
215149
215612
  skipOptionalPhasesWhenTokenUsageUnknown: boolean2().optional()
@@ -215153,6 +215616,18 @@ var kyosoReviewRequestSchema = object({
215153
215616
  allowSecretRedaction: boolean2().optional()
215154
215617
  }).optional()
215155
215618
  });
215619
+ function secondsSchema(field) {
215620
+ return number2().superRefine((value, context) => {
215621
+ try {
215622
+ secondsToMilliseconds(value, field);
215623
+ } catch (error51) {
215624
+ context.addIssue({
215625
+ code: "custom",
215626
+ message: error51 instanceof TimeUnitValidationError ? error51.message : `${field} is invalid.`
215627
+ });
215628
+ }
215629
+ });
215630
+ }
215156
215631
 
215157
215632
  // src/mcp/server.ts
215158
215633
  var KYOSO_MCP_INSTRUCTIONS = "Kyoso is a multi-agent planning and review gate. Use it only when the user explicitly asks for Kyoso, multi-agent review, plan review, security review, CISA Secure by Design review, or diff review. Kyoso does not apply code changes. It returns structured review results and Markdown summaries.";