claude-use 9.5.0 → 9.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -2625,7 +2625,7 @@ var init_package = __esm({
2625
2625
  "package.json"() {
2626
2626
  package_default = {
2627
2627
  name: "claude-use",
2628
- version: "9.5.0",
2628
+ version: "9.6.0",
2629
2629
  description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
2630
2630
  license: "MIT",
2631
2631
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -2676,9 +2676,10 @@ var init_package = __esm({
2676
2676
  dependencies: {
2677
2677
  "@anthropic-ai/claude-agent-sdk": "0.3.292",
2678
2678
  "@clack/prompts": "^1.8.0",
2679
- "@orpc/client": "1.15.4",
2680
- "@orpc/openapi": "1.15.4",
2681
- "@orpc/server": "1.15.4",
2679
+ "@modelcontextprotocol/sdk": "1.32.0",
2680
+ "@orpc/client": "2.0.0-beta.41",
2681
+ "@orpc/openapi": "2.0.0-beta.41",
2682
+ "@orpc/server": "2.0.0-beta.41",
2682
2683
  commander: "^15.0.0",
2683
2684
  cosmiconfig: "^10.0.1",
2684
2685
  picomatch: "^4.0.7",
@@ -5742,7 +5743,7 @@ function cascadeProviderName(cascade) {
5742
5743
  }
5743
5744
  return name;
5744
5745
  }
5745
- function resolveProvider(params) {
5746
+ function selectProvider(params) {
5746
5747
  const cliName = params.cliProvider !== void 0 && params.cliProvider !== "" ? params.cliProvider : void 0;
5747
5748
  const name = cliName ?? (params.cascade === void 0 ? void 0 : cascadeProviderName(params.cascade));
5748
5749
  if (name === void 0) {
@@ -5757,6 +5758,14 @@ function resolveProvider(params) {
5757
5758
  message: `agent-shim: no provider named "${name}". ` + (known.length > 0 ? `Known providers: ${known.join(", ")}.` : "No providers are defined yet; run `agent-shim provider add`.")
5758
5759
  };
5759
5760
  }
5761
+ return { ok: true, provider: { name, definition } };
5762
+ }
5763
+ function resolveProvider(params) {
5764
+ const selection = selectProvider(params);
5765
+ if (selection?.ok !== true) {
5766
+ return selection;
5767
+ }
5768
+ const { name, definition } = selection.provider;
5760
5769
  if (params.credentials === void 0) {
5761
5770
  return { ok: false, status: 1, message: `agent-shim: provider ${name} needs its credential resolved, but this launcher has no credential port wired` };
5762
5771
  }
@@ -6037,6 +6046,51 @@ var init_claudeShim = __esm({
6037
6046
  }
6038
6047
  });
6039
6048
 
6049
+ // src/update/update.ts
6050
+ function compareVersions3(left, right) {
6051
+ const parse = (version) => {
6052
+ const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
6053
+ if (match === null) {
6054
+ throw new Error(`not a plain release version: ${version}`);
6055
+ }
6056
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
6057
+ };
6058
+ const leftParts = parse(left);
6059
+ const rightParts = parse(right);
6060
+ return leftParts.map((part, index) => part - (rightParts[index] ?? 0)).find((difference) => difference !== 0) ?? 0;
6061
+ }
6062
+ function releaseTagFromUrl(url) {
6063
+ const segment = url.split("?")[0]?.split("/").at(-1);
6064
+ const candidate = segment?.startsWith("v") === true ? segment.slice(1) : void 0;
6065
+ return candidate !== void 0 && /^\d+\.\d+\.\d+$/.test(candidate) ? candidate : void 0;
6066
+ }
6067
+ var LATEST_RELEASE_URL, UpdateChannelError, UpdateConflictError, UpdateDownloadError;
6068
+ var init_update = __esm({
6069
+ "src/update/update.ts"() {
6070
+ "use strict";
6071
+ init_cliError();
6072
+ LATEST_RELEASE_URL = "https://github.com/ExaDev/agent-shim/releases/latest";
6073
+ UpdateChannelError = class extends CliError {
6074
+ constructor(message) {
6075
+ super(message);
6076
+ this.name = "UpdateChannelError";
6077
+ }
6078
+ };
6079
+ UpdateConflictError = class extends CliError {
6080
+ constructor(message) {
6081
+ super(message);
6082
+ this.name = "UpdateConflictError";
6083
+ }
6084
+ };
6085
+ UpdateDownloadError = class extends CliError {
6086
+ constructor(message) {
6087
+ super(message);
6088
+ this.name = "UpdateDownloadError";
6089
+ }
6090
+ };
6091
+ }
6092
+ });
6093
+
6040
6094
  // src/frontdoor/ensure.ts
6041
6095
  import { randomUUID as randomUUID3 } from "node:crypto";
6042
6096
  function ensureFrontDoor(params) {
@@ -6442,7 +6496,7 @@ var init_headers = __esm({
6442
6496
  });
6443
6497
 
6444
6498
  // src/launcher/flags.ts
6445
- import path31 from "node:path";
6499
+ import path32 from "node:path";
6446
6500
  function resolveLaunchFlags(params) {
6447
6501
  return {
6448
6502
  skipPermissions: params.flags?.skipPermissions ?? parseEnvBool("AGENT_SHIM_SKIP_PERMISSIONS", params.env.AGENT_SHIM_SKIP_PERMISSIONS) ?? params.cascade?.skipPermissions ?? false,
@@ -6473,7 +6527,7 @@ function buildEnv(params) {
6473
6527
  const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
6474
6528
  let providerCustomHeaders;
6475
6529
  if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
6476
- env.CLAUDE_CONFIG_DIR = path31.join(params.identitiesDir, params.resolvedIdentityName);
6530
+ env.CLAUDE_CONFIG_DIR = path32.join(params.identitiesDir, params.resolvedIdentityName);
6477
6531
  }
6478
6532
  if (params.provider !== void 0) {
6479
6533
  const providerEnv = params.provider.definition.env ?? {};
@@ -6596,7 +6650,9 @@ function resolvePoolLaunch(params) {
6596
6650
  }
6597
6651
  const { pick, earliestReturn, movedOff } = graph.ranking;
6598
6652
  if (pick !== void 0) {
6599
- recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
6653
+ if (params.recordPick) {
6654
+ recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
6655
+ }
6600
6656
  const move = movedOff === void 0 ? "" : `moved off ${movedOff.identity} (${movedOff.reason}); `;
6601
6657
  return {
6602
6658
  ok: true,
@@ -6662,33 +6718,6 @@ var init_spawn = __esm({
6662
6718
  }
6663
6719
  });
6664
6720
 
6665
- // src/update/update.ts
6666
- function compareVersions3(left, right) {
6667
- const parse = (version) => {
6668
- const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
6669
- if (match === null) {
6670
- throw new Error(`not a plain release version: ${version}`);
6671
- }
6672
- return [Number(match[1]), Number(match[2]), Number(match[3])];
6673
- };
6674
- const leftParts = parse(left);
6675
- const rightParts = parse(right);
6676
- return leftParts.map((part, index) => part - (rightParts[index] ?? 0)).find((difference) => difference !== 0) ?? 0;
6677
- }
6678
- function releaseTagFromUrl(url) {
6679
- const segment = url.split("?")[0]?.split("/").at(-1);
6680
- const candidate = segment?.startsWith("v") === true ? segment.slice(1) : void 0;
6681
- return candidate !== void 0 && /^\d+\.\d+\.\d+$/.test(candidate) ? candidate : void 0;
6682
- }
6683
- var LATEST_RELEASE_URL;
6684
- var init_update = __esm({
6685
- "src/update/update.ts"() {
6686
- "use strict";
6687
- init_cliError();
6688
- LATEST_RELEASE_URL = "https://github.com/ExaDev/agent-shim/releases/latest";
6689
- }
6690
- });
6691
-
6692
6721
  // src/update/launchHook.ts
6693
6722
  function resolveUpdateMode(globalConfig) {
6694
6723
  return globalConfig?.update?.mode ?? "off";
@@ -6760,7 +6789,7 @@ var init_launchHook = __esm({
6760
6789
 
6761
6790
  // src/launcher.ts
6762
6791
  import { randomUUID as randomUUID4 } from "node:crypto";
6763
- import path32 from "node:path";
6792
+ import path33 from "node:path";
6764
6793
  function resolveIdentityCredential(identity, credential, env, port) {
6765
6794
  if (port === void 0) {
6766
6795
  return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
@@ -6768,7 +6797,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
6768
6797
  const resolution = resolveCredential({ credential, env, port, subject: `identity ${identity}` });
6769
6798
  return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
6770
6799
  }
6771
- function pickFromPool(decided, params, parsedArgv) {
6800
+ function pickFromPool(decided, params, parsedArgv, readOnly) {
6772
6801
  const { paths, fs: fs12, proc, log } = params;
6773
6802
  if (decided.pool === void 0) {
6774
6803
  return { identityDecision: decided };
@@ -6789,7 +6818,9 @@ function pickFromPool(decided, params, parsedArgv) {
6789
6818
  now: farmRuntime.now,
6790
6819
  sleep: farmRuntime.lock.sleep,
6791
6820
  passthrough: parsedArgv.rest,
6792
- wait: parsedArgv.wait === true,
6821
+ // A read-only decision never sleeps for a refused pool and never records its pick, so asking what a launch would pick leaves the next real launch's keep-warm preference as it was.
6822
+ wait: !readOnly && parsedArgv.wait === true,
6823
+ recordPick: !readOnly,
6793
6824
  log
6794
6825
  });
6795
6826
  if (!resolution.ok) {
@@ -6802,7 +6833,7 @@ function pickFromPool(decided, params, parsedArgv) {
6802
6833
  poolPick: { name: decided.pool, reasons: resolution.reasons, ...resolution.movedOff === void 0 ? {} : { movedOff: resolution.movedOff } }
6803
6834
  };
6804
6835
  }
6805
- function prepareLaunch(params) {
6836
+ function decideLaunch(params, readOnly) {
6806
6837
  const { paths, fs: fs12, proc, log } = params;
6807
6838
  const { env, argv } = proc;
6808
6839
  const parsedArgv = parseLauncherArgv(argv);
@@ -6826,10 +6857,10 @@ function prepareLaunch(params) {
6826
6857
  return trimmed === "" ? void 0 : trimmed;
6827
6858
  }
6828
6859
  });
6829
- const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv);
6860
+ const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv, readOnly);
6830
6861
  const farmIdentity = configDirEscapeHatchApplies ? void 0 : identityDecision.name;
6831
6862
  const farm = farmIdentity === void 0 ? void 0 : params.farm;
6832
- if (farm !== void 0 && farmIdentity !== void 0) {
6863
+ if (!readOnly && farm !== void 0 && farmIdentity !== void 0) {
6833
6864
  let recovery;
6834
6865
  try {
6835
6866
  recovery = recoverFarm({
@@ -6868,33 +6899,44 @@ function prepareLaunch(params) {
6868
6899
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
6869
6900
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
6870
6901
  });
6871
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(path32.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
6902
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(path33.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
6872
6903
  log.error(
6873
6904
  `agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
6874
6905
  );
6875
6906
  proc.exit(1);
6876
6907
  }
6877
6908
  const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
6878
- const provider = parsedArgv.provider === false ? void 0 : resolveProvider({
6909
+ const providerParams = {
6879
6910
  paths,
6880
6911
  port: fs12,
6881
- env,
6882
- ...params.credentials === void 0 ? {} : { credentials: params.credentials },
6883
- ...parsedArgv.provider === void 0 ? {} : { cliProvider: parsedArgv.provider },
6912
+ ...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
6884
6913
  ...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
6885
- });
6886
- if (provider !== void 0 && !provider.ok) {
6887
- log.error(provider.message);
6888
- proc.exit(provider.status);
6889
- }
6890
- const resolvedProvider = provider?.ok === true ? provider.provider : void 0;
6891
- for (const warning of provider?.ok === true ? provider.warnings : []) {
6892
- log.warn(warning);
6914
+ };
6915
+ let selectedProvider;
6916
+ let resolvedProvider;
6917
+ if (parsedArgv.provider !== false && readOnly) {
6918
+ const selection = selectProvider(providerParams);
6919
+ if (selection !== void 0 && !selection.ok) {
6920
+ log.error(selection.message);
6921
+ proc.exit(selection.status);
6922
+ }
6923
+ selectedProvider = selection?.ok === true ? selection.provider : void 0;
6924
+ } else if (parsedArgv.provider !== false) {
6925
+ const provider = resolveProvider({ ...providerParams, env, ...params.credentials === void 0 ? {} : { credentials: params.credentials } });
6926
+ if (provider !== void 0 && !provider.ok) {
6927
+ log.error(provider.message);
6928
+ proc.exit(provider.status);
6929
+ }
6930
+ resolvedProvider = provider?.ok === true ? provider.provider : void 0;
6931
+ selectedProvider = resolvedProvider;
6932
+ for (const warning of provider?.ok === true ? provider.warnings : []) {
6933
+ log.warn(warning);
6934
+ }
6893
6935
  }
6894
6936
  if (farm !== void 0 && farmIdentity !== void 0) {
6895
6937
  try {
6896
6938
  const snapshot = readUsageSnapshot(farm.fs, paths.usageSnapshotsDir, farmIdentity);
6897
- for (const warning of quotaWarnings(snapshot, resolvedProvider?.name ?? ANTHROPIC_PROVIDER, farm.now())) {
6939
+ for (const warning of quotaWarnings(snapshot, selectedProvider?.name ?? ANTHROPIC_PROVIDER, farm.now())) {
6898
6940
  log.warn(warning);
6899
6941
  }
6900
6942
  } catch (error) {
@@ -6904,8 +6946,8 @@ function prepareLaunch(params) {
6904
6946
  log.warn(`agent-shim: ${error.message}`);
6905
6947
  }
6906
6948
  }
6907
- const identityCredentialBlock = loadedIdentity?.config.credential;
6908
- const identityResolution = resolvedProvider === void 0 && farmIdentity !== void 0 && identityCredentialBlock !== void 0 ? resolveIdentityCredential(farmIdentity, identityCredentialBlock, env, params.credentials) : void 0;
6949
+ const identityCredentialBlock = selectedProvider === void 0 && farmIdentity !== void 0 ? loadedIdentity?.config.credential : void 0;
6950
+ const identityResolution = !readOnly && identityCredentialBlock !== void 0 && farmIdentity !== void 0 ? resolveIdentityCredential(farmIdentity, identityCredentialBlock, env, params.credentials) : void 0;
6909
6951
  if (identityResolution !== void 0 && !identityResolution.ok) {
6910
6952
  log.error(identityResolution.message);
6911
6953
  proc.exit(identityResolution.status);
@@ -6919,25 +6961,97 @@ function prepareLaunch(params) {
6919
6961
  allowAmbientCredential: loadedIdentity?.config.allowAmbientCredential ?? false,
6920
6962
  allowAmbientCredentialOverride: parseEnvBool("AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL", env.AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL) === true,
6921
6963
  identityName: identityDecision.name,
6922
- providerSelected: resolvedProvider !== void 0,
6964
+ providerSelected: selectedProvider !== void 0,
6923
6965
  ...identityCredential === void 0 ? {} : { injectedCredential: { variable: CREDENTIAL_TARGET_VARS[identityCredential.target], token: identityCredential.token } }
6924
6966
  });
6925
6967
  if (!guardResult.ok) {
6926
- log.error(guardResult.message);
6927
- proc.exit(1);
6968
+ if (readOnly && identityCredentialBlock !== void 0) {
6969
+ log.warn(`${guardResult.message} (not resolved here: the launch proceeds only if that value is the identity's own injected credential)`);
6970
+ } else {
6971
+ log.error(guardResult.message);
6972
+ proc.exit(1);
6973
+ }
6974
+ }
6975
+ const launchCascade = farmContext?.cascade ?? (params.farm === void 0 ? void 0 : params.farm.loadCascade(configProfileDecision.name, cliOverride));
6976
+ let cascadeLaunch;
6977
+ if (launchCascade !== void 0 && params.farm !== void 0) {
6978
+ const assembled = assembleCascade(launchCascade);
6979
+ const flattened = flattenLayers(assembled.layers, { home: params.farm.home });
6980
+ cascadeLaunch = flattened.launch;
6981
+ if (readOnly) {
6982
+ for (const diagnostic of [...assembled.diagnostics, ...flattened.diagnostics]) {
6983
+ if (diagnostic.severity !== "info") {
6984
+ log.warn(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
6985
+ }
6986
+ }
6987
+ }
6928
6988
  }
6989
+ const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
6990
+ const discovered = params.resolveClaudeBinary(pinnedVersion === void 0 ? void 0 : { version: pinnedVersion.version });
6991
+ const flags = resolveLaunchFlags({
6992
+ env,
6993
+ // A pool pick reads the usage the front door records, so a pool launch records its own unless something says otherwise.
6994
+ ...poolExplanation === void 0 ? {} : { trackUsageDefault: true },
6995
+ ...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
6996
+ flags: {
6997
+ ...parsedArgv.skipPermissions === void 0 ? {} : { skipPermissions: parsedArgv.skipPermissions },
6998
+ ...parsedArgv.remoteControl === void 0 ? {} : { remoteControl: parsedArgv.remoteControl },
6999
+ ...parsedArgv.headroom === void 0 ? {} : { headroom: parsedArgv.headroom },
7000
+ ...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
7001
+ }
7002
+ });
7003
+ const args = buildArgv({
7004
+ toolFlags: buildFlagArgs(flags),
7005
+ extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
7006
+ passthrough: parsedArgv.rest
7007
+ });
7008
+ const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path33.join(paths.identitiesDir, identityDecision.name);
7009
+ const decision = {
7010
+ identitySource: identityDecision.source,
7011
+ configDirEscapeHatch: identityDecision.configDirEscapeHatch,
7012
+ configProfileSource: configProfileDecision.source,
7013
+ ...identityDecision.name === void 0 ? {} : { identity: identityDecision.name },
7014
+ ...poolPick === void 0 ? {} : { pool: poolPick },
7015
+ ...configDir === void 0 || configDir === "" ? {} : { configDir },
7016
+ ...configProfileDecision.name === void 0 ? {} : { configProfile: configProfileDecision.name },
7017
+ ...selectedProvider === void 0 ? {} : { provider: selectedProvider.name }
7018
+ };
7019
+ return {
7020
+ parsedArgv,
7021
+ identityDecision,
7022
+ poolExplanation,
7023
+ poolPick,
7024
+ configDirEscapeHatch: configDirEscapeHatchApplies,
7025
+ farmIdentity,
7026
+ farmContext,
7027
+ configProfileDecision,
7028
+ provider: selectedProvider,
7029
+ resolvedProvider,
7030
+ identityCredentialBlock,
7031
+ identityCredential,
7032
+ pinnedVersion,
7033
+ flags,
7034
+ bin: discovered.path,
7035
+ args,
7036
+ decision
7037
+ };
7038
+ }
7039
+ function prepareLaunch(params) {
7040
+ const { paths, proc, log } = params;
7041
+ const { env } = proc;
7042
+ const decided = decideLaunch(params, false);
7043
+ const { identityDecision, configProfileDecision, resolvedProvider, identityCredential, poolExplanation, flags: resolvedFlags, args: finalArgv, configDirEscapeHatch: configDirEscapeHatchApplies, decision } = decided;
6929
7044
  log.info(
6930
7045
  `agent-shim: identity ${identityDecision.name ?? "(none)"} (${identityDecision.source}${poolExplanation === void 0 ? "" : `, ${poolExplanation}`}), config profile ${configProfileDecision.name ?? "(none)"} (${configProfileDecision.source})` + (resolvedProvider === void 0 ? "" : `, provider ${resolvedProvider.name} (credential ${resolvedProvider.credential.target} from ${describeSource(resolvedProvider.credential.source)})`) + (identityCredential === void 0 ? "" : `, identity credential ${identityCredential.target} from ${describeSource(identityCredential.source)}`)
6931
7046
  );
6932
7047
  const updateCheck = runLaunchUpdateCheck({
6933
7048
  mode: params.updateMode ?? "off",
6934
- checkPath: path32.join(paths.root, "update.check"),
7049
+ checkPath: path33.join(paths.root, "update.check"),
6935
7050
  currentVersion: package_default.version,
6936
7051
  port: params.update
6937
7052
  });
6938
- let cascadeLaunch;
6939
- if (farmContext !== void 0) {
6940
- const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = farmContext;
7053
+ if (decided.farmContext !== void 0) {
7054
+ const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = decided.farmContext;
6941
7055
  let result;
6942
7056
  try {
6943
7057
  result = resyncFarm({
@@ -6974,27 +7088,10 @@ function prepareLaunch(params) {
6974
7088
  log.info(
6975
7089
  result.noOp ? `agent-shim: farm at ${result.farmRoot} already matches the resolved cascade` : `agent-shim: farm at ${result.farmRoot} resynced (${String(result.manifest.links.length)} link(s), ${String(result.manifest.materialised.length)} built director(ies)${result.adopted.length === 0 ? "" : `, ${String(result.adopted.length)} adopted into ${resyncFarmRuntime.claudeHome}`})`
6976
7090
  );
6977
- cascadeLaunch = result.resolved.flattened.launch;
6978
- } else if (params.farm !== void 0) {
6979
- cascadeLaunch = flattenLayers(assembleCascade(params.farm.loadCascade(configProfileDecision.name, cliOverride)).layers, { home: params.farm.home }).launch;
6980
7091
  }
6981
- const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
6982
- const discovered = params.resolveClaudeBinary(pinnedVersion === void 0 ? void 0 : { version: pinnedVersion.version });
6983
- if (pinnedVersion !== void 0) {
6984
- log.info(`agent-shim: Claude Code ${pinnedVersion.version} (pinned by ${pinnedVersion.source})`);
7092
+ if (decided.pinnedVersion !== void 0) {
7093
+ log.info(`agent-shim: Claude Code ${decided.pinnedVersion.version} (pinned by ${decided.pinnedVersion.source})`);
6985
7094
  }
6986
- const resolvedFlags = resolveLaunchFlags({
6987
- env,
6988
- // A pool pick reads the usage the front door records, so a pool launch records its own unless something says otherwise.
6989
- ...poolExplanation === void 0 ? {} : { trackUsageDefault: true },
6990
- ...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
6991
- flags: {
6992
- ...parsedArgv.skipPermissions === void 0 ? {} : { skipPermissions: parsedArgv.skipPermissions },
6993
- ...parsedArgv.remoteControl === void 0 ? {} : { remoteControl: parsedArgv.remoteControl },
6994
- ...parsedArgv.headroom === void 0 ? {} : { headroom: parsedArgv.headroom },
6995
- ...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
6996
- }
6997
- });
6998
7095
  const frontDoorPort = params.frontdoor;
6999
7096
  const frontDoorEngaged = resolvedProvider !== void 0 || resolvedFlags.headroom || resolvedFlags.trackUsage;
7000
7097
  if (frontDoorEngaged && frontDoorPort === void 0) {
@@ -7018,11 +7115,6 @@ function prepareLaunch(params) {
7018
7115
  log.info(`agent-shim: routing through the front door on 127.0.0.1:${String(frontDoor.port)}${resolvedProvider === void 0 ? ` (OAuth via the door's CONNECT surface on 127.0.0.1:${String(frontDoor.connectPort)}, usage recorded)` : ` (provider ${resolvedProvider.name})`}`);
7019
7116
  }
7020
7117
  const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
7021
- const finalArgv = buildArgv({
7022
- toolFlags: buildFlagArgs(resolvedFlags),
7023
- extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
7024
- passthrough: parsedArgv.rest
7025
- });
7026
7118
  const finalEnv = buildEnv({
7027
7119
  baseEnv: env,
7028
7120
  configDirEscapeHatch: configDirEscapeHatchApplies,
@@ -7040,18 +7132,35 @@ function prepareLaunch(params) {
7040
7132
  registered();
7041
7133
  }
7042
7134
  };
7043
- const configDir = finalEnv.CLAUDE_CONFIG_DIR;
7044
- const decision = {
7045
- identitySource: identityDecision.source,
7046
- configDirEscapeHatch: identityDecision.configDirEscapeHatch,
7047
- configProfileSource: configProfileDecision.source,
7048
- ...identityDecision.name === void 0 ? {} : { identity: identityDecision.name },
7049
- ...poolPick === void 0 ? {} : { pool: poolPick },
7050
- ...configDir === void 0 || configDir === "" ? {} : { configDir },
7051
- ...configProfileDecision.name === void 0 ? {} : { configProfile: configProfileDecision.name },
7052
- ...resolvedProvider === void 0 ? {} : { provider: resolvedProvider.name }
7135
+ return { bin: decided.bin, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
7136
+ }
7137
+ function resolveLaunch(params) {
7138
+ const decided = decideLaunch(params, true);
7139
+ const { env } = params.proc;
7140
+ const frontDoor = decided.provider !== void 0 || decided.flags.headroom || decided.flags.trackUsage;
7141
+ const built = buildEnv({
7142
+ baseEnv: env,
7143
+ configDirEscapeHatch: decided.configDirEscapeHatch,
7144
+ resolvedIdentityName: decided.identityDecision.name,
7145
+ identitiesDir: params.paths.identitiesDir,
7146
+ ...decided.provider === void 0 ? {} : { provider: decided.provider },
7147
+ ...frontDoor ? { frontdoor: { port: 0, connectPort: 0, trustBundlePath: "", sessionToken: "" } } : {},
7148
+ ...decided.flags.headroom ? { headroom: { socketPath: "", projectId: "" } } : {},
7149
+ sessionId: ""
7150
+ });
7151
+ const credentialNames = decided.identityCredentialBlock === void 0 ? [] : Object.keys(credentialVariables(decided.identityCredentialBlock.target ?? "bearer", ""));
7152
+ const environment = [.../* @__PURE__ */ new Set([...Object.keys(built).filter((name) => built[name] !== env[name]), ...credentialNames])].sort();
7153
+ const credential = decided.provider !== void 0 ? { subject: "provider", name: decided.provider.name, summary: summariseCredential(decided.provider.definition.credential) } : decided.identityCredentialBlock !== void 0 && decided.farmIdentity !== void 0 ? { subject: "identity", name: decided.farmIdentity, summary: summariseCredential(decided.identityCredentialBlock) } : void 0;
7154
+ return {
7155
+ decision: decided.decision,
7156
+ flags: decided.flags,
7157
+ ...decided.pinnedVersion === void 0 ? {} : { claudeVersion: decided.pinnedVersion },
7158
+ bin: decided.bin,
7159
+ args: decided.args,
7160
+ ...credential === void 0 ? {} : { credential },
7161
+ routing: { frontDoor, headroom: decided.flags.headroom },
7162
+ environment
7053
7163
  };
7054
- return { bin: discovered.path, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
7055
7164
  }
7056
7165
  function runLaunchPlan(plan, spawn2) {
7057
7166
  try {
@@ -7097,12 +7206,12 @@ var init_launcher = __esm({
7097
7206
  });
7098
7207
 
7099
7208
  // src/ownCli.ts
7100
- import path33 from "node:path";
7209
+ import path34 from "node:path";
7101
7210
  function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
7102
7211
  if (distDir === void 0) {
7103
7212
  throw new OwnCliPathUnknownError();
7104
7213
  }
7105
- return path33.join(distDir, OWN_CLI_FILE_NAME);
7214
+ return path34.join(distDir, OWN_CLI_FILE_NAME);
7106
7215
  }
7107
7216
  var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
7108
7217
  var init_ownCli = __esm({
@@ -7191,10 +7300,10 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
7191
7300
 
7192
7301
  // src/frontdoor/trust.ts
7193
7302
  import { createHash as createHash6 } from "node:crypto";
7194
- import path34 from "node:path";
7303
+ import path35 from "node:path";
7195
7304
  function resolveTrustBundle(params) {
7196
7305
  const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
7197
- if (inherited === void 0 || inherited === "" || path34.resolve(inherited) === path34.resolve(caCertFile)) {
7306
+ if (inherited === void 0 || inherited === "" || path35.resolve(inherited) === path35.resolve(caCertFile)) {
7198
7307
  return { path: caCertFile };
7199
7308
  }
7200
7309
  const caPem = fs12.readFileUtf8(caCertFile);
@@ -7212,7 +7321,7 @@ function resolveTrustBundle(params) {
7212
7321
  }
7213
7322
  const combined = `${inheritedPem.trimEnd()}
7214
7323
  ${caPem}`;
7215
- const bundle = path34.join(bundlesDir, `${createHash6("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
7324
+ const bundle = path35.join(bundlesDir, `${createHash6("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
7216
7325
  if (!fs12.exists(bundle)) {
7217
7326
  fs12.mkdirp(bundlesDir);
7218
7327
  fs12.writeFileAtomic(bundle, combined);
@@ -7369,6 +7478,31 @@ function prepareClaudeLaunch(options) {
7369
7478
  const spawnDaemon = daemonSpawnerFor(options.agentShim);
7370
7479
  return prepareLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) }));
7371
7480
  }
7481
+ function resolveClaudeLaunch(options) {
7482
+ const paths = options.paths ?? resolveLayoutPaths();
7483
+ const refusals = [];
7484
+ const warnings = [];
7485
+ const log = {
7486
+ info: () => void 0,
7487
+ warn: (message) => {
7488
+ warnings.push(message);
7489
+ },
7490
+ error: (message) => {
7491
+ refusals.push(message);
7492
+ }
7493
+ };
7494
+ const proc = {
7495
+ env: options.env,
7496
+ argv: options.argv,
7497
+ exit: (code) => {
7498
+ throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
7499
+ }
7500
+ };
7501
+ const spawnDaemon = () => {
7502
+ throw new Error("resolving a launch starts no daemon");
7503
+ };
7504
+ return { resolution: resolveLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) })), warnings };
7505
+ }
7372
7506
  var LaunchRefusedError;
7373
7507
  var init_launchWiring = __esm({
7374
7508
  "src/launchWiring.ts"() {
@@ -7535,7 +7669,7 @@ var init_anthropicUsageRefresh = __esm({
7535
7669
  });
7536
7670
 
7537
7671
  // src/usage/providerQuota.ts
7538
- import { z as z21 } from "zod";
7672
+ import { z as z22 } from "zod";
7539
7673
  var MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY3, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema;
7540
7674
  var init_providerQuota = __esm({
7541
7675
  "src/usage/providerQuota.ts"() {
@@ -7553,35 +7687,35 @@ var init_providerQuota = __esm({
7553
7687
  [ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
7554
7688
  [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7]
7555
7689
  ]);
7556
- ZaiLimitSchema = z21.object({
7557
- type: z21.string(),
7558
- unit: z21.number().int(),
7559
- number: z21.number().int().positive(),
7560
- percentage: z21.number().nonnegative(),
7561
- nextResetTime: z21.number().positive().optional(),
7562
- usage: z21.number().nonnegative().optional(),
7563
- currentValue: z21.number().nonnegative().optional(),
7564
- remaining: z21.number().nonnegative().optional()
7690
+ ZaiLimitSchema = z22.object({
7691
+ type: z22.string(),
7692
+ unit: z22.number().int(),
7693
+ number: z22.number().int().positive(),
7694
+ percentage: z22.number().nonnegative(),
7695
+ nextResetTime: z22.number().positive().optional(),
7696
+ usage: z22.number().nonnegative().optional(),
7697
+ currentValue: z22.number().nonnegative().optional(),
7698
+ remaining: z22.number().nonnegative().optional()
7565
7699
  });
7566
- ZaiResponseSchema = z21.object({
7567
- success: z21.boolean(),
7568
- msg: z21.string().optional(),
7569
- data: z21.object({ level: z21.string().optional(), limits: z21.array(ZaiLimitSchema) })
7700
+ ZaiResponseSchema = z22.object({
7701
+ success: z22.boolean(),
7702
+ msg: z22.string().optional(),
7703
+ data: z22.object({ level: z22.string().optional(), limits: z22.array(ZaiLimitSchema) })
7570
7704
  });
7571
7705
  OPENROUTER_HOST = "openrouter.ai";
7572
7706
  OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
7573
7707
  OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
7574
7708
  MS_PER_DAY3 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7;
7575
- OpenRouterKeySchema = z21.object({
7576
- data: z21.object({
7577
- limit: z21.number().nonnegative().nullable(),
7578
- limit_remaining: z21.number().nullable(),
7579
- limit_reset: z21.string().nullable(),
7580
- is_free_tier: z21.boolean().optional(),
7581
- free_model_daily_requests: z21.object({ used: z21.number().nonnegative(), limit: z21.number().nonnegative(), remaining: z21.number() }).optional()
7709
+ OpenRouterKeySchema = z22.object({
7710
+ data: z22.object({
7711
+ limit: z22.number().nonnegative().nullable(),
7712
+ limit_remaining: z22.number().nullable(),
7713
+ limit_reset: z22.string().nullable(),
7714
+ is_free_tier: z22.boolean().optional(),
7715
+ free_model_daily_requests: z22.object({ used: z22.number().nonnegative(), limit: z22.number().nonnegative(), remaining: z22.number() }).optional()
7582
7716
  })
7583
7717
  });
7584
- OpenRouterCreditsSchema = z21.object({ data: z21.object({ total_credits: z21.number().nonnegative(), total_usage: z21.number().nonnegative() }) });
7718
+ OpenRouterCreditsSchema = z22.object({ data: z22.object({ total_credits: z22.number().nonnegative(), total_usage: z22.number().nonnegative() }) });
7585
7719
  }
7586
7720
  });
7587
7721
 
@@ -8197,8 +8331,8 @@ function parseConnectTarget(authority) {
8197
8331
  function isInterceptedHost(host, interceptHosts) {
8198
8332
  return interceptHosts.includes(host);
8199
8333
  }
8200
- function servedByPipeline(path35) {
8201
- return path35?.startsWith(ROUTED_PATH_PREFIX) === true;
8334
+ function servedByPipeline(path36) {
8335
+ return path36?.startsWith(ROUTED_PATH_PREFIX) === true;
8202
8336
  }
8203
8337
  var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
8204
8338
  "connection",
@@ -8732,11 +8866,11 @@ function createRcSessionTracker(deps) {
8732
8866
  };
8733
8867
  const observeExchange = (request4) => {
8734
8868
  const method = (request4.method ?? "").toUpperCase();
8735
- const path35 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
8736
- if (!path35.startsWith(RC_SESSIONS_PATH_PREFIX)) {
8869
+ const path36 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
8870
+ if (!path36.startsWith(RC_SESSIONS_PATH_PREFIX)) {
8737
8871
  return void 0;
8738
8872
  }
8739
- const tail = path35.slice(RC_SESSIONS_PATH_PREFIX.length);
8873
+ const tail = path36.slice(RC_SESSIONS_PATH_PREFIX.length);
8740
8874
  const facts = {
8741
8875
  oauthAuthorization: oauthAuthorizationOf(request4.headers),
8742
8876
  anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
@@ -9118,8 +9252,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
9118
9252
  function isRcReadFileEncoding(value) {
9119
9253
  return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
9120
9254
  }
9121
- function buildRcReadFilePayload(requestId, path35, options) {
9122
- return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path35, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
9255
+ function buildRcReadFilePayload(requestId, path36, options) {
9256
+ return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path36, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
9123
9257
  }
9124
9258
  function buildRcFileSuggestionsPayload(requestId, query) {
9125
9259
  return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
@@ -9221,15 +9355,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
9221
9355
  const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
9222
9356
  return result.ok ? { ...result, requestId } : result;
9223
9357
  }
9224
- async function readRcSessionFile(deps, sessionId, path35, options) {
9225
- if (path35 === "") {
9358
+ async function readRcSessionFile(deps, sessionId, path36, options) {
9359
+ if (path36 === "") {
9226
9360
  return { ok: false, message: "a read-file write needs a non-empty path: the SDK's own field names the file the worker resolves against the session's cwd, and an empty string names none" };
9227
9361
  }
9228
9362
  if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
9229
9363
  return { ok: false, message: "a read-file write's max-bytes is a positive whole number of bytes: the SDK's own field caps the read, and a zero or negative cap reads nothing" };
9230
9364
  }
9231
9365
  const requestId = deps.newUuid();
9232
- const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path35, options), `read ${path35} from session ${sessionId}`);
9366
+ const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path36, options), `read ${path36} from session ${sessionId}`);
9233
9367
  return result.ok ? { ...result, requestId } : result;
9234
9368
  }
9235
9369
  async function suggestRcSessionFiles(deps, sessionId, query) {
@@ -9398,11 +9532,11 @@ function createRcControlHandler(deps) {
9398
9532
  path: "read-file",
9399
9533
  read: (body) => {
9400
9534
  const session = bodyString(body, "session");
9401
- const path35 = bodyString(body, "path");
9535
+ const path36 = bodyString(body, "path");
9402
9536
  const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
9403
9537
  const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
9404
- const refused2 = session === void 0 || path35 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
9405
- return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path35, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
9538
+ const refused2 = session === void 0 || path36 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
9539
+ return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path36, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
9406
9540
  }
9407
9541
  },
9408
9542
  {
@@ -9712,9 +9846,9 @@ function requestIdOfBody(body) {
9712
9846
  }
9713
9847
  function frontDoorRcControl(transport, token) {
9714
9848
  const headers = { authorization: `Bearer ${token}` };
9715
- const listAnswerOf = async (path35, what) => {
9849
+ const listAnswerOf = async (path36, what) => {
9716
9850
  try {
9717
- return await transport.request({ method: "GET", path: path35, headers });
9851
+ return await transport.request({ method: "GET", path: path36, headers });
9718
9852
  } catch (error) {
9719
9853
  throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
9720
9854
  }
@@ -9786,10 +9920,10 @@ function frontDoorRcControl(transport, token) {
9786
9920
  }
9787
9921
  return pending;
9788
9922
  };
9789
- const writeOf = async (path35, body, describeFailure) => {
9923
+ const writeOf = async (path36, body, describeFailure) => {
9790
9924
  let answer;
9791
9925
  try {
9792
- answer = await transport.request({ method: "POST", path: path35, headers: { ...headers, "content-type": "application/json" }, body });
9926
+ answer = await transport.request({ method: "POST", path: path36, headers: { ...headers, "content-type": "application/json" }, body });
9793
9927
  } catch (error) {
9794
9928
  return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
9795
9929
  }
@@ -9820,10 +9954,10 @@ function frontDoorRcControl(transport, token) {
9820
9954
  endSession: async (sessionId, reason) => await writeOf(`${CONTROL_PATH_PREFIX}/end-session`, JSON.stringify({ session: sessionId, ...reason === void 0 ? {} : { reason } }), (status, message) => `ending ${sessionId} failed (HTTP ${String(status)}): ${message}`),
9821
9955
  getUsage: async (sessionId, skipBehaviors) => await writeOf(`${CONTROL_PATH_PREFIX}/get-usage`, JSON.stringify({ session: sessionId, ...skipBehaviors === void 0 ? {} : { skipBehaviors } }), (status, message) => `requesting the usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
9822
9956
  getContextUsage: async (sessionId, detail) => await writeOf(`${CONTROL_PATH_PREFIX}/get-context-usage`, JSON.stringify({ session: sessionId, ...detail === void 0 ? {} : { detail } }), (status, message) => `requesting the context usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
9823
- readFile: async (sessionId, path35, options) => await writeOf(
9957
+ readFile: async (sessionId, path36, options) => await writeOf(
9824
9958
  `${CONTROL_PATH_PREFIX}/read-file`,
9825
- JSON.stringify({ session: sessionId, path: path35, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
9826
- (status, message) => `reading ${path35} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
9959
+ JSON.stringify({ session: sessionId, path: path36, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
9960
+ (status, message) => `reading ${path36} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
9827
9961
  ),
9828
9962
  fileSuggestions: async (sessionId, query) => await writeOf(`${CONTROL_PATH_PREFIX}/file-suggestions`, JSON.stringify({ session: sessionId, query }), (status, message) => `requesting file suggestions from ${sessionId} failed (HTTP ${String(status)}): ${message}`),
9829
9963
  keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
@@ -9982,12 +10116,12 @@ function tlsFacts(options) {
9982
10116
  }
9983
10117
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
9984
10118
  const agent = new ExemptTlsAgent();
9985
- const post = async (path35, headers, body) => await new Promise((resolve, reject) => {
10119
+ const post = async (path36, headers, body) => await new Promise((resolve, reject) => {
9986
10120
  const options = {
9987
10121
  host: target.host,
9988
10122
  port: target.port,
9989
10123
  method: "POST",
9990
- path: path35,
10124
+ path: path36,
9991
10125
  // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
9992
10126
  headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
9993
10127
  agent
@@ -10052,12 +10186,12 @@ function lateRcStreamDial(resolve) {
10052
10186
  }
10053
10187
  function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
10054
10188
  const agent = new ExemptTlsAgent();
10055
- const request4 = async (method, path35, headers, body, signal) => await new Promise((resolve, reject) => {
10189
+ const request4 = async (method, path36, headers, body, signal) => await new Promise((resolve, reject) => {
10056
10190
  const options = {
10057
10191
  host: target.host,
10058
10192
  port: target.port,
10059
10193
  method,
10060
- path: path35,
10194
+ path: path36,
10061
10195
  // The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
10062
10196
  headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
10063
10197
  agent,
@@ -10099,9 +10233,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
10099
10233
  return { status, body: await readAll(response) };
10100
10234
  },
10101
10235
  openStream: async (sessionId, headers, resume, signal) => {
10102
- const path35 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
10236
+ const path36 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
10103
10237
  const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
10104
- const { status, response } = await request4("GET", path35, streamHeaders, void 0, signal);
10238
+ const { status, response } = await request4("GET", path36, streamHeaders, void 0, signal);
10105
10239
  if (!isSuccessful2(status)) {
10106
10240
  await readAll(response);
10107
10241
  return { status, chunks: NO_CHUNKS };
@@ -10397,7 +10531,7 @@ function createRcCredentialStore(fs12, dir) {
10397
10531
  init_package();
10398
10532
  import { createORPCClient, ORPCError } from "@orpc/client";
10399
10533
  import { RPCLink } from "@orpc/client/fetch";
10400
- import { OpenAPIGenerator } from "@orpc/openapi";
10534
+ import { openapi, OpenAPIGenerator } from "@orpc/openapi";
10401
10535
  import { OpenAPIHandler } from "@orpc/openapi/node";
10402
10536
  import { eventIterator, os as os2, withEventMeta } from "@orpc/server";
10403
10537
  import { BodyLimitPlugin, RPCHandler } from "@orpc/server/node";
@@ -10601,41 +10735,41 @@ function createRcApiRouter(deps) {
10601
10735
  };
10602
10736
  return {
10603
10737
  rc: {
10604
- list: authed.route({ method: "GET", path: "/rest/rc/sessions", summary: "List the observed Remote Control sessions", tags: [RC_API_TAG] }).output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
10605
- status: authed.route({ method: "GET", path: "/rest/rc/status", summary: "Read session status, one session's when named", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input }) => {
10738
+ list: authed.meta(openapi({ method: "GET", path: "/rest/rc/sessions", summary: "List the observed Remote Control sessions", tags: [RC_API_TAG] })).output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
10739
+ status: authed.meta(openapi({ method: "GET", path: "/rest/rc/status", summary: "Read session status, one session's when named", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output(RcStatusOutputSchema).handler(({ input }) => {
10606
10740
  const statuses = deps.statusOf(input.session);
10607
10741
  if (input.session !== void 0 && !statuses.some((entry) => entry.id === input.session)) {
10608
10742
  throw new ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
10609
10743
  }
10610
10744
  return { statuses };
10611
10745
  }),
10612
- pending: authed.route({ method: "GET", path: "/rest/rc/pending", summary: "Read the control requests awaiting an answer", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input }) => {
10746
+ pending: authed.meta(openapi({ method: "GET", path: "/rest/rc/pending", summary: "Read the control requests awaiting an answer", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output(RcPendingOutputSchema).handler(({ input }) => {
10613
10747
  const pending = deps.pendingOf(input.session);
10614
10748
  if (input.session !== void 0 && deps.statusOf(input.session).length === 0) {
10615
10749
  throw new ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
10616
10750
  }
10617
10751
  return { pending };
10618
10752
  }),
10619
- send: authed.route({ method: "POST", path: "/rest/rc/send", summary: "Send one message into a session", tags: [RC_API_TAG] }).input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.inject(input.session, input.text)) })),
10620
- answer: authed.route({ method: "POST", path: "/rest/rc/answer", summary: "Answer one pending control request", tags: [RC_API_TAG] }).input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input }) => {
10753
+ send: authed.meta(openapi({ method: "POST", path: "/rest/rc/send", summary: "Send one message into a session", tags: [RC_API_TAG] })).input(RcSendInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.inject(input.session, input.text)) })),
10754
+ answer: authed.meta(openapi({ method: "POST", path: "/rest/rc/answer", summary: "Answer one pending control request", tags: [RC_API_TAG] })).input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input }) => {
10621
10755
  const decision = { approve: input.approve, message: input.approve || input.text === void 0 ? void 0 : input.text };
10622
10756
  return { session: input.session, request: input.request, sequenceNums: delivered(input.session, await deps.answer(input.session, input.request, decision)) };
10623
10757
  }),
10624
- interrupt: authed.route({ method: "POST", path: "/rest/rc/interrupt", summary: "Interrupt a session's running turn", tags: [RC_API_TAG] }).input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.interrupt(input.session)) })),
10625
- setModel: authed.route({ method: "POST", path: "/rest/rc/set-model", summary: "Switch a session's model", tags: [RC_API_TAG] }).input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setModel(input.session, input.model)) })),
10626
- setPermissionMode: authed.route({ method: "POST", path: "/rest/rc/set-permission-mode", summary: "Switch a session's permission mode", tags: [RC_API_TAG] }).input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setPermissionMode(input.session, input.mode)) })),
10627
- endSession: authed.route({ method: "POST", path: "/rest/rc/end-session", summary: "End a session", tags: [RC_API_TAG] }).input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.endSession(input.session, input.reason)) })),
10628
- getUsage: authed.route({ method: "POST", path: "/rest/rc/get-usage", summary: "Ask a session for its usage snapshot", tags: [RC_API_TAG] }).input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getUsage(input.session, input.skipBehaviors)) })),
10629
- getContextUsage: authed.route({ method: "POST", path: "/rest/rc/get-context-usage", summary: "Ask a session for its context usage", tags: [RC_API_TAG] }).input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getContextUsage(input.session, input.detail)) })),
10630
- readFile: authed.route({ method: "POST", path: "/rest/rc/read-file", summary: "Ask a session to read one file", tags: [RC_API_TAG] }).input(RcReadFileInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.readFile(input.session, input.path, { ...input.maxBytes === void 0 ? {} : { maxBytes: input.maxBytes }, ...input.encoding === void 0 ? {} : { encoding: input.encoding } })) })),
10631
- fileSuggestions: authed.route({ method: "POST", path: "/rest/rc/file-suggestions", summary: "Ask a session for file-path suggestions", tags: [RC_API_TAG] }).input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.fileSuggestions(input.session, input.query)) })),
10632
- keepAlive: authed.route({ method: "POST", path: "/rest/rc/keep-alive", summary: "Keep a session's bridge alive", tags: [RC_API_TAG] }).input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.keepAlive(input.session)) })),
10633
- mcpStatus: authed.route({ method: "POST", path: "/rest/rc/mcp-status", summary: "Ask a session for its MCP servers' status", tags: [RC_API_TAG] }).input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpStatus(input.session)) })),
10634
- mcpReconnect: authed.route({ method: "POST", path: "/rest/rc/mcp-reconnect", summary: "Ask a session to reconnect one MCP server", tags: [RC_API_TAG] }).input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpReconnect(input.session, input.serverName)) })),
10635
- mcpAuthenticate: authed.route({ method: "POST", path: "/rest/rc/mcp-authenticate", summary: "Start OAuth for one MCP server on a session", tags: [RC_API_TAG] }).input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpAuthenticate(input.session, input.serverName, input.redirectUri)) })),
10636
- mcpOAuthCallbackUrl: authed.route({ method: "POST", path: "/rest/rc/mcp-oauth-callback-url", summary: "Hand a completed MCP OAuth callback to a session", tags: [RC_API_TAG] }).input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpOAuthCallbackUrl(input.session, input.serverName, input.callbackUrl)) })),
10637
- teleport: authed.route({ method: "POST", path: "/rest/rc/teleport", summary: "Teleport a session to a conversation marker", tags: [RC_API_TAG] }).input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.teleport(input.session, input.marker)) })),
10638
- subscribe: authed.route({ method: "GET", path: "/rest/rc/events", summary: "Stream a session's Remote Control events (SSE)", tags: [RC_API_TAG] }).input(RcSessionQuerySchema).output(eventIterator(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
10758
+ interrupt: authed.meta(openapi({ method: "POST", path: "/rest/rc/interrupt", summary: "Interrupt a session's running turn", tags: [RC_API_TAG] })).input(RcInterruptInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.interrupt(input.session)) })),
10759
+ setModel: authed.meta(openapi({ method: "POST", path: "/rest/rc/set-model", summary: "Switch a session's model", tags: [RC_API_TAG] })).input(RcSetModelInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setModel(input.session, input.model)) })),
10760
+ setPermissionMode: authed.meta(openapi({ method: "POST", path: "/rest/rc/set-permission-mode", summary: "Switch a session's permission mode", tags: [RC_API_TAG] })).input(RcSetPermissionModeInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.setPermissionMode(input.session, input.mode)) })),
10761
+ endSession: authed.meta(openapi({ method: "POST", path: "/rest/rc/end-session", summary: "End a session", tags: [RC_API_TAG] })).input(RcEndSessionInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.endSession(input.session, input.reason)) })),
10762
+ getUsage: authed.meta(openapi({ method: "POST", path: "/rest/rc/get-usage", summary: "Ask a session for its usage snapshot", tags: [RC_API_TAG] })).input(RcGetUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getUsage(input.session, input.skipBehaviors)) })),
10763
+ getContextUsage: authed.meta(openapi({ method: "POST", path: "/rest/rc/get-context-usage", summary: "Ask a session for its context usage", tags: [RC_API_TAG] })).input(RcGetContextUsageInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.getContextUsage(input.session, input.detail)) })),
10764
+ readFile: authed.meta(openapi({ method: "POST", path: "/rest/rc/read-file", summary: "Ask a session to read one file", tags: [RC_API_TAG] })).input(RcReadFileInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.readFile(input.session, input.path, { ...input.maxBytes === void 0 ? {} : { maxBytes: input.maxBytes }, ...input.encoding === void 0 ? {} : { encoding: input.encoding } })) })),
10765
+ fileSuggestions: authed.meta(openapi({ method: "POST", path: "/rest/rc/file-suggestions", summary: "Ask a session for file-path suggestions", tags: [RC_API_TAG] })).input(RcFileSuggestionsInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.fileSuggestions(input.session, input.query)) })),
10766
+ keepAlive: authed.meta(openapi({ method: "POST", path: "/rest/rc/keep-alive", summary: "Keep a session's bridge alive", tags: [RC_API_TAG] })).input(RcKeepAliveInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.keepAlive(input.session)) })),
10767
+ mcpStatus: authed.meta(openapi({ method: "POST", path: "/rest/rc/mcp-status", summary: "Ask a session for its MCP servers' status", tags: [RC_API_TAG] })).input(RcMcpStatusInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpStatus(input.session)) })),
10768
+ mcpReconnect: authed.meta(openapi({ method: "POST", path: "/rest/rc/mcp-reconnect", summary: "Ask a session to reconnect one MCP server", tags: [RC_API_TAG] })).input(RcMcpReconnectInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpReconnect(input.session, input.serverName)) })),
10769
+ mcpAuthenticate: authed.meta(openapi({ method: "POST", path: "/rest/rc/mcp-authenticate", summary: "Start OAuth for one MCP server on a session", tags: [RC_API_TAG] })).input(RcMcpAuthenticateInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpAuthenticate(input.session, input.serverName, input.redirectUri)) })),
10770
+ mcpOAuthCallbackUrl: authed.meta(openapi({ method: "POST", path: "/rest/rc/mcp-oauth-callback-url", summary: "Hand a completed MCP OAuth callback to a session", tags: [RC_API_TAG] })).input(RcMcpOAuthCallbackUrlInputSchema).output(RcControlWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, ...deliveredControl(input.session, await deps.mcpOAuthCallbackUrl(input.session, input.serverName, input.callbackUrl)) })),
10771
+ teleport: authed.meta(openapi({ method: "POST", path: "/rest/rc/teleport", summary: "Teleport a session to a conversation marker", tags: [RC_API_TAG] })).input(RcTeleportInputSchema).output(RcWriteOutputSchema).handler(async ({ input }) => ({ session: input.session, sequenceNums: delivered(input.session, await deps.teleport(input.session, input.marker)) })),
10772
+ subscribe: authed.meta(openapi({ method: "GET", path: "/rest/rc/events", summary: "Stream a session's Remote Control events (SSE)", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output(eventIterator(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
10639
10773
  const queue = [];
10640
10774
  let wake;
10641
10775
  const detach = deps.fanout.subscribe(input.session, (event) => {
@@ -10677,7 +10811,7 @@ function doorApiNodeHandlerOf(router, expectedToken) {
10677
10811
  const rpcHandler = new RPCHandler(router, { plugins });
10678
10812
  const restHandler = new OpenAPIHandler(router, { plugins });
10679
10813
  let document;
10680
- const documentOf = async () => document ??= new OpenAPIGenerator().generate(router, { info: { title: "agent-shim front door API", version: package_default.version } });
10814
+ const documentOf = async () => document ??= new OpenAPIGenerator().generate(router, { base: { info: { title: "agent-shim front door API", version: package_default.version } } });
10681
10815
  return {
10682
10816
  pathPrefix: RC_ORPC_PATH_PREFIX,
10683
10817
  handle: async (request4, response) => {
@@ -10700,11 +10834,15 @@ function doorApiNodeHandlerOf(router, expectedToken) {
10700
10834
  }
10701
10835
  return { matched: true };
10702
10836
  }
10703
- const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers }, prefix: RC_ORPC_PATH_PREFIX });
10837
+ const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers, afterResponse: (action) => {
10838
+ response.once("finish", action);
10839
+ } }, prefix: RC_ORPC_PATH_PREFIX });
10704
10840
  if (rest.matched) {
10705
10841
  return rest;
10706
10842
  }
10707
- return await rpcHandler.handle(request4, response, { context: { headers: request4.headers }, prefix: RC_ORPC_PATH_PREFIX });
10843
+ return await rpcHandler.handle(request4, response, { context: { headers: request4.headers, afterResponse: (action) => {
10844
+ response.once("finish", action);
10845
+ } }, prefix: RC_ORPC_PATH_PREFIX });
10708
10846
  }
10709
10847
  };
10710
10848
  }
