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/README.md +1 -0
- package/dist/cli.cjs +40864 -21064
- package/dist/index.cjs +528 -211
- package/dist/index.mjs +511 -206
- package/dist/types/index.d.ts +952 -348
- package/package.json +5 -4
package/dist/index.cjs
CHANGED
|
@@ -2649,7 +2649,7 @@ var init_package = __esm({
|
|
|
2649
2649
|
"package.json"() {
|
|
2650
2650
|
package_default = {
|
|
2651
2651
|
name: "claude-use",
|
|
2652
|
-
version: "9.
|
|
2652
|
+
version: "9.6.0",
|
|
2653
2653
|
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.",
|
|
2654
2654
|
license: "MIT",
|
|
2655
2655
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -2700,9 +2700,10 @@ var init_package = __esm({
|
|
|
2700
2700
|
dependencies: {
|
|
2701
2701
|
"@anthropic-ai/claude-agent-sdk": "0.3.292",
|
|
2702
2702
|
"@clack/prompts": "^1.8.0",
|
|
2703
|
-
"@
|
|
2704
|
-
"@orpc/
|
|
2705
|
-
"@orpc/
|
|
2703
|
+
"@modelcontextprotocol/sdk": "1.32.0",
|
|
2704
|
+
"@orpc/client": "2.0.0-beta.41",
|
|
2705
|
+
"@orpc/openapi": "2.0.0-beta.41",
|
|
2706
|
+
"@orpc/server": "2.0.0-beta.41",
|
|
2706
2707
|
commander: "^15.0.0",
|
|
2707
2708
|
cosmiconfig: "^10.0.1",
|
|
2708
2709
|
picomatch: "^4.0.7",
|
|
@@ -5767,7 +5768,7 @@ function cascadeProviderName(cascade) {
|
|
|
5767
5768
|
}
|
|
5768
5769
|
return name;
|
|
5769
5770
|
}
|
|
5770
|
-
function
|
|
5771
|
+
function selectProvider(params) {
|
|
5771
5772
|
const cliName = params.cliProvider !== void 0 && params.cliProvider !== "" ? params.cliProvider : void 0;
|
|
5772
5773
|
const name = cliName ?? (params.cascade === void 0 ? void 0 : cascadeProviderName(params.cascade));
|
|
5773
5774
|
if (name === void 0) {
|
|
@@ -5782,6 +5783,14 @@ function resolveProvider(params) {
|
|
|
5782
5783
|
message: `agent-shim: no provider named "${name}". ` + (known.length > 0 ? `Known providers: ${known.join(", ")}.` : "No providers are defined yet; run `agent-shim provider add`.")
|
|
5783
5784
|
};
|
|
5784
5785
|
}
|
|
5786
|
+
return { ok: true, provider: { name, definition } };
|
|
5787
|
+
}
|
|
5788
|
+
function resolveProvider(params) {
|
|
5789
|
+
const selection = selectProvider(params);
|
|
5790
|
+
if (selection?.ok !== true) {
|
|
5791
|
+
return selection;
|
|
5792
|
+
}
|
|
5793
|
+
const { name, definition } = selection.provider;
|
|
5785
5794
|
if (params.credentials === void 0) {
|
|
5786
5795
|
return { ok: false, status: 1, message: `agent-shim: provider ${name} needs its credential resolved, but this launcher has no credential port wired` };
|
|
5787
5796
|
}
|
|
@@ -6064,6 +6073,51 @@ var init_claudeShim = __esm({
|
|
|
6064
6073
|
}
|
|
6065
6074
|
});
|
|
6066
6075
|
|
|
6076
|
+
// src/update/update.ts
|
|
6077
|
+
function compareVersions3(left, right) {
|
|
6078
|
+
const parse = (version) => {
|
|
6079
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
|
|
6080
|
+
if (match === null) {
|
|
6081
|
+
throw new Error(`not a plain release version: ${version}`);
|
|
6082
|
+
}
|
|
6083
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
6084
|
+
};
|
|
6085
|
+
const leftParts = parse(left);
|
|
6086
|
+
const rightParts = parse(right);
|
|
6087
|
+
return leftParts.map((part, index) => part - (rightParts[index] ?? 0)).find((difference) => difference !== 0) ?? 0;
|
|
6088
|
+
}
|
|
6089
|
+
function releaseTagFromUrl(url) {
|
|
6090
|
+
const segment = url.split("?")[0]?.split("/").at(-1);
|
|
6091
|
+
const candidate = segment?.startsWith("v") === true ? segment.slice(1) : void 0;
|
|
6092
|
+
return candidate !== void 0 && /^\d+\.\d+\.\d+$/.test(candidate) ? candidate : void 0;
|
|
6093
|
+
}
|
|
6094
|
+
var LATEST_RELEASE_URL, UpdateChannelError, UpdateConflictError, UpdateDownloadError;
|
|
6095
|
+
var init_update = __esm({
|
|
6096
|
+
"src/update/update.ts"() {
|
|
6097
|
+
"use strict";
|
|
6098
|
+
init_cliError();
|
|
6099
|
+
LATEST_RELEASE_URL = "https://github.com/ExaDev/agent-shim/releases/latest";
|
|
6100
|
+
UpdateChannelError = class extends CliError {
|
|
6101
|
+
constructor(message) {
|
|
6102
|
+
super(message);
|
|
6103
|
+
this.name = "UpdateChannelError";
|
|
6104
|
+
}
|
|
6105
|
+
};
|
|
6106
|
+
UpdateConflictError = class extends CliError {
|
|
6107
|
+
constructor(message) {
|
|
6108
|
+
super(message);
|
|
6109
|
+
this.name = "UpdateConflictError";
|
|
6110
|
+
}
|
|
6111
|
+
};
|
|
6112
|
+
UpdateDownloadError = class extends CliError {
|
|
6113
|
+
constructor(message) {
|
|
6114
|
+
super(message);
|
|
6115
|
+
this.name = "UpdateDownloadError";
|
|
6116
|
+
}
|
|
6117
|
+
};
|
|
6118
|
+
}
|
|
6119
|
+
});
|
|
6120
|
+
|
|
6067
6121
|
// src/frontdoor/ensure.ts
|
|
6068
6122
|
function ensureFrontDoor(params) {
|
|
6069
6123
|
const { paths, ports } = params;
|
|
@@ -6499,7 +6553,7 @@ function buildEnv(params) {
|
|
|
6499
6553
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
6500
6554
|
let providerCustomHeaders;
|
|
6501
6555
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
6502
|
-
env.CLAUDE_CONFIG_DIR =
|
|
6556
|
+
env.CLAUDE_CONFIG_DIR = import_node_path32.default.join(params.identitiesDir, params.resolvedIdentityName);
|
|
6503
6557
|
}
|
|
6504
6558
|
if (params.provider !== void 0) {
|
|
6505
6559
|
const providerEnv = params.provider.definition.env ?? {};
|
|
@@ -6543,11 +6597,11 @@ function buildEnv(params) {
|
|
|
6543
6597
|
}
|
|
6544
6598
|
return env;
|
|
6545
6599
|
}
|
|
6546
|
-
var
|
|
6600
|
+
var import_node_path32, LOOPBACK_HOSTS;
|
|
6547
6601
|
var init_flags = __esm({
|
|
6548
6602
|
"src/launcher/flags.ts"() {
|
|
6549
6603
|
"use strict";
|
|
6550
|
-
|
|
6604
|
+
import_node_path32 = __toESM(require("node:path"), 1);
|
|
6551
6605
|
init_envBool();
|
|
6552
6606
|
init_credential();
|
|
6553
6607
|
init_headers();
|
|
@@ -6623,7 +6677,9 @@ function resolvePoolLaunch(params) {
|
|
|
6623
6677
|
}
|
|
6624
6678
|
const { pick, earliestReturn, movedOff } = graph.ranking;
|
|
6625
6679
|
if (pick !== void 0) {
|
|
6626
|
-
|
|
6680
|
+
if (params.recordPick) {
|
|
6681
|
+
recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
|
|
6682
|
+
}
|
|
6627
6683
|
const move = movedOff === void 0 ? "" : `moved off ${movedOff.identity} (${movedOff.reason}); `;
|
|
6628
6684
|
return {
|
|
6629
6685
|
ok: true,
|
|
@@ -6689,33 +6745,6 @@ var init_spawn = __esm({
|
|
|
6689
6745
|
}
|
|
6690
6746
|
});
|
|
6691
6747
|
|
|
6692
|
-
// src/update/update.ts
|
|
6693
|
-
function compareVersions3(left, right) {
|
|
6694
|
-
const parse = (version) => {
|
|
6695
|
-
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
|
|
6696
|
-
if (match === null) {
|
|
6697
|
-
throw new Error(`not a plain release version: ${version}`);
|
|
6698
|
-
}
|
|
6699
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
6700
|
-
};
|
|
6701
|
-
const leftParts = parse(left);
|
|
6702
|
-
const rightParts = parse(right);
|
|
6703
|
-
return leftParts.map((part, index) => part - (rightParts[index] ?? 0)).find((difference) => difference !== 0) ?? 0;
|
|
6704
|
-
}
|
|
6705
|
-
function releaseTagFromUrl(url) {
|
|
6706
|
-
const segment = url.split("?")[0]?.split("/").at(-1);
|
|
6707
|
-
const candidate = segment?.startsWith("v") === true ? segment.slice(1) : void 0;
|
|
6708
|
-
return candidate !== void 0 && /^\d+\.\d+\.\d+$/.test(candidate) ? candidate : void 0;
|
|
6709
|
-
}
|
|
6710
|
-
var LATEST_RELEASE_URL;
|
|
6711
|
-
var init_update = __esm({
|
|
6712
|
-
"src/update/update.ts"() {
|
|
6713
|
-
"use strict";
|
|
6714
|
-
init_cliError();
|
|
6715
|
-
LATEST_RELEASE_URL = "https://github.com/ExaDev/agent-shim/releases/latest";
|
|
6716
|
-
}
|
|
6717
|
-
});
|
|
6718
|
-
|
|
6719
6748
|
// src/update/launchHook.ts
|
|
6720
6749
|
function resolveUpdateMode(globalConfig) {
|
|
6721
6750
|
return globalConfig?.update?.mode ?? "off";
|
|
@@ -6793,7 +6822,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
|
|
|
6793
6822
|
const resolution = resolveCredential({ credential, env, port, subject: `identity ${identity}` });
|
|
6794
6823
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
6795
6824
|
}
|
|
6796
|
-
function pickFromPool(decided, params, parsedArgv) {
|
|
6825
|
+
function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
6797
6826
|
const { paths, fs: fs12, proc, log } = params;
|
|
6798
6827
|
if (decided.pool === void 0) {
|
|
6799
6828
|
return { identityDecision: decided };
|
|
@@ -6814,7 +6843,9 @@ function pickFromPool(decided, params, parsedArgv) {
|
|
|
6814
6843
|
now: farmRuntime.now,
|
|
6815
6844
|
sleep: farmRuntime.lock.sleep,
|
|
6816
6845
|
passthrough: parsedArgv.rest,
|
|
6817
|
-
|
|
6846
|
+
// 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.
|
|
6847
|
+
wait: !readOnly && parsedArgv.wait === true,
|
|
6848
|
+
recordPick: !readOnly,
|
|
6818
6849
|
log
|
|
6819
6850
|
});
|
|
6820
6851
|
if (!resolution.ok) {
|
|
@@ -6827,7 +6858,7 @@ function pickFromPool(decided, params, parsedArgv) {
|
|
|
6827
6858
|
poolPick: { name: decided.pool, reasons: resolution.reasons, ...resolution.movedOff === void 0 ? {} : { movedOff: resolution.movedOff } }
|
|
6828
6859
|
};
|
|
6829
6860
|
}
|
|
6830
|
-
function
|
|
6861
|
+
function decideLaunch(params, readOnly) {
|
|
6831
6862
|
const { paths, fs: fs12, proc, log } = params;
|
|
6832
6863
|
const { env, argv } = proc;
|
|
6833
6864
|
const parsedArgv = parseLauncherArgv(argv);
|
|
@@ -6851,10 +6882,10 @@ function prepareLaunch(params) {
|
|
|
6851
6882
|
return trimmed === "" ? void 0 : trimmed;
|
|
6852
6883
|
}
|
|
6853
6884
|
});
|
|
6854
|
-
const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv);
|
|
6885
|
+
const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv, readOnly);
|
|
6855
6886
|
const farmIdentity = configDirEscapeHatchApplies ? void 0 : identityDecision.name;
|
|
6856
6887
|
const farm = farmIdentity === void 0 ? void 0 : params.farm;
|
|
6857
|
-
if (farm !== void 0 && farmIdentity !== void 0) {
|
|
6888
|
+
if (!readOnly && farm !== void 0 && farmIdentity !== void 0) {
|
|
6858
6889
|
let recovery;
|
|
6859
6890
|
try {
|
|
6860
6891
|
recovery = recoverFarm({
|
|
@@ -6893,33 +6924,44 @@ function prepareLaunch(params) {
|
|
|
6893
6924
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
6894
6925
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
6895
6926
|
});
|
|
6896
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(
|
|
6927
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(import_node_path33.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
6897
6928
|
log.error(
|
|
6898
6929
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
6899
6930
|
);
|
|
6900
6931
|
proc.exit(1);
|
|
6901
6932
|
}
|
|
6902
6933
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
6903
|
-
const
|
|
6934
|
+
const providerParams = {
|
|
6904
6935
|
paths,
|
|
6905
6936
|
port: fs12,
|
|
6906
|
-
|
|
6907
|
-
...params.credentials === void 0 ? {} : { credentials: params.credentials },
|
|
6908
|
-
...parsedArgv.provider === void 0 ? {} : { cliProvider: parsedArgv.provider },
|
|
6937
|
+
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
6909
6938
|
...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
|
|
6910
|
-
}
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6939
|
+
};
|
|
6940
|
+
let selectedProvider;
|
|
6941
|
+
let resolvedProvider;
|
|
6942
|
+
if (parsedArgv.provider !== false && readOnly) {
|
|
6943
|
+
const selection = selectProvider(providerParams);
|
|
6944
|
+
if (selection !== void 0 && !selection.ok) {
|
|
6945
|
+
log.error(selection.message);
|
|
6946
|
+
proc.exit(selection.status);
|
|
6947
|
+
}
|
|
6948
|
+
selectedProvider = selection?.ok === true ? selection.provider : void 0;
|
|
6949
|
+
} else if (parsedArgv.provider !== false) {
|
|
6950
|
+
const provider = resolveProvider({ ...providerParams, env, ...params.credentials === void 0 ? {} : { credentials: params.credentials } });
|
|
6951
|
+
if (provider !== void 0 && !provider.ok) {
|
|
6952
|
+
log.error(provider.message);
|
|
6953
|
+
proc.exit(provider.status);
|
|
6954
|
+
}
|
|
6955
|
+
resolvedProvider = provider?.ok === true ? provider.provider : void 0;
|
|
6956
|
+
selectedProvider = resolvedProvider;
|
|
6957
|
+
for (const warning of provider?.ok === true ? provider.warnings : []) {
|
|
6958
|
+
log.warn(warning);
|
|
6959
|
+
}
|
|
6918
6960
|
}
|
|
6919
6961
|
if (farm !== void 0 && farmIdentity !== void 0) {
|
|
6920
6962
|
try {
|
|
6921
6963
|
const snapshot = readUsageSnapshot(farm.fs, paths.usageSnapshotsDir, farmIdentity);
|
|
6922
|
-
for (const warning of quotaWarnings(snapshot,
|
|
6964
|
+
for (const warning of quotaWarnings(snapshot, selectedProvider?.name ?? ANTHROPIC_PROVIDER, farm.now())) {
|
|
6923
6965
|
log.warn(warning);
|
|
6924
6966
|
}
|
|
6925
6967
|
} catch (error) {
|
|
@@ -6929,8 +6971,8 @@ function prepareLaunch(params) {
|
|
|
6929
6971
|
log.warn(`agent-shim: ${error.message}`);
|
|
6930
6972
|
}
|
|
6931
6973
|
}
|
|
6932
|
-
const identityCredentialBlock = loadedIdentity?.config.credential;
|
|
6933
|
-
const identityResolution =
|
|
6974
|
+
const identityCredentialBlock = selectedProvider === void 0 && farmIdentity !== void 0 ? loadedIdentity?.config.credential : void 0;
|
|
6975
|
+
const identityResolution = !readOnly && identityCredentialBlock !== void 0 && farmIdentity !== void 0 ? resolveIdentityCredential(farmIdentity, identityCredentialBlock, env, params.credentials) : void 0;
|
|
6934
6976
|
if (identityResolution !== void 0 && !identityResolution.ok) {
|
|
6935
6977
|
log.error(identityResolution.message);
|
|
6936
6978
|
proc.exit(identityResolution.status);
|
|
@@ -6944,25 +6986,97 @@ function prepareLaunch(params) {
|
|
|
6944
6986
|
allowAmbientCredential: loadedIdentity?.config.allowAmbientCredential ?? false,
|
|
6945
6987
|
allowAmbientCredentialOverride: parseEnvBool("AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL", env.AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL) === true,
|
|
6946
6988
|
identityName: identityDecision.name,
|
|
6947
|
-
providerSelected:
|
|
6989
|
+
providerSelected: selectedProvider !== void 0,
|
|
6948
6990
|
...identityCredential === void 0 ? {} : { injectedCredential: { variable: CREDENTIAL_TARGET_VARS[identityCredential.target], token: identityCredential.token } }
|
|
6949
6991
|
});
|
|
6950
6992
|
if (!guardResult.ok) {
|
|
6951
|
-
|
|
6952
|
-
|
|
6993
|
+
if (readOnly && identityCredentialBlock !== void 0) {
|
|
6994
|
+
log.warn(`${guardResult.message} (not resolved here: the launch proceeds only if that value is the identity's own injected credential)`);
|
|
6995
|
+
} else {
|
|
6996
|
+
log.error(guardResult.message);
|
|
6997
|
+
proc.exit(1);
|
|
6998
|
+
}
|
|
6953
6999
|
}
|
|
7000
|
+
const launchCascade = farmContext?.cascade ?? (params.farm === void 0 ? void 0 : params.farm.loadCascade(configProfileDecision.name, cliOverride));
|
|
7001
|
+
let cascadeLaunch;
|
|
7002
|
+
if (launchCascade !== void 0 && params.farm !== void 0) {
|
|
7003
|
+
const assembled = assembleCascade(launchCascade);
|
|
7004
|
+
const flattened = flattenLayers(assembled.layers, { home: params.farm.home });
|
|
7005
|
+
cascadeLaunch = flattened.launch;
|
|
7006
|
+
if (readOnly) {
|
|
7007
|
+
for (const diagnostic of [...assembled.diagnostics, ...flattened.diagnostics]) {
|
|
7008
|
+
if (diagnostic.severity !== "info") {
|
|
7009
|
+
log.warn(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
|
|
7010
|
+
}
|
|
7011
|
+
}
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
|
|
7015
|
+
const discovered = params.resolveClaudeBinary(pinnedVersion === void 0 ? void 0 : { version: pinnedVersion.version });
|
|
7016
|
+
const flags = resolveLaunchFlags({
|
|
7017
|
+
env,
|
|
7018
|
+
// A pool pick reads the usage the front door records, so a pool launch records its own unless something says otherwise.
|
|
7019
|
+
...poolExplanation === void 0 ? {} : { trackUsageDefault: true },
|
|
7020
|
+
...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
|
|
7021
|
+
flags: {
|
|
7022
|
+
...parsedArgv.skipPermissions === void 0 ? {} : { skipPermissions: parsedArgv.skipPermissions },
|
|
7023
|
+
...parsedArgv.remoteControl === void 0 ? {} : { remoteControl: parsedArgv.remoteControl },
|
|
7024
|
+
...parsedArgv.headroom === void 0 ? {} : { headroom: parsedArgv.headroom },
|
|
7025
|
+
...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
|
|
7026
|
+
}
|
|
7027
|
+
});
|
|
7028
|
+
const args = buildArgv({
|
|
7029
|
+
toolFlags: buildFlagArgs(flags),
|
|
7030
|
+
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
7031
|
+
passthrough: parsedArgv.rest
|
|
7032
|
+
});
|
|
7033
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path33.default.join(paths.identitiesDir, identityDecision.name);
|
|
7034
|
+
const decision = {
|
|
7035
|
+
identitySource: identityDecision.source,
|
|
7036
|
+
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
7037
|
+
configProfileSource: configProfileDecision.source,
|
|
7038
|
+
...identityDecision.name === void 0 ? {} : { identity: identityDecision.name },
|
|
7039
|
+
...poolPick === void 0 ? {} : { pool: poolPick },
|
|
7040
|
+
...configDir === void 0 || configDir === "" ? {} : { configDir },
|
|
7041
|
+
...configProfileDecision.name === void 0 ? {} : { configProfile: configProfileDecision.name },
|
|
7042
|
+
...selectedProvider === void 0 ? {} : { provider: selectedProvider.name }
|
|
7043
|
+
};
|
|
7044
|
+
return {
|
|
7045
|
+
parsedArgv,
|
|
7046
|
+
identityDecision,
|
|
7047
|
+
poolExplanation,
|
|
7048
|
+
poolPick,
|
|
7049
|
+
configDirEscapeHatch: configDirEscapeHatchApplies,
|
|
7050
|
+
farmIdentity,
|
|
7051
|
+
farmContext,
|
|
7052
|
+
configProfileDecision,
|
|
7053
|
+
provider: selectedProvider,
|
|
7054
|
+
resolvedProvider,
|
|
7055
|
+
identityCredentialBlock,
|
|
7056
|
+
identityCredential,
|
|
7057
|
+
pinnedVersion,
|
|
7058
|
+
flags,
|
|
7059
|
+
bin: discovered.path,
|
|
7060
|
+
args,
|
|
7061
|
+
decision
|
|
7062
|
+
};
|
|
7063
|
+
}
|
|
7064
|
+
function prepareLaunch(params) {
|
|
7065
|
+
const { paths, proc, log } = params;
|
|
7066
|
+
const { env } = proc;
|
|
7067
|
+
const decided = decideLaunch(params, false);
|
|
7068
|
+
const { identityDecision, configProfileDecision, resolvedProvider, identityCredential, poolExplanation, flags: resolvedFlags, args: finalArgv, configDirEscapeHatch: configDirEscapeHatchApplies, decision } = decided;
|
|
6954
7069
|
log.info(
|
|
6955
7070
|
`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)}`)
|
|
6956
7071
|
);
|
|
6957
7072
|
const updateCheck = runLaunchUpdateCheck({
|
|
6958
7073
|
mode: params.updateMode ?? "off",
|
|
6959
|
-
checkPath:
|
|
7074
|
+
checkPath: import_node_path33.default.join(paths.root, "update.check"),
|
|
6960
7075
|
currentVersion: package_default.version,
|
|
6961
7076
|
port: params.update
|
|
6962
7077
|
});
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = farmContext;
|
|
7078
|
+
if (decided.farmContext !== void 0) {
|
|
7079
|
+
const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = decided.farmContext;
|
|
6966
7080
|
let result;
|
|
6967
7081
|
try {
|
|
6968
7082
|
result = resyncFarm({
|
|
@@ -6999,27 +7113,10 @@ function prepareLaunch(params) {
|
|
|
6999
7113
|
log.info(
|
|
7000
7114
|
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}`})`
|
|
7001
7115
|
);
|
|
7002
|
-
cascadeLaunch = result.resolved.flattened.launch;
|
|
7003
|
-
} else if (params.farm !== void 0) {
|
|
7004
|
-
cascadeLaunch = flattenLayers(assembleCascade(params.farm.loadCascade(configProfileDecision.name, cliOverride)).layers, { home: params.farm.home }).launch;
|
|
7005
7116
|
}
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
if (pinnedVersion !== void 0) {
|
|
7009
|
-
log.info(`agent-shim: Claude Code ${pinnedVersion.version} (pinned by ${pinnedVersion.source})`);
|
|
7117
|
+
if (decided.pinnedVersion !== void 0) {
|
|
7118
|
+
log.info(`agent-shim: Claude Code ${decided.pinnedVersion.version} (pinned by ${decided.pinnedVersion.source})`);
|
|
7010
7119
|
}
|
|
7011
|
-
const resolvedFlags = resolveLaunchFlags({
|
|
7012
|
-
env,
|
|
7013
|
-
// A pool pick reads the usage the front door records, so a pool launch records its own unless something says otherwise.
|
|
7014
|
-
...poolExplanation === void 0 ? {} : { trackUsageDefault: true },
|
|
7015
|
-
...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
|
|
7016
|
-
flags: {
|
|
7017
|
-
...parsedArgv.skipPermissions === void 0 ? {} : { skipPermissions: parsedArgv.skipPermissions },
|
|
7018
|
-
...parsedArgv.remoteControl === void 0 ? {} : { remoteControl: parsedArgv.remoteControl },
|
|
7019
|
-
...parsedArgv.headroom === void 0 ? {} : { headroom: parsedArgv.headroom },
|
|
7020
|
-
...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
|
|
7021
|
-
}
|
|
7022
|
-
});
|
|
7023
7120
|
const frontDoorPort = params.frontdoor;
|
|
7024
7121
|
const frontDoorEngaged = resolvedProvider !== void 0 || resolvedFlags.headroom || resolvedFlags.trackUsage;
|
|
7025
7122
|
if (frontDoorEngaged && frontDoorPort === void 0) {
|
|
@@ -7043,11 +7140,6 @@ function prepareLaunch(params) {
|
|
|
7043
7140
|
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})`}`);
|
|
7044
7141
|
}
|
|
7045
7142
|
const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
|
|
7046
|
-
const finalArgv = buildArgv({
|
|
7047
|
-
toolFlags: buildFlagArgs(resolvedFlags),
|
|
7048
|
-
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
7049
|
-
passthrough: parsedArgv.rest
|
|
7050
|
-
});
|
|
7051
7143
|
const finalEnv = buildEnv({
|
|
7052
7144
|
baseEnv: env,
|
|
7053
7145
|
configDirEscapeHatch: configDirEscapeHatchApplies,
|
|
@@ -7065,18 +7157,35 @@ function prepareLaunch(params) {
|
|
|
7065
7157
|
registered();
|
|
7066
7158
|
}
|
|
7067
7159
|
};
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7160
|
+
return { bin: decided.bin, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
|
|
7161
|
+
}
|
|
7162
|
+
function resolveLaunch(params) {
|
|
7163
|
+
const decided = decideLaunch(params, true);
|
|
7164
|
+
const { env } = params.proc;
|
|
7165
|
+
const frontDoor = decided.provider !== void 0 || decided.flags.headroom || decided.flags.trackUsage;
|
|
7166
|
+
const built = buildEnv({
|
|
7167
|
+
baseEnv: env,
|
|
7168
|
+
configDirEscapeHatch: decided.configDirEscapeHatch,
|
|
7169
|
+
resolvedIdentityName: decided.identityDecision.name,
|
|
7170
|
+
identitiesDir: params.paths.identitiesDir,
|
|
7171
|
+
...decided.provider === void 0 ? {} : { provider: decided.provider },
|
|
7172
|
+
...frontDoor ? { frontdoor: { port: 0, connectPort: 0, trustBundlePath: "", sessionToken: "" } } : {},
|
|
7173
|
+
...decided.flags.headroom ? { headroom: { socketPath: "", projectId: "" } } : {},
|
|
7174
|
+
sessionId: ""
|
|
7175
|
+
});
|
|
7176
|
+
const credentialNames = decided.identityCredentialBlock === void 0 ? [] : Object.keys(credentialVariables(decided.identityCredentialBlock.target ?? "bearer", ""));
|
|
7177
|
+
const environment = [.../* @__PURE__ */ new Set([...Object.keys(built).filter((name) => built[name] !== env[name]), ...credentialNames])].sort();
|
|
7178
|
+
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;
|
|
7179
|
+
return {
|
|
7180
|
+
decision: decided.decision,
|
|
7181
|
+
flags: decided.flags,
|
|
7182
|
+
...decided.pinnedVersion === void 0 ? {} : { claudeVersion: decided.pinnedVersion },
|
|
7183
|
+
bin: decided.bin,
|
|
7184
|
+
args: decided.args,
|
|
7185
|
+
...credential === void 0 ? {} : { credential },
|
|
7186
|
+
routing: { frontDoor, headroom: decided.flags.headroom },
|
|
7187
|
+
environment
|
|
7078
7188
|
};
|
|
7079
|
-
return { bin: discovered.path, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
|
|
7080
7189
|
}
|
|
7081
7190
|
function runLaunchPlan(plan, spawn2) {
|
|
7082
7191
|
try {
|
|
@@ -7093,12 +7202,12 @@ function runLaunchPlan(plan, spawn2) {
|
|
|
7093
7202
|
function runLauncher(params) {
|
|
7094
7203
|
params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
|
|
7095
7204
|
}
|
|
7096
|
-
var import_node_crypto10,
|
|
7205
|
+
var import_node_crypto10, import_node_path33;
|
|
7097
7206
|
var init_launcher = __esm({
|
|
7098
7207
|
"src/launcher.ts"() {
|
|
7099
7208
|
"use strict";
|
|
7100
7209
|
import_node_crypto10 = require("node:crypto");
|
|
7101
|
-
|
|
7210
|
+
import_node_path33 = __toESM(require("node:path"), 1);
|
|
7102
7211
|
init_package();
|
|
7103
7212
|
init_envBool();
|
|
7104
7213
|
init_argv();
|
|
@@ -7129,13 +7238,13 @@ function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string"
|
|
|
7129
7238
|
if (distDir === void 0) {
|
|
7130
7239
|
throw new OwnCliPathUnknownError();
|
|
7131
7240
|
}
|
|
7132
|
-
return
|
|
7241
|
+
return import_node_path34.default.join(distDir, OWN_CLI_FILE_NAME);
|
|
7133
7242
|
}
|
|
7134
|
-
var
|
|
7243
|
+
var import_node_path34, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
7135
7244
|
var init_ownCli = __esm({
|
|
7136
7245
|
"src/ownCli.ts"() {
|
|
7137
7246
|
"use strict";
|
|
7138
|
-
|
|
7247
|
+
import_node_path34 = __toESM(require("node:path"), 1);
|
|
7139
7248
|
init_cliError();
|
|
7140
7249
|
OWN_CLI_FILE_NAME = "cli.cjs";
|
|
7141
7250
|
OwnCliPathUnknownError = class extends CliError {
|
|
@@ -7220,7 +7329,7 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
|
|
|
7220
7329
|
// src/frontdoor/trust.ts
|
|
7221
7330
|
function resolveTrustBundle(params) {
|
|
7222
7331
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
|
|
7223
|
-
if (inherited === void 0 || inherited === "" ||
|
|
7332
|
+
if (inherited === void 0 || inherited === "" || import_node_path35.default.resolve(inherited) === import_node_path35.default.resolve(caCertFile)) {
|
|
7224
7333
|
return { path: caCertFile };
|
|
7225
7334
|
}
|
|
7226
7335
|
const caPem = fs12.readFileUtf8(caCertFile);
|
|
@@ -7238,19 +7347,19 @@ function resolveTrustBundle(params) {
|
|
|
7238
7347
|
}
|
|
7239
7348
|
const combined = `${inheritedPem.trimEnd()}
|
|
7240
7349
|
${caPem}`;
|
|
7241
|
-
const bundle =
|
|
7350
|
+
const bundle = import_node_path35.default.join(bundlesDir, `${(0, import_node_crypto11.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
7242
7351
|
if (!fs12.exists(bundle)) {
|
|
7243
7352
|
fs12.mkdirp(bundlesDir);
|
|
7244
7353
|
fs12.writeFileAtomic(bundle, combined);
|
|
7245
7354
|
}
|
|
7246
7355
|
return { path: bundle };
|
|
7247
7356
|
}
|
|
7248
|
-
var import_node_crypto11,
|
|
7357
|
+
var import_node_crypto11, import_node_path35, BUNDLE_NAME_HEX_DIGITS;
|
|
7249
7358
|
var init_trust = __esm({
|
|
7250
7359
|
"src/frontdoor/trust.ts"() {
|
|
7251
7360
|
"use strict";
|
|
7252
7361
|
import_node_crypto11 = require("node:crypto");
|
|
7253
|
-
|
|
7362
|
+
import_node_path35 = __toESM(require("node:path"), 1);
|
|
7254
7363
|
BUNDLE_NAME_HEX_DIGITS = 16;
|
|
7255
7364
|
}
|
|
7256
7365
|
});
|
|
@@ -7395,6 +7504,31 @@ function prepareClaudeLaunch(options) {
|
|
|
7395
7504
|
const spawnDaemon = daemonSpawnerFor(options.agentShim);
|
|
7396
7505
|
return prepareLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) }));
|
|
7397
7506
|
}
|
|
7507
|
+
function resolveClaudeLaunch(options) {
|
|
7508
|
+
const paths = options.paths ?? resolveLayoutPaths();
|
|
7509
|
+
const refusals = [];
|
|
7510
|
+
const warnings = [];
|
|
7511
|
+
const log = {
|
|
7512
|
+
info: () => void 0,
|
|
7513
|
+
warn: (message) => {
|
|
7514
|
+
warnings.push(message);
|
|
7515
|
+
},
|
|
7516
|
+
error: (message) => {
|
|
7517
|
+
refusals.push(message);
|
|
7518
|
+
}
|
|
7519
|
+
};
|
|
7520
|
+
const proc = {
|
|
7521
|
+
env: options.env,
|
|
7522
|
+
argv: options.argv,
|
|
7523
|
+
exit: (code) => {
|
|
7524
|
+
throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
|
|
7525
|
+
}
|
|
7526
|
+
};
|
|
7527
|
+
const spawnDaemon = () => {
|
|
7528
|
+
throw new Error("resolving a launch starts no daemon");
|
|
7529
|
+
};
|
|
7530
|
+
return { resolution: resolveLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) })), warnings };
|
|
7531
|
+
}
|
|
7398
7532
|
var import_node_os7, import_node_crypto12, LaunchRefusedError;
|
|
7399
7533
|
var init_launchWiring = __esm({
|
|
7400
7534
|
"src/launchWiring.ts"() {
|
|
@@ -7563,11 +7697,11 @@ var init_anthropicUsageRefresh = __esm({
|
|
|
7563
7697
|
});
|
|
7564
7698
|
|
|
7565
7699
|
// src/usage/providerQuota.ts
|
|
7566
|
-
var
|
|
7700
|
+
var import_zod22, 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;
|
|
7567
7701
|
var init_providerQuota = __esm({
|
|
7568
7702
|
"src/usage/providerQuota.ts"() {
|
|
7569
7703
|
"use strict";
|
|
7570
|
-
|
|
7704
|
+
import_zod22 = require("zod");
|
|
7571
7705
|
init_schema2();
|
|
7572
7706
|
MS_PER_SECOND7 = 1e3;
|
|
7573
7707
|
SECONDS_PER_HOUR = 3600;
|
|
@@ -7581,35 +7715,35 @@ var init_providerQuota = __esm({
|
|
|
7581
7715
|
[ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
|
|
7582
7716
|
[ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7]
|
|
7583
7717
|
]);
|
|
7584
|
-
ZaiLimitSchema =
|
|
7585
|
-
type:
|
|
7586
|
-
unit:
|
|
7587
|
-
number:
|
|
7588
|
-
percentage:
|
|
7589
|
-
nextResetTime:
|
|
7590
|
-
usage:
|
|
7591
|
-
currentValue:
|
|
7592
|
-
remaining:
|
|
7718
|
+
ZaiLimitSchema = import_zod22.z.object({
|
|
7719
|
+
type: import_zod22.z.string(),
|
|
7720
|
+
unit: import_zod22.z.number().int(),
|
|
7721
|
+
number: import_zod22.z.number().int().positive(),
|
|
7722
|
+
percentage: import_zod22.z.number().nonnegative(),
|
|
7723
|
+
nextResetTime: import_zod22.z.number().positive().optional(),
|
|
7724
|
+
usage: import_zod22.z.number().nonnegative().optional(),
|
|
7725
|
+
currentValue: import_zod22.z.number().nonnegative().optional(),
|
|
7726
|
+
remaining: import_zod22.z.number().nonnegative().optional()
|
|
7593
7727
|
});
|
|
7594
|
-
ZaiResponseSchema =
|
|
7595
|
-
success:
|
|
7596
|
-
msg:
|
|
7597
|
-
data:
|
|
7728
|
+
ZaiResponseSchema = import_zod22.z.object({
|
|
7729
|
+
success: import_zod22.z.boolean(),
|
|
7730
|
+
msg: import_zod22.z.string().optional(),
|
|
7731
|
+
data: import_zod22.z.object({ level: import_zod22.z.string().optional(), limits: import_zod22.z.array(ZaiLimitSchema) })
|
|
7598
7732
|
});
|
|
7599
7733
|
OPENROUTER_HOST = "openrouter.ai";
|
|
7600
7734
|
OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
7601
7735
|
OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
7602
7736
|
MS_PER_DAY3 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7;
|
|
7603
|
-
OpenRouterKeySchema =
|
|
7604
|
-
data:
|
|
7605
|
-
limit:
|
|
7606
|
-
limit_remaining:
|
|
7607
|
-
limit_reset:
|
|
7608
|
-
is_free_tier:
|
|
7609
|
-
free_model_daily_requests:
|
|
7737
|
+
OpenRouterKeySchema = import_zod22.z.object({
|
|
7738
|
+
data: import_zod22.z.object({
|
|
7739
|
+
limit: import_zod22.z.number().nonnegative().nullable(),
|
|
7740
|
+
limit_remaining: import_zod22.z.number().nullable(),
|
|
7741
|
+
limit_reset: import_zod22.z.string().nullable(),
|
|
7742
|
+
is_free_tier: import_zod22.z.boolean().optional(),
|
|
7743
|
+
free_model_daily_requests: import_zod22.z.object({ used: import_zod22.z.number().nonnegative(), limit: import_zod22.z.number().nonnegative(), remaining: import_zod22.z.number() }).optional()
|
|
7610
7744
|
})
|
|
7611
7745
|
});
|
|
7612
|
-
OpenRouterCreditsSchema =
|
|
7746
|
+
OpenRouterCreditsSchema = import_zod22.z.object({ data: import_zod22.z.object({ total_credits: import_zod22.z.number().nonnegative(), total_usage: import_zod22.z.number().nonnegative() }) });
|
|
7613
7747
|
}
|
|
7614
7748
|
});
|
|
7615
7749
|
|
|
@@ -7741,6 +7875,9 @@ __export(index_exports, {
|
|
|
7741
7875
|
CheckReportJsonSchema: () => CheckReportJsonSchema,
|
|
7742
7876
|
CheckRunInputSchema: () => CheckRunInputSchema,
|
|
7743
7877
|
CliError: () => CliError,
|
|
7878
|
+
CodexLogoutOutputSchema: () => CodexLogoutOutputSchema,
|
|
7879
|
+
CodexSignInSchema: () => CodexSignInSchema,
|
|
7880
|
+
CodexStatusOutputSchema: () => CodexStatusOutputSchema,
|
|
7744
7881
|
ConfigProfileSchema: () => ConfigProfileSchema,
|
|
7745
7882
|
CredentialCacheSchema: () => CredentialCacheSchema,
|
|
7746
7883
|
CredentialSchema: () => CredentialSchema,
|
|
@@ -7765,6 +7902,7 @@ __export(index_exports, {
|
|
|
7765
7902
|
FARM_MANIFEST_FILENAME: () => FARM_MANIFEST_FILENAME,
|
|
7766
7903
|
FrontDoorControlMaterialError: () => FrontDoorControlMaterialError,
|
|
7767
7904
|
FrontDoorNotServingError: () => FrontDoorNotServingError,
|
|
7905
|
+
FrontDoorRestartOutputSchema: () => FrontDoorRestartOutputSchema,
|
|
7768
7906
|
FrontDoorSessionStatusSchema: () => FrontDoorSessionStatusSchema,
|
|
7769
7907
|
FrontDoorSessionsOutputSchema: () => FrontDoorSessionsOutputSchema,
|
|
7770
7908
|
FrontDoorStartError: () => FrontDoorStartError,
|
|
@@ -7782,6 +7920,8 @@ __export(index_exports, {
|
|
|
7782
7920
|
LAUNCH_EVENT_SOURCE: () => LAUNCH_EVENT_SOURCE,
|
|
7783
7921
|
LaunchLifecycleEventSchema: () => LaunchLifecycleEventSchema,
|
|
7784
7922
|
LaunchRefusedError: () => LaunchRefusedError,
|
|
7923
|
+
LaunchResolveInputSchema: () => LaunchResolveInputSchema,
|
|
7924
|
+
LaunchResolveOutputSchema: () => LaunchResolveOutputSchema,
|
|
7785
7925
|
LegacyProviderFileError: () => LegacyProviderFileError,
|
|
7786
7926
|
OWN_CLI_FILE_NAME: () => OWN_CLI_FILE_NAME,
|
|
7787
7927
|
PROMPT_CACHE_TTL_MS: () => PROMPT_CACHE_TTL_MS,
|
|
@@ -7828,6 +7968,7 @@ __export(index_exports, {
|
|
|
7828
7968
|
RcStreamEnvelopeSchema: () => RcStreamEnvelopeSchema,
|
|
7829
7969
|
RcStreamEventSchema: () => RcStreamEventSchema,
|
|
7830
7970
|
USAGE_EVENT_SOURCE: () => USAGE_EVENT_SOURCE,
|
|
7971
|
+
UpdateCheckOutputSchema: () => UpdateCheckOutputSchema,
|
|
7831
7972
|
UsageError: () => UsageError,
|
|
7832
7973
|
UsageListOutputSchema: () => UsageListOutputSchema,
|
|
7833
7974
|
UsageLiveOutputSchema: () => UsageLiveOutputSchema,
|
|
@@ -7870,14 +8011,17 @@ __export(index_exports, {
|
|
|
7870
8011
|
collectDoctorReport: () => collectDoctorReport,
|
|
7871
8012
|
collectFrontDoorStatus: () => collectFrontDoorStatus,
|
|
7872
8013
|
collectPoolPick: () => collectPoolPick,
|
|
8014
|
+
createCodexApiRouter: () => createCodexApiRouter,
|
|
7873
8015
|
createControlApiRouter: () => createControlApiRouter,
|
|
7874
8016
|
createDoorApiNodeHandler: () => createDoorApiNodeHandler,
|
|
7875
8017
|
createDoorApiRouter: () => createDoorApiRouter,
|
|
7876
8018
|
createDoorEventHub: () => createDoorEventHub,
|
|
7877
8019
|
createDoorHealthPublisher: () => createDoorHealthPublisher,
|
|
7878
8020
|
createEventsApiRouter: () => createEventsApiRouter,
|
|
8021
|
+
createLaunchApiRouter: () => createLaunchApiRouter,
|
|
7879
8022
|
createLaunchEventPublisher: () => createLaunchEventPublisher,
|
|
7880
8023
|
createLeafCache: () => createLeafCache,
|
|
8024
|
+
createLifecycleApiRouter: () => createLifecycleApiRouter,
|
|
7881
8025
|
createProfile: () => createProfile,
|
|
7882
8026
|
createQuotaExpiringPublisher: () => createQuotaExpiringPublisher,
|
|
7883
8027
|
createRcApiNodeHandler: () => createRcApiNodeHandler,
|
|
@@ -7985,7 +8129,9 @@ __export(index_exports, {
|
|
|
7985
8129
|
requirePool: () => requirePool,
|
|
7986
8130
|
resolveAgentShimHome: () => resolveAgentShimHome,
|
|
7987
8131
|
resolveClaudeHome: () => resolveClaudeHome,
|
|
8132
|
+
resolveClaudeLaunch: () => resolveClaudeLaunch,
|
|
7988
8133
|
resolveDecisions: () => resolveDecisions,
|
|
8134
|
+
resolveLaunch: () => resolveLaunch,
|
|
7989
8135
|
resolveLaunchSelection: () => resolveLaunchSelection,
|
|
7990
8136
|
resolveLayoutPaths: () => resolveLayoutPaths,
|
|
7991
8137
|
resolveSupervisorConfig: () => resolveSupervisorConfig,
|
|
@@ -8522,8 +8668,8 @@ function parseConnectTarget(authority) {
|
|
|
8522
8668
|
function isInterceptedHost(host, interceptHosts) {
|
|
8523
8669
|
return interceptHosts.includes(host);
|
|
8524
8670
|
}
|
|
8525
|
-
function servedByPipeline(
|
|
8526
|
-
return
|
|
8671
|
+
function servedByPipeline(path36) {
|
|
8672
|
+
return path36?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
8527
8673
|
}
|
|
8528
8674
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
8529
8675
|
"connection",
|
|
@@ -9057,11 +9203,11 @@ function createRcSessionTracker(deps) {
|
|
|
9057
9203
|
};
|
|
9058
9204
|
const observeExchange = (request4) => {
|
|
9059
9205
|
const method = (request4.method ?? "").toUpperCase();
|
|
9060
|
-
const
|
|
9061
|
-
if (!
|
|
9206
|
+
const path36 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
9207
|
+
if (!path36.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
9062
9208
|
return void 0;
|
|
9063
9209
|
}
|
|
9064
|
-
const tail =
|
|
9210
|
+
const tail = path36.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
9065
9211
|
const facts = {
|
|
9066
9212
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
9067
9213
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -9443,8 +9589,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
9443
9589
|
function isRcReadFileEncoding(value) {
|
|
9444
9590
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
9445
9591
|
}
|
|
9446
|
-
function buildRcReadFilePayload(requestId,
|
|
9447
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
9592
|
+
function buildRcReadFilePayload(requestId, path36, options) {
|
|
9593
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path36, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
9448
9594
|
}
|
|
9449
9595
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
9450
9596
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -9546,15 +9692,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
9546
9692
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
9547
9693
|
return result.ok ? { ...result, requestId } : result;
|
|
9548
9694
|
}
|
|
9549
|
-
async function readRcSessionFile(deps, sessionId,
|
|
9550
|
-
if (
|
|
9695
|
+
async function readRcSessionFile(deps, sessionId, path36, options) {
|
|
9696
|
+
if (path36 === "") {
|
|
9551
9697
|
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" };
|
|
9552
9698
|
}
|
|
9553
9699
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
9554
9700
|
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" };
|
|
9555
9701
|
}
|
|
9556
9702
|
const requestId = deps.newUuid();
|
|
9557
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
9703
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path36, options), `read ${path36} from session ${sessionId}`);
|
|
9558
9704
|
return result.ok ? { ...result, requestId } : result;
|
|
9559
9705
|
}
|
|
9560
9706
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -9723,11 +9869,11 @@ function createRcControlHandler(deps) {
|
|
|
9723
9869
|
path: "read-file",
|
|
9724
9870
|
read: (body) => {
|
|
9725
9871
|
const session = bodyString(body, "session");
|
|
9726
|
-
const
|
|
9872
|
+
const path36 = bodyString(body, "path");
|
|
9727
9873
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
9728
9874
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
9729
|
-
const refused2 = session === void 0 ||
|
|
9730
|
-
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,
|
|
9875
|
+
const refused2 = session === void 0 || path36 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
9876
|
+
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 } }) };
|
|
9731
9877
|
}
|
|
9732
9878
|
},
|
|
9733
9879
|
{
|
|
@@ -10037,9 +10183,9 @@ function requestIdOfBody(body) {
|
|
|
10037
10183
|
}
|
|
10038
10184
|
function frontDoorRcControl(transport, token) {
|
|
10039
10185
|
const headers = { authorization: `Bearer ${token}` };
|
|
10040
|
-
const listAnswerOf = async (
|
|
10186
|
+
const listAnswerOf = async (path36, what) => {
|
|
10041
10187
|
try {
|
|
10042
|
-
return await transport.request({ method: "GET", path:
|
|
10188
|
+
return await transport.request({ method: "GET", path: path36, headers });
|
|
10043
10189
|
} catch (error) {
|
|
10044
10190
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
10045
10191
|
}
|
|
@@ -10111,10 +10257,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
10111
10257
|
}
|
|
10112
10258
|
return pending;
|
|
10113
10259
|
};
|
|
10114
|
-
const writeOf = async (
|
|
10260
|
+
const writeOf = async (path36, body, describeFailure) => {
|
|
10115
10261
|
let answer;
|
|
10116
10262
|
try {
|
|
10117
|
-
answer = await transport.request({ method: "POST", path:
|
|
10263
|
+
answer = await transport.request({ method: "POST", path: path36, headers: { ...headers, "content-type": "application/json" }, body });
|
|
10118
10264
|
} catch (error) {
|
|
10119
10265
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
10120
10266
|
}
|
|
@@ -10145,10 +10291,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
10145
10291
|
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}`),
|
|
10146
10292
|
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}`),
|
|
10147
10293
|
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}`),
|
|
10148
|
-
readFile: async (sessionId,
|
|
10294
|
+
readFile: async (sessionId, path36, options) => await writeOf(
|
|
10149
10295
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
10150
|
-
JSON.stringify({ session: sessionId, path:
|
|
10151
|
-
(status, message) => `reading ${
|
|
10296
|
+
JSON.stringify({ session: sessionId, path: path36, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
10297
|
+
(status, message) => `reading ${path36} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
10152
10298
|
),
|
|
10153
10299
|
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}`),
|
|
10154
10300
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -10307,12 +10453,12 @@ function tlsFacts(options) {
|
|
|
10307
10453
|
}
|
|
10308
10454
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10309
10455
|
const agent = new ExemptTlsAgent();
|
|
10310
|
-
const post = async (
|
|
10456
|
+
const post = async (path36, headers, body) => await new Promise((resolve, reject) => {
|
|
10311
10457
|
const options = {
|
|
10312
10458
|
host: target.host,
|
|
10313
10459
|
port: target.port,
|
|
10314
10460
|
method: "POST",
|
|
10315
|
-
path:
|
|
10461
|
+
path: path36,
|
|
10316
10462
|
// 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.
|
|
10317
10463
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
10318
10464
|
agent
|
|
@@ -10377,12 +10523,12 @@ function lateRcStreamDial(resolve) {
|
|
|
10377
10523
|
}
|
|
10378
10524
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10379
10525
|
const agent = new ExemptTlsAgent();
|
|
10380
|
-
const request4 = async (method,
|
|
10526
|
+
const request4 = async (method, path36, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
10381
10527
|
const options = {
|
|
10382
10528
|
host: target.host,
|
|
10383
10529
|
port: target.port,
|
|
10384
10530
|
method,
|
|
10385
|
-
path:
|
|
10531
|
+
path: path36,
|
|
10386
10532
|
// 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.
|
|
10387
10533
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
10388
10534
|
agent,
|
|
@@ -10424,9 +10570,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
10424
10570
|
return { status, body: await readAll(response) };
|
|
10425
10571
|
},
|
|
10426
10572
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
10427
|
-
const
|
|
10573
|
+
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)}`;
|
|
10428
10574
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
10429
|
-
const { status, response } = await request4("GET",
|
|
10575
|
+
const { status, response } = await request4("GET", path36, streamHeaders, void 0, signal);
|
|
10430
10576
|
if (!isSuccessful2(status)) {
|
|
10431
10577
|
await readAll(response);
|
|
10432
10578
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -10926,41 +11072,41 @@ function createRcApiRouter(deps) {
|
|
|
10926
11072
|
};
|
|
10927
11073
|
return {
|
|
10928
11074
|
rc: {
|
|
10929
|
-
list: authed.
|
|
10930
|
-
status: authed.
|
|
11075
|
+
list: authed.meta((0, import_openapi.openapi)({ method: "GET", path: "/rest/rc/sessions", summary: "List the observed Remote Control sessions", tags: [RC_API_TAG] })).output(RcListOutputSchema).handler(() => ({ sessions: deps.list() })),
|
|
11076
|
+
status: authed.meta((0, import_openapi.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 }) => {
|
|
10931
11077
|
const statuses = deps.statusOf(input.session);
|
|
10932
11078
|
if (input.session !== void 0 && !statuses.some((entry) => entry.id === input.session)) {
|
|
10933
11079
|
throw new import_client.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
10934
11080
|
}
|
|
10935
11081
|
return { statuses };
|
|
10936
11082
|
}),
|
|
10937
|
-
pending: authed.
|
|
11083
|
+
pending: authed.meta((0, import_openapi.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 }) => {
|
|
10938
11084
|
const pending = deps.pendingOf(input.session);
|
|
10939
11085
|
if (input.session !== void 0 && deps.statusOf(input.session).length === 0) {
|
|
10940
11086
|
throw new import_client.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
10941
11087
|
}
|
|
10942
11088
|
return { pending };
|
|
10943
11089
|
}),
|
|
10944
|
-
send: authed.
|
|
10945
|
-
answer: authed.
|
|
11090
|
+
send: authed.meta((0, import_openapi.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)) })),
|
|
11091
|
+
answer: authed.meta((0, import_openapi.openapi)({ method: "POST", path: "/rest/rc/answer", summary: "Answer one pending control request", tags: [RC_API_TAG] })).input(RcAnswerInputSchema).output(RcAnswerOutputSchema).handler(async ({ input }) => {
|
|
10946
11092
|
const decision = { approve: input.approve, message: input.approve || input.text === void 0 ? void 0 : input.text };
|
|
10947
11093
|
return { session: input.session, request: input.request, sequenceNums: delivered(input.session, await deps.answer(input.session, input.request, decision)) };
|
|
10948
11094
|
}),
|
|
10949
|
-
interrupt: authed.
|
|
10950
|
-
setModel: authed.
|
|
10951
|
-
setPermissionMode: authed.
|
|
10952
|
-
endSession: authed.
|
|
10953
|
-
getUsage: authed.
|
|
10954
|
-
getContextUsage: authed.
|
|
10955
|
-
readFile: authed.
|
|
10956
|
-
fileSuggestions: authed.
|
|
10957
|
-
keepAlive: authed.
|
|
10958
|
-
mcpStatus: authed.
|
|
10959
|
-
mcpReconnect: authed.
|
|
10960
|
-
mcpAuthenticate: authed.
|
|
10961
|
-
mcpOAuthCallbackUrl: authed.
|
|
10962
|
-
teleport: authed.
|
|
10963
|
-
subscribe: authed.
|
|
11095
|
+
interrupt: authed.meta((0, import_openapi.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)) })),
|
|
11096
|
+
setModel: authed.meta((0, import_openapi.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)) })),
|
|
11097
|
+
setPermissionMode: authed.meta((0, import_openapi.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)) })),
|
|
11098
|
+
endSession: authed.meta((0, import_openapi.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)) })),
|
|
11099
|
+
getUsage: authed.meta((0, import_openapi.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)) })),
|
|
11100
|
+
getContextUsage: authed.meta((0, import_openapi.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)) })),
|
|
11101
|
+
readFile: authed.meta((0, import_openapi.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 } })) })),
|
|
11102
|
+
fileSuggestions: authed.meta((0, import_openapi.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)) })),
|
|
11103
|
+
keepAlive: authed.meta((0, import_openapi.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)) })),
|
|
11104
|
+
mcpStatus: authed.meta((0, import_openapi.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)) })),
|
|
11105
|
+
mcpReconnect: authed.meta((0, import_openapi.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)) })),
|
|
11106
|
+
mcpAuthenticate: authed.meta((0, import_openapi.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)) })),
|
|
11107
|
+
mcpOAuthCallbackUrl: authed.meta((0, import_openapi.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)) })),
|
|
11108
|
+
teleport: authed.meta((0, import_openapi.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)) })),
|
|
11109
|
+
subscribe: authed.meta((0, import_openapi.openapi)({ method: "GET", path: "/rest/rc/events", summary: "Stream a session's Remote Control events (SSE)", tags: [RC_API_TAG] })).input(RcSessionQuerySchema).output((0, import_server2.eventIterator)(RcStreamEventSchema)).handler(async function* ({ input, signal }) {
|
|
10964
11110
|
const queue = [];
|
|
10965
11111
|
let wake;
|
|
10966
11112
|
const detach = deps.fanout.subscribe(input.session, (event) => {
|
|
@@ -11002,7 +11148,7 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
11002
11148
|
const rpcHandler = new import_node2.RPCHandler(router, { plugins });
|
|
11003
11149
|
const restHandler = new import_node.OpenAPIHandler(router, { plugins });
|
|
11004
11150
|
let document;
|
|
11005
|
-
const documentOf = async () => document ??= new import_openapi.OpenAPIGenerator().generate(router, { info: { title: "agent-shim front door API", version: package_default.version } });
|
|
11151
|
+
const documentOf = async () => document ??= new import_openapi.OpenAPIGenerator().generate(router, { base: { info: { title: "agent-shim front door API", version: package_default.version } } });
|
|
11006
11152
|
return {
|
|
11007
11153
|
pathPrefix: RC_ORPC_PATH_PREFIX,
|
|
11008
11154
|
handle: async (request4, response) => {
|
|
@@ -11025,11 +11171,15 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
11025
11171
|
}
|
|
11026
11172
|
return { matched: true };
|
|
11027
11173
|
}
|
|
11028
|
-
const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers
|
|
11174
|
+
const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers, afterResponse: (action) => {
|
|
11175
|
+
response.once("finish", action);
|
|
11176
|
+
} }, prefix: RC_ORPC_PATH_PREFIX });
|
|
11029
11177
|
if (rest.matched) {
|
|
11030
11178
|
return rest;
|
|
11031
11179
|
}
|
|
11032
|
-
return await rpcHandler.handle(request4, response, { context: { headers: request4.headers
|
|
11180
|
+
return await rpcHandler.handle(request4, response, { context: { headers: request4.headers, afterResponse: (action) => {
|
|
11181
|
+
response.once("finish", action);
|
|
11182
|
+
} }, prefix: RC_ORPC_PATH_PREFIX });
|
|
11033
11183
|
}
|
|
11034
11184
|
};
|
|
11035
11185
|
}
|
|
@@ -11039,10 +11189,12 @@ function createRcApiNodeHandler(deps) {
|
|
|
11039
11189
|
function frontDoorApiLink(port, ca, token) {
|
|
11040
11190
|
const dispatcher = new import_undici.Agent({ connect: { ca } });
|
|
11041
11191
|
return new import_fetch.RPCLink({
|
|
11042
|
-
|
|
11192
|
+
origin: `https://127.0.0.1:${String(port)}`,
|
|
11193
|
+
url: RC_ORPC_PATH_PREFIX,
|
|
11043
11194
|
headers: { authorization: `Bearer ${token}` },
|
|
11044
11195
|
// 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.
|
|
11045
|
-
fetch: async (
|
|
11196
|
+
fetch: async (url, init, options) => {
|
|
11197
|
+
const request4 = new Request(url, init);
|
|
11046
11198
|
const body = request4.body === null ? void 0 : Buffer.from(await request4.arrayBuffer());
|
|
11047
11199
|
const answered = await (0, import_undici.fetch)(request4.url, {
|
|
11048
11200
|
method: request4.method,
|
|
@@ -11064,7 +11216,8 @@ init_cliError();
|
|
|
11064
11216
|
init_realPorts();
|
|
11065
11217
|
|
|
11066
11218
|
// src/frontdoor/controlApi.ts
|
|
11067
|
-
var
|
|
11219
|
+
var import_client5 = require("@orpc/client");
|
|
11220
|
+
var import_openapi6 = require("@orpc/openapi");
|
|
11068
11221
|
|
|
11069
11222
|
// src/checkReport.ts
|
|
11070
11223
|
var import_node_os5 = __toESM(require("node:os"), 1);
|
|
@@ -11291,19 +11444,19 @@ function writePools(paths, pools) {
|
|
|
11291
11444
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
11292
11445
|
}
|
|
11293
11446
|
function poolCycleOf(pools, name) {
|
|
11294
|
-
const walk = (current,
|
|
11447
|
+
const walk = (current, path36) => {
|
|
11295
11448
|
for (const entry of pools[current]?.identities ?? []) {
|
|
11296
11449
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
11297
11450
|
if (nested === void 0) {
|
|
11298
11451
|
continue;
|
|
11299
11452
|
}
|
|
11300
11453
|
if (nested === name) {
|
|
11301
|
-
return [...
|
|
11454
|
+
return [...path36, nested];
|
|
11302
11455
|
}
|
|
11303
|
-
if (
|
|
11456
|
+
if (path36.includes(nested)) {
|
|
11304
11457
|
continue;
|
|
11305
11458
|
}
|
|
11306
|
-
const found = walk(nested, [...
|
|
11459
|
+
const found = walk(nested, [...path36, nested]);
|
|
11307
11460
|
if (found !== void 0) {
|
|
11308
11461
|
return found;
|
|
11309
11462
|
}
|
|
@@ -12874,9 +13027,48 @@ var DoctorRunOutputSchema = import_zod19.z.strictObject({
|
|
|
12874
13027
|
ok: import_zod19.z.boolean(),
|
|
12875
13028
|
findings: import_zod19.z.readonly(import_zod19.z.array(DoctorFindingSchema))
|
|
12876
13029
|
});
|
|
13030
|
+
var FrontDoorRestartOutputSchema = import_zod19.z.strictObject({
|
|
13031
|
+
action: import_zod19.z.literal("restarting"),
|
|
13032
|
+
previousPid: import_zod19.z.int().positive()
|
|
13033
|
+
});
|
|
13034
|
+
var UpdateCheckOutputSchema = import_zod19.z.strictObject({
|
|
13035
|
+
current: import_zod19.z.string(),
|
|
13036
|
+
latest: import_zod19.z.string(),
|
|
13037
|
+
action: import_zod19.z.enum(["current", "available", "updated"])
|
|
13038
|
+
});
|
|
13039
|
+
var CodexSignInSchema = import_zod19.z.discriminatedUnion("state", [
|
|
13040
|
+
import_zod19.z.strictObject({ state: import_zod19.z.literal("none") }),
|
|
13041
|
+
import_zod19.z.strictObject({ state: import_zod19.z.literal("signed-in"), email: import_zod19.z.string().optional(), planScope: import_zod19.z.boolean(), accessTokenExpiresAt: import_zod19.z.number() }),
|
|
13042
|
+
import_zod19.z.strictObject({ state: import_zod19.z.literal("unreadable"), message: import_zod19.z.string() })
|
|
13043
|
+
]);
|
|
13044
|
+
var CodexStatusOutputSchema = import_zod19.z.strictObject({
|
|
13045
|
+
signIn: CodexSignInSchema,
|
|
13046
|
+
codexProviders: import_zod19.z.readonly(import_zod19.z.array(import_zod19.z.string()))
|
|
13047
|
+
});
|
|
13048
|
+
var CodexLogoutOutputSchema = import_zod19.z.strictObject({
|
|
13049
|
+
hadGrant: import_zod19.z.boolean(),
|
|
13050
|
+
revoked: import_zod19.z.boolean()
|
|
13051
|
+
});
|
|
13052
|
+
|
|
13053
|
+
// src/frontdoor/codexApi.ts
|
|
13054
|
+
var import_openapi2 = require("@orpc/openapi");
|
|
13055
|
+
var CODEX_API_TAG = "codex";
|
|
13056
|
+
function createCodexApiRouter(deps) {
|
|
13057
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13058
|
+
return {
|
|
13059
|
+
codex: {
|
|
13060
|
+
status: authed.meta((0, import_openapi2.openapi)({ method: "GET", path: "/rest/codex/status", summary: "Read the Codex sign-in and the codex providers", tags: [CODEX_API_TAG] })).output(CodexStatusOutputSchema).handler(() => {
|
|
13061
|
+
const status = deps.codexStatus();
|
|
13062
|
+
return { signIn: status.signIn, codexProviders: status.codexProviders };
|
|
13063
|
+
}),
|
|
13064
|
+
logout: authed.meta((0, import_openapi2.openapi)({ 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())
|
|
13065
|
+
}
|
|
13066
|
+
};
|
|
13067
|
+
}
|
|
12877
13068
|
|
|
12878
13069
|
// src/frontdoor/eventsApi.ts
|
|
12879
13070
|
var import_client2 = require("@orpc/client");
|
|
13071
|
+
var import_openapi3 = require("@orpc/openapi");
|
|
12880
13072
|
var import_server3 = require("@orpc/server");
|
|
12881
13073
|
|
|
12882
13074
|
// src/frontdoor/eventSchemas.ts
|
|
@@ -12923,7 +13115,7 @@ function createEventsApiRouter(deps) {
|
|
|
12923
13115
|
const authed = doorApiAuth(deps.expectedToken);
|
|
12924
13116
|
return {
|
|
12925
13117
|
events: {
|
|
12926
|
-
subscribe: authed.
|
|
13118
|
+
subscribe: authed.meta((0, import_openapi3.openapi)({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] })).input(DoorEventSourceQuerySchema).output((0, import_server3.eventIterator)(DoorEventSchema)).handler(async function* ({ input, signal }) {
|
|
12927
13119
|
if (input.sources !== void 0) {
|
|
12928
13120
|
const live = deps.events.sources();
|
|
12929
13121
|
const unknown = input.sources.filter((source) => !live.includes(source));
|
|
@@ -12955,9 +13147,120 @@ function createEventsApiRouter(deps) {
|
|
|
12955
13147
|
};
|
|
12956
13148
|
}
|
|
12957
13149
|
|
|
13150
|
+
// src/frontdoor/lifecycleApi.ts
|
|
13151
|
+
var import_client3 = require("@orpc/client");
|
|
13152
|
+
var import_openapi4 = require("@orpc/openapi");
|
|
13153
|
+
init_update();
|
|
13154
|
+
var FRONTDOOR_API_TAG = "frontdoor";
|
|
13155
|
+
var UPDATE_API_TAG = "update";
|
|
13156
|
+
function createLifecycleApiRouter(deps) {
|
|
13157
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13158
|
+
return {
|
|
13159
|
+
frontdoor: {
|
|
13160
|
+
restart: authed.meta((0, import_openapi4.openapi)({ 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 }) => {
|
|
13161
|
+
context.afterResponse(deps.restartDoor);
|
|
13162
|
+
return { action: "restarting", previousPid: deps.doorPid };
|
|
13163
|
+
})
|
|
13164
|
+
},
|
|
13165
|
+
update: {
|
|
13166
|
+
check: authed.meta((0, import_openapi4.openapi)({ method: "GET", path: "/rest/update/check", summary: "Check whether a newer release exists", tags: [UPDATE_API_TAG] })).output(UpdateCheckOutputSchema).handler(async () => {
|
|
13167
|
+
try {
|
|
13168
|
+
return await deps.checkForUpdate();
|
|
13169
|
+
} catch (error) {
|
|
13170
|
+
if (error instanceof UpdateChannelError) {
|
|
13171
|
+
throw new import_client3.ORPCError("PRECONDITION_FAILED", { message: error.message });
|
|
13172
|
+
}
|
|
13173
|
+
if (error instanceof UpdateConflictError) {
|
|
13174
|
+
throw new import_client3.ORPCError("CONFLICT", { message: error.message });
|
|
13175
|
+
}
|
|
13176
|
+
if (error instanceof UpdateDownloadError) {
|
|
13177
|
+
throw new import_client3.ORPCError("BAD_GATEWAY", { message: error.message });
|
|
13178
|
+
}
|
|
13179
|
+
throw error;
|
|
13180
|
+
}
|
|
13181
|
+
})
|
|
13182
|
+
}
|
|
13183
|
+
};
|
|
13184
|
+
}
|
|
13185
|
+
|
|
13186
|
+
// src/frontdoor/launchApi.ts
|
|
13187
|
+
var import_client4 = require("@orpc/client");
|
|
13188
|
+
var import_openapi5 = require("@orpc/openapi");
|
|
13189
|
+
init_cliError();
|
|
13190
|
+
|
|
13191
|
+
// src/frontdoor/launchSchemas.ts
|
|
13192
|
+
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
13193
|
+
var import_zod21 = require("zod");
|
|
13194
|
+
init_claudeVersion();
|
|
13195
|
+
init_identity();
|
|
13196
|
+
var LaunchResolveInputSchema = import_zod21.z.strictObject({
|
|
13197
|
+
path: import_zod21.z.string().min(1),
|
|
13198
|
+
/** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
|
|
13199
|
+
argv: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string())).optional(),
|
|
13200
|
+
/** 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. */
|
|
13201
|
+
env: import_zod21.z.record(import_zod21.z.string(), import_zod21.z.string()).optional()
|
|
13202
|
+
}).refine((input) => import_node_path30.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
13203
|
+
var LaunchPoolDecisionSchema = import_zod21.z.strictObject({
|
|
13204
|
+
name: import_zod21.z.string(),
|
|
13205
|
+
reasons: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string())),
|
|
13206
|
+
movedOff: import_zod21.z.strictObject({ identity: import_zod21.z.string(), reason: import_zod21.z.string() }).optional()
|
|
13207
|
+
});
|
|
13208
|
+
var LaunchDecisionSchema = import_zod21.z.strictObject({
|
|
13209
|
+
identity: import_zod21.z.string().optional(),
|
|
13210
|
+
identitySource: import_zod21.z.enum(IDENTITY_DECISION_SOURCES),
|
|
13211
|
+
pool: LaunchPoolDecisionSchema.optional(),
|
|
13212
|
+
configDirEscapeHatch: import_zod21.z.boolean(),
|
|
13213
|
+
configDir: import_zod21.z.string().optional(),
|
|
13214
|
+
configProfile: import_zod21.z.string().optional(),
|
|
13215
|
+
configProfileSource: import_zod21.z.enum(CONFIG_PROFILE_DECISION_SOURCES),
|
|
13216
|
+
provider: import_zod21.z.string().optional()
|
|
13217
|
+
});
|
|
13218
|
+
var LaunchFlagsSchema = import_zod21.z.strictObject({
|
|
13219
|
+
skipPermissions: import_zod21.z.boolean(),
|
|
13220
|
+
remoteControl: import_zod21.z.boolean(),
|
|
13221
|
+
headroom: import_zod21.z.boolean(),
|
|
13222
|
+
trackUsage: import_zod21.z.boolean()
|
|
13223
|
+
});
|
|
13224
|
+
var LaunchResolveOutputSchema = import_zod21.z.strictObject({
|
|
13225
|
+
decision: LaunchDecisionSchema,
|
|
13226
|
+
flags: LaunchFlagsSchema,
|
|
13227
|
+
claudeVersion: import_zod21.z.strictObject({ version: import_zod21.z.string(), source: import_zod21.z.enum(CLAUDE_VERSION_SOURCES) }).optional(),
|
|
13228
|
+
/** The real `claude` binary the launch would spawn, on the door's host. */
|
|
13229
|
+
bin: import_zod21.z.string(),
|
|
13230
|
+
/** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
|
|
13231
|
+
args: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string())),
|
|
13232
|
+
/** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
|
|
13233
|
+
credential: import_zod21.z.strictObject({ subject: import_zod21.z.enum(["provider", "identity"]), name: import_zod21.z.string(), summary: CredentialSummarySchema }).optional(),
|
|
13234
|
+
routing: import_zod21.z.strictObject({ frontDoor: import_zod21.z.boolean(), headroom: import_zod21.z.boolean() }),
|
|
13235
|
+
/** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
|
|
13236
|
+
environment: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string())),
|
|
13237
|
+
warnings: import_zod21.z.readonly(import_zod21.z.array(import_zod21.z.string()))
|
|
13238
|
+
});
|
|
13239
|
+
|
|
13240
|
+
// src/frontdoor/launchApi.ts
|
|
13241
|
+
var LAUNCH_API_TAG = "launch";
|
|
13242
|
+
function createLaunchApiRouter(deps) {
|
|
13243
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13244
|
+
return {
|
|
13245
|
+
launch: {
|
|
13246
|
+
resolve: authed.meta((0, import_openapi5.openapi)({ 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 }) => {
|
|
13247
|
+
try {
|
|
13248
|
+
const { resolution, warnings } = deps.resolveLaunch({ path: input.path, argv: input.argv ?? [], env: input.env ?? {} });
|
|
13249
|
+
return { ...resolution, warnings };
|
|
13250
|
+
} catch (error) {
|
|
13251
|
+
if (error instanceof CliError) {
|
|
13252
|
+
throw new import_client4.ORPCError("BAD_REQUEST", { message: error.message });
|
|
13253
|
+
}
|
|
13254
|
+
throw error;
|
|
13255
|
+
}
|
|
13256
|
+
})
|
|
13257
|
+
}
|
|
13258
|
+
};
|
|
13259
|
+
}
|
|
13260
|
+
|
|
12958
13261
|
// src/frontdoor/controlApi.ts
|
|
12959
13262
|
var USAGE_API_TAG = "usage";
|
|
12960
|
-
var
|
|
13263
|
+
var FRONTDOOR_API_TAG2 = "frontdoor";
|
|
12961
13264
|
var CHECK_API_TAG = "check";
|
|
12962
13265
|
var DOCTOR_API_TAG = "doctor";
|
|
12963
13266
|
var POOL_API_TAG = "pool";
|
|
@@ -12965,11 +13268,11 @@ function createControlApiRouter(deps) {
|
|
|
12965
13268
|
const authed = doorApiAuth(deps.expectedToken);
|
|
12966
13269
|
return {
|
|
12967
13270
|
usage: {
|
|
12968
|
-
list: authed.
|
|
12969
|
-
effectiveWindow: authed.
|
|
13271
|
+
list: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
|
|
13272
|
+
effectiveWindow: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
|
|
12970
13273
|
const snapshot = deps.usageSnapshotOf(input.identity);
|
|
12971
13274
|
if (snapshot === void 0) {
|
|
12972
|
-
throw new
|
|
13275
|
+
throw new import_client5.ORPCError("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
|
|
12973
13276
|
}
|
|
12974
13277
|
const provider = input.provider ?? ANTHROPIC_PROVIDER;
|
|
12975
13278
|
const rateLimit = snapshot.providers[provider]?.rateLimit;
|
|
@@ -12983,34 +13286,34 @@ function createControlApiRouter(deps) {
|
|
|
12983
13286
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
12984
13287
|
};
|
|
12985
13288
|
}),
|
|
12986
|
-
live: authed.
|
|
13289
|
+
live: authed.meta((0, import_openapi6.openapi)({ 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 }) => {
|
|
12987
13290
|
const sessions = deps.liveRateLimits(input.session);
|
|
12988
13291
|
if (input.session !== void 0 && sessions.length === 0) {
|
|
12989
13292
|
if (deps.list().some((session) => session.id === input.session)) {
|
|
12990
|
-
throw new
|
|
13293
|
+
throw new import_client5.ORPCError("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` });
|
|
12991
13294
|
}
|
|
12992
|
-
throw new
|
|
13295
|
+
throw new import_client5.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
12993
13296
|
}
|
|
12994
13297
|
return { latest: deps.latestRateLimit(), sessions };
|
|
12995
13298
|
})
|
|
12996
13299
|
},
|
|
12997
13300
|
frontdoor: {
|
|
12998
|
-
status: authed.
|
|
12999
|
-
sessions: authed.
|
|
13301
|
+
status: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
|
|
13302
|
+
sessions: authed.meta((0, import_openapi6.openapi)({ 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 }))
|
|
13000
13303
|
},
|
|
13001
13304
|
check: {
|
|
13002
13305
|
// 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.
|
|
13003
|
-
run: authed.
|
|
13306
|
+
run: authed.meta((0, import_openapi6.openapi)({ 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)))
|
|
13004
13307
|
},
|
|
13005
13308
|
doctor: {
|
|
13006
|
-
run: authed.
|
|
13309
|
+
run: authed.meta((0, import_openapi6.openapi)({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
|
|
13007
13310
|
},
|
|
13008
13311
|
pool: {
|
|
13009
|
-
pick: authed.
|
|
13312
|
+
pick: authed.meta((0, import_openapi6.openapi)({ 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 }) => {
|
|
13010
13313
|
const report = deps.poolPick(input.pool, input.path);
|
|
13011
13314
|
if (report === void 0) {
|
|
13012
13315
|
const live = deps.poolNames();
|
|
13013
|
-
throw new
|
|
13316
|
+
throw new import_client5.ORPCError("NOT_FOUND", {
|
|
13014
13317
|
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(", ")}`
|
|
13015
13318
|
});
|
|
13016
13319
|
}
|
|
@@ -13020,13 +13323,15 @@ function createControlApiRouter(deps) {
|
|
|
13020
13323
|
};
|
|
13021
13324
|
}
|
|
13022
13325
|
function createDoorApiRouter(deps) {
|
|
13023
|
-
|
|
13326
|
+
const control = createControlApiRouter(deps);
|
|
13327
|
+
const lifecycle = createLifecycleApiRouter(deps);
|
|
13328
|
+
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
13024
13329
|
}
|
|
13025
13330
|
function createDoorApiNodeHandler(deps) {
|
|
13026
13331
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
13027
13332
|
}
|
|
13028
13333
|
function frontDoorApiClient(port, ca, token) {
|
|
13029
|
-
return (0,
|
|
13334
|
+
return (0, import_client5.createORPCClient)(frontDoorApiLink(port, ca, token));
|
|
13030
13335
|
}
|
|
13031
13336
|
|
|
13032
13337
|
// src/frontdoor/doorClient.ts
|
|
@@ -14980,7 +15285,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
14980
15285
|
}
|
|
14981
15286
|
|
|
14982
15287
|
// src/frontdoor/rcSelfHostMint.ts
|
|
14983
|
-
var
|
|
15288
|
+
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
14984
15289
|
init_account();
|
|
14985
15290
|
var CREDENTIALS_FILE = ".credentials.json";
|
|
14986
15291
|
var CLAUDE_JSON2 = ".claude.json";
|
|
@@ -15005,7 +15310,7 @@ function readJsonObject(fs12, file) {
|
|
|
15005
15310
|
return isRecord11(parsed) ? parsed : void 0;
|
|
15006
15311
|
}
|
|
15007
15312
|
function readRcSelfHostRecord(fs12, frontdoorDir) {
|
|
15008
|
-
const parsed = readJsonObject(fs12,
|
|
15313
|
+
const parsed = readJsonObject(fs12, import_node_path31.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
15009
15314
|
if (parsed === void 0) {
|
|
15010
15315
|
return void 0;
|
|
15011
15316
|
}
|
|
@@ -15019,11 +15324,11 @@ function mintRcSelfHostCredential(deps) {
|
|
|
15019
15324
|
if (!isIdentityName(deps.identity)) {
|
|
15020
15325
|
throw new Error(`"${deps.identity}" is not a valid identity name.`);
|
|
15021
15326
|
}
|
|
15022
|
-
const identityDir =
|
|
15023
|
-
const credentialsFile =
|
|
15024
|
-
const claudeJsonFile =
|
|
15025
|
-
const recordDir =
|
|
15026
|
-
const recordFile =
|
|
15327
|
+
const identityDir = import_node_path31.default.join(deps.identitiesDir, deps.identity);
|
|
15328
|
+
const credentialsFile = import_node_path31.default.join(identityDir, CREDENTIALS_FILE);
|
|
15329
|
+
const claudeJsonFile = import_node_path31.default.join(identityDir, CLAUDE_JSON2);
|
|
15330
|
+
const recordDir = import_node_path31.default.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
|
|
15331
|
+
const recordFile = import_node_path31.default.join(recordDir, RC_SELF_HOST_RECORD_FILE);
|
|
15027
15332
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
15028
15333
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
15029
15334
|
const existingOauth = isRecord11(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
@@ -15039,7 +15344,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
15039
15344
|
const organizationUuid = deps.newUuid();
|
|
15040
15345
|
const accountUuid = deps.newUuid();
|
|
15041
15346
|
const mintedAt = new Date(deps.now()).toISOString();
|
|
15042
|
-
deps.fs.mkdirPrivate(
|
|
15347
|
+
deps.fs.mkdirPrivate(import_node_path31.default.dirname(credentialsFile));
|
|
15043
15348
|
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)}
|
|
15044
15349
|
`);
|
|
15045
15350
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|
|
@@ -15294,6 +15599,9 @@ init_ownCli();
|
|
|
15294
15599
|
CheckReportJsonSchema,
|
|
15295
15600
|
CheckRunInputSchema,
|
|
15296
15601
|
CliError,
|
|
15602
|
+
CodexLogoutOutputSchema,
|
|
15603
|
+
CodexSignInSchema,
|
|
15604
|
+
CodexStatusOutputSchema,
|
|
15297
15605
|
ConfigProfileSchema,
|
|
15298
15606
|
CredentialCacheSchema,
|
|
15299
15607
|
CredentialSchema,
|
|
@@ -15318,6 +15626,7 @@ init_ownCli();
|
|
|
15318
15626
|
FARM_MANIFEST_FILENAME,
|
|
15319
15627
|
FrontDoorControlMaterialError,
|
|
15320
15628
|
FrontDoorNotServingError,
|
|
15629
|
+
FrontDoorRestartOutputSchema,
|
|
15321
15630
|
FrontDoorSessionStatusSchema,
|
|
15322
15631
|
FrontDoorSessionsOutputSchema,
|
|
15323
15632
|
FrontDoorStartError,
|
|
@@ -15335,6 +15644,8 @@ init_ownCli();
|
|
|
15335
15644
|
LAUNCH_EVENT_SOURCE,
|
|
15336
15645
|
LaunchLifecycleEventSchema,
|
|
15337
15646
|
LaunchRefusedError,
|
|
15647
|
+
LaunchResolveInputSchema,
|
|
15648
|
+
LaunchResolveOutputSchema,
|
|
15338
15649
|
LegacyProviderFileError,
|
|
15339
15650
|
OWN_CLI_FILE_NAME,
|
|
15340
15651
|
PROMPT_CACHE_TTL_MS,
|
|
@@ -15381,6 +15692,7 @@ init_ownCli();
|
|
|
15381
15692
|
RcStreamEnvelopeSchema,
|
|
15382
15693
|
RcStreamEventSchema,
|
|
15383
15694
|
USAGE_EVENT_SOURCE,
|
|
15695
|
+
UpdateCheckOutputSchema,
|
|
15384
15696
|
UsageError,
|
|
15385
15697
|
UsageListOutputSchema,
|
|
15386
15698
|
UsageLiveOutputSchema,
|
|
@@ -15423,14 +15735,17 @@ init_ownCli();
|
|
|
15423
15735
|
collectDoctorReport,
|
|
15424
15736
|
collectFrontDoorStatus,
|
|
15425
15737
|
collectPoolPick,
|
|
15738
|
+
createCodexApiRouter,
|
|
15426
15739
|
createControlApiRouter,
|
|
15427
15740
|
createDoorApiNodeHandler,
|
|
15428
15741
|
createDoorApiRouter,
|
|
15429
15742
|
createDoorEventHub,
|
|
15430
15743
|
createDoorHealthPublisher,
|
|
15431
15744
|
createEventsApiRouter,
|
|
15745
|
+
createLaunchApiRouter,
|
|
15432
15746
|
createLaunchEventPublisher,
|
|
15433
15747
|
createLeafCache,
|
|
15748
|
+
createLifecycleApiRouter,
|
|
15434
15749
|
createProfile,
|
|
15435
15750
|
createQuotaExpiringPublisher,
|
|
15436
15751
|
createRcApiNodeHandler,
|
|
@@ -15538,7 +15853,9 @@ init_ownCli();
|
|
|
15538
15853
|
requirePool,
|
|
15539
15854
|
resolveAgentShimHome,
|
|
15540
15855
|
resolveClaudeHome,
|
|
15856
|
+
resolveClaudeLaunch,
|
|
15541
15857
|
resolveDecisions,
|
|
15858
|
+
resolveLaunch,
|
|
15542
15859
|
resolveLaunchSelection,
|
|
15543
15860
|
resolveLayoutPaths,
|
|
15544
15861
|
resolveSupervisorConfig,
|