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.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.
|
|
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
|
-
"@
|
|
2680
|
-
"@orpc/
|
|
2681
|
-
"@orpc/
|
|
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
|
|
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
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
|
6909
|
+
const providerParams = {
|
|
6879
6910
|
paths,
|
|
6880
6911
|
port: fs12,
|
|
6881
|
-
|
|
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
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
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,
|
|
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 =
|
|
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:
|
|
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
|
-
|
|
6927
|
-
|
|
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:
|
|
7049
|
+
checkPath: path33.join(paths.root, "update.check"),
|
|
6935
7050
|
currentVersion: package_default.version,
|
|
6936
7051
|
port: params.update
|
|
6937
7052
|
});
|
|
6938
|
-
|
|
6939
|
-
|
|
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
|
-
|
|
6982
|
-
|
|
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
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
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
|
|
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
|
|
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
|
|
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 === "" ||
|
|
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 =
|
|
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
|
|
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 =
|
|
7557
|
-
type:
|
|
7558
|
-
unit:
|
|
7559
|
-
number:
|
|
7560
|
-
percentage:
|
|
7561
|
-
nextResetTime:
|
|
7562
|
-
usage:
|
|
7563
|
-
currentValue:
|
|
7564
|
-
remaining:
|
|
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 =
|
|
7567
|
-
success:
|
|
7568
|
-
msg:
|
|
7569
|
-
data:
|
|
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 =
|
|
7576
|
-
data:
|
|
7577
|
-
limit:
|
|
7578
|
-
limit_remaining:
|
|
7579
|
-
limit_reset:
|
|
7580
|
-
is_free_tier:
|
|
7581
|
-
free_model_daily_requests:
|
|
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 =
|
|
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(
|
|
8201
|
-
return
|
|
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
|
|
8736
|
-
if (!
|
|
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 =
|
|
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,
|
|
9122
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
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,
|
|
9225
|
-
if (
|
|
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,
|
|
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
|
|
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 ||
|
|
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,
|
|
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 (
|
|
9849
|
+
const listAnswerOf = async (path36, what) => {
|
|
9716
9850
|
try {
|
|
9717
|
-
return await transport.request({ method: "GET", path:
|
|
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 (
|
|
9923
|
+
const writeOf = async (path36, body, describeFailure) => {
|
|
9790
9924
|
let answer;
|
|
9791
9925
|
try {
|
|
9792
|
-
answer = await transport.request({ method: "POST", path:
|
|
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,
|
|
9957
|
+
readFile: async (sessionId, path36, options) => await writeOf(
|
|
9824
9958
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
9825
|
-
JSON.stringify({ session: sessionId, path:
|
|
9826
|
-
(status, message) => `reading ${
|
|
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 (
|
|
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:
|
|
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,
|
|
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:
|
|
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
|
|
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",
|
|
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.
|
|
10605
|
-
status: authed.
|
|
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.
|
|
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.
|
|
10620
|
-
answer: authed.
|
|
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.
|
|
10625
|
-
setModel: authed.
|
|
10626
|
-
setPermissionMode: authed.
|
|
10627
|
-
endSession: authed.
|
|
10628
|
-
getUsage: authed.
|
|
10629
|
-
getContextUsage: authed.
|
|
10630
|
-
readFile: authed.
|
|
10631
|
-
fileSuggestions: authed.
|
|
10632
|
-
keepAlive: authed.
|
|
10633
|
-
mcpStatus: authed.
|
|
10634
|
-
mcpReconnect: authed.
|
|
10635
|
-
mcpAuthenticate: authed.
|
|
10636
|
-
mcpOAuthCallbackUrl: authed.
|
|
10637
|
-
teleport: authed.
|
|
10638
|
-
subscribe: authed.
|
|
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
|
|
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
|
|
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
|
-
|
|
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 (
|
|
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
|
|
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,
|
|
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 [...
|
|
11117
|
+
return [...path36, nested];
|
|
10977
11118
|
}
|
|
10978
|
-
if (
|
|
11119
|
+
if (path36.includes(nested)) {
|
|
10979
11120
|
continue;
|
|
10980
11121
|
}
|
|
10981
|
-
const found = walk(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.
|
|
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
|
|
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.
|
|
12644
|
-
effectiveWindow: authed.
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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.
|
|
12674
|
-
sessions: authed.
|
|
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.
|
|
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.
|
|
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.
|
|
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
|
|
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
|
-
|
|
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
|
|
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,
|
|
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 =
|
|
14698
|
-
const credentialsFile =
|
|
14699
|
-
const claudeJsonFile =
|
|
14700
|
-
const recordDir =
|
|
14701
|
-
const recordFile =
|
|
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(
|
|
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,
|