@@ -10714,10 +10852,12 @@ function createRcApiNodeHandler(deps) {
10714
10852
  function frontDoorApiLink(port, ca, token) {
10715
10853
  const dispatcher = new Agent3({ connect: { ca } });
10716
10854
  return new RPCLink({
10717
- url: `https://127.0.0.1:${String(port)}${RC_ORPC_PATH_PREFIX}`,
10855
+ origin: `https://127.0.0.1:${String(port)}`,
10856
+ url: RC_ORPC_PATH_PREFIX,
10718
10857
  headers: { authorization: `Bearer ${token}` },
10719
10858
  // undici's own Request and Response types and the global ones are distinct declarations of the same standard shapes (the package's bundled types sit beside @types/node's own), and its fetch refuses the global Request instance outright, so the call is rebuilt from the request's parts and the answer re-wrapped through the global constructors, never cast between the two. The request body is one bounded JSON object (the same protocol cap the handler enforces), so reading it whole costs nothing; it is the answer that streams.
10720
- fetch: async (request4, _init, options) => {
10859
+ fetch: async (url, init, options) => {
10860
+ const request4 = new Request(url, init);
10721
10861
  const body = request4.body === null ? void 0 : Buffer.from(await request4.arrayBuffer());
10722
10862
  const answered = await undiciFetch(request4.url, {
10723
10863
  method: request4.method,
@@ -10739,7 +10879,8 @@ init_cliError();
10739
10879
  init_realPorts();
10740
10880
 
10741
10881
  // src/frontdoor/controlApi.ts
10742
- import { createORPCClient as createORPCClient2, ORPCError as ORPCError3 } from "@orpc/client";
10882
+ import { createORPCClient as createORPCClient2, ORPCError as ORPCError5 } from "@orpc/client";
10883
+ import { openapi as openapi6 } from "@orpc/openapi";
10743
10884
 
10744
10885
  // src/checkReport.ts
10745
10886
  init_classify();
@@ -10966,19 +11107,19 @@ function writePools(paths, pools) {
10966
11107
  applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
10967
11108
  }
10968
11109
  function poolCycleOf(pools, name) {
10969
- const walk = (current, path35) => {
11110
+ const walk = (current, path36) => {
10970
11111
  for (const entry of pools[current]?.identities ?? []) {
10971
11112
  const nested = poolNameOf(poolMemberIdentity(entry));
10972
11113
  if (nested === void 0) {
10973
11114
  continue;
10974
11115
  }
10975
11116
  if (nested === name) {
10976
- return [...path35, nested];
11117
+ return [...path36, nested];
10977
11118
  }
10978
- if (path35.includes(nested)) {
11119
+ if (path36.includes(nested)) {
10979
11120
  continue;
10980
11121
  }
10981
- const found = walk(nested, [...path35, nested]);
11122
+ const found = walk(nested, [...path36, nested]);
10982
11123
  if (found !== void 0) {
10983
11124
  return found;
10984
11125
  }
@@ -12549,9 +12690,48 @@ var DoctorRunOutputSchema = z19.strictObject({
12549
12690
  ok: z19.boolean(),
12550
12691
  findings: z19.readonly(z19.array(DoctorFindingSchema))
12551
12692
  });
12693
+ var FrontDoorRestartOutputSchema = z19.strictObject({
12694
+ action: z19.literal("restarting"),
12695
+ previousPid: z19.int().positive()
12696
+ });
12697
+ var UpdateCheckOutputSchema = z19.strictObject({
12698
+ current: z19.string(),
12699
+ latest: z19.string(),
12700
+ action: z19.enum(["current", "available", "updated"])
12701
+ });
12702
+ var CodexSignInSchema = z19.discriminatedUnion("state", [
12703
+ z19.strictObject({ state: z19.literal("none") }),
12704
+ z19.strictObject({ state: z19.literal("signed-in"), email: z19.string().optional(), planScope: z19.boolean(), accessTokenExpiresAt: z19.number() }),
12705
+ z19.strictObject({ state: z19.literal("unreadable"), message: z19.string() })
12706
+ ]);
12707
+ var CodexStatusOutputSchema = z19.strictObject({
12708
+ signIn: CodexSignInSchema,
12709
+ codexProviders: z19.readonly(z19.array(z19.string()))
12710
+ });
12711
+ var CodexLogoutOutputSchema = z19.strictObject({
12712
+ hadGrant: z19.boolean(),
12713
+ revoked: z19.boolean()
12714
+ });
12715
+
12716
+ // src/frontdoor/codexApi.ts
12717
+ import { openapi as openapi2 } from "@orpc/openapi";
12718
+ var CODEX_API_TAG = "codex";
12719
+ function createCodexApiRouter(deps) {
12720
+ const authed = doorApiAuth(deps.expectedToken);
12721
+ return {
12722
+ codex: {
12723
+ status: authed.meta(openapi2({ method: "GET", path: "/rest/codex/status", summary: "Read the Codex sign-in and the codex providers", tags: [CODEX_API_TAG] })).output(CodexStatusOutputSchema).handler(() => {
12724
+ const status = deps.codexStatus();
12725
+ return { signIn: status.signIn, codexProviders: status.codexProviders };
12726
+ }),
12727
+ logout: authed.meta(openapi2({ method: "POST", path: "/rest/codex/logout", summary: "Revoke the Sign in with ChatGPT login and remove it", tags: [CODEX_API_TAG] })).output(CodexLogoutOutputSchema).handler(async () => await deps.codexLogout())
12728
+ }
12729
+ };
12730
+ }
12552
12731
 
12553
12732
  // src/frontdoor/eventsApi.ts
12554
12733
  import { ORPCError as ORPCError2 } from "@orpc/client";
12734
+ import { openapi as openapi3 } from "@orpc/openapi";
12555
12735
  import { eventIterator as eventIterator2, withEventMeta as withEventMeta2 } from "@orpc/server";
12556
12736
 
12557
12737
  // src/frontdoor/eventSchemas.ts
@@ -12598,7 +12778,7 @@ function createEventsApiRouter(deps) {
12598
12778
  const authed = doorApiAuth(deps.expectedToken);
12599
12779
  return {
12600
12780
  events: {
12601
- subscribe: authed.route({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] }).input(DoorEventSourceQuerySchema).output(eventIterator2(DoorEventSchema)).handler(async function* ({ input, signal }) {
12781
+ subscribe: authed.meta(openapi3({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] })).input(DoorEventSourceQuerySchema).output(eventIterator2(DoorEventSchema)).handler(async function* ({ input, signal }) {
12602
12782
  if (input.sources !== void 0) {
12603
12783
  const live = deps.events.sources();
12604
12784
  const unknown = input.sources.filter((source) => !live.includes(source));
@@ -12630,9 +12810,120 @@ function createEventsApiRouter(deps) {
12630
12810
  };
12631
12811
  }
12632
12812
 
12813
+ // src/frontdoor/lifecycleApi.ts
12814
+ init_update();
12815
+ import { ORPCError as ORPCError3 } from "@orpc/client";
12816
+ import { openapi as openapi4 } from "@orpc/openapi";
12817
+ var FRONTDOOR_API_TAG = "frontdoor";
12818
+ var UPDATE_API_TAG = "update";
12819
+ function createLifecycleApiRouter(deps) {
12820
+ const authed = doorApiAuth(deps.expectedToken);
12821
+ return {
12822
+ frontdoor: {
12823
+ restart: authed.meta(openapi4({ method: "POST", path: "/rest/frontdoor/restart", summary: "Replace the serving front door in place", description: "Answers with the pid of the door being replaced, then replaces it. The replacement is a new generation with its own control token: the caller reopens its client from the state root once the door's supervisor pid differs from the one returned.", tags: [FRONTDOOR_API_TAG] })).output(FrontDoorRestartOutputSchema).handler(({ context }) => {
12824
+ context.afterResponse(deps.restartDoor);
12825
+ return { action: "restarting", previousPid: deps.doorPid };
12826
+ })
12827
+ },
12828
+ update: {
12829
+ check: authed.meta(openapi4({ method: "GET", path: "/rest/update/check", summary: "Check whether a newer release exists", tags: [UPDATE_API_TAG] })).output(UpdateCheckOutputSchema).handler(async () => {
12830
+ try {
12831
+ return await deps.checkForUpdate();
12832
+ } catch (error) {
12833
+ if (error instanceof UpdateChannelError) {
12834
+ throw new ORPCError3("PRECONDITION_FAILED", { message: error.message });
12835
+ }
12836
+ if (error instanceof UpdateConflictError) {
12837
+ throw new ORPCError3("CONFLICT", { message: error.message });
12838
+ }
12839
+ if (error instanceof UpdateDownloadError) {
12840
+ throw new ORPCError3("BAD_GATEWAY", { message: error.message });
12841
+ }
12842
+ throw error;
12843
+ }
12844
+ })
12845
+ }
12846
+ };
12847
+ }
12848
+
12849
+ // src/frontdoor/launchApi.ts
12850
+ init_cliError();
12851
+ import { ORPCError as ORPCError4 } from "@orpc/client";
12852
+ import { openapi as openapi5 } from "@orpc/openapi";
12853
+
12854
+ // src/frontdoor/launchSchemas.ts
12855
+ import path30 from "node:path";
12856
+ import { z as z21 } from "zod";
12857
+ init_claudeVersion();
12858
+ init_identity();
12859
+ var LaunchResolveInputSchema = z21.strictObject({
12860
+ path: z21.string().min(1),
12861
+ /** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
12862
+ argv: z21.readonly(z21.array(z21.string())).optional(),
12863
+ /** The launch's inherited environment. Absent means an empty one: the door's own environment is never a substitute for the caller's, so a caller that wants `AGENT_SHIM_*` switches or a `CLAUDE_CONFIG_DIR` considered names them here. Values are read, never reported. */
12864
+ env: z21.record(z21.string(), z21.string()).optional()
12865
+ }).refine((input) => path30.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
12866
+ var LaunchPoolDecisionSchema = z21.strictObject({
12867
+ name: z21.string(),
12868
+ reasons: z21.readonly(z21.array(z21.string())),
12869
+ movedOff: z21.strictObject({ identity: z21.string(), reason: z21.string() }).optional()
12870
+ });
12871
+ var LaunchDecisionSchema = z21.strictObject({
12872
+ identity: z21.string().optional(),
12873
+ identitySource: z21.enum(IDENTITY_DECISION_SOURCES),
12874
+ pool: LaunchPoolDecisionSchema.optional(),
12875
+ configDirEscapeHatch: z21.boolean(),
12876
+ configDir: z21.string().optional(),
12877
+ configProfile: z21.string().optional(),
12878
+ configProfileSource: z21.enum(CONFIG_PROFILE_DECISION_SOURCES),
12879
+ provider: z21.string().optional()
12880
+ });
12881
+ var LaunchFlagsSchema = z21.strictObject({
12882
+ skipPermissions: z21.boolean(),
12883
+ remoteControl: z21.boolean(),
12884
+ headroom: z21.boolean(),
12885
+ trackUsage: z21.boolean()
12886
+ });
12887
+ var LaunchResolveOutputSchema = z21.strictObject({
12888
+ decision: LaunchDecisionSchema,
12889
+ flags: LaunchFlagsSchema,
12890
+ claudeVersion: z21.strictObject({ version: z21.string(), source: z21.enum(CLAUDE_VERSION_SOURCES) }).optional(),
12891
+ /** The real `claude` binary the launch would spawn, on the door's host. */
12892
+ bin: z21.string(),
12893
+ /** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
12894
+ args: z21.readonly(z21.array(z21.string())),
12895
+ /** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
12896
+ credential: z21.strictObject({ subject: z21.enum(["provider", "identity"]), name: z21.string(), summary: CredentialSummarySchema }).optional(),
12897
+ routing: z21.strictObject({ frontDoor: z21.boolean(), headroom: z21.boolean() }),
12898
+ /** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
12899
+ environment: z21.readonly(z21.array(z21.string())),
12900
+ warnings: z21.readonly(z21.array(z21.string()))
12901
+ });
12902
+
12903
+ // src/frontdoor/launchApi.ts
12904
+ var LAUNCH_API_TAG = "launch";
12905
+ function createLaunchApiRouter(deps) {
12906
+ const authed = doorApiAuth(deps.expectedToken);
12907
+ return {
12908
+ launch: {
12909
+ resolve: authed.meta(openapi5({ method: "POST", path: "/rest/launch/resolve", summary: "Resolve what a launch from one directory would do, without performing it", tags: [LAUNCH_API_TAG] })).input(LaunchResolveInputSchema).output(LaunchResolveOutputSchema).handler(({ input }) => {
12910
+ try {
12911
+ const { resolution, warnings } = deps.resolveLaunch({ path: input.path, argv: input.argv ?? [], env: input.env ?? {} });
12912
+ return { ...resolution, warnings };
12913
+ } catch (error) {
12914
+ if (error instanceof CliError) {
12915
+ throw new ORPCError4("BAD_REQUEST", { message: error.message });
12916
+ }
12917
+ throw error;
12918
+ }
12919
+ })
12920
+ }
12921
+ };
12922
+ }
12923
+
12633
12924
  // src/frontdoor/controlApi.ts
12634
12925
  var USAGE_API_TAG = "usage";
12635
- var FRONTDOOR_API_TAG = "frontdoor";
12926
+ var FRONTDOOR_API_TAG2 = "frontdoor";
12636
12927
  var CHECK_API_TAG = "check";
12637
12928
  var DOCTOR_API_TAG = "doctor";
12638
12929
  var POOL_API_TAG = "pool";
@@ -12640,11 +12931,11 @@ function createControlApiRouter(deps) {
12640
12931
  const authed = doorApiAuth(deps.expectedToken);
12641
12932
  return {
12642
12933
  usage: {
12643
- list: authed.route({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] }).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
12644
- effectiveWindow: authed.route({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] }).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
12934
+ list: authed.meta(openapi6({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
12935
+ effectiveWindow: authed.meta(openapi6({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
12645
12936
  const snapshot = deps.usageSnapshotOf(input.identity);
12646
12937
  if (snapshot === void 0) {
12647
- throw new ORPCError3("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
12938
+ throw new ORPCError5("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
12648
12939
  }
12649
12940
  const provider = input.provider ?? ANTHROPIC_PROVIDER;
12650
12941
  const rateLimit = snapshot.providers[provider]?.rateLimit;
@@ -12658,34 +12949,34 @@ function createControlApiRouter(deps) {
12658
12949
  ...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
12659
12950
  };
12660
12951
  }),
12661
- live: authed.route({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] }).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
12952
+ live: authed.meta(openapi6({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] })).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
12662
12953
  const sessions = deps.liveRateLimits(input.session);
12663
12954
  if (input.session !== void 0 && sessions.length === 0) {
12664
12955
  if (deps.list().some((session) => session.id === input.session)) {
12665
- throw new ORPCError3("NOT_FOUND", { message: `session ${input.session} has filed no rate_limit_event on its stream yet: the worker emits one only once a turn has completed, so retry after this session's next turn` });
12956
+ throw new ORPCError5("NOT_FOUND", { message: `session ${input.session} has filed no rate_limit_event on its stream yet: the worker emits one only once a turn has completed, so retry after this session's next turn` });
12666
12957
  }
12667
- throw new ORPCError3("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
12958
+ throw new ORPCError5("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
12668
12959
  }
12669
12960
  return { latest: deps.latestRateLimit(), sessions };
12670
12961
  })
12671
12962
  },
12672
12963
  frontdoor: {
12673
- status: authed.route({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG] }).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
12674
- sessions: authed.route({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG] }).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
12964
+ status: authed.meta(openapi6({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
12965
+ sessions: authed.meta(openapi6({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
12675
12966
  },
12676
12967
  check: {
12677
12968
  // The report's own JSON shape is the contract (the same one `check --json` prints and `checkReportSchema.ts` defines), so the procedure returns exactly that conversion.
12678
- run: authed.route({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] }).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
12969
+ run: authed.meta(openapi6({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] })).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
12679
12970
  },
12680
12971
  doctor: {
12681
- run: authed.route({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] }).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
12972
+ run: authed.meta(openapi6({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
12682
12973
  },
12683
12974
  pool: {
12684
- pick: authed.route({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] }).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
12975
+ pick: authed.meta(openapi6({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] })).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
12685
12976
  const report = deps.poolPick(input.pool, input.path);
12686
12977
  if (report === void 0) {
12687
12978
  const live = deps.poolNames();
12688
- throw new ORPCError3("NOT_FOUND", {
12979
+ throw new ORPCError5("NOT_FOUND", {
12689
12980
  message: live.length === 0 ? `no pools are configured, so none is named ${input.pool}` : `no pool is named ${input.pool}; the live pools are ${live.map((name) => `"${name}"`).join(", ")}`
12690
12981
  });
12691
12982
  }
@@ -12695,7 +12986,9 @@ function createControlApiRouter(deps) {
12695
12986
  };
12696
12987
  }
12697
12988
  function createDoorApiRouter(deps) {
12698
- return { ...createRcApiRouter(deps), ...createControlApiRouter(deps), ...createEventsApiRouter(deps) };
12989
+ const control = createControlApiRouter(deps);
12990
+ const lifecycle = createLifecycleApiRouter(deps);
12991
+ return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
12699
12992
  }
12700
12993
  function createDoorApiNodeHandler(deps) {
12701
12994
  return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
@@ -14656,7 +14949,7 @@ data: ${JSON.stringify(envelope)}
14656
14949
 
14657
14950
  // src/frontdoor/rcSelfHostMint.ts
14658
14951
  init_account();
14659
- import path30 from "node:path";
14952
+ import path31 from "node:path";
14660
14953
  var CREDENTIALS_FILE = ".credentials.json";
14661
14954
  var CLAUDE_JSON2 = ".claude.json";
14662
14955
  var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
@@ -14680,7 +14973,7 @@ function readJsonObject(fs12, file) {
14680
14973
  return isRecord11(parsed) ? parsed : void 0;
14681
14974
  }
14682
14975
  function readRcSelfHostRecord(fs12, frontdoorDir) {
14683
- const parsed = readJsonObject(fs12, path30.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
14976
+ const parsed = readJsonObject(fs12, path31.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
14684
14977
  if (parsed === void 0) {
14685
14978
  return void 0;
14686
14979
  }
@@ -14694,11 +14987,11 @@ function mintRcSelfHostCredential(deps) {
14694
14987
  if (!isIdentityName(deps.identity)) {
14695
14988
  throw new Error(`"${deps.identity}" is not a valid identity name.`);
14696
14989
  }
14697
- const identityDir = path30.join(deps.identitiesDir, deps.identity);
14698
- const credentialsFile = path30.join(identityDir, CREDENTIALS_FILE);
14699
- const claudeJsonFile = path30.join(identityDir, CLAUDE_JSON2);
14700
- const recordDir = path30.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
14701
- const recordFile = path30.join(recordDir, RC_SELF_HOST_RECORD_FILE);
14990
+ const identityDir = path31.join(deps.identitiesDir, deps.identity);
14991
+ const credentialsFile = path31.join(identityDir, CREDENTIALS_FILE);
14992
+ const claudeJsonFile = path31.join(identityDir, CLAUDE_JSON2);
14993
+ const recordDir = path31.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
14994
+ const recordFile = path31.join(recordDir, RC_SELF_HOST_RECORD_FILE);
14702
14995
  const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
14703
14996
  const existingCredentials = readJsonObject(deps.fs, credentialsFile);
14704
14997
  const existingOauth = isRecord11(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
@@ -14714,7 +15007,7 @@ function mintRcSelfHostCredential(deps) {
14714
15007
  const organizationUuid = deps.newUuid();
14715
15008
  const accountUuid = deps.newUuid();
14716
15009
  const mintedAt = new Date(deps.now()).toISOString();
14717
- deps.fs.mkdirPrivate(path30.dirname(credentialsFile));
15010
+ deps.fs.mkdirPrivate(path31.dirname(credentialsFile));
14718
15011
  deps.fs.writeFilePrivate(credentialsFile, `${JSON.stringify({ ...existingCredentials, claudeAiOauth: { accessToken, refreshToken, expiresAt: null, scopes: [...RC_SELF_HOST_SCOPE_LIST], subscriptionType: SELF_HOST_SUBSCRIPTION_TYPE, rateLimitTier: null } }, null, 2)}
14719
15012
  `);
14720
15013
  const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
@@ -14968,6 +15261,9 @@ export {
14968
15261
  CheckReportJsonSchema,
14969
15262
  CheckRunInputSchema,
14970
15263
  CliError,
15264
+ CodexLogoutOutputSchema,
15265
+ CodexSignInSchema,
15266
+ CodexStatusOutputSchema,
14971
15267
  ConfigProfileSchema,
14972
15268
  CredentialCacheSchema,
14973
15269
  CredentialSchema,
@@ -14992,6 +15288,7 @@ export {
14992
15288
  FARM_MANIFEST_FILENAME,
14993
15289
  FrontDoorControlMaterialError,
14994
15290
  FrontDoorNotServingError,
15291
+ FrontDoorRestartOutputSchema,
14995
15292
  FrontDoorSessionStatusSchema,
14996
15293
  FrontDoorSessionsOutputSchema,
14997
15294
  FrontDoorStartError,
@@ -15009,6 +15306,8 @@ export {
15009
15306
  LAUNCH_EVENT_SOURCE,
15010
15307
  LaunchLifecycleEventSchema,
15011
15308
  LaunchRefusedError,
15309
+ LaunchResolveInputSchema,
15310
+ LaunchResolveOutputSchema,
15012
15311
  LegacyProviderFileError,
15013
15312
  OWN_CLI_FILE_NAME,
15014
15313
  PROMPT_CACHE_TTL_MS,
@@ -15055,6 +15354,7 @@ export {
15055
15354
  RcStreamEnvelopeSchema,
15056
15355
  RcStreamEventSchema,
15057
15356
  USAGE_EVENT_SOURCE,
15357
+ UpdateCheckOutputSchema,
15058
15358
  UsageError,
15059
15359
  UsageListOutputSchema,
15060
15360
  UsageLiveOutputSchema,
@@ -15097,14 +15397,17 @@ export {
15097
15397
  collectDoctorReport,
15098
15398
  collectFrontDoorStatus,
15099
15399
  collectPoolPick,
15400
+ createCodexApiRouter,
15100
15401
  createControlApiRouter,
15101
15402
  createDoorApiNodeHandler,
15102
15403
  createDoorApiRouter,
15103
15404
  createDoorEventHub,
15104
15405
  createDoorHealthPublisher,
15105
15406
  createEventsApiRouter,
15407
+ createLaunchApiRouter,
15106
15408
  createLaunchEventPublisher,
15107
15409
  createLeafCache,
15410
+ createLifecycleApiRouter,
15108
15411
  createProfile,
15109
15412
  createQuotaExpiringPublisher,
15110
15413
  createRcApiNodeHandler,
@@ -15212,7 +15515,9 @@ export {
15212
15515
  requirePool,
15213
15516
  resolveAgentShimHome,
15214
15517
  resolveClaudeHome,
15518
+ resolveClaudeLaunch,
15215
15519
  resolveDecisions,
15520
+ resolveLaunch,
15216
15521
  resolveLaunchSelection,
15217
15522
  resolveLayoutPaths,
15218
15523
  resolveSupervisorConfig,