claude-use 9.5.1 → 9.7.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 +40802 -23017
- package/dist/index.cjs +1327 -414
- package/dist/index.mjs +1271 -405
- package/dist/types/index.d.ts +6095 -1756
- package/package.json +2 -1
package/dist/index.cjs
CHANGED
|
@@ -228,7 +228,7 @@ function isCodexProvider(provider) {
|
|
|
228
228
|
function poolMemberIdentity(member) {
|
|
229
229
|
return typeof member === "string" ? member : member.identity;
|
|
230
230
|
}
|
|
231
|
-
var import_node_path2, import_zod, import_trilean, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, CredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
|
|
231
|
+
var import_node_path2, import_zod, import_trilean, CATEGORY_NAMES, OVERRIDABLE_CATEGORIES, CategoryMapSchema, DURATION_RE, DurationSchema, WhenConditionObjectSchema, WhenSchema, EntryValueSchema, ENTRY_KEY_RE, EntriesSchema, LaunchSchema, CREDENTIAL_TARGETS, PROVIDER_CREDENTIAL_TARGETS, CREDENTIAL_TARGET_VARS, ArgvSchema, CommandSourceOptions, EnvCredentialSourceSchema, FileCredentialSourceSchema, CommandCredentialSourceSchema, OpCredentialSourceSchema, KeychainCredentialSourceSchema, LiteralCredentialSourceSchema, CredentialSourceSchema, RemoteCredentialSourceSchema, CREDENTIAL_CACHE_STORES, CredentialCacheSchema, CredentialSchema, ProviderCredentialSchema, RESERVED_PROVIDER_ENV_KEYS, ProviderEnvSchema, PROVIDER_KINDS, CODEX_EFFORTS, CODEX_LOGINS, CODEX_DEFAULT_TIER_MODELS, CodexProviderConfigSchema, ProviderRouteSchema, HttpProviderSchema, CodexProviderSchema, ProviderSchema, ConfigProfileSchema, POOL_SELECTOR_PREFIX, POOL_NAME_PATTERN, IDENTITY_NAME_PATTERN, PoolNameSchema, SELECTOR_RE, IdentitySelectorSchema, PoolMemberSchema, POOL_PREFERENCES, PoolPreferenceSchema, PoolSchema, DirectoryRuleSchema, DirectoryRulesSchema, PortableConfigSchema, HEADROOM_MODES, HEADROOM_CCR_MODES, HEADROOM_ROLLOUT_CHANNELS, INTERCEPT_CHANNELS, READ_MATURATION_CHANNELS, HeadroomGlobalConfigObjectSchema, HeadroomGlobalConfigSchema, HEADROOM_DEFAULT_SOURCE, HEADROOM_DEFAULT_IDLE_SHUTDOWN_MINUTES, FrontDoorGlobalConfigSchema, UPDATE_MODES, UpdateGlobalConfigSchema, GlobalConfigSchema, IdentitySchema, CategoryClassificationSchema, CategoryClassificationOverlaySchema, SHIPPED_CATEGORY_DEFAULTS;
|
|
232
232
|
var init_schema = __esm({
|
|
233
233
|
"src/config/schema.ts"() {
|
|
234
234
|
"use strict";
|
|
@@ -284,20 +284,33 @@ var init_schema = __esm({
|
|
|
284
284
|
/** How long the command may run before it is killed and counted as failed. Defaults to `CREDENTIAL_COMMAND_TIMEOUT_MS`, or `CREDENTIAL_INTERACTIVE_TIMEOUT_MS` for an interactive source. */
|
|
285
285
|
timeoutMs: import_zod.z.int().positive().optional()
|
|
286
286
|
};
|
|
287
|
+
EnvCredentialSourceSchema = import_zod.z.strictObject({ env: import_zod.z.string().min(1) });
|
|
288
|
+
FileCredentialSourceSchema = import_zod.z.strictObject({
|
|
289
|
+
file: import_zod.z.string().min(1).refine((filePath) => filePath.startsWith("~/") || import_node_path2.default.isAbsolute(filePath), {
|
|
290
|
+
message: "a credential file must be an absolute or ~-rooted path, since a launch can start in any directory"
|
|
291
|
+
})
|
|
292
|
+
});
|
|
293
|
+
CommandCredentialSourceSchema = import_zod.z.strictObject({ command: ArgvSchema, ...CommandSourceOptions });
|
|
294
|
+
OpCredentialSourceSchema = import_zod.z.strictObject({ op: import_zod.z.string().startsWith("op://"), ...CommandSourceOptions });
|
|
295
|
+
KeychainCredentialSourceSchema = import_zod.z.strictObject({
|
|
296
|
+
keychain: import_zod.z.strictObject({ service: import_zod.z.string().min(1), account: import_zod.z.string().min(1).optional() }),
|
|
297
|
+
...CommandSourceOptions
|
|
298
|
+
});
|
|
299
|
+
LiteralCredentialSourceSchema = import_zod.z.strictObject({ literal: import_zod.z.string().min(1) });
|
|
287
300
|
CredentialSourceSchema = import_zod.z.union([
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
+
EnvCredentialSourceSchema,
|
|
302
|
+
FileCredentialSourceSchema,
|
|
303
|
+
CommandCredentialSourceSchema,
|
|
304
|
+
OpCredentialSourceSchema,
|
|
305
|
+
KeychainCredentialSourceSchema,
|
|
306
|
+
LiteralCredentialSourceSchema
|
|
307
|
+
]);
|
|
308
|
+
RemoteCredentialSourceSchema = import_zod.z.union([
|
|
309
|
+
EnvCredentialSourceSchema,
|
|
310
|
+
FileCredentialSourceSchema,
|
|
311
|
+
OpCredentialSourceSchema,
|
|
312
|
+
KeychainCredentialSourceSchema,
|
|
313
|
+
LiteralCredentialSourceSchema
|
|
301
314
|
]);
|
|
302
315
|
CREDENTIAL_CACHE_STORES = ["keychain", "file"];
|
|
303
316
|
CredentialCacheSchema = import_zod.z.strictObject({
|
|
@@ -314,6 +327,7 @@ var init_schema = __esm({
|
|
|
314
327
|
ProviderEnvSchema = import_zod.z.record(import_zod.z.string().min(1), import_zod.z.string()).refine((env) => !Object.keys(env).some((key) => RESERVED_PROVIDER_ENV_KEYS.includes(key)), {
|
|
315
328
|
message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and agent-shim removes the others`
|
|
316
329
|
});
|
|
330
|
+
PROVIDER_KINDS = ["http", "codex"];
|
|
317
331
|
CODEX_EFFORTS = ["none", "low", "medium", "high"];
|
|
318
332
|
CODEX_LOGINS = ["codex-cli", "chatgpt-sign-in"];
|
|
319
333
|
CODEX_DEFAULT_TIER_MODELS = Object.freeze({
|
|
@@ -2649,7 +2663,7 @@ var init_package = __esm({
|
|
|
2649
2663
|
"package.json"() {
|
|
2650
2664
|
package_default = {
|
|
2651
2665
|
name: "claude-use",
|
|
2652
|
-
version: "9.
|
|
2666
|
+
version: "9.7.0",
|
|
2653
2667
|
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
2668
|
license: "MIT",
|
|
2655
2669
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -2700,6 +2714,7 @@ var init_package = __esm({
|
|
|
2700
2714
|
dependencies: {
|
|
2701
2715
|
"@anthropic-ai/claude-agent-sdk": "0.3.292",
|
|
2702
2716
|
"@clack/prompts": "^1.8.0",
|
|
2717
|
+
"@modelcontextprotocol/sdk": "1.32.0",
|
|
2703
2718
|
"@orpc/client": "2.0.0-beta.41",
|
|
2704
2719
|
"@orpc/openapi": "2.0.0-beta.41",
|
|
2705
2720
|
"@orpc/server": "2.0.0-beta.41",
|
|
@@ -3051,8 +3066,8 @@ function verifyHeadroomSocket(socketPath, ports) {
|
|
|
3051
3066
|
}
|
|
3052
3067
|
const uid = ports.currentUid();
|
|
3053
3068
|
const directory = import_node_path12.default.dirname(socketPath);
|
|
3054
|
-
const
|
|
3055
|
-
return
|
|
3069
|
+
const refusal2 = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
|
|
3070
|
+
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
3056
3071
|
}
|
|
3057
3072
|
function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
3058
3073
|
const unsupported = platformRefusal(ports.platform);
|
|
@@ -3070,8 +3085,8 @@ function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
|
3070
3085
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
3071
3086
|
}
|
|
3072
3087
|
fs12.mkdirPrivate(paths.headroomSocketDir);
|
|
3073
|
-
const
|
|
3074
|
-
return
|
|
3088
|
+
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
3089
|
+
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
3075
3090
|
}
|
|
3076
3091
|
function pruneStaleHeadroomSockets(fs12, paths, isRunning) {
|
|
3077
3092
|
const removed = [];
|
|
@@ -4585,14 +4600,14 @@ function capacityOf(plan) {
|
|
|
4585
4600
|
return plan.kind === "subscription" ? plan.capacity : 1;
|
|
4586
4601
|
}
|
|
4587
4602
|
function assessRefusedNested(member, nested, nowMs) {
|
|
4588
|
-
const
|
|
4603
|
+
const refusal2 = nested.earliestReturn === void 0 ? { reason: `no member of pool "${nested.pool}" can be picked` } : { reason: `every member of pool "${nested.pool}" is refused; ${nested.earliestReturn.identity} returns at ${new Date(nested.earliestReturn.atMs).toISOString()} (in ${formatAge(nested.earliestReturn.atMs - nowMs)})`, blockedUntilMs: nested.earliestReturn.atMs };
|
|
4589
4604
|
return {
|
|
4590
4605
|
candidate: {
|
|
4591
4606
|
identity: member.identity,
|
|
4592
4607
|
class: "ineligible",
|
|
4593
|
-
...
|
|
4608
|
+
...refusal2.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal2.blockedUntilMs },
|
|
4594
4609
|
plan: planOf(member.account),
|
|
4595
|
-
reasons: [
|
|
4610
|
+
reasons: [refusal2.reason]
|
|
4596
4611
|
}
|
|
4597
4612
|
};
|
|
4598
4613
|
}
|
|
@@ -4683,7 +4698,7 @@ function rankPool(input) {
|
|
|
4683
4698
|
const assessments = members.map((member) => ({ member, ...assess(member, nowMs) }));
|
|
4684
4699
|
const demands = assessments.flatMap(({ candidate, burn }) => burn === void 0 ? [] : [burn * capacityOf(candidate.plan)]);
|
|
4685
4700
|
const sharedDemand = demands.length === 0 ? void 0 : Math.max(...demands);
|
|
4686
|
-
const
|
|
4701
|
+
const guarded2 = assessments.map((assessment) => {
|
|
4687
4702
|
const { candidate } = assessment;
|
|
4688
4703
|
if (candidate.class === "ineligible" || assessment.member.policy === void 0) {
|
|
4689
4704
|
return assessment;
|
|
@@ -4698,7 +4713,7 @@ function rankPool(input) {
|
|
|
4698
4713
|
}
|
|
4699
4714
|
return { ...assessment, candidate: { ...candidate, class: "ineligible", reasons: [`skipped by policy (${verdict.checked.join(", ")}: did not hold)`, ...candidate.reasons] } };
|
|
4700
4715
|
});
|
|
4701
|
-
const candidates =
|
|
4716
|
+
const candidates = guarded2.map((assessment) => {
|
|
4702
4717
|
const { candidate, fiveHour, burn } = assessment;
|
|
4703
4718
|
const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
|
|
4704
4719
|
const { sevenDay, sevenDayBurn } = assessment;
|
|
@@ -5767,7 +5782,7 @@ function cascadeProviderName(cascade) {
|
|
|
5767
5782
|
}
|
|
5768
5783
|
return name;
|
|
5769
5784
|
}
|
|
5770
|
-
function
|
|
5785
|
+
function selectProvider(params) {
|
|
5771
5786
|
const cliName = params.cliProvider !== void 0 && params.cliProvider !== "" ? params.cliProvider : void 0;
|
|
5772
5787
|
const name = cliName ?? (params.cascade === void 0 ? void 0 : cascadeProviderName(params.cascade));
|
|
5773
5788
|
if (name === void 0) {
|
|
@@ -5782,6 +5797,14 @@ function resolveProvider(params) {
|
|
|
5782
5797
|
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
5798
|
};
|
|
5784
5799
|
}
|
|
5800
|
+
return { ok: true, provider: { name, definition } };
|
|
5801
|
+
}
|
|
5802
|
+
function resolveProvider(params) {
|
|
5803
|
+
const selection = selectProvider(params);
|
|
5804
|
+
if (selection?.ok !== true) {
|
|
5805
|
+
return selection;
|
|
5806
|
+
}
|
|
5807
|
+
const { name, definition } = selection.provider;
|
|
5785
5808
|
if (params.credentials === void 0) {
|
|
5786
5809
|
return { ok: false, status: 1, message: `agent-shim: provider ${name} needs its credential resolved, but this launcher has no credential port wired` };
|
|
5787
5810
|
}
|
|
@@ -6064,6 +6087,51 @@ var init_claudeShim = __esm({
|
|
|
6064
6087
|
}
|
|
6065
6088
|
});
|
|
6066
6089
|
|
|
6090
|
+
// src/update/update.ts
|
|
6091
|
+
function compareVersions3(left, right) {
|
|
6092
|
+
const parse = (version) => {
|
|
6093
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
|
|
6094
|
+
if (match === null) {
|
|
6095
|
+
throw new Error(`not a plain release version: ${version}`);
|
|
6096
|
+
}
|
|
6097
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
6098
|
+
};
|
|
6099
|
+
const leftParts = parse(left);
|
|
6100
|
+
const rightParts = parse(right);
|
|
6101
|
+
return leftParts.map((part, index) => part - (rightParts[index] ?? 0)).find((difference) => difference !== 0) ?? 0;
|
|
6102
|
+
}
|
|
6103
|
+
function releaseTagFromUrl(url) {
|
|
6104
|
+
const segment = url.split("?")[0]?.split("/").at(-1);
|
|
6105
|
+
const candidate = segment?.startsWith("v") === true ? segment.slice(1) : void 0;
|
|
6106
|
+
return candidate !== void 0 && /^\d+\.\d+\.\d+$/.test(candidate) ? candidate : void 0;
|
|
6107
|
+
}
|
|
6108
|
+
var LATEST_RELEASE_URL, UpdateChannelError, UpdateConflictError, UpdateDownloadError;
|
|
6109
|
+
var init_update = __esm({
|
|
6110
|
+
"src/update/update.ts"() {
|
|
6111
|
+
"use strict";
|
|
6112
|
+
init_cliError();
|
|
6113
|
+
LATEST_RELEASE_URL = "https://github.com/ExaDev/agent-shim/releases/latest";
|
|
6114
|
+
UpdateChannelError = class extends CliError {
|
|
6115
|
+
constructor(message) {
|
|
6116
|
+
super(message);
|
|
6117
|
+
this.name = "UpdateChannelError";
|
|
6118
|
+
}
|
|
6119
|
+
};
|
|
6120
|
+
UpdateConflictError = class extends CliError {
|
|
6121
|
+
constructor(message) {
|
|
6122
|
+
super(message);
|
|
6123
|
+
this.name = "UpdateConflictError";
|
|
6124
|
+
}
|
|
6125
|
+
};
|
|
6126
|
+
UpdateDownloadError = class extends CliError {
|
|
6127
|
+
constructor(message) {
|
|
6128
|
+
super(message);
|
|
6129
|
+
this.name = "UpdateDownloadError";
|
|
6130
|
+
}
|
|
6131
|
+
};
|
|
6132
|
+
}
|
|
6133
|
+
});
|
|
6134
|
+
|
|
6067
6135
|
// src/frontdoor/ensure.ts
|
|
6068
6136
|
function ensureFrontDoor(params) {
|
|
6069
6137
|
const { paths, ports } = params;
|
|
@@ -6499,7 +6567,7 @@ function buildEnv(params) {
|
|
|
6499
6567
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
6500
6568
|
let providerCustomHeaders;
|
|
6501
6569
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
6502
|
-
env.CLAUDE_CONFIG_DIR =
|
|
6570
|
+
env.CLAUDE_CONFIG_DIR = import_node_path32.default.join(params.identitiesDir, params.resolvedIdentityName);
|
|
6503
6571
|
}
|
|
6504
6572
|
if (params.provider !== void 0) {
|
|
6505
6573
|
const providerEnv = params.provider.definition.env ?? {};
|
|
@@ -6543,11 +6611,11 @@ function buildEnv(params) {
|
|
|
6543
6611
|
}
|
|
6544
6612
|
return env;
|
|
6545
6613
|
}
|
|
6546
|
-
var
|
|
6614
|
+
var import_node_path32, LOOPBACK_HOSTS;
|
|
6547
6615
|
var init_flags = __esm({
|
|
6548
6616
|
"src/launcher/flags.ts"() {
|
|
6549
6617
|
"use strict";
|
|
6550
|
-
|
|
6618
|
+
import_node_path32 = __toESM(require("node:path"), 1);
|
|
6551
6619
|
init_envBool();
|
|
6552
6620
|
init_credential();
|
|
6553
6621
|
init_headers();
|
|
@@ -6623,7 +6691,9 @@ function resolvePoolLaunch(params) {
|
|
|
6623
6691
|
}
|
|
6624
6692
|
const { pick, earliestReturn, movedOff } = graph.ranking;
|
|
6625
6693
|
if (pick !== void 0) {
|
|
6626
|
-
|
|
6694
|
+
if (params.recordPick) {
|
|
6695
|
+
recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
|
|
6696
|
+
}
|
|
6627
6697
|
const move = movedOff === void 0 ? "" : `moved off ${movedOff.identity} (${movedOff.reason}); `;
|
|
6628
6698
|
return {
|
|
6629
6699
|
ok: true,
|
|
@@ -6689,33 +6759,6 @@ var init_spawn = __esm({
|
|
|
6689
6759
|
}
|
|
6690
6760
|
});
|
|
6691
6761
|
|
|
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
6762
|
// src/update/launchHook.ts
|
|
6720
6763
|
function resolveUpdateMode(globalConfig) {
|
|
6721
6764
|
return globalConfig?.update?.mode ?? "off";
|
|
@@ -6793,7 +6836,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
|
|
|
6793
6836
|
const resolution = resolveCredential({ credential, env, port, subject: `identity ${identity}` });
|
|
6794
6837
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
6795
6838
|
}
|
|
6796
|
-
function pickFromPool(decided, params, parsedArgv) {
|
|
6839
|
+
function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
6797
6840
|
const { paths, fs: fs12, proc, log } = params;
|
|
6798
6841
|
if (decided.pool === void 0) {
|
|
6799
6842
|
return { identityDecision: decided };
|
|
@@ -6814,7 +6857,9 @@ function pickFromPool(decided, params, parsedArgv) {
|
|
|
6814
6857
|
now: farmRuntime.now,
|
|
6815
6858
|
sleep: farmRuntime.lock.sleep,
|
|
6816
6859
|
passthrough: parsedArgv.rest,
|
|
6817
|
-
|
|
6860
|
+
// 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.
|
|
6861
|
+
wait: !readOnly && parsedArgv.wait === true,
|
|
6862
|
+
recordPick: !readOnly,
|
|
6818
6863
|
log
|
|
6819
6864
|
});
|
|
6820
6865
|
if (!resolution.ok) {
|
|
@@ -6827,7 +6872,7 @@ function pickFromPool(decided, params, parsedArgv) {
|
|
|
6827
6872
|
poolPick: { name: decided.pool, reasons: resolution.reasons, ...resolution.movedOff === void 0 ? {} : { movedOff: resolution.movedOff } }
|
|
6828
6873
|
};
|
|
6829
6874
|
}
|
|
6830
|
-
function
|
|
6875
|
+
function decideLaunch(params, readOnly) {
|
|
6831
6876
|
const { paths, fs: fs12, proc, log } = params;
|
|
6832
6877
|
const { env, argv } = proc;
|
|
6833
6878
|
const parsedArgv = parseLauncherArgv(argv);
|
|
@@ -6851,10 +6896,10 @@ function prepareLaunch(params) {
|
|
|
6851
6896
|
return trimmed === "" ? void 0 : trimmed;
|
|
6852
6897
|
}
|
|
6853
6898
|
});
|
|
6854
|
-
const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv);
|
|
6899
|
+
const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv, readOnly);
|
|
6855
6900
|
const farmIdentity = configDirEscapeHatchApplies ? void 0 : identityDecision.name;
|
|
6856
6901
|
const farm = farmIdentity === void 0 ? void 0 : params.farm;
|
|
6857
|
-
if (farm !== void 0 && farmIdentity !== void 0) {
|
|
6902
|
+
if (!readOnly && farm !== void 0 && farmIdentity !== void 0) {
|
|
6858
6903
|
let recovery;
|
|
6859
6904
|
try {
|
|
6860
6905
|
recovery = recoverFarm({
|
|
@@ -6893,33 +6938,44 @@ function prepareLaunch(params) {
|
|
|
6893
6938
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
6894
6939
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
6895
6940
|
});
|
|
6896
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(
|
|
6941
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(import_node_path33.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
6897
6942
|
log.error(
|
|
6898
6943
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
6899
6944
|
);
|
|
6900
6945
|
proc.exit(1);
|
|
6901
6946
|
}
|
|
6902
6947
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
6903
|
-
const
|
|
6948
|
+
const providerParams = {
|
|
6904
6949
|
paths,
|
|
6905
6950
|
port: fs12,
|
|
6906
|
-
|
|
6907
|
-
...params.credentials === void 0 ? {} : { credentials: params.credentials },
|
|
6908
|
-
...parsedArgv.provider === void 0 ? {} : { cliProvider: parsedArgv.provider },
|
|
6951
|
+
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
6909
6952
|
...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
|
|
6910
|
-
}
|
|
6911
|
-
|
|
6912
|
-
|
|
6913
|
-
|
|
6914
|
-
|
|
6915
|
-
|
|
6916
|
-
|
|
6917
|
-
|
|
6953
|
+
};
|
|
6954
|
+
let selectedProvider;
|
|
6955
|
+
let resolvedProvider;
|
|
6956
|
+
if (parsedArgv.provider !== false && readOnly) {
|
|
6957
|
+
const selection = selectProvider(providerParams);
|
|
6958
|
+
if (selection !== void 0 && !selection.ok) {
|
|
6959
|
+
log.error(selection.message);
|
|
6960
|
+
proc.exit(selection.status);
|
|
6961
|
+
}
|
|
6962
|
+
selectedProvider = selection?.ok === true ? selection.provider : void 0;
|
|
6963
|
+
} else if (parsedArgv.provider !== false) {
|
|
6964
|
+
const provider = resolveProvider({ ...providerParams, env, ...params.credentials === void 0 ? {} : { credentials: params.credentials } });
|
|
6965
|
+
if (provider !== void 0 && !provider.ok) {
|
|
6966
|
+
log.error(provider.message);
|
|
6967
|
+
proc.exit(provider.status);
|
|
6968
|
+
}
|
|
6969
|
+
resolvedProvider = provider?.ok === true ? provider.provider : void 0;
|
|
6970
|
+
selectedProvider = resolvedProvider;
|
|
6971
|
+
for (const warning of provider?.ok === true ? provider.warnings : []) {
|
|
6972
|
+
log.warn(warning);
|
|
6973
|
+
}
|
|
6918
6974
|
}
|
|
6919
6975
|
if (farm !== void 0 && farmIdentity !== void 0) {
|
|
6920
6976
|
try {
|
|
6921
6977
|
const snapshot = readUsageSnapshot(farm.fs, paths.usageSnapshotsDir, farmIdentity);
|
|
6922
|
-
for (const warning of quotaWarnings(snapshot,
|
|
6978
|
+
for (const warning of quotaWarnings(snapshot, selectedProvider?.name ?? ANTHROPIC_PROVIDER, farm.now())) {
|
|
6923
6979
|
log.warn(warning);
|
|
6924
6980
|
}
|
|
6925
6981
|
} catch (error) {
|
|
@@ -6929,8 +6985,8 @@ function prepareLaunch(params) {
|
|
|
6929
6985
|
log.warn(`agent-shim: ${error.message}`);
|
|
6930
6986
|
}
|
|
6931
6987
|
}
|
|
6932
|
-
const identityCredentialBlock = loadedIdentity?.config.credential;
|
|
6933
|
-
const identityResolution =
|
|
6988
|
+
const identityCredentialBlock = selectedProvider === void 0 && farmIdentity !== void 0 ? loadedIdentity?.config.credential : void 0;
|
|
6989
|
+
const identityResolution = !readOnly && identityCredentialBlock !== void 0 && farmIdentity !== void 0 ? resolveIdentityCredential(farmIdentity, identityCredentialBlock, env, params.credentials) : void 0;
|
|
6934
6990
|
if (identityResolution !== void 0 && !identityResolution.ok) {
|
|
6935
6991
|
log.error(identityResolution.message);
|
|
6936
6992
|
proc.exit(identityResolution.status);
|
|
@@ -6944,25 +7000,97 @@ function prepareLaunch(params) {
|
|
|
6944
7000
|
allowAmbientCredential: loadedIdentity?.config.allowAmbientCredential ?? false,
|
|
6945
7001
|
allowAmbientCredentialOverride: parseEnvBool("AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL", env.AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL) === true,
|
|
6946
7002
|
identityName: identityDecision.name,
|
|
6947
|
-
providerSelected:
|
|
7003
|
+
providerSelected: selectedProvider !== void 0,
|
|
6948
7004
|
...identityCredential === void 0 ? {} : { injectedCredential: { variable: CREDENTIAL_TARGET_VARS[identityCredential.target], token: identityCredential.token } }
|
|
6949
7005
|
});
|
|
6950
7006
|
if (!guardResult.ok) {
|
|
6951
|
-
|
|
6952
|
-
|
|
7007
|
+
if (readOnly && identityCredentialBlock !== void 0) {
|
|
7008
|
+
log.warn(`${guardResult.message} (not resolved here: the launch proceeds only if that value is the identity's own injected credential)`);
|
|
7009
|
+
} else {
|
|
7010
|
+
log.error(guardResult.message);
|
|
7011
|
+
proc.exit(1);
|
|
7012
|
+
}
|
|
7013
|
+
}
|
|
7014
|
+
const launchCascade = farmContext?.cascade ?? (params.farm === void 0 ? void 0 : params.farm.loadCascade(configProfileDecision.name, cliOverride));
|
|
7015
|
+
let cascadeLaunch;
|
|
7016
|
+
if (launchCascade !== void 0 && params.farm !== void 0) {
|
|
7017
|
+
const assembled = assembleCascade(launchCascade);
|
|
7018
|
+
const flattened = flattenLayers(assembled.layers, { home: params.farm.home });
|
|
7019
|
+
cascadeLaunch = flattened.launch;
|
|
7020
|
+
if (readOnly) {
|
|
7021
|
+
for (const diagnostic of [...assembled.diagnostics, ...flattened.diagnostics]) {
|
|
7022
|
+
if (diagnostic.severity !== "info") {
|
|
7023
|
+
log.warn(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
|
|
7024
|
+
}
|
|
7025
|
+
}
|
|
7026
|
+
}
|
|
6953
7027
|
}
|
|
7028
|
+
const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
|
|
7029
|
+
const discovered = params.resolveClaudeBinary(pinnedVersion === void 0 ? void 0 : { version: pinnedVersion.version });
|
|
7030
|
+
const flags = resolveLaunchFlags({
|
|
7031
|
+
env,
|
|
7032
|
+
// A pool pick reads the usage the front door records, so a pool launch records its own unless something says otherwise.
|
|
7033
|
+
...poolExplanation === void 0 ? {} : { trackUsageDefault: true },
|
|
7034
|
+
...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
|
|
7035
|
+
flags: {
|
|
7036
|
+
...parsedArgv.skipPermissions === void 0 ? {} : { skipPermissions: parsedArgv.skipPermissions },
|
|
7037
|
+
...parsedArgv.remoteControl === void 0 ? {} : { remoteControl: parsedArgv.remoteControl },
|
|
7038
|
+
...parsedArgv.headroom === void 0 ? {} : { headroom: parsedArgv.headroom },
|
|
7039
|
+
...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
|
|
7040
|
+
}
|
|
7041
|
+
});
|
|
7042
|
+
const args = buildArgv({
|
|
7043
|
+
toolFlags: buildFlagArgs(flags),
|
|
7044
|
+
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
7045
|
+
passthrough: parsedArgv.rest
|
|
7046
|
+
});
|
|
7047
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path33.default.join(paths.identitiesDir, identityDecision.name);
|
|
7048
|
+
const decision = {
|
|
7049
|
+
identitySource: identityDecision.source,
|
|
7050
|
+
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
7051
|
+
configProfileSource: configProfileDecision.source,
|
|
7052
|
+
...identityDecision.name === void 0 ? {} : { identity: identityDecision.name },
|
|
7053
|
+
...poolPick === void 0 ? {} : { pool: poolPick },
|
|
7054
|
+
...configDir === void 0 || configDir === "" ? {} : { configDir },
|
|
7055
|
+
...configProfileDecision.name === void 0 ? {} : { configProfile: configProfileDecision.name },
|
|
7056
|
+
...selectedProvider === void 0 ? {} : { provider: selectedProvider.name }
|
|
7057
|
+
};
|
|
7058
|
+
return {
|
|
7059
|
+
parsedArgv,
|
|
7060
|
+
identityDecision,
|
|
7061
|
+
poolExplanation,
|
|
7062
|
+
poolPick,
|
|
7063
|
+
configDirEscapeHatch: configDirEscapeHatchApplies,
|
|
7064
|
+
farmIdentity,
|
|
7065
|
+
farmContext,
|
|
7066
|
+
configProfileDecision,
|
|
7067
|
+
provider: selectedProvider,
|
|
7068
|
+
resolvedProvider,
|
|
7069
|
+
identityCredentialBlock,
|
|
7070
|
+
identityCredential,
|
|
7071
|
+
pinnedVersion,
|
|
7072
|
+
flags,
|
|
7073
|
+
bin: discovered.path,
|
|
7074
|
+
args,
|
|
7075
|
+
decision
|
|
7076
|
+
};
|
|
7077
|
+
}
|
|
7078
|
+
function prepareLaunch(params) {
|
|
7079
|
+
const { paths, proc, log } = params;
|
|
7080
|
+
const { env } = proc;
|
|
7081
|
+
const decided = decideLaunch(params, false);
|
|
7082
|
+
const { identityDecision, configProfileDecision, resolvedProvider, identityCredential, poolExplanation, flags: resolvedFlags, args: finalArgv, configDirEscapeHatch: configDirEscapeHatchApplies, decision } = decided;
|
|
6954
7083
|
log.info(
|
|
6955
7084
|
`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
7085
|
);
|
|
6957
7086
|
const updateCheck = runLaunchUpdateCheck({
|
|
6958
7087
|
mode: params.updateMode ?? "off",
|
|
6959
|
-
checkPath:
|
|
7088
|
+
checkPath: import_node_path33.default.join(paths.root, "update.check"),
|
|
6960
7089
|
currentVersion: package_default.version,
|
|
6961
7090
|
port: params.update
|
|
6962
7091
|
});
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = farmContext;
|
|
7092
|
+
if (decided.farmContext !== void 0) {
|
|
7093
|
+
const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = decided.farmContext;
|
|
6966
7094
|
let result;
|
|
6967
7095
|
try {
|
|
6968
7096
|
result = resyncFarm({
|
|
@@ -6999,27 +7127,10 @@ function prepareLaunch(params) {
|
|
|
6999
7127
|
log.info(
|
|
7000
7128
|
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
7129
|
);
|
|
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
7130
|
}
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
if (pinnedVersion !== void 0) {
|
|
7009
|
-
log.info(`agent-shim: Claude Code ${pinnedVersion.version} (pinned by ${pinnedVersion.source})`);
|
|
7131
|
+
if (decided.pinnedVersion !== void 0) {
|
|
7132
|
+
log.info(`agent-shim: Claude Code ${decided.pinnedVersion.version} (pinned by ${decided.pinnedVersion.source})`);
|
|
7010
7133
|
}
|
|
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
7134
|
const frontDoorPort = params.frontdoor;
|
|
7024
7135
|
const frontDoorEngaged = resolvedProvider !== void 0 || resolvedFlags.headroom || resolvedFlags.trackUsage;
|
|
7025
7136
|
if (frontDoorEngaged && frontDoorPort === void 0) {
|
|
@@ -7043,11 +7154,6 @@ function prepareLaunch(params) {
|
|
|
7043
7154
|
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
7155
|
}
|
|
7045
7156
|
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
7157
|
const finalEnv = buildEnv({
|
|
7052
7158
|
baseEnv: env,
|
|
7053
7159
|
configDirEscapeHatch: configDirEscapeHatchApplies,
|
|
@@ -7065,18 +7171,35 @@ function prepareLaunch(params) {
|
|
|
7065
7171
|
registered();
|
|
7066
7172
|
}
|
|
7067
7173
|
};
|
|
7068
|
-
|
|
7069
|
-
|
|
7070
|
-
|
|
7071
|
-
|
|
7072
|
-
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
|
|
7174
|
+
return { bin: decided.bin, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
|
|
7175
|
+
}
|
|
7176
|
+
function resolveLaunch(params) {
|
|
7177
|
+
const decided = decideLaunch(params, true);
|
|
7178
|
+
const { env } = params.proc;
|
|
7179
|
+
const frontDoor = decided.provider !== void 0 || decided.flags.headroom || decided.flags.trackUsage;
|
|
7180
|
+
const built = buildEnv({
|
|
7181
|
+
baseEnv: env,
|
|
7182
|
+
configDirEscapeHatch: decided.configDirEscapeHatch,
|
|
7183
|
+
resolvedIdentityName: decided.identityDecision.name,
|
|
7184
|
+
identitiesDir: params.paths.identitiesDir,
|
|
7185
|
+
...decided.provider === void 0 ? {} : { provider: decided.provider },
|
|
7186
|
+
...frontDoor ? { frontdoor: { port: 0, connectPort: 0, trustBundlePath: "", sessionToken: "" } } : {},
|
|
7187
|
+
...decided.flags.headroom ? { headroom: { socketPath: "", projectId: "" } } : {},
|
|
7188
|
+
sessionId: ""
|
|
7189
|
+
});
|
|
7190
|
+
const credentialNames = decided.identityCredentialBlock === void 0 ? [] : Object.keys(credentialVariables(decided.identityCredentialBlock.target ?? "bearer", ""));
|
|
7191
|
+
const environment = [.../* @__PURE__ */ new Set([...Object.keys(built).filter((name) => built[name] !== env[name]), ...credentialNames])].sort();
|
|
7192
|
+
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;
|
|
7193
|
+
return {
|
|
7194
|
+
decision: decided.decision,
|
|
7195
|
+
flags: decided.flags,
|
|
7196
|
+
...decided.pinnedVersion === void 0 ? {} : { claudeVersion: decided.pinnedVersion },
|
|
7197
|
+
bin: decided.bin,
|
|
7198
|
+
args: decided.args,
|
|
7199
|
+
...credential === void 0 ? {} : { credential },
|
|
7200
|
+
routing: { frontDoor, headroom: decided.flags.headroom },
|
|
7201
|
+
environment
|
|
7078
7202
|
};
|
|
7079
|
-
return { bin: discovered.path, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
|
|
7080
7203
|
}
|
|
7081
7204
|
function runLaunchPlan(plan, spawn2) {
|
|
7082
7205
|
try {
|
|
@@ -7093,12 +7216,12 @@ function runLaunchPlan(plan, spawn2) {
|
|
|
7093
7216
|
function runLauncher(params) {
|
|
7094
7217
|
params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
|
|
7095
7218
|
}
|
|
7096
|
-
var import_node_crypto10,
|
|
7219
|
+
var import_node_crypto10, import_node_path33;
|
|
7097
7220
|
var init_launcher = __esm({
|
|
7098
7221
|
"src/launcher.ts"() {
|
|
7099
7222
|
"use strict";
|
|
7100
7223
|
import_node_crypto10 = require("node:crypto");
|
|
7101
|
-
|
|
7224
|
+
import_node_path33 = __toESM(require("node:path"), 1);
|
|
7102
7225
|
init_package();
|
|
7103
7226
|
init_envBool();
|
|
7104
7227
|
init_argv();
|
|
@@ -7129,13 +7252,13 @@ function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string"
|
|
|
7129
7252
|
if (distDir === void 0) {
|
|
7130
7253
|
throw new OwnCliPathUnknownError();
|
|
7131
7254
|
}
|
|
7132
|
-
return
|
|
7255
|
+
return import_node_path34.default.join(distDir, OWN_CLI_FILE_NAME);
|
|
7133
7256
|
}
|
|
7134
|
-
var
|
|
7257
|
+
var import_node_path34, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
7135
7258
|
var init_ownCli = __esm({
|
|
7136
7259
|
"src/ownCli.ts"() {
|
|
7137
7260
|
"use strict";
|
|
7138
|
-
|
|
7261
|
+
import_node_path34 = __toESM(require("node:path"), 1);
|
|
7139
7262
|
init_cliError();
|
|
7140
7263
|
OWN_CLI_FILE_NAME = "cli.cjs";
|
|
7141
7264
|
OwnCliPathUnknownError = class extends CliError {
|
|
@@ -7220,7 +7343,7 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
|
|
|
7220
7343
|
// src/frontdoor/trust.ts
|
|
7221
7344
|
function resolveTrustBundle(params) {
|
|
7222
7345
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
|
|
7223
|
-
if (inherited === void 0 || inherited === "" ||
|
|
7346
|
+
if (inherited === void 0 || inherited === "" || import_node_path35.default.resolve(inherited) === import_node_path35.default.resolve(caCertFile)) {
|
|
7224
7347
|
return { path: caCertFile };
|
|
7225
7348
|
}
|
|
7226
7349
|
const caPem = fs12.readFileUtf8(caCertFile);
|
|
@@ -7238,19 +7361,19 @@ function resolveTrustBundle(params) {
|
|
|
7238
7361
|
}
|
|
7239
7362
|
const combined = `${inheritedPem.trimEnd()}
|
|
7240
7363
|
${caPem}`;
|
|
7241
|
-
const bundle =
|
|
7364
|
+
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
7365
|
if (!fs12.exists(bundle)) {
|
|
7243
7366
|
fs12.mkdirp(bundlesDir);
|
|
7244
7367
|
fs12.writeFileAtomic(bundle, combined);
|
|
7245
7368
|
}
|
|
7246
7369
|
return { path: bundle };
|
|
7247
7370
|
}
|
|
7248
|
-
var import_node_crypto11,
|
|
7371
|
+
var import_node_crypto11, import_node_path35, BUNDLE_NAME_HEX_DIGITS;
|
|
7249
7372
|
var init_trust = __esm({
|
|
7250
7373
|
"src/frontdoor/trust.ts"() {
|
|
7251
7374
|
"use strict";
|
|
7252
7375
|
import_node_crypto11 = require("node:crypto");
|
|
7253
|
-
|
|
7376
|
+
import_node_path35 = __toESM(require("node:path"), 1);
|
|
7254
7377
|
BUNDLE_NAME_HEX_DIGITS = 16;
|
|
7255
7378
|
}
|
|
7256
7379
|
});
|
|
@@ -7395,6 +7518,31 @@ function prepareClaudeLaunch(options) {
|
|
|
7395
7518
|
const spawnDaemon = daemonSpawnerFor(options.agentShim);
|
|
7396
7519
|
return prepareLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) }));
|
|
7397
7520
|
}
|
|
7521
|
+
function resolveClaudeLaunch(options) {
|
|
7522
|
+
const paths = options.paths ?? resolveLayoutPaths();
|
|
7523
|
+
const refusals = [];
|
|
7524
|
+
const warnings = [];
|
|
7525
|
+
const log = {
|
|
7526
|
+
info: () => void 0,
|
|
7527
|
+
warn: (message) => {
|
|
7528
|
+
warnings.push(message);
|
|
7529
|
+
},
|
|
7530
|
+
error: (message) => {
|
|
7531
|
+
refusals.push(message);
|
|
7532
|
+
}
|
|
7533
|
+
};
|
|
7534
|
+
const proc = {
|
|
7535
|
+
env: options.env,
|
|
7536
|
+
argv: options.argv,
|
|
7537
|
+
exit: (code) => {
|
|
7538
|
+
throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
|
|
7539
|
+
}
|
|
7540
|
+
};
|
|
7541
|
+
const spawnDaemon = () => {
|
|
7542
|
+
throw new Error("resolving a launch starts no daemon");
|
|
7543
|
+
};
|
|
7544
|
+
return { resolution: resolveLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) })), warnings };
|
|
7545
|
+
}
|
|
7398
7546
|
var import_node_os7, import_node_crypto12, LaunchRefusedError;
|
|
7399
7547
|
var init_launchWiring = __esm({
|
|
7400
7548
|
"src/launchWiring.ts"() {
|
|
@@ -7563,11 +7711,11 @@ var init_anthropicUsageRefresh = __esm({
|
|
|
7563
7711
|
});
|
|
7564
7712
|
|
|
7565
7713
|
// src/usage/providerQuota.ts
|
|
7566
|
-
var
|
|
7714
|
+
var import_zod23, 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
7715
|
var init_providerQuota = __esm({
|
|
7568
7716
|
"src/usage/providerQuota.ts"() {
|
|
7569
7717
|
"use strict";
|
|
7570
|
-
|
|
7718
|
+
import_zod23 = require("zod");
|
|
7571
7719
|
init_schema2();
|
|
7572
7720
|
MS_PER_SECOND7 = 1e3;
|
|
7573
7721
|
SECONDS_PER_HOUR = 3600;
|
|
@@ -7581,35 +7729,35 @@ var init_providerQuota = __esm({
|
|
|
7581
7729
|
[ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
|
|
7582
7730
|
[ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7]
|
|
7583
7731
|
]);
|
|
7584
|
-
ZaiLimitSchema =
|
|
7585
|
-
type:
|
|
7586
|
-
unit:
|
|
7587
|
-
number:
|
|
7588
|
-
percentage:
|
|
7589
|
-
nextResetTime:
|
|
7590
|
-
usage:
|
|
7591
|
-
currentValue:
|
|
7592
|
-
remaining:
|
|
7732
|
+
ZaiLimitSchema = import_zod23.z.object({
|
|
7733
|
+
type: import_zod23.z.string(),
|
|
7734
|
+
unit: import_zod23.z.number().int(),
|
|
7735
|
+
number: import_zod23.z.number().int().positive(),
|
|
7736
|
+
percentage: import_zod23.z.number().nonnegative(),
|
|
7737
|
+
nextResetTime: import_zod23.z.number().positive().optional(),
|
|
7738
|
+
usage: import_zod23.z.number().nonnegative().optional(),
|
|
7739
|
+
currentValue: import_zod23.z.number().nonnegative().optional(),
|
|
7740
|
+
remaining: import_zod23.z.number().nonnegative().optional()
|
|
7593
7741
|
});
|
|
7594
|
-
ZaiResponseSchema =
|
|
7595
|
-
success:
|
|
7596
|
-
msg:
|
|
7597
|
-
data:
|
|
7742
|
+
ZaiResponseSchema = import_zod23.z.object({
|
|
7743
|
+
success: import_zod23.z.boolean(),
|
|
7744
|
+
msg: import_zod23.z.string().optional(),
|
|
7745
|
+
data: import_zod23.z.object({ level: import_zod23.z.string().optional(), limits: import_zod23.z.array(ZaiLimitSchema) })
|
|
7598
7746
|
});
|
|
7599
7747
|
OPENROUTER_HOST = "openrouter.ai";
|
|
7600
7748
|
OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
7601
7749
|
OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
7602
7750
|
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:
|
|
7751
|
+
OpenRouterKeySchema = import_zod23.z.object({
|
|
7752
|
+
data: import_zod23.z.object({
|
|
7753
|
+
limit: import_zod23.z.number().nonnegative().nullable(),
|
|
7754
|
+
limit_remaining: import_zod23.z.number().nullable(),
|
|
7755
|
+
limit_reset: import_zod23.z.string().nullable(),
|
|
7756
|
+
is_free_tier: import_zod23.z.boolean().optional(),
|
|
7757
|
+
free_model_daily_requests: import_zod23.z.object({ used: import_zod23.z.number().nonnegative(), limit: import_zod23.z.number().nonnegative(), remaining: import_zod23.z.number() }).optional()
|
|
7610
7758
|
})
|
|
7611
7759
|
});
|
|
7612
|
-
OpenRouterCreditsSchema =
|
|
7760
|
+
OpenRouterCreditsSchema = import_zod23.z.object({ data: import_zod23.z.object({ total_credits: import_zod23.z.number().nonnegative(), total_usage: import_zod23.z.number().nonnegative() }) });
|
|
7613
7761
|
}
|
|
7614
7762
|
});
|
|
7615
7763
|
|
|
@@ -7741,10 +7889,47 @@ __export(index_exports, {
|
|
|
7741
7889
|
CheckReportJsonSchema: () => CheckReportJsonSchema,
|
|
7742
7890
|
CheckRunInputSchema: () => CheckRunInputSchema,
|
|
7743
7891
|
CliError: () => CliError,
|
|
7892
|
+
CodexLogoutOutputSchema: () => CodexLogoutOutputSchema,
|
|
7893
|
+
CodexSignInSchema: () => CodexSignInSchema,
|
|
7894
|
+
CodexStatusOutputSchema: () => CodexStatusOutputSchema,
|
|
7895
|
+
ConfigIdentityAddOutputSchema: () => ConfigIdentityAddOutputSchema,
|
|
7896
|
+
ConfigIdentityRemoveInputSchema: () => ConfigIdentityRemoveInputSchema,
|
|
7897
|
+
ConfigIdentityRemoveOutputSchema: () => ConfigIdentityRemoveOutputSchema,
|
|
7898
|
+
ConfigIdentitySetInputSchema: () => ConfigIdentitySetInputSchema,
|
|
7899
|
+
ConfigIdentitySetOutputSchema: () => ConfigIdentitySetOutputSchema,
|
|
7900
|
+
ConfigIdentityUseOutputSchema: () => ConfigIdentityUseOutputSchema,
|
|
7901
|
+
ConfigNameInputSchema: () => ConfigNameInputSchema,
|
|
7902
|
+
ConfigPoolAddInputSchema: () => ConfigPoolAddInputSchema,
|
|
7903
|
+
ConfigPoolAddOutputSchema: () => ConfigPoolAddOutputSchema,
|
|
7904
|
+
ConfigPoolRemoveInputSchema: () => ConfigPoolRemoveInputSchema,
|
|
7905
|
+
ConfigPoolRemoveOutputSchema: () => ConfigPoolRemoveOutputSchema,
|
|
7906
|
+
ConfigPoolSetInputSchema: () => ConfigPoolSetInputSchema,
|
|
7907
|
+
ConfigPoolSetOutputSchema: () => ConfigPoolSetOutputSchema,
|
|
7908
|
+
ConfigPoolUseOutputSchema: () => ConfigPoolUseOutputSchema,
|
|
7909
|
+
ConfigProfileAddInputSchema: () => ConfigProfileAddInputSchema,
|
|
7910
|
+
ConfigProfileAddOutputSchema: () => ConfigProfileAddOutputSchema,
|
|
7911
|
+
ConfigProfileRemoveInputSchema: () => ConfigProfileRemoveInputSchema,
|
|
7912
|
+
ConfigProfileRemoveOutputSchema: () => ConfigProfileRemoveOutputSchema,
|
|
7744
7913
|
ConfigProfileSchema: () => ConfigProfileSchema,
|
|
7914
|
+
ConfigProfileSetInputSchema: () => ConfigProfileSetInputSchema,
|
|
7915
|
+
ConfigProfileSetOutputSchema: () => ConfigProfileSetOutputSchema,
|
|
7916
|
+
ConfigProfileUseOutputSchema: () => ConfigProfileUseOutputSchema,
|
|
7917
|
+
ConfigProviderAddInputSchema: () => ConfigProviderAddInputSchema,
|
|
7918
|
+
ConfigProviderAddOutputSchema: () => ConfigProviderAddOutputSchema,
|
|
7919
|
+
ConfigProviderRemoveInputSchema: () => ConfigProviderRemoveInputSchema,
|
|
7920
|
+
ConfigProviderRemoveOutputSchema: () => ConfigProviderRemoveOutputSchema,
|
|
7921
|
+
ConfigProviderSetInputSchema: () => ConfigProviderSetInputSchema,
|
|
7922
|
+
ConfigProviderSetOutputSchema: () => ConfigProviderSetOutputSchema,
|
|
7923
|
+
ConfigRuleAddInputSchema: () => ConfigRuleAddInputSchema,
|
|
7924
|
+
ConfigRuleAddOutputSchema: () => ConfigRuleAddOutputSchema,
|
|
7925
|
+
ConfigRuleRemoveInputSchema: () => ConfigRuleRemoveInputSchema,
|
|
7926
|
+
ConfigRuleRemoveOutputSchema: () => ConfigRuleRemoveOutputSchema,
|
|
7927
|
+
ConfigRuleSetInputSchema: () => ConfigRuleSetInputSchema,
|
|
7928
|
+
ConfigRuleSetOutputSchema: () => ConfigRuleSetOutputSchema,
|
|
7745
7929
|
CredentialCacheSchema: () => CredentialCacheSchema,
|
|
7746
7930
|
CredentialSchema: () => CredentialSchema,
|
|
7747
7931
|
CredentialSourceSchema: () => CredentialSourceSchema,
|
|
7932
|
+
CredentialSummarySchema: () => CredentialSummarySchema2,
|
|
7748
7933
|
DOOR_EVENT_BUFFER_EVENTS: () => DOOR_EVENT_BUFFER_EVENTS,
|
|
7749
7934
|
DOOR_EVENT_SOURCE_RC: () => DOOR_EVENT_SOURCE_RC,
|
|
7750
7935
|
DOOR_HEALTH_EVENT_SOURCE: () => DOOR_HEALTH_EVENT_SOURCE,
|
|
@@ -7765,6 +7950,7 @@ __export(index_exports, {
|
|
|
7765
7950
|
FARM_MANIFEST_FILENAME: () => FARM_MANIFEST_FILENAME,
|
|
7766
7951
|
FrontDoorControlMaterialError: () => FrontDoorControlMaterialError,
|
|
7767
7952
|
FrontDoorNotServingError: () => FrontDoorNotServingError,
|
|
7953
|
+
FrontDoorRestartOutputSchema: () => FrontDoorRestartOutputSchema,
|
|
7768
7954
|
FrontDoorSessionStatusSchema: () => FrontDoorSessionStatusSchema,
|
|
7769
7955
|
FrontDoorSessionsOutputSchema: () => FrontDoorSessionsOutputSchema,
|
|
7770
7956
|
FrontDoorStartError: () => FrontDoorStartError,
|
|
@@ -7782,6 +7968,8 @@ __export(index_exports, {
|
|
|
7782
7968
|
LAUNCH_EVENT_SOURCE: () => LAUNCH_EVENT_SOURCE,
|
|
7783
7969
|
LaunchLifecycleEventSchema: () => LaunchLifecycleEventSchema,
|
|
7784
7970
|
LaunchRefusedError: () => LaunchRefusedError,
|
|
7971
|
+
LaunchResolveInputSchema: () => LaunchResolveInputSchema,
|
|
7972
|
+
LaunchResolveOutputSchema: () => LaunchResolveOutputSchema,
|
|
7785
7973
|
LegacyProviderFileError: () => LegacyProviderFileError,
|
|
7786
7974
|
OWN_CLI_FILE_NAME: () => OWN_CLI_FILE_NAME,
|
|
7787
7975
|
PROMPT_CACHE_TTL_MS: () => PROMPT_CACHE_TTL_MS,
|
|
@@ -7828,6 +8016,7 @@ __export(index_exports, {
|
|
|
7828
8016
|
RcStreamEnvelopeSchema: () => RcStreamEnvelopeSchema,
|
|
7829
8017
|
RcStreamEventSchema: () => RcStreamEventSchema,
|
|
7830
8018
|
USAGE_EVENT_SOURCE: () => USAGE_EVENT_SOURCE,
|
|
8019
|
+
UpdateCheckOutputSchema: () => UpdateCheckOutputSchema,
|
|
7831
8020
|
UsageError: () => UsageError,
|
|
7832
8021
|
UsageListOutputSchema: () => UsageListOutputSchema,
|
|
7833
8022
|
UsageLiveOutputSchema: () => UsageLiveOutputSchema,
|
|
@@ -7870,14 +8059,18 @@ __export(index_exports, {
|
|
|
7870
8059
|
collectDoctorReport: () => collectDoctorReport,
|
|
7871
8060
|
collectFrontDoorStatus: () => collectFrontDoorStatus,
|
|
7872
8061
|
collectPoolPick: () => collectPoolPick,
|
|
8062
|
+
createCodexApiRouter: () => createCodexApiRouter,
|
|
8063
|
+
createConfigApiRouter: () => createConfigApiRouter,
|
|
7873
8064
|
createControlApiRouter: () => createControlApiRouter,
|
|
7874
8065
|
createDoorApiNodeHandler: () => createDoorApiNodeHandler,
|
|
7875
8066
|
createDoorApiRouter: () => createDoorApiRouter,
|
|
7876
8067
|
createDoorEventHub: () => createDoorEventHub,
|
|
7877
8068
|
createDoorHealthPublisher: () => createDoorHealthPublisher,
|
|
7878
8069
|
createEventsApiRouter: () => createEventsApiRouter,
|
|
8070
|
+
createLaunchApiRouter: () => createLaunchApiRouter,
|
|
7879
8071
|
createLaunchEventPublisher: () => createLaunchEventPublisher,
|
|
7880
8072
|
createLeafCache: () => createLeafCache,
|
|
8073
|
+
createLifecycleApiRouter: () => createLifecycleApiRouter,
|
|
7881
8074
|
createProfile: () => createProfile,
|
|
7882
8075
|
createQuotaExpiringPublisher: () => createQuotaExpiringPublisher,
|
|
7883
8076
|
createRcApiNodeHandler: () => createRcApiNodeHandler,
|
|
@@ -7985,7 +8178,9 @@ __export(index_exports, {
|
|
|
7985
8178
|
requirePool: () => requirePool,
|
|
7986
8179
|
resolveAgentShimHome: () => resolveAgentShimHome,
|
|
7987
8180
|
resolveClaudeHome: () => resolveClaudeHome,
|
|
8181
|
+
resolveClaudeLaunch: () => resolveClaudeLaunch,
|
|
7988
8182
|
resolveDecisions: () => resolveDecisions,
|
|
8183
|
+
resolveLaunch: () => resolveLaunch,
|
|
7989
8184
|
resolveLaunchSelection: () => resolveLaunchSelection,
|
|
7990
8185
|
resolveLayoutPaths: () => resolveLayoutPaths,
|
|
7991
8186
|
resolveSupervisorConfig: () => resolveSupervisorConfig,
|
|
@@ -8522,8 +8717,8 @@ function parseConnectTarget(authority) {
|
|
|
8522
8717
|
function isInterceptedHost(host, interceptHosts) {
|
|
8523
8718
|
return interceptHosts.includes(host);
|
|
8524
8719
|
}
|
|
8525
|
-
function servedByPipeline(
|
|
8526
|
-
return
|
|
8720
|
+
function servedByPipeline(path36) {
|
|
8721
|
+
return path36?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
8527
8722
|
}
|
|
8528
8723
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
8529
8724
|
"connection",
|
|
@@ -8884,6 +9079,7 @@ var HTTP_STATUS = {
|
|
|
8884
9079
|
forbidden: 403,
|
|
8885
9080
|
notFound: 404,
|
|
8886
9081
|
methodNotAllowed: 405,
|
|
9082
|
+
conflict: 409,
|
|
8887
9083
|
payloadTooLarge: 413,
|
|
8888
9084
|
tooManyRequests: 429,
|
|
8889
9085
|
/** Not sent to anyone: the client is gone. Recorded for a response abandoned because the client disconnected, following the convention nginx uses for the same case. */
|
|
@@ -9057,11 +9253,11 @@ function createRcSessionTracker(deps) {
|
|
|
9057
9253
|
};
|
|
9058
9254
|
const observeExchange = (request4) => {
|
|
9059
9255
|
const method = (request4.method ?? "").toUpperCase();
|
|
9060
|
-
const
|
|
9061
|
-
if (!
|
|
9256
|
+
const path36 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
9257
|
+
if (!path36.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
9062
9258
|
return void 0;
|
|
9063
9259
|
}
|
|
9064
|
-
const tail =
|
|
9260
|
+
const tail = path36.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
9065
9261
|
const facts = {
|
|
9066
9262
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
9067
9263
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -9443,8 +9639,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
9443
9639
|
function isRcReadFileEncoding(value) {
|
|
9444
9640
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
9445
9641
|
}
|
|
9446
|
-
function buildRcReadFilePayload(requestId,
|
|
9447
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
9642
|
+
function buildRcReadFilePayload(requestId, path36, options) {
|
|
9643
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path36, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
9448
9644
|
}
|
|
9449
9645
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
9450
9646
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -9546,15 +9742,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
9546
9742
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
9547
9743
|
return result.ok ? { ...result, requestId } : result;
|
|
9548
9744
|
}
|
|
9549
|
-
async function readRcSessionFile(deps, sessionId,
|
|
9550
|
-
if (
|
|
9745
|
+
async function readRcSessionFile(deps, sessionId, path36, options) {
|
|
9746
|
+
if (path36 === "") {
|
|
9551
9747
|
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
9748
|
}
|
|
9553
9749
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
9554
9750
|
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
9751
|
}
|
|
9556
9752
|
const requestId = deps.newUuid();
|
|
9557
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
9753
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path36, options), `read ${path36} from session ${sessionId}`);
|
|
9558
9754
|
return result.ok ? { ...result, requestId } : result;
|
|
9559
9755
|
}
|
|
9560
9756
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -9723,11 +9919,11 @@ function createRcControlHandler(deps) {
|
|
|
9723
9919
|
path: "read-file",
|
|
9724
9920
|
read: (body) => {
|
|
9725
9921
|
const session = bodyString(body, "session");
|
|
9726
|
-
const
|
|
9922
|
+
const path36 = bodyString(body, "path");
|
|
9727
9923
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
9728
9924
|
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,
|
|
9925
|
+
const refused2 = session === void 0 || path36 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
9926
|
+
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
9927
|
}
|
|
9732
9928
|
},
|
|
9733
9929
|
{
|
|
@@ -10037,9 +10233,9 @@ function requestIdOfBody(body) {
|
|
|
10037
10233
|
}
|
|
10038
10234
|
function frontDoorRcControl(transport, token) {
|
|
10039
10235
|
const headers = { authorization: `Bearer ${token}` };
|
|
10040
|
-
const listAnswerOf = async (
|
|
10236
|
+
const listAnswerOf = async (path36, what) => {
|
|
10041
10237
|
try {
|
|
10042
|
-
return await transport.request({ method: "GET", path:
|
|
10238
|
+
return await transport.request({ method: "GET", path: path36, headers });
|
|
10043
10239
|
} catch (error) {
|
|
10044
10240
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
10045
10241
|
}
|
|
@@ -10111,10 +10307,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
10111
10307
|
}
|
|
10112
10308
|
return pending;
|
|
10113
10309
|
};
|
|
10114
|
-
const writeOf = async (
|
|
10310
|
+
const writeOf = async (path36, body, describeFailure) => {
|
|
10115
10311
|
let answer;
|
|
10116
10312
|
try {
|
|
10117
|
-
answer = await transport.request({ method: "POST", path:
|
|
10313
|
+
answer = await transport.request({ method: "POST", path: path36, headers: { ...headers, "content-type": "application/json" }, body });
|
|
10118
10314
|
} catch (error) {
|
|
10119
10315
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
10120
10316
|
}
|
|
@@ -10145,10 +10341,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
10145
10341
|
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
10342
|
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
10343
|
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,
|
|
10344
|
+
readFile: async (sessionId, path36, options) => await writeOf(
|
|
10149
10345
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
10150
|
-
JSON.stringify({ session: sessionId, path:
|
|
10151
|
-
(status, message) => `reading ${
|
|
10346
|
+
JSON.stringify({ session: sessionId, path: path36, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
10347
|
+
(status, message) => `reading ${path36} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
10152
10348
|
),
|
|
10153
10349
|
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
10350
|
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 +10503,12 @@ function tlsFacts(options) {
|
|
|
10307
10503
|
}
|
|
10308
10504
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10309
10505
|
const agent = new ExemptTlsAgent();
|
|
10310
|
-
const post = async (
|
|
10506
|
+
const post = async (path36, headers, body) => await new Promise((resolve, reject) => {
|
|
10311
10507
|
const options = {
|
|
10312
10508
|
host: target.host,
|
|
10313
10509
|
port: target.port,
|
|
10314
10510
|
method: "POST",
|
|
10315
|
-
path:
|
|
10511
|
+
path: path36,
|
|
10316
10512
|
// 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
10513
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
10318
10514
|
agent
|
|
@@ -10377,12 +10573,12 @@ function lateRcStreamDial(resolve) {
|
|
|
10377
10573
|
}
|
|
10378
10574
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10379
10575
|
const agent = new ExemptTlsAgent();
|
|
10380
|
-
const request4 = async (method,
|
|
10576
|
+
const request4 = async (method, path36, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
10381
10577
|
const options = {
|
|
10382
10578
|
host: target.host,
|
|
10383
10579
|
port: target.port,
|
|
10384
10580
|
method,
|
|
10385
|
-
path:
|
|
10581
|
+
path: path36,
|
|
10386
10582
|
// 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
10583
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
10388
10584
|
agent,
|
|
@@ -10424,9 +10620,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
10424
10620
|
return { status, body: await readAll(response) };
|
|
10425
10621
|
},
|
|
10426
10622
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
10427
|
-
const
|
|
10623
|
+
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
10624
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
10429
|
-
const { status, response } = await request4("GET",
|
|
10625
|
+
const { status, response } = await request4("GET", path36, streamHeaders, void 0, signal);
|
|
10430
10626
|
if (!isSuccessful2(status)) {
|
|
10431
10627
|
await readAll(response);
|
|
10432
10628
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -11009,9 +11205,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
11009
11205
|
if (request4.method === "GET" && request4.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
|
|
11010
11206
|
const token = doorApiBearer(request4.headers);
|
|
11011
11207
|
if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
|
|
11012
|
-
const
|
|
11208
|
+
const refusal2 = new import_client.ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
|
|
11013
11209
|
response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
|
|
11014
|
-
response.end(JSON.stringify(
|
|
11210
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
11015
11211
|
return { matched: true };
|
|
11016
11212
|
}
|
|
11017
11213
|
try {
|
|
@@ -11019,17 +11215,21 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
11019
11215
|
response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
|
|
11020
11216
|
response.end(JSON.stringify(doc));
|
|
11021
11217
|
} catch (error) {
|
|
11022
|
-
const
|
|
11218
|
+
const refusal2 = new import_client.ORPCError("INTERNAL_SERVER_ERROR", { message: `the OpenAPI document could not be generated from the door's own router: ${error instanceof Error ? error.message : String(error)}` });
|
|
11023
11219
|
response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
|
|
11024
|
-
response.end(JSON.stringify(
|
|
11220
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
11025
11221
|
}
|
|
11026
11222
|
return { matched: true };
|
|
11027
11223
|
}
|
|
11028
|
-
const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers
|
|
11224
|
+
const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers, afterResponse: (action) => {
|
|
11225
|
+
response.once("finish", action);
|
|
11226
|
+
} }, prefix: RC_ORPC_PATH_PREFIX });
|
|
11029
11227
|
if (rest.matched) {
|
|
11030
11228
|
return rest;
|
|
11031
11229
|
}
|
|
11032
|
-
return await rpcHandler.handle(request4, response, { context: { headers: request4.headers
|
|
11230
|
+
return await rpcHandler.handle(request4, response, { context: { headers: request4.headers, afterResponse: (action) => {
|
|
11231
|
+
response.once("finish", action);
|
|
11232
|
+
} }, prefix: RC_ORPC_PATH_PREFIX });
|
|
11033
11233
|
}
|
|
11034
11234
|
};
|
|
11035
11235
|
}
|
|
@@ -11066,8 +11266,8 @@ init_cliError();
|
|
|
11066
11266
|
init_realPorts();
|
|
11067
11267
|
|
|
11068
11268
|
// src/frontdoor/controlApi.ts
|
|
11069
|
-
var
|
|
11070
|
-
var
|
|
11269
|
+
var import_client6 = require("@orpc/client");
|
|
11270
|
+
var import_openapi7 = require("@orpc/openapi");
|
|
11071
11271
|
|
|
11072
11272
|
// src/checkReport.ts
|
|
11073
11273
|
var import_node_os5 = __toESM(require("node:os"), 1);
|
|
@@ -11251,6 +11451,48 @@ function removeProfile(paths, name) {
|
|
|
11251
11451
|
requireProfileExists(paths, name);
|
|
11252
11452
|
import_node_fs3.default.rmSync(profileJsonPath(paths, name));
|
|
11253
11453
|
}
|
|
11454
|
+
function applyProfileChange(paths, name, change) {
|
|
11455
|
+
let touched = false;
|
|
11456
|
+
if (change.category !== void 0) {
|
|
11457
|
+
setProfileCategories(paths, name, change.category);
|
|
11458
|
+
touched = true;
|
|
11459
|
+
}
|
|
11460
|
+
if (change.entry !== void 0) {
|
|
11461
|
+
setProfileEntries(paths, name, change.entry);
|
|
11462
|
+
touched = true;
|
|
11463
|
+
}
|
|
11464
|
+
if (change.extends !== void 0 || change.description !== void 0) {
|
|
11465
|
+
setProfileMetadata(paths, name, {
|
|
11466
|
+
...change.extends === void 0 ? {} : { extends: change.extends === false ? [] : change.extends },
|
|
11467
|
+
...change.description === void 0 ? {} : { description: change.description }
|
|
11468
|
+
});
|
|
11469
|
+
touched = true;
|
|
11470
|
+
}
|
|
11471
|
+
const launchPatch = {};
|
|
11472
|
+
if (change.launchSkipPermissions !== void 0) {
|
|
11473
|
+
launchPatch.skipPermissions = change.launchSkipPermissions;
|
|
11474
|
+
}
|
|
11475
|
+
if (change.launchRemoteControl !== void 0) {
|
|
11476
|
+
launchPatch.remoteControl = change.launchRemoteControl;
|
|
11477
|
+
}
|
|
11478
|
+
if (change.launchHeadroom !== void 0) {
|
|
11479
|
+
launchPatch.headroom = change.launchHeadroom;
|
|
11480
|
+
}
|
|
11481
|
+
if (change.launchTrackUsage !== void 0) {
|
|
11482
|
+
launchPatch.trackUsage = change.launchTrackUsage;
|
|
11483
|
+
}
|
|
11484
|
+
if (change.launchProvider !== void 0) {
|
|
11485
|
+
launchPatch.provider = change.launchProvider === false ? void 0 : change.launchProvider;
|
|
11486
|
+
}
|
|
11487
|
+
if (change.launchClaudeVersion !== void 0) {
|
|
11488
|
+
launchPatch.claudeVersion = change.launchClaudeVersion === false ? void 0 : change.launchClaudeVersion;
|
|
11489
|
+
}
|
|
11490
|
+
if (Object.keys(launchPatch).length > 0) {
|
|
11491
|
+
setProfileLaunchFlags(paths, name, launchPatch);
|
|
11492
|
+
touched = true;
|
|
11493
|
+
}
|
|
11494
|
+
return touched;
|
|
11495
|
+
}
|
|
11254
11496
|
|
|
11255
11497
|
// src/poolStore.ts
|
|
11256
11498
|
init_store();
|
|
@@ -11294,19 +11536,19 @@ function writePools(paths, pools) {
|
|
|
11294
11536
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
11295
11537
|
}
|
|
11296
11538
|
function poolCycleOf(pools, name) {
|
|
11297
|
-
const walk = (current,
|
|
11539
|
+
const walk = (current, path36) => {
|
|
11298
11540
|
for (const entry of pools[current]?.identities ?? []) {
|
|
11299
11541
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
11300
11542
|
if (nested === void 0) {
|
|
11301
11543
|
continue;
|
|
11302
11544
|
}
|
|
11303
11545
|
if (nested === name) {
|
|
11304
|
-
return [...
|
|
11546
|
+
return [...path36, nested];
|
|
11305
11547
|
}
|
|
11306
|
-
if (
|
|
11548
|
+
if (path36.includes(nested)) {
|
|
11307
11549
|
continue;
|
|
11308
11550
|
}
|
|
11309
|
-
const found = walk(nested, [...
|
|
11551
|
+
const found = walk(nested, [...path36, nested]);
|
|
11310
11552
|
if (found !== void 0) {
|
|
11311
11553
|
return found;
|
|
11312
11554
|
}
|
|
@@ -12024,6 +12266,14 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
12024
12266
|
function identityJsonPath(paths, name) {
|
|
12025
12267
|
return import_node_path27.default.join(paths.identitiesDir, name, "identity.json");
|
|
12026
12268
|
}
|
|
12269
|
+
function requireIdentityNames(paths, names) {
|
|
12270
|
+
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
12271
|
+
for (const name of names) {
|
|
12272
|
+
if (poolNameOf(name) === void 0 && !existing.has(name)) {
|
|
12273
|
+
throw new IdentityNotFoundError(name);
|
|
12274
|
+
}
|
|
12275
|
+
}
|
|
12276
|
+
}
|
|
12027
12277
|
function identityExists(paths, name) {
|
|
12028
12278
|
return import_node_fs8.default.existsSync(identityJsonPath(paths, name));
|
|
12029
12279
|
}
|
|
@@ -12877,103 +13127,813 @@ var DoctorRunOutputSchema = import_zod19.z.strictObject({
|
|
|
12877
13127
|
ok: import_zod19.z.boolean(),
|
|
12878
13128
|
findings: import_zod19.z.readonly(import_zod19.z.array(DoctorFindingSchema))
|
|
12879
13129
|
});
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
|
|
12883
|
-
|
|
12884
|
-
var
|
|
12885
|
-
|
|
12886
|
-
|
|
12887
|
-
|
|
12888
|
-
|
|
12889
|
-
var
|
|
12890
|
-
|
|
12891
|
-
|
|
12892
|
-
|
|
12893
|
-
var DoorEventSchema = import_zod20.z.strictObject({
|
|
12894
|
-
source: import_zod20.z.string().min(1),
|
|
12895
|
-
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
12896
|
-
sequence: import_zod20.z.number().int().positive(),
|
|
12897
|
-
payload: import_zod20.z.unknown()
|
|
12898
|
-
});
|
|
12899
|
-
var DoorEventSourceQuerySchema = import_zod20.z.strictObject({
|
|
12900
|
-
sources: import_zod20.z.array(import_zod20.z.string().min(1)).min(1).optional()
|
|
12901
|
-
});
|
|
12902
|
-
var LaunchLifecycleEventSchema = import_zod20.z.strictObject({
|
|
12903
|
-
kind: import_zod20.z.enum(["registered", "pruned", "ended"]),
|
|
12904
|
-
pid: import_zod20.z.number().int().positive(),
|
|
12905
|
-
startedAt: import_zod20.z.number(),
|
|
12906
|
-
observedAt: import_zod20.z.number()
|
|
12907
|
-
});
|
|
12908
|
-
var DoorHealthEventSchema = import_zod20.z.discriminatedUnion("kind", [
|
|
12909
|
-
import_zod20.z.strictObject({ kind: import_zod20.z.literal("generation"), pid: import_zod20.z.number().int().positive(), providerPort: import_zod20.z.number().int().positive(), connectPort: import_zod20.z.number().int().positive(), directPort: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() }),
|
|
12910
|
-
import_zod20.z.strictObject({ kind: import_zod20.z.literal("listenerFailed"), pid: import_zod20.z.number().int().positive(), listener: import_zod20.z.enum(["provider", "connect", "direct"]), message: import_zod20.z.string(), observedAt: import_zod20.z.number() }),
|
|
12911
|
-
import_zod20.z.strictObject({ kind: import_zod20.z.literal("binaryTurnover"), pid: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() }),
|
|
12912
|
-
import_zod20.z.strictObject({ kind: import_zod20.z.literal("idleShutdown"), pid: import_zod20.z.number().int().positive(), observedAt: import_zod20.z.number() })
|
|
13130
|
+
var FrontDoorRestartOutputSchema = import_zod19.z.strictObject({
|
|
13131
|
+
action: import_zod19.z.literal("restarting"),
|
|
13132
|
+
previousPid: import_zod19.z.int().positive()
|
|
13133
|
+
});
|
|
13134
|
+
var UpdateCheckOutputSchema = import_zod19.z.strictObject({
|
|
13135
|
+
current: import_zod19.z.string(),
|
|
13136
|
+
latest: import_zod19.z.string(),
|
|
13137
|
+
action: import_zod19.z.enum(["current", "available", "updated"])
|
|
13138
|
+
});
|
|
13139
|
+
var CodexSignInSchema = import_zod19.z.discriminatedUnion("state", [
|
|
13140
|
+
import_zod19.z.strictObject({ state: import_zod19.z.literal("none") }),
|
|
13141
|
+
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() }),
|
|
13142
|
+
import_zod19.z.strictObject({ state: import_zod19.z.literal("unreadable"), message: import_zod19.z.string() })
|
|
12913
13143
|
]);
|
|
12914
|
-
var
|
|
12915
|
-
|
|
12916
|
-
|
|
12917
|
-
|
|
12918
|
-
|
|
12919
|
-
|
|
12920
|
-
|
|
12921
|
-
observedAt: import_zod20.z.number()
|
|
13144
|
+
var CodexStatusOutputSchema = import_zod19.z.strictObject({
|
|
13145
|
+
signIn: CodexSignInSchema,
|
|
13146
|
+
codexProviders: import_zod19.z.readonly(import_zod19.z.array(import_zod19.z.string()))
|
|
13147
|
+
});
|
|
13148
|
+
var CodexLogoutOutputSchema = import_zod19.z.strictObject({
|
|
13149
|
+
hadGrant: import_zod19.z.boolean(),
|
|
13150
|
+
revoked: import_zod19.z.boolean()
|
|
12922
13151
|
});
|
|
12923
13152
|
|
|
12924
|
-
// src/frontdoor/
|
|
12925
|
-
var
|
|
12926
|
-
|
|
13153
|
+
// src/frontdoor/codexApi.ts
|
|
13154
|
+
var import_openapi2 = require("@orpc/openapi");
|
|
13155
|
+
var CODEX_API_TAG = "codex";
|
|
13156
|
+
function createCodexApiRouter(deps) {
|
|
12927
13157
|
const authed = doorApiAuth(deps.expectedToken);
|
|
12928
13158
|
return {
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
throw new import_client2.ORPCError("NOT_FOUND", { message: `the door publishes no event source named ${unknown.map((source) => `"${source}"`).join(", ")}; the live sources are ${live.map((source) => `"${source}"`).join(", ")}` });
|
|
12936
|
-
}
|
|
12937
|
-
}
|
|
12938
|
-
const stream = deps.events.stream(input.sources);
|
|
12939
|
-
const ended = new Promise((resolve) => {
|
|
12940
|
-
signal?.addEventListener("abort", () => {
|
|
12941
|
-
resolve();
|
|
12942
|
-
}, { once: true });
|
|
12943
|
-
});
|
|
12944
|
-
try {
|
|
12945
|
-
for (; ; ) {
|
|
12946
|
-
signal?.throwIfAborted();
|
|
12947
|
-
const next = await Promise.race([stream.next(), ended.then(() => ({ value: void 0, done: true }))]);
|
|
12948
|
-
if (next.done === true) {
|
|
12949
|
-
signal?.throwIfAborted();
|
|
12950
|
-
return;
|
|
12951
|
-
}
|
|
12952
|
-
yield (0, import_server3.withEventMeta)(next.value, { id: String(next.value.sequence) });
|
|
12953
|
-
}
|
|
12954
|
-
} finally {
|
|
12955
|
-
stream.close();
|
|
12956
|
-
}
|
|
12957
|
-
})
|
|
13159
|
+
codex: {
|
|
13160
|
+
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(() => {
|
|
13161
|
+
const status = deps.codexStatus();
|
|
13162
|
+
return { signIn: status.signIn, codexProviders: status.codexProviders };
|
|
13163
|
+
}),
|
|
13164
|
+
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())
|
|
12958
13165
|
}
|
|
12959
13166
|
};
|
|
12960
13167
|
}
|
|
12961
13168
|
|
|
12962
|
-
// src/frontdoor/
|
|
12963
|
-
var
|
|
12964
|
-
var
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
|
|
12970
|
-
|
|
12971
|
-
|
|
12972
|
-
|
|
12973
|
-
|
|
12974
|
-
|
|
13169
|
+
// src/frontdoor/configApi.ts
|
|
13170
|
+
var import_client2 = require("@orpc/client");
|
|
13171
|
+
var import_openapi3 = require("@orpc/openapi");
|
|
13172
|
+
init_cliError();
|
|
13173
|
+
init_schema();
|
|
13174
|
+
init_credential();
|
|
13175
|
+
|
|
13176
|
+
// src/credentialCacheChange.ts
|
|
13177
|
+
init_cliError();
|
|
13178
|
+
init_schema();
|
|
13179
|
+
function mergeCredentialCache(request4, existing) {
|
|
13180
|
+
if (request4.enabled === false) {
|
|
13181
|
+
return false;
|
|
13182
|
+
}
|
|
13183
|
+
if (request4.ttl === void 0 && request4.store === void 0 && request4.enabled !== true) {
|
|
13184
|
+
return void 0;
|
|
13185
|
+
}
|
|
13186
|
+
const parsed = CredentialCacheSchema.safeParse({
|
|
13187
|
+
...existing,
|
|
13188
|
+
...request4.ttl === void 0 ? {} : { ttl: request4.ttl },
|
|
13189
|
+
...request4.store === void 0 ? {} : { store: request4.store }
|
|
13190
|
+
});
|
|
13191
|
+
if (!parsed.success) {
|
|
13192
|
+
throw new UsageError(parsed.error.issues.map((issue) => issue.message).join("; "));
|
|
13193
|
+
}
|
|
13194
|
+
return parsed.data;
|
|
13195
|
+
}
|
|
13196
|
+
|
|
13197
|
+
// src/directoryRulesStore.ts
|
|
13198
|
+
init_store();
|
|
13199
|
+
init_load();
|
|
13200
|
+
init_schema();
|
|
13201
|
+
init_cliError();
|
|
13202
|
+
var DirectoryRuleNotFoundError = class extends CliError {
|
|
13203
|
+
constructor(rulePath) {
|
|
13204
|
+
super(`No directory rule found for path "${rulePath}".`);
|
|
13205
|
+
this.rulePath = rulePath;
|
|
13206
|
+
this.name = "DirectoryRuleNotFoundError";
|
|
13207
|
+
}
|
|
13208
|
+
rulePath;
|
|
13209
|
+
};
|
|
13210
|
+
var DirectoryRuleMissingTargetError = class extends CliError {
|
|
13211
|
+
constructor() {
|
|
13212
|
+
super("A directory rule must set at least one of --config-profile or --identity.");
|
|
13213
|
+
this.name = "DirectoryRuleMissingTargetError";
|
|
13214
|
+
}
|
|
13215
|
+
};
|
|
13216
|
+
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
13217
|
+
constructor(rulePath) {
|
|
13218
|
+
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
13219
|
+
this.rulePath = rulePath;
|
|
13220
|
+
this.name = "DirectoryRuleAlreadyExistsError";
|
|
13221
|
+
}
|
|
13222
|
+
rulePath;
|
|
13223
|
+
};
|
|
13224
|
+
function readDirectoryRules(paths) {
|
|
13225
|
+
return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
|
|
13226
|
+
}
|
|
13227
|
+
function writeDirectoryRules(paths, rules) {
|
|
13228
|
+
const parsed = DirectoryRulesSchema.safeParse(rules);
|
|
13229
|
+
if (!parsed.success) {
|
|
13230
|
+
throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
|
|
13231
|
+
}
|
|
13232
|
+
writeJsonAtomic(paths.directoryRulesFile, parsed.data);
|
|
13233
|
+
}
|
|
13234
|
+
function listDirectoryRules(paths) {
|
|
13235
|
+
return readDirectoryRules(paths).rules;
|
|
13236
|
+
}
|
|
13237
|
+
function addDirectoryRule(paths, rulePath, options) {
|
|
13238
|
+
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
13239
|
+
throw new DirectoryRuleMissingTargetError();
|
|
13240
|
+
}
|
|
13241
|
+
const current = readDirectoryRules(paths);
|
|
13242
|
+
if (current.rules.some((rule) => rule.path === rulePath)) {
|
|
13243
|
+
throw new DirectoryRuleAlreadyExistsError(rulePath);
|
|
13244
|
+
}
|
|
13245
|
+
const created = buildNewRule(rulePath, options);
|
|
13246
|
+
writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
|
|
13247
|
+
return created;
|
|
13248
|
+
}
|
|
13249
|
+
function ruleHasEffect(rule) {
|
|
13250
|
+
return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
|
|
13251
|
+
}
|
|
13252
|
+
function updateDirectoryRule(paths, rulePath, options) {
|
|
13253
|
+
const current = readDirectoryRules(paths);
|
|
13254
|
+
const index = current.rules.findIndex((rule) => rule.path === rulePath);
|
|
13255
|
+
const existing = index === -1 ? void 0 : current.rules[index];
|
|
13256
|
+
if (existing === void 0) {
|
|
13257
|
+
throw new DirectoryRuleNotFoundError(rulePath);
|
|
13258
|
+
}
|
|
13259
|
+
const { configProfile, identity, ...rest } = existing;
|
|
13260
|
+
const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
|
|
13261
|
+
const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
|
|
13262
|
+
const updated = {
|
|
13263
|
+
...rest,
|
|
13264
|
+
...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
|
|
13265
|
+
...nextIdentity === void 0 ? {} : { identity: nextIdentity }
|
|
13266
|
+
};
|
|
13267
|
+
if (!ruleHasEffect(updated)) {
|
|
13268
|
+
throw new DirectoryRuleMissingTargetError();
|
|
13269
|
+
}
|
|
13270
|
+
const nextRules = [...current.rules];
|
|
13271
|
+
nextRules[index] = updated;
|
|
13272
|
+
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
13273
|
+
return updated;
|
|
13274
|
+
}
|
|
13275
|
+
function buildNewRule(rulePath, options) {
|
|
13276
|
+
return {
|
|
13277
|
+
path: rulePath,
|
|
13278
|
+
...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
|
|
13279
|
+
...options.identity !== void 0 ? { identity: options.identity } : {}
|
|
13280
|
+
};
|
|
13281
|
+
}
|
|
13282
|
+
function removeDirectoryRule(paths, rulePath) {
|
|
13283
|
+
const current = readDirectoryRules(paths);
|
|
13284
|
+
const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
|
|
13285
|
+
if (nextRules.length === current.rules.length) {
|
|
13286
|
+
throw new DirectoryRuleNotFoundError(rulePath);
|
|
13287
|
+
}
|
|
13288
|
+
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
13289
|
+
}
|
|
13290
|
+
function requireRuleSelector(paths, selector) {
|
|
13291
|
+
if (selector.startsWith(POOL_SELECTOR_PREFIX)) {
|
|
13292
|
+
const poolName = selector.slice(POOL_SELECTOR_PREFIX.length);
|
|
13293
|
+
if (readPools(paths)[poolName] === void 0) {
|
|
13294
|
+
throw new PoolNotFoundError(poolName);
|
|
13295
|
+
}
|
|
13296
|
+
} else if (readIdentity(paths, selector) === void 0) {
|
|
13297
|
+
throw new IdentityNotFoundError(selector);
|
|
13298
|
+
}
|
|
13299
|
+
}
|
|
13300
|
+
|
|
13301
|
+
// src/frontdoor/configApi.ts
|
|
13302
|
+
init_identity();
|
|
13303
|
+
init_providersStore();
|
|
13304
|
+
|
|
13305
|
+
// src/frontdoor/configSchemas.ts
|
|
13306
|
+
var import_zod20 = require("zod");
|
|
13307
|
+
init_schema();
|
|
13308
|
+
var RemovalConfirmationSchema = import_zod20.z.boolean();
|
|
13309
|
+
var CredentialWriteSchema = (targets) => import_zod20.z.strictObject({
|
|
13310
|
+
sources: import_zod20.z.array(RemoteCredentialSourceSchema).min(1).optional(),
|
|
13311
|
+
target: import_zod20.z.enum(targets).optional(),
|
|
13312
|
+
cache: import_zod20.z.union([import_zod20.z.literal(false), CredentialCacheSchema]).optional()
|
|
13313
|
+
});
|
|
13314
|
+
var CredentialSummarySchema2 = import_zod20.z.strictObject({
|
|
13315
|
+
target: import_zod20.z.enum(CREDENTIAL_TARGETS),
|
|
13316
|
+
sources: import_zod20.z.readonly(import_zod20.z.array(
|
|
13317
|
+
import_zod20.z.discriminatedUnion("kind", [
|
|
13318
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("env"), variable: import_zod20.z.string() }),
|
|
13319
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("file"), path: import_zod20.z.string() }),
|
|
13320
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("command"), program: import_zod20.z.string() }),
|
|
13321
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("op"), reference: import_zod20.z.string() }),
|
|
13322
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("keychain"), service: import_zod20.z.string(), account: import_zod20.z.string().optional() }),
|
|
13323
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("literal") })
|
|
13324
|
+
])
|
|
13325
|
+
)),
|
|
13326
|
+
cache: CredentialCacheSchema.optional()
|
|
13327
|
+
});
|
|
13328
|
+
var mutationOutput = (kind, action) => import_zod20.z.strictObject({ action: import_zod20.z.literal(action), kind: import_zod20.z.literal(kind), name: import_zod20.z.string() });
|
|
13329
|
+
var storedMutationOutput = (kind, action, value) => import_zod20.z.strictObject({ action: import_zod20.z.literal(action), kind: import_zod20.z.literal(kind), name: import_zod20.z.string(), value });
|
|
13330
|
+
var IdentityValueSchema = import_zod20.z.strictObject({
|
|
13331
|
+
name: import_zod20.z.string(),
|
|
13332
|
+
defaultConfigProfile: import_zod20.z.string().optional(),
|
|
13333
|
+
allowAmbientCredential: import_zod20.z.boolean(),
|
|
13334
|
+
credential: CredentialSummarySchema2.optional()
|
|
13335
|
+
});
|
|
13336
|
+
var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
|
|
13337
|
+
var ProviderValueSchema = import_zod20.z.strictObject({
|
|
13338
|
+
name: import_zod20.z.string(),
|
|
13339
|
+
kind: import_zod20.z.enum(PROVIDER_KINDS),
|
|
13340
|
+
displayName: import_zod20.z.string(),
|
|
13341
|
+
baseUrl: import_zod20.z.string().optional(),
|
|
13342
|
+
codex: CodexProviderConfigSchema.optional(),
|
|
13343
|
+
credential: CredentialSummarySchema2,
|
|
13344
|
+
env: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.string()).optional()
|
|
13345
|
+
});
|
|
13346
|
+
var ConfigNameInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1) });
|
|
13347
|
+
var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
|
|
13348
|
+
var ConfigIdentitySetInputSchema = import_zod20.z.strictObject({
|
|
13349
|
+
name: import_zod20.z.string().min(1),
|
|
13350
|
+
defaultConfigProfile: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
|
|
13351
|
+
allowAmbientCredential: import_zod20.z.boolean().optional(),
|
|
13352
|
+
credential: import_zod20.z.union([import_zod20.z.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
|
|
13353
|
+
});
|
|
13354
|
+
var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
|
|
13355
|
+
var ConfigIdentityRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13356
|
+
var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
|
|
13357
|
+
var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
|
|
13358
|
+
var ConfigProfileAddInputSchema = import_zod20.z.strictObject({
|
|
13359
|
+
name: import_zod20.z.string().min(1),
|
|
13360
|
+
extends: import_zod20.z.array(import_zod20.z.string().min(1)).optional(),
|
|
13361
|
+
description: import_zod20.z.string().optional()
|
|
13362
|
+
});
|
|
13363
|
+
var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
|
|
13364
|
+
var ConfigProfileSetInputSchema = import_zod20.z.strictObject({
|
|
13365
|
+
name: import_zod20.z.string().min(1),
|
|
13366
|
+
category: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.boolean()).optional(),
|
|
13367
|
+
entry: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.boolean()).optional(),
|
|
13368
|
+
extends: import_zod20.z.union([import_zod20.z.array(import_zod20.z.string().min(1)), import_zod20.z.literal(false)]).optional(),
|
|
13369
|
+
description: import_zod20.z.union([import_zod20.z.string(), import_zod20.z.literal(false)]).optional(),
|
|
13370
|
+
launch: import_zod20.z.strictObject({
|
|
13371
|
+
skipPermissions: import_zod20.z.boolean().optional(),
|
|
13372
|
+
remoteControl: import_zod20.z.boolean().optional(),
|
|
13373
|
+
headroom: import_zod20.z.boolean().optional(),
|
|
13374
|
+
trackUsage: import_zod20.z.boolean().optional(),
|
|
13375
|
+
provider: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
|
|
13376
|
+
claudeVersion: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional()
|
|
13377
|
+
}).optional()
|
|
13378
|
+
});
|
|
13379
|
+
var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
|
|
13380
|
+
var ConfigProfileRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13381
|
+
var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
|
|
13382
|
+
var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
|
|
13383
|
+
var PoolMembersInputSchema = import_zod20.z.array(import_zod20.z.string().min(1)).min(1);
|
|
13384
|
+
var ConfigPoolAddInputSchema = import_zod20.z.strictObject({
|
|
13385
|
+
name: import_zod20.z.string().min(1),
|
|
13386
|
+
identities: PoolMembersInputSchema,
|
|
13387
|
+
preference: import_zod20.z.enum(POOL_PREFERENCES).optional()
|
|
13388
|
+
});
|
|
13389
|
+
var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
|
|
13390
|
+
var ConfigPoolSetInputSchema = import_zod20.z.strictObject({
|
|
13391
|
+
name: import_zod20.z.string().min(1),
|
|
13392
|
+
identities: PoolMembersInputSchema.optional(),
|
|
13393
|
+
preference: import_zod20.z.union([import_zod20.z.enum(POOL_PREFERENCES), import_zod20.z.literal(false)]).optional()
|
|
13394
|
+
});
|
|
13395
|
+
var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
|
|
13396
|
+
var ConfigPoolRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13397
|
+
var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
|
|
13398
|
+
var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
|
|
13399
|
+
var ConfigProviderAddInputSchema = import_zod20.z.strictObject({
|
|
13400
|
+
name: import_zod20.z.string().min(1),
|
|
13401
|
+
kind: import_zod20.z.enum(PROVIDER_KINDS).optional(),
|
|
13402
|
+
displayName: import_zod20.z.string().min(1),
|
|
13403
|
+
baseUrl: import_zod20.z.string().min(1).optional(),
|
|
13404
|
+
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
|
|
13405
|
+
codex: CodexProviderConfigSchema.optional()
|
|
13406
|
+
});
|
|
13407
|
+
var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
|
|
13408
|
+
var ConfigProviderSetInputSchema = import_zod20.z.strictObject({
|
|
13409
|
+
name: import_zod20.z.string().min(1),
|
|
13410
|
+
displayName: import_zod20.z.string().min(1).optional(),
|
|
13411
|
+
baseUrl: import_zod20.z.string().min(1).optional(),
|
|
13412
|
+
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
|
|
13413
|
+
codex: CodexProviderConfigSchema.optional()
|
|
13414
|
+
});
|
|
13415
|
+
var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
|
|
13416
|
+
var ConfigProviderRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13417
|
+
var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
|
|
13418
|
+
var ConfigRuleAddInputSchema = import_zod20.z.strictObject({
|
|
13419
|
+
path: import_zod20.z.string().min(1),
|
|
13420
|
+
configProfile: import_zod20.z.string().min(1).optional(),
|
|
13421
|
+
identity: import_zod20.z.string().min(1).optional()
|
|
13422
|
+
});
|
|
13423
|
+
var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
|
|
13424
|
+
var ConfigRuleSetInputSchema = import_zod20.z.strictObject({
|
|
13425
|
+
path: import_zod20.z.string().min(1),
|
|
13426
|
+
configProfile: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
|
|
13427
|
+
identity: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional()
|
|
13428
|
+
});
|
|
13429
|
+
var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
|
|
13430
|
+
var ConfigRuleRemoveInputSchema = import_zod20.z.strictObject({ path: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13431
|
+
var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
|
|
13432
|
+
|
|
13433
|
+
// src/frontdoor/configApi.ts
|
|
13434
|
+
var CONFIG_API_TAG = "config";
|
|
13435
|
+
function refusal(error) {
|
|
13436
|
+
if (error instanceof IdentityNotFoundError || error instanceof ProfileNotFoundError || error instanceof PoolNotFoundError || error instanceof ProviderNotFoundError || error instanceof DirectoryRuleNotFoundError) {
|
|
13437
|
+
throw new import_client2.ORPCError("NOT_FOUND", { message: error.message });
|
|
13438
|
+
}
|
|
13439
|
+
if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError) {
|
|
13440
|
+
throw new import_client2.ORPCError("CONFLICT", { message: error.message });
|
|
13441
|
+
}
|
|
13442
|
+
if (error instanceof CliError) {
|
|
13443
|
+
throw new import_client2.ORPCError("BAD_REQUEST", { message: error.message });
|
|
13444
|
+
}
|
|
13445
|
+
throw error;
|
|
13446
|
+
}
|
|
13447
|
+
function guarded(write) {
|
|
13448
|
+
try {
|
|
13449
|
+
return write();
|
|
13450
|
+
} catch (error) {
|
|
13451
|
+
return refusal(error);
|
|
13452
|
+
}
|
|
13453
|
+
}
|
|
13454
|
+
function requireConfirmation(confirm, what) {
|
|
13455
|
+
if (!confirm) {
|
|
13456
|
+
throw new import_client2.ORPCError("BAD_REQUEST", { message: `removing ${what} needs confirm: true, the API's form of the CLI's --yes` });
|
|
13457
|
+
}
|
|
13458
|
+
}
|
|
13459
|
+
function requireChange(given, fields) {
|
|
13460
|
+
if (!given) {
|
|
13461
|
+
throw new import_client2.ORPCError("BAD_REQUEST", { message: `Nothing to change: pass ${fields}.` });
|
|
13462
|
+
}
|
|
13463
|
+
}
|
|
13464
|
+
function identityValue(name, paths) {
|
|
13465
|
+
const identity = readIdentity(paths, name);
|
|
13466
|
+
if (identity === void 0) {
|
|
13467
|
+
throw new IdentityNotFoundError(name);
|
|
13468
|
+
}
|
|
13469
|
+
return {
|
|
13470
|
+
name: identity.name,
|
|
13471
|
+
...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
|
|
13472
|
+
allowAmbientCredential: identity.allowAmbientCredential,
|
|
13473
|
+
...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
|
|
13474
|
+
};
|
|
13475
|
+
}
|
|
13476
|
+
function providerValue(name, provider) {
|
|
13477
|
+
return {
|
|
13478
|
+
name,
|
|
13479
|
+
kind: provider.kind ?? "http",
|
|
13480
|
+
displayName: provider.displayName,
|
|
13481
|
+
...isCodexProvider(provider) ? provider.codex === void 0 ? {} : { codex: provider.codex } : { baseUrl: provider.baseUrl },
|
|
13482
|
+
credential: summariseCredential(provider.credential),
|
|
13483
|
+
...provider.env === void 0 ? {} : { env: provider.env }
|
|
13484
|
+
};
|
|
13485
|
+
}
|
|
13486
|
+
function profileValue(name, paths) {
|
|
13487
|
+
const profile = { ...readProfile(paths, name) };
|
|
13488
|
+
delete profile.$schema;
|
|
13489
|
+
return profile;
|
|
13490
|
+
}
|
|
13491
|
+
function createConfigApiRouter(deps) {
|
|
13492
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13493
|
+
const { paths } = deps;
|
|
13494
|
+
const route = (path36, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path36, summary, tags: [CONFIG_API_TAG] }));
|
|
13495
|
+
return {
|
|
13496
|
+
config: {
|
|
13497
|
+
identity: {
|
|
13498
|
+
add: route("/rest/config/identity/add", "Create an identity").input(ConfigNameInputSchema).output(ConfigIdentityAddOutputSchema).handler(
|
|
13499
|
+
({ input }) => guarded(() => {
|
|
13500
|
+
addIdentity(paths, input.name);
|
|
13501
|
+
return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
13502
|
+
})
|
|
13503
|
+
),
|
|
13504
|
+
set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
|
|
13505
|
+
({ input }) => guarded(() => {
|
|
13506
|
+
requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
|
|
13507
|
+
if (!identityExists(paths, input.name)) {
|
|
13508
|
+
throw new IdentityNotFoundError(input.name);
|
|
13509
|
+
}
|
|
13510
|
+
if (typeof input.defaultConfigProfile === "string") {
|
|
13511
|
+
requireProfileExists(paths, input.defaultConfigProfile);
|
|
13512
|
+
}
|
|
13513
|
+
if (input.defaultConfigProfile !== void 0) {
|
|
13514
|
+
setDefaultConfigProfile(paths, input.name, input.defaultConfigProfile === false ? void 0 : input.defaultConfigProfile);
|
|
13515
|
+
}
|
|
13516
|
+
if (input.allowAmbientCredential !== void 0) {
|
|
13517
|
+
setAllowAmbientCredential(paths, input.name, input.allowAmbientCredential);
|
|
13518
|
+
}
|
|
13519
|
+
if (input.credential === false) {
|
|
13520
|
+
setIdentityCredential(paths, input.name, false);
|
|
13521
|
+
} else if (input.credential !== void 0) {
|
|
13522
|
+
const { sources, target, cache } = input.credential;
|
|
13523
|
+
const merged = cache === void 0 ? void 0 : mergeCredentialCache(cache === false ? { enabled: false } : { ...cache, enabled: true }, readIdentity(paths, input.name)?.credential?.cache);
|
|
13524
|
+
const change = {
|
|
13525
|
+
...sources === void 0 ? {} : { sources },
|
|
13526
|
+
...target === void 0 ? {} : { target },
|
|
13527
|
+
...merged === void 0 ? {} : { cache: merged }
|
|
13528
|
+
};
|
|
13529
|
+
setIdentityCredential(paths, input.name, change);
|
|
13530
|
+
}
|
|
13531
|
+
return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
13532
|
+
})
|
|
13533
|
+
),
|
|
13534
|
+
remove: route("/rest/config/identity/remove", "Delete an identity and its directory").input(ConfigIdentityRemoveInputSchema).output(ConfigIdentityRemoveOutputSchema).handler(({ input }) => {
|
|
13535
|
+
requireConfirmation(input.confirm, `identity "${input.name}" and its directory`);
|
|
13536
|
+
return guarded(() => {
|
|
13537
|
+
removeIdentity(paths, input.name);
|
|
13538
|
+
return { action: "removed", kind: "identity", name: input.name };
|
|
13539
|
+
});
|
|
13540
|
+
}),
|
|
13541
|
+
use: route("/rest/config/identity/use", "Select the active identity").input(ConfigNameInputSchema).output(ConfigIdentityUseOutputSchema).handler(
|
|
13542
|
+
({ input }) => guarded(() => {
|
|
13543
|
+
if (poolNameOf(input.name) === void 0 && !identityExists(paths, input.name)) {
|
|
13544
|
+
throw new IdentityNotFoundError(input.name);
|
|
13545
|
+
}
|
|
13546
|
+
useIdentity(paths, input.name);
|
|
13547
|
+
return { action: "selected", kind: "identity", name: input.name };
|
|
13548
|
+
})
|
|
13549
|
+
)
|
|
13550
|
+
},
|
|
13551
|
+
profile: {
|
|
13552
|
+
add: route("/rest/config/profile/add", "Create a configuration profile").input(ConfigProfileAddInputSchema).output(ConfigProfileAddOutputSchema).handler(
|
|
13553
|
+
({ input }) => guarded(() => {
|
|
13554
|
+
createProfile(paths, input.name, input.extends, input.description);
|
|
13555
|
+
return { action: "created", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
|
|
13556
|
+
})
|
|
13557
|
+
),
|
|
13558
|
+
set: route("/rest/config/profile/set", "Update a configuration profile's categories, entries, extends list, description or launch settings").input(ConfigProfileSetInputSchema).output(ConfigProfileSetOutputSchema).handler(
|
|
13559
|
+
({ input }) => guarded(() => {
|
|
13560
|
+
const { launch } = input;
|
|
13561
|
+
requireChange(
|
|
13562
|
+
input.category !== void 0 || input.entry !== void 0 || input.extends !== void 0 || input.description !== void 0 || launch !== void 0,
|
|
13563
|
+
"category, entry, extends, description or launch"
|
|
13564
|
+
);
|
|
13565
|
+
requireProfileExists(paths, input.name);
|
|
13566
|
+
applyProfileChange(paths, input.name, {
|
|
13567
|
+
...input.category === void 0 ? {} : { category: input.category },
|
|
13568
|
+
...input.entry === void 0 ? {} : { entry: input.entry },
|
|
13569
|
+
...input.extends === void 0 ? {} : { extends: input.extends },
|
|
13570
|
+
...input.description === void 0 ? {} : { description: input.description },
|
|
13571
|
+
...launch?.skipPermissions === void 0 ? {} : { launchSkipPermissions: launch.skipPermissions },
|
|
13572
|
+
...launch?.remoteControl === void 0 ? {} : { launchRemoteControl: launch.remoteControl },
|
|
13573
|
+
...launch?.headroom === void 0 ? {} : { launchHeadroom: launch.headroom },
|
|
13574
|
+
...launch?.trackUsage === void 0 ? {} : { launchTrackUsage: launch.trackUsage },
|
|
13575
|
+
...launch?.provider === void 0 ? {} : { launchProvider: launch.provider },
|
|
13576
|
+
...launch?.claudeVersion === void 0 ? {} : { launchClaudeVersion: launch.claudeVersion }
|
|
13577
|
+
});
|
|
13578
|
+
return { action: "updated", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
|
|
13579
|
+
})
|
|
13580
|
+
),
|
|
13581
|
+
remove: route("/rest/config/profile/remove", "Delete a configuration profile").input(ConfigProfileRemoveInputSchema).output(ConfigProfileRemoveOutputSchema).handler(({ input }) => {
|
|
13582
|
+
requireConfirmation(input.confirm, `configuration profile "${input.name}"`);
|
|
13583
|
+
return guarded(() => {
|
|
13584
|
+
removeProfile(paths, input.name);
|
|
13585
|
+
return { action: "removed", kind: "profile", name: input.name };
|
|
13586
|
+
});
|
|
13587
|
+
}),
|
|
13588
|
+
use: route("/rest/config/profile/use", "Make a configuration profile the global default").input(ConfigNameInputSchema).output(ConfigProfileUseOutputSchema).handler(
|
|
13589
|
+
({ input }) => guarded(() => {
|
|
13590
|
+
requireProfileExists(paths, input.name);
|
|
13591
|
+
setGlobalDefaultProfile(paths, input.name);
|
|
13592
|
+
return { action: "selected", kind: "profile", name: input.name };
|
|
13593
|
+
})
|
|
13594
|
+
)
|
|
13595
|
+
},
|
|
13596
|
+
pool: {
|
|
13597
|
+
add: route("/rest/config/pool/add", "Define a pool").input(ConfigPoolAddInputSchema).output(ConfigPoolAddOutputSchema).handler(
|
|
13598
|
+
({ input }) => guarded(() => {
|
|
13599
|
+
requireIdentityNames(paths, input.identities);
|
|
13600
|
+
const created = addPool(paths, input.name, input.identities, input.preference);
|
|
13601
|
+
return { action: "created", kind: "pool", name: input.name, value: created };
|
|
13602
|
+
})
|
|
13603
|
+
),
|
|
13604
|
+
set: route("/rest/config/pool/set", "Replace a pool's members, its preference or both").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
|
|
13605
|
+
({ input }) => guarded(() => {
|
|
13606
|
+
requireChange(input.identities !== void 0 || input.preference !== void 0, "identities or preference");
|
|
13607
|
+
const existing = requirePool(paths, input.name);
|
|
13608
|
+
if (input.identities !== void 0) {
|
|
13609
|
+
requireIdentityNames(paths, input.identities);
|
|
13610
|
+
}
|
|
13611
|
+
const members = input.identities ?? existing.identities;
|
|
13612
|
+
const preference = input.preference === void 0 ? existing.preference : input.preference === false ? void 0 : input.preference;
|
|
13613
|
+
return { action: "updated", kind: "pool", name: input.name, value: setPool(paths, input.name, members, preference) };
|
|
13614
|
+
})
|
|
13615
|
+
),
|
|
13616
|
+
remove: route("/rest/config/pool/remove", "Delete a pool").input(ConfigPoolRemoveInputSchema).output(ConfigPoolRemoveOutputSchema).handler(({ input }) => {
|
|
13617
|
+
requireConfirmation(input.confirm, `pool "${input.name}"`);
|
|
13618
|
+
return guarded(() => {
|
|
13619
|
+
removePool(paths, input.name);
|
|
13620
|
+
return { action: "removed", kind: "pool", name: input.name };
|
|
13621
|
+
});
|
|
13622
|
+
}),
|
|
13623
|
+
use: route("/rest/config/pool/use", "Make launches with no other selection pick a member of a pool").input(ConfigNameInputSchema).output(ConfigPoolUseOutputSchema).handler(
|
|
13624
|
+
({ input }) => guarded(() => {
|
|
13625
|
+
if (readPools(paths)[input.name] === void 0) {
|
|
13626
|
+
throw new PoolNotFoundError(input.name);
|
|
13627
|
+
}
|
|
13628
|
+
useIdentity(paths, `pool:${input.name}`);
|
|
13629
|
+
return { action: "selected", kind: "pool", name: input.name };
|
|
13630
|
+
})
|
|
13631
|
+
)
|
|
13632
|
+
},
|
|
13633
|
+
provider: {
|
|
13634
|
+
add: route("/rest/config/provider/add", "Create an API provider definition").input(ConfigProviderAddInputSchema).output(ConfigProviderAddOutputSchema).handler(
|
|
13635
|
+
({ input }) => guarded(() => {
|
|
13636
|
+
const created = addProvider(paths, input.name, {
|
|
13637
|
+
...input.kind === void 0 ? {} : { kind: input.kind },
|
|
13638
|
+
displayName: input.displayName,
|
|
13639
|
+
...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
|
|
13640
|
+
sources: input.credential.sources,
|
|
13641
|
+
...input.credential.target === void 0 ? {} : { target: input.credential.target },
|
|
13642
|
+
...input.codex === void 0 ? {} : { codex: input.codex }
|
|
13643
|
+
});
|
|
13644
|
+
const cache = input.credential.cache;
|
|
13645
|
+
const stored = cache === void 0 || cache === false ? created : updateProvider(paths, input.name, { cache });
|
|
13646
|
+
return { action: "created", kind: "provider", name: input.name, value: providerValue(input.name, stored) };
|
|
13647
|
+
})
|
|
13648
|
+
),
|
|
13649
|
+
set: route("/rest/config/provider/set", "Update an API provider definition").input(ConfigProviderSetInputSchema).output(ConfigProviderSetOutputSchema).handler(
|
|
13650
|
+
({ input }) => guarded(() => {
|
|
13651
|
+
requireChange(input.displayName !== void 0 || input.baseUrl !== void 0 || input.credential !== void 0 || input.codex !== void 0, "displayName, baseUrl, credential or codex");
|
|
13652
|
+
const existing = readProvider(paths, input.name);
|
|
13653
|
+
if (existing === void 0) {
|
|
13654
|
+
throw new ProviderNotFoundError(input.name);
|
|
13655
|
+
}
|
|
13656
|
+
const credential = input.credential;
|
|
13657
|
+
if (input.baseUrl !== void 0 && !isCodexProvider(existing) && input.baseUrl !== existing.baseUrl && credential?.sources === void 0) {
|
|
13658
|
+
throw new import_client2.ORPCError("BAD_REQUEST", { message: `Changing the base URL of provider "${input.name}" requires a credential block in the same call: the stored credential is not sent to a different endpoint.` });
|
|
13659
|
+
}
|
|
13660
|
+
const cache = credential?.cache === void 0 ? void 0 : mergeCredentialCache(credential.cache === false ? { enabled: false } : { ...credential.cache, enabled: true }, existing.credential.cache);
|
|
13661
|
+
const updated = updateProvider(paths, input.name, {
|
|
13662
|
+
...input.displayName === void 0 ? {} : { displayName: input.displayName },
|
|
13663
|
+
...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
|
|
13664
|
+
...credential?.sources === void 0 ? {} : { sources: credential.sources },
|
|
13665
|
+
...credential?.target === void 0 ? {} : { target: credential.target },
|
|
13666
|
+
...cache === void 0 ? {} : { cache },
|
|
13667
|
+
...input.codex === void 0 ? {} : { codex: input.codex }
|
|
13668
|
+
});
|
|
13669
|
+
return { action: "updated", kind: "provider", name: input.name, value: providerValue(input.name, updated) };
|
|
13670
|
+
})
|
|
13671
|
+
),
|
|
13672
|
+
remove: route("/rest/config/provider/remove", "Delete an API provider definition").input(ConfigProviderRemoveInputSchema).output(ConfigProviderRemoveOutputSchema).handler(({ input }) => {
|
|
13673
|
+
requireConfirmation(input.confirm, `provider "${input.name}"`);
|
|
13674
|
+
return guarded(() => {
|
|
13675
|
+
if (!providerExists(paths, input.name)) {
|
|
13676
|
+
throw new ProviderNotFoundError(input.name);
|
|
13677
|
+
}
|
|
13678
|
+
removeProvider(paths, input.name);
|
|
13679
|
+
return { action: "removed", kind: "provider", name: input.name };
|
|
13680
|
+
});
|
|
13681
|
+
})
|
|
13682
|
+
},
|
|
13683
|
+
rule: {
|
|
13684
|
+
add: route("/rest/config/rule/add", "Add a directory rule for a path").input(ConfigRuleAddInputSchema).output(ConfigRuleAddOutputSchema).handler(
|
|
13685
|
+
({ input }) => guarded(() => {
|
|
13686
|
+
if (input.identity !== void 0) {
|
|
13687
|
+
requireRuleSelector(paths, input.identity);
|
|
13688
|
+
}
|
|
13689
|
+
if (input.configProfile !== void 0) {
|
|
13690
|
+
requireProfileExists(paths, input.configProfile);
|
|
13691
|
+
}
|
|
13692
|
+
const created = addDirectoryRule(paths, input.path, {
|
|
13693
|
+
...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
|
|
13694
|
+
...input.identity === void 0 ? {} : { identity: input.identity }
|
|
13695
|
+
});
|
|
13696
|
+
return { action: "created", kind: "rule", name: input.path, value: created };
|
|
13697
|
+
})
|
|
13698
|
+
),
|
|
13699
|
+
set: route("/rest/config/rule/set", "Update the directory rule for a path").input(ConfigRuleSetInputSchema).output(ConfigRuleSetOutputSchema).handler(
|
|
13700
|
+
({ input }) => guarded(() => {
|
|
13701
|
+
requireChange(input.configProfile !== void 0 || input.identity !== void 0, "configProfile or identity");
|
|
13702
|
+
if (typeof input.identity === "string") {
|
|
13703
|
+
requireRuleSelector(paths, input.identity);
|
|
13704
|
+
}
|
|
13705
|
+
if (typeof input.configProfile === "string") {
|
|
13706
|
+
requireProfileExists(paths, input.configProfile);
|
|
13707
|
+
}
|
|
13708
|
+
const updated = updateDirectoryRule(paths, input.path, {
|
|
13709
|
+
...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
|
|
13710
|
+
...input.identity === void 0 ? {} : { identity: input.identity }
|
|
13711
|
+
});
|
|
13712
|
+
return { action: "updated", kind: "rule", name: input.path, value: updated };
|
|
13713
|
+
})
|
|
13714
|
+
),
|
|
13715
|
+
remove: route("/rest/config/rule/remove", "Remove the directory rule for a path").input(ConfigRuleRemoveInputSchema).output(ConfigRuleRemoveOutputSchema).handler(({ input }) => {
|
|
13716
|
+
requireConfirmation(input.confirm, `the directory rule for "${input.path}"`);
|
|
13717
|
+
return guarded(() => {
|
|
13718
|
+
if (!listDirectoryRules(paths).some((entry) => entry.path === input.path)) {
|
|
13719
|
+
throw new DirectoryRuleNotFoundError(input.path);
|
|
13720
|
+
}
|
|
13721
|
+
removeDirectoryRule(paths, input.path);
|
|
13722
|
+
return { action: "removed", kind: "rule", name: input.path };
|
|
13723
|
+
});
|
|
13724
|
+
})
|
|
13725
|
+
}
|
|
13726
|
+
}
|
|
13727
|
+
};
|
|
13728
|
+
}
|
|
13729
|
+
|
|
13730
|
+
// src/frontdoor/eventsApi.ts
|
|
13731
|
+
var import_client3 = require("@orpc/client");
|
|
13732
|
+
var import_openapi4 = require("@orpc/openapi");
|
|
13733
|
+
var import_server3 = require("@orpc/server");
|
|
13734
|
+
|
|
13735
|
+
// src/frontdoor/eventSchemas.ts
|
|
13736
|
+
var import_zod21 = require("zod");
|
|
13737
|
+
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
13738
|
+
var LAUNCH_EVENT_SOURCE = "launch";
|
|
13739
|
+
var USAGE_EVENT_SOURCE = "usage";
|
|
13740
|
+
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
13741
|
+
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
13742
|
+
var DoorEventSchema = import_zod21.z.strictObject({
|
|
13743
|
+
source: import_zod21.z.string().min(1),
|
|
13744
|
+
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
13745
|
+
sequence: import_zod21.z.number().int().positive(),
|
|
13746
|
+
payload: import_zod21.z.unknown()
|
|
13747
|
+
});
|
|
13748
|
+
var DoorEventSourceQuerySchema = import_zod21.z.strictObject({
|
|
13749
|
+
sources: import_zod21.z.array(import_zod21.z.string().min(1)).min(1).optional()
|
|
13750
|
+
});
|
|
13751
|
+
var LaunchLifecycleEventSchema = import_zod21.z.strictObject({
|
|
13752
|
+
kind: import_zod21.z.enum(["registered", "pruned", "ended"]),
|
|
13753
|
+
pid: import_zod21.z.number().int().positive(),
|
|
13754
|
+
startedAt: import_zod21.z.number(),
|
|
13755
|
+
observedAt: import_zod21.z.number()
|
|
13756
|
+
});
|
|
13757
|
+
var DoorHealthEventSchema = import_zod21.z.discriminatedUnion("kind", [
|
|
13758
|
+
import_zod21.z.strictObject({ kind: import_zod21.z.literal("generation"), pid: import_zod21.z.number().int().positive(), providerPort: import_zod21.z.number().int().positive(), connectPort: import_zod21.z.number().int().positive(), directPort: import_zod21.z.number().int().positive(), observedAt: import_zod21.z.number() }),
|
|
13759
|
+
import_zod21.z.strictObject({ kind: import_zod21.z.literal("listenerFailed"), pid: import_zod21.z.number().int().positive(), listener: import_zod21.z.enum(["provider", "connect", "direct"]), message: import_zod21.z.string(), observedAt: import_zod21.z.number() }),
|
|
13760
|
+
import_zod21.z.strictObject({ kind: import_zod21.z.literal("binaryTurnover"), pid: import_zod21.z.number().int().positive(), observedAt: import_zod21.z.number() }),
|
|
13761
|
+
import_zod21.z.strictObject({ kind: import_zod21.z.literal("idleShutdown"), pid: import_zod21.z.number().int().positive(), observedAt: import_zod21.z.number() })
|
|
13762
|
+
]);
|
|
13763
|
+
var QuotaExpiringEventSchema = import_zod21.z.strictObject({
|
|
13764
|
+
identity: import_zod21.z.string().min(1),
|
|
13765
|
+
provider: import_zod21.z.string().min(1),
|
|
13766
|
+
window: import_zod21.z.enum(["fiveHour", "sevenDay"]),
|
|
13767
|
+
/** The fraction of the window already used when it was seen expiring, always below one because a fully used window has nothing left to spend. */
|
|
13768
|
+
utilization: import_zod21.z.number().min(0).max(1),
|
|
13769
|
+
resetsAt: import_zod21.z.iso.datetime(),
|
|
13770
|
+
observedAt: import_zod21.z.number()
|
|
13771
|
+
});
|
|
13772
|
+
|
|
13773
|
+
// src/frontdoor/eventsApi.ts
|
|
13774
|
+
var EVENTS_API_TAG = "events";
|
|
13775
|
+
function createEventsApiRouter(deps) {
|
|
13776
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13777
|
+
return {
|
|
13778
|
+
events: {
|
|
13779
|
+
subscribe: authed.meta((0, import_openapi4.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 }) {
|
|
13780
|
+
if (input.sources !== void 0) {
|
|
13781
|
+
const live = deps.events.sources();
|
|
13782
|
+
const unknown = input.sources.filter((source) => !live.includes(source));
|
|
13783
|
+
if (unknown.length > 0) {
|
|
13784
|
+
throw new import_client3.ORPCError("NOT_FOUND", { message: `the door publishes no event source named ${unknown.map((source) => `"${source}"`).join(", ")}; the live sources are ${live.map((source) => `"${source}"`).join(", ")}` });
|
|
13785
|
+
}
|
|
13786
|
+
}
|
|
13787
|
+
const stream = deps.events.stream(input.sources);
|
|
13788
|
+
const ended = new Promise((resolve) => {
|
|
13789
|
+
signal?.addEventListener("abort", () => {
|
|
13790
|
+
resolve();
|
|
13791
|
+
}, { once: true });
|
|
13792
|
+
});
|
|
13793
|
+
try {
|
|
13794
|
+
for (; ; ) {
|
|
13795
|
+
signal?.throwIfAborted();
|
|
13796
|
+
const next = await Promise.race([stream.next(), ended.then(() => ({ value: void 0, done: true }))]);
|
|
13797
|
+
if (next.done === true) {
|
|
13798
|
+
signal?.throwIfAborted();
|
|
13799
|
+
return;
|
|
13800
|
+
}
|
|
13801
|
+
yield (0, import_server3.withEventMeta)(next.value, { id: String(next.value.sequence) });
|
|
13802
|
+
}
|
|
13803
|
+
} finally {
|
|
13804
|
+
stream.close();
|
|
13805
|
+
}
|
|
13806
|
+
})
|
|
13807
|
+
}
|
|
13808
|
+
};
|
|
13809
|
+
}
|
|
13810
|
+
|
|
13811
|
+
// src/frontdoor/lifecycleApi.ts
|
|
13812
|
+
var import_client4 = require("@orpc/client");
|
|
13813
|
+
var import_openapi5 = require("@orpc/openapi");
|
|
13814
|
+
init_update();
|
|
13815
|
+
var FRONTDOOR_API_TAG = "frontdoor";
|
|
13816
|
+
var UPDATE_API_TAG = "update";
|
|
13817
|
+
function createLifecycleApiRouter(deps) {
|
|
13818
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13819
|
+
return {
|
|
13820
|
+
frontdoor: {
|
|
13821
|
+
restart: authed.meta((0, import_openapi5.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 }) => {
|
|
13822
|
+
context.afterResponse(deps.restartDoor);
|
|
13823
|
+
return { action: "restarting", previousPid: deps.doorPid };
|
|
13824
|
+
})
|
|
13825
|
+
},
|
|
13826
|
+
update: {
|
|
13827
|
+
check: authed.meta((0, import_openapi5.openapi)({ method: "GET", path: "/rest/update/check", summary: "Check whether a newer release exists", tags: [UPDATE_API_TAG] })).output(UpdateCheckOutputSchema).handler(async () => {
|
|
13828
|
+
try {
|
|
13829
|
+
return await deps.checkForUpdate();
|
|
13830
|
+
} catch (error) {
|
|
13831
|
+
if (error instanceof UpdateChannelError) {
|
|
13832
|
+
throw new import_client4.ORPCError("PRECONDITION_FAILED", { message: error.message });
|
|
13833
|
+
}
|
|
13834
|
+
if (error instanceof UpdateConflictError) {
|
|
13835
|
+
throw new import_client4.ORPCError("CONFLICT", { message: error.message });
|
|
13836
|
+
}
|
|
13837
|
+
if (error instanceof UpdateDownloadError) {
|
|
13838
|
+
throw new import_client4.ORPCError("BAD_GATEWAY", { message: error.message });
|
|
13839
|
+
}
|
|
13840
|
+
throw error;
|
|
13841
|
+
}
|
|
13842
|
+
})
|
|
13843
|
+
}
|
|
13844
|
+
};
|
|
13845
|
+
}
|
|
13846
|
+
|
|
13847
|
+
// src/frontdoor/launchApi.ts
|
|
13848
|
+
var import_client5 = require("@orpc/client");
|
|
13849
|
+
var import_openapi6 = require("@orpc/openapi");
|
|
13850
|
+
init_cliError();
|
|
13851
|
+
|
|
13852
|
+
// src/frontdoor/launchSchemas.ts
|
|
13853
|
+
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
13854
|
+
var import_zod22 = require("zod");
|
|
13855
|
+
init_claudeVersion();
|
|
13856
|
+
init_identity();
|
|
13857
|
+
var LaunchResolveInputSchema = import_zod22.z.strictObject({
|
|
13858
|
+
path: import_zod22.z.string().min(1),
|
|
13859
|
+
/** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
|
|
13860
|
+
argv: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())).optional(),
|
|
13861
|
+
/** 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. */
|
|
13862
|
+
env: import_zod22.z.record(import_zod22.z.string(), import_zod22.z.string()).optional()
|
|
13863
|
+
}).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" });
|
|
13864
|
+
var LaunchPoolDecisionSchema = import_zod22.z.strictObject({
|
|
13865
|
+
name: import_zod22.z.string(),
|
|
13866
|
+
reasons: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
|
|
13867
|
+
movedOff: import_zod22.z.strictObject({ identity: import_zod22.z.string(), reason: import_zod22.z.string() }).optional()
|
|
13868
|
+
});
|
|
13869
|
+
var LaunchDecisionSchema = import_zod22.z.strictObject({
|
|
13870
|
+
identity: import_zod22.z.string().optional(),
|
|
13871
|
+
identitySource: import_zod22.z.enum(IDENTITY_DECISION_SOURCES),
|
|
13872
|
+
pool: LaunchPoolDecisionSchema.optional(),
|
|
13873
|
+
configDirEscapeHatch: import_zod22.z.boolean(),
|
|
13874
|
+
configDir: import_zod22.z.string().optional(),
|
|
13875
|
+
configProfile: import_zod22.z.string().optional(),
|
|
13876
|
+
configProfileSource: import_zod22.z.enum(CONFIG_PROFILE_DECISION_SOURCES),
|
|
13877
|
+
provider: import_zod22.z.string().optional()
|
|
13878
|
+
});
|
|
13879
|
+
var LaunchFlagsSchema = import_zod22.z.strictObject({
|
|
13880
|
+
skipPermissions: import_zod22.z.boolean(),
|
|
13881
|
+
remoteControl: import_zod22.z.boolean(),
|
|
13882
|
+
headroom: import_zod22.z.boolean(),
|
|
13883
|
+
trackUsage: import_zod22.z.boolean()
|
|
13884
|
+
});
|
|
13885
|
+
var LaunchResolveOutputSchema = import_zod22.z.strictObject({
|
|
13886
|
+
decision: LaunchDecisionSchema,
|
|
13887
|
+
flags: LaunchFlagsSchema,
|
|
13888
|
+
claudeVersion: import_zod22.z.strictObject({ version: import_zod22.z.string(), source: import_zod22.z.enum(CLAUDE_VERSION_SOURCES) }).optional(),
|
|
13889
|
+
/** The real `claude` binary the launch would spawn, on the door's host. */
|
|
13890
|
+
bin: import_zod22.z.string(),
|
|
13891
|
+
/** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
|
|
13892
|
+
args: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
|
|
13893
|
+
/** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
|
|
13894
|
+
credential: import_zod22.z.strictObject({ subject: import_zod22.z.enum(["provider", "identity"]), name: import_zod22.z.string(), summary: CredentialSummarySchema }).optional(),
|
|
13895
|
+
routing: import_zod22.z.strictObject({ frontDoor: import_zod22.z.boolean(), headroom: import_zod22.z.boolean() }),
|
|
13896
|
+
/** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
|
|
13897
|
+
environment: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
|
|
13898
|
+
warnings: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string()))
|
|
13899
|
+
});
|
|
13900
|
+
|
|
13901
|
+
// src/frontdoor/launchApi.ts
|
|
13902
|
+
var LAUNCH_API_TAG = "launch";
|
|
13903
|
+
function createLaunchApiRouter(deps) {
|
|
13904
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13905
|
+
return {
|
|
13906
|
+
launch: {
|
|
13907
|
+
resolve: authed.meta((0, import_openapi6.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 }) => {
|
|
13908
|
+
try {
|
|
13909
|
+
const { resolution, warnings } = deps.resolveLaunch({ path: input.path, argv: input.argv ?? [], env: input.env ?? {} });
|
|
13910
|
+
return { ...resolution, warnings };
|
|
13911
|
+
} catch (error) {
|
|
13912
|
+
if (error instanceof CliError) {
|
|
13913
|
+
throw new import_client5.ORPCError("BAD_REQUEST", { message: error.message });
|
|
13914
|
+
}
|
|
13915
|
+
throw error;
|
|
13916
|
+
}
|
|
13917
|
+
})
|
|
13918
|
+
}
|
|
13919
|
+
};
|
|
13920
|
+
}
|
|
13921
|
+
|
|
13922
|
+
// src/frontdoor/controlApi.ts
|
|
13923
|
+
var USAGE_API_TAG = "usage";
|
|
13924
|
+
var FRONTDOOR_API_TAG2 = "frontdoor";
|
|
13925
|
+
var CHECK_API_TAG = "check";
|
|
13926
|
+
var DOCTOR_API_TAG = "doctor";
|
|
13927
|
+
var POOL_API_TAG = "pool";
|
|
13928
|
+
function createControlApiRouter(deps) {
|
|
13929
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13930
|
+
return {
|
|
13931
|
+
usage: {
|
|
13932
|
+
list: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
|
|
13933
|
+
effectiveWindow: authed.meta((0, import_openapi7.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 }) => {
|
|
13934
|
+
const snapshot = deps.usageSnapshotOf(input.identity);
|
|
12975
13935
|
if (snapshot === void 0) {
|
|
12976
|
-
throw new
|
|
13936
|
+
throw new import_client6.ORPCError("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
|
|
12977
13937
|
}
|
|
12978
13938
|
const provider = input.provider ?? ANTHROPIC_PROVIDER;
|
|
12979
13939
|
const rateLimit = snapshot.providers[provider]?.rateLimit;
|
|
@@ -12987,34 +13947,34 @@ function createControlApiRouter(deps) {
|
|
|
12987
13947
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
12988
13948
|
};
|
|
12989
13949
|
}),
|
|
12990
|
-
live: authed.meta((0,
|
|
13950
|
+
live: authed.meta((0, import_openapi7.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 }) => {
|
|
12991
13951
|
const sessions = deps.liveRateLimits(input.session);
|
|
12992
13952
|
if (input.session !== void 0 && sessions.length === 0) {
|
|
12993
13953
|
if (deps.list().some((session) => session.id === input.session)) {
|
|
12994
|
-
throw new
|
|
13954
|
+
throw new import_client6.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` });
|
|
12995
13955
|
}
|
|
12996
|
-
throw new
|
|
13956
|
+
throw new import_client6.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
12997
13957
|
}
|
|
12998
13958
|
return { latest: deps.latestRateLimit(), sessions };
|
|
12999
13959
|
})
|
|
13000
13960
|
},
|
|
13001
13961
|
frontdoor: {
|
|
13002
|
-
status: authed.meta((0,
|
|
13003
|
-
sessions: authed.meta((0,
|
|
13962
|
+
status: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
|
|
13963
|
+
sessions: authed.meta((0, import_openapi7.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 }))
|
|
13004
13964
|
},
|
|
13005
13965
|
check: {
|
|
13006
13966
|
// 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.
|
|
13007
|
-
run: authed.meta((0,
|
|
13967
|
+
run: authed.meta((0, import_openapi7.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)))
|
|
13008
13968
|
},
|
|
13009
13969
|
doctor: {
|
|
13010
|
-
run: authed.meta((0,
|
|
13970
|
+
run: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
|
|
13011
13971
|
},
|
|
13012
13972
|
pool: {
|
|
13013
|
-
pick: authed.meta((0,
|
|
13973
|
+
pick: authed.meta((0, import_openapi7.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 }) => {
|
|
13014
13974
|
const report = deps.poolPick(input.pool, input.path);
|
|
13015
13975
|
if (report === void 0) {
|
|
13016
13976
|
const live = deps.poolNames();
|
|
13017
|
-
throw new
|
|
13977
|
+
throw new import_client6.ORPCError("NOT_FOUND", {
|
|
13018
13978
|
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(", ")}`
|
|
13019
13979
|
});
|
|
13020
13980
|
}
|
|
@@ -13024,13 +13984,15 @@ function createControlApiRouter(deps) {
|
|
|
13024
13984
|
};
|
|
13025
13985
|
}
|
|
13026
13986
|
function createDoorApiRouter(deps) {
|
|
13027
|
-
|
|
13987
|
+
const control = createControlApiRouter(deps);
|
|
13988
|
+
const lifecycle = createLifecycleApiRouter(deps);
|
|
13989
|
+
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
13028
13990
|
}
|
|
13029
13991
|
function createDoorApiNodeHandler(deps) {
|
|
13030
13992
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
13031
13993
|
}
|
|
13032
13994
|
function frontDoorApiClient(port, ca, token) {
|
|
13033
|
-
return (0,
|
|
13995
|
+
return (0, import_client6.createORPCClient)(frontDoorApiLink(port, ca, token));
|
|
13034
13996
|
}
|
|
13035
13997
|
|
|
13036
13998
|
// src/frontdoor/doorClient.ts
|
|
@@ -13836,9 +14798,9 @@ async function serveRcCompatSessions(ctx, pathname, compatPath) {
|
|
|
13836
14798
|
const slash = rest.indexOf("/");
|
|
13837
14799
|
const address = slash === -1 ? rest : rest.slice(0, slash);
|
|
13838
14800
|
const compatTail = slash === -1 ? "" : rest.slice(slash + 1);
|
|
13839
|
-
const
|
|
13840
|
-
if (
|
|
13841
|
-
await ctx.unauthorized(response,
|
|
14801
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14802
|
+
if (refusal2 !== void 0) {
|
|
14803
|
+
await ctx.unauthorized(response, refusal2);
|
|
13842
14804
|
return;
|
|
13843
14805
|
}
|
|
13844
14806
|
const session = ctx.sessions.get(address) ?? ctx.sessions.get(`cse_${address}`);
|
|
@@ -13916,9 +14878,9 @@ function conversationRow(conversation) {
|
|
|
13916
14878
|
}
|
|
13917
14879
|
async function serveRcConversations(ctx, pathname, method) {
|
|
13918
14880
|
const { request: request4, response, conversations } = ctx;
|
|
13919
|
-
const
|
|
13920
|
-
if (
|
|
13921
|
-
await ctx.unauthorized(response,
|
|
14881
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14882
|
+
if (refusal2 !== void 0) {
|
|
14883
|
+
await ctx.unauthorized(response, refusal2);
|
|
13922
14884
|
return;
|
|
13923
14885
|
}
|
|
13924
14886
|
if (pathname === RC_CONVERSATIONS_PATH_PREFIX) {
|
|
@@ -14242,9 +15204,9 @@ async function fetchThroughWebProxy(url, deps) {
|
|
|
14242
15204
|
try {
|
|
14243
15205
|
let redirects = 0;
|
|
14244
15206
|
for (; ; ) {
|
|
14245
|
-
const
|
|
14246
|
-
if (
|
|
14247
|
-
return
|
|
15207
|
+
const refusal2 = await checkTarget(current, deps);
|
|
15208
|
+
if (refusal2 !== void 0) {
|
|
15209
|
+
return refusal2;
|
|
14248
15210
|
}
|
|
14249
15211
|
let hop;
|
|
14250
15212
|
try {
|
|
@@ -14614,8 +15576,8 @@ data: ${JSON.stringify(envelope)}
|
|
|
14614
15576
|
"doubled-scheme-word": "the self-hosted Remote Control surface reads one Bearer scheme word, and this call's Authorization header carried it twice: a persisted session record holds the whole header value with the scheme word included, so prefixing Bearer onto it presents a different credential",
|
|
14615
15577
|
unrecognised: "the self-hosted Remote Control surface did not recognise the presented credential"
|
|
14616
15578
|
};
|
|
14617
|
-
const unauthorized = async (response,
|
|
14618
|
-
await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[
|
|
15579
|
+
const unauthorized = async (response, refusal2) => {
|
|
15580
|
+
await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[refusal2] } });
|
|
14619
15581
|
};
|
|
14620
15582
|
const serveSessionPath = async (session, tail, request4, response) => {
|
|
14621
15583
|
const method = request4.method.toUpperCase();
|
|
@@ -14626,9 +15588,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14626
15588
|
session.lastTrafficAt = deps.now();
|
|
14627
15589
|
if (tail === "") {
|
|
14628
15590
|
if (method === "PATCH" || method === "PUT") {
|
|
14629
|
-
const
|
|
14630
|
-
if (
|
|
14631
|
-
await unauthorized(response,
|
|
15591
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15592
|
+
if (refusal2 !== void 0) {
|
|
15593
|
+
await unauthorized(response, refusal2);
|
|
14632
15594
|
return;
|
|
14633
15595
|
}
|
|
14634
15596
|
const body = parseJsonObject5(await readBody2(request4.body, CONTROL_BODY_CAP_BYTES));
|
|
@@ -14651,9 +15613,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14651
15613
|
return;
|
|
14652
15614
|
}
|
|
14653
15615
|
if (tail === "bridge" && method === "POST") {
|
|
14654
|
-
const
|
|
14655
|
-
if (
|
|
14656
|
-
await unauthorized(response,
|
|
15616
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15617
|
+
if (refusal2 !== void 0) {
|
|
15618
|
+
await unauthorized(response, refusal2);
|
|
14657
15619
|
return;
|
|
14658
15620
|
}
|
|
14659
15621
|
const workerJwt = mintWorkerJwt(deps.randomToken, deps.now());
|
|
@@ -14663,9 +15625,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14663
15625
|
return;
|
|
14664
15626
|
}
|
|
14665
15627
|
if (tail === "archive" && method === "POST") {
|
|
14666
|
-
const
|
|
14667
|
-
if (
|
|
14668
|
-
await unauthorized(response,
|
|
15628
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15629
|
+
if (refusal2 !== void 0) {
|
|
15630
|
+
await unauthorized(response, refusal2);
|
|
14669
15631
|
return;
|
|
14670
15632
|
}
|
|
14671
15633
|
retireSession(session);
|
|
@@ -14676,9 +15638,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14676
15638
|
if (tail === "worker" || tail.startsWith("worker/")) {
|
|
14677
15639
|
const workerTail = tail === "worker" ? "" : tail.slice("worker/".length);
|
|
14678
15640
|
const webProxy = workerTail === "web-fetch" || workerTail === "web-search";
|
|
14679
|
-
const
|
|
14680
|
-
if (
|
|
14681
|
-
await unauthorized(response,
|
|
15641
|
+
const refusal2 = webProxy ? workerOrCredentialRefusal(request4.headers, session) : workerRefusal(request4.headers, session);
|
|
15642
|
+
if (refusal2 !== void 0) {
|
|
15643
|
+
await unauthorized(response, refusal2);
|
|
14682
15644
|
return;
|
|
14683
15645
|
}
|
|
14684
15646
|
if (workerTail === "" && method === "GET") {
|
|
@@ -14984,7 +15946,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
14984
15946
|
}
|
|
14985
15947
|
|
|
14986
15948
|
// src/frontdoor/rcSelfHostMint.ts
|
|
14987
|
-
var
|
|
15949
|
+
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
14988
15950
|
init_account();
|
|
14989
15951
|
var CREDENTIALS_FILE = ".credentials.json";
|
|
14990
15952
|
var CLAUDE_JSON2 = ".claude.json";
|
|
@@ -15009,7 +15971,7 @@ function readJsonObject(fs12, file) {
|
|
|
15009
15971
|
return isRecord11(parsed) ? parsed : void 0;
|
|
15010
15972
|
}
|
|
15011
15973
|
function readRcSelfHostRecord(fs12, frontdoorDir) {
|
|
15012
|
-
const parsed = readJsonObject(fs12,
|
|
15974
|
+
const parsed = readJsonObject(fs12, import_node_path31.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
15013
15975
|
if (parsed === void 0) {
|
|
15014
15976
|
return void 0;
|
|
15015
15977
|
}
|
|
@@ -15023,11 +15985,11 @@ function mintRcSelfHostCredential(deps) {
|
|
|
15023
15985
|
if (!isIdentityName(deps.identity)) {
|
|
15024
15986
|
throw new Error(`"${deps.identity}" is not a valid identity name.`);
|
|
15025
15987
|
}
|
|
15026
|
-
const identityDir =
|
|
15027
|
-
const credentialsFile =
|
|
15028
|
-
const claudeJsonFile =
|
|
15029
|
-
const recordDir =
|
|
15030
|
-
const recordFile =
|
|
15988
|
+
const identityDir = import_node_path31.default.join(deps.identitiesDir, deps.identity);
|
|
15989
|
+
const credentialsFile = import_node_path31.default.join(identityDir, CREDENTIALS_FILE);
|
|
15990
|
+
const claudeJsonFile = import_node_path31.default.join(identityDir, CLAUDE_JSON2);
|
|
15991
|
+
const recordDir = import_node_path31.default.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
|
|
15992
|
+
const recordFile = import_node_path31.default.join(recordDir, RC_SELF_HOST_RECORD_FILE);
|
|
15031
15993
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
15032
15994
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
15033
15995
|
const existingOauth = isRecord11(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
@@ -15043,7 +16005,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
15043
16005
|
const organizationUuid = deps.newUuid();
|
|
15044
16006
|
const accountUuid = deps.newUuid();
|
|
15045
16007
|
const mintedAt = new Date(deps.now()).toISOString();
|
|
15046
|
-
deps.fs.mkdirPrivate(
|
|
16008
|
+
deps.fs.mkdirPrivate(import_node_path31.default.dirname(credentialsFile));
|
|
15047
16009
|
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)}
|
|
15048
16010
|
`);
|
|
15049
16011
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|
|
@@ -15091,102 +16053,6 @@ init_paths();
|
|
|
15091
16053
|
init_cliError();
|
|
15092
16054
|
init_schema();
|
|
15093
16055
|
init_providersStore();
|
|
15094
|
-
|
|
15095
|
-
// src/directoryRulesStore.ts
|
|
15096
|
-
init_store();
|
|
15097
|
-
init_load();
|
|
15098
|
-
init_schema();
|
|
15099
|
-
init_cliError();
|
|
15100
|
-
var DirectoryRuleNotFoundError = class extends CliError {
|
|
15101
|
-
constructor(rulePath) {
|
|
15102
|
-
super(`No directory rule found for path "${rulePath}".`);
|
|
15103
|
-
this.rulePath = rulePath;
|
|
15104
|
-
this.name = "DirectoryRuleNotFoundError";
|
|
15105
|
-
}
|
|
15106
|
-
rulePath;
|
|
15107
|
-
};
|
|
15108
|
-
var DirectoryRuleMissingTargetError = class extends CliError {
|
|
15109
|
-
constructor() {
|
|
15110
|
-
super("A directory rule must set at least one of --config-profile or --identity.");
|
|
15111
|
-
this.name = "DirectoryRuleMissingTargetError";
|
|
15112
|
-
}
|
|
15113
|
-
};
|
|
15114
|
-
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
15115
|
-
constructor(rulePath) {
|
|
15116
|
-
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
15117
|
-
this.rulePath = rulePath;
|
|
15118
|
-
this.name = "DirectoryRuleAlreadyExistsError";
|
|
15119
|
-
}
|
|
15120
|
-
rulePath;
|
|
15121
|
-
};
|
|
15122
|
-
function readDirectoryRules(paths) {
|
|
15123
|
-
return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
|
|
15124
|
-
}
|
|
15125
|
-
function writeDirectoryRules(paths, rules) {
|
|
15126
|
-
const parsed = DirectoryRulesSchema.safeParse(rules);
|
|
15127
|
-
if (!parsed.success) {
|
|
15128
|
-
throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
|
|
15129
|
-
}
|
|
15130
|
-
writeJsonAtomic(paths.directoryRulesFile, parsed.data);
|
|
15131
|
-
}
|
|
15132
|
-
function listDirectoryRules(paths) {
|
|
15133
|
-
return readDirectoryRules(paths).rules;
|
|
15134
|
-
}
|
|
15135
|
-
function addDirectoryRule(paths, rulePath, options) {
|
|
15136
|
-
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
15137
|
-
throw new DirectoryRuleMissingTargetError();
|
|
15138
|
-
}
|
|
15139
|
-
const current = readDirectoryRules(paths);
|
|
15140
|
-
if (current.rules.some((rule) => rule.path === rulePath)) {
|
|
15141
|
-
throw new DirectoryRuleAlreadyExistsError(rulePath);
|
|
15142
|
-
}
|
|
15143
|
-
const created = buildNewRule(rulePath, options);
|
|
15144
|
-
writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
|
|
15145
|
-
return created;
|
|
15146
|
-
}
|
|
15147
|
-
function ruleHasEffect(rule) {
|
|
15148
|
-
return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
|
|
15149
|
-
}
|
|
15150
|
-
function updateDirectoryRule(paths, rulePath, options) {
|
|
15151
|
-
const current = readDirectoryRules(paths);
|
|
15152
|
-
const index = current.rules.findIndex((rule) => rule.path === rulePath);
|
|
15153
|
-
const existing = index === -1 ? void 0 : current.rules[index];
|
|
15154
|
-
if (existing === void 0) {
|
|
15155
|
-
throw new DirectoryRuleNotFoundError(rulePath);
|
|
15156
|
-
}
|
|
15157
|
-
const { configProfile, identity, ...rest } = existing;
|
|
15158
|
-
const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
|
|
15159
|
-
const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
|
|
15160
|
-
const updated = {
|
|
15161
|
-
...rest,
|
|
15162
|
-
...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
|
|
15163
|
-
...nextIdentity === void 0 ? {} : { identity: nextIdentity }
|
|
15164
|
-
};
|
|
15165
|
-
if (!ruleHasEffect(updated)) {
|
|
15166
|
-
throw new DirectoryRuleMissingTargetError();
|
|
15167
|
-
}
|
|
15168
|
-
const nextRules = [...current.rules];
|
|
15169
|
-
nextRules[index] = updated;
|
|
15170
|
-
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
15171
|
-
return updated;
|
|
15172
|
-
}
|
|
15173
|
-
function buildNewRule(rulePath, options) {
|
|
15174
|
-
return {
|
|
15175
|
-
path: rulePath,
|
|
15176
|
-
...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
|
|
15177
|
-
...options.identity !== void 0 ? { identity: options.identity } : {}
|
|
15178
|
-
};
|
|
15179
|
-
}
|
|
15180
|
-
function removeDirectoryRule(paths, rulePath) {
|
|
15181
|
-
const current = readDirectoryRules(paths);
|
|
15182
|
-
const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
|
|
15183
|
-
if (nextRules.length === current.rules.length) {
|
|
15184
|
-
throw new DirectoryRuleNotFoundError(rulePath);
|
|
15185
|
-
}
|
|
15186
|
-
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
15187
|
-
}
|
|
15188
|
-
|
|
15189
|
-
// src/index.ts
|
|
15190
16056
|
init_launcher();
|
|
15191
16057
|
init_spawn();
|
|
15192
16058
|
init_launchWiring();
|
|
@@ -15298,10 +16164,47 @@ init_ownCli();
|
|
|
15298
16164
|
CheckReportJsonSchema,
|
|
15299
16165
|
CheckRunInputSchema,
|
|
15300
16166
|
CliError,
|
|
16167
|
+
CodexLogoutOutputSchema,
|
|
16168
|
+
CodexSignInSchema,
|
|
16169
|
+
CodexStatusOutputSchema,
|
|
16170
|
+
ConfigIdentityAddOutputSchema,
|
|
16171
|
+
ConfigIdentityRemoveInputSchema,
|
|
16172
|
+
ConfigIdentityRemoveOutputSchema,
|
|
16173
|
+
ConfigIdentitySetInputSchema,
|
|
16174
|
+
ConfigIdentitySetOutputSchema,
|
|
16175
|
+
ConfigIdentityUseOutputSchema,
|
|
16176
|
+
ConfigNameInputSchema,
|
|
16177
|
+
ConfigPoolAddInputSchema,
|
|
16178
|
+
ConfigPoolAddOutputSchema,
|
|
16179
|
+
ConfigPoolRemoveInputSchema,
|
|
16180
|
+
ConfigPoolRemoveOutputSchema,
|
|
16181
|
+
ConfigPoolSetInputSchema,
|
|
16182
|
+
ConfigPoolSetOutputSchema,
|
|
16183
|
+
ConfigPoolUseOutputSchema,
|
|
16184
|
+
ConfigProfileAddInputSchema,
|
|
16185
|
+
ConfigProfileAddOutputSchema,
|
|
16186
|
+
ConfigProfileRemoveInputSchema,
|
|
16187
|
+
ConfigProfileRemoveOutputSchema,
|
|
15301
16188
|
ConfigProfileSchema,
|
|
16189
|
+
ConfigProfileSetInputSchema,
|
|
16190
|
+
ConfigProfileSetOutputSchema,
|
|
16191
|
+
ConfigProfileUseOutputSchema,
|
|
16192
|
+
ConfigProviderAddInputSchema,
|
|
16193
|
+
ConfigProviderAddOutputSchema,
|
|
16194
|
+
ConfigProviderRemoveInputSchema,
|
|
16195
|
+
ConfigProviderRemoveOutputSchema,
|
|
16196
|
+
ConfigProviderSetInputSchema,
|
|
16197
|
+
ConfigProviderSetOutputSchema,
|
|
16198
|
+
ConfigRuleAddInputSchema,
|
|
16199
|
+
ConfigRuleAddOutputSchema,
|
|
16200
|
+
ConfigRuleRemoveInputSchema,
|
|
16201
|
+
ConfigRuleRemoveOutputSchema,
|
|
16202
|
+
ConfigRuleSetInputSchema,
|
|
16203
|
+
ConfigRuleSetOutputSchema,
|
|
15302
16204
|
CredentialCacheSchema,
|
|
15303
16205
|
CredentialSchema,
|
|
15304
16206
|
CredentialSourceSchema,
|
|
16207
|
+
CredentialSummarySchema,
|
|
15305
16208
|
DOOR_EVENT_BUFFER_EVENTS,
|
|
15306
16209
|
DOOR_EVENT_SOURCE_RC,
|
|
15307
16210
|
DOOR_HEALTH_EVENT_SOURCE,
|
|
@@ -15322,6 +16225,7 @@ init_ownCli();
|
|
|
15322
16225
|
FARM_MANIFEST_FILENAME,
|
|
15323
16226
|
FrontDoorControlMaterialError,
|
|
15324
16227
|
FrontDoorNotServingError,
|
|
16228
|
+
FrontDoorRestartOutputSchema,
|
|
15325
16229
|
FrontDoorSessionStatusSchema,
|
|
15326
16230
|
FrontDoorSessionsOutputSchema,
|
|
15327
16231
|
FrontDoorStartError,
|
|
@@ -15339,6 +16243,8 @@ init_ownCli();
|
|
|
15339
16243
|
LAUNCH_EVENT_SOURCE,
|
|
15340
16244
|
LaunchLifecycleEventSchema,
|
|
15341
16245
|
LaunchRefusedError,
|
|
16246
|
+
LaunchResolveInputSchema,
|
|
16247
|
+
LaunchResolveOutputSchema,
|
|
15342
16248
|
LegacyProviderFileError,
|
|
15343
16249
|
OWN_CLI_FILE_NAME,
|
|
15344
16250
|
PROMPT_CACHE_TTL_MS,
|
|
@@ -15385,6 +16291,7 @@ init_ownCli();
|
|
|
15385
16291
|
RcStreamEnvelopeSchema,
|
|
15386
16292
|
RcStreamEventSchema,
|
|
15387
16293
|
USAGE_EVENT_SOURCE,
|
|
16294
|
+
UpdateCheckOutputSchema,
|
|
15388
16295
|
UsageError,
|
|
15389
16296
|
UsageListOutputSchema,
|
|
15390
16297
|
UsageLiveOutputSchema,
|
|
@@ -15427,14 +16334,18 @@ init_ownCli();
|
|
|
15427
16334
|
collectDoctorReport,
|
|
15428
16335
|
collectFrontDoorStatus,
|
|
15429
16336
|
collectPoolPick,
|
|
16337
|
+
createCodexApiRouter,
|
|
16338
|
+
createConfigApiRouter,
|
|
15430
16339
|
createControlApiRouter,
|
|
15431
16340
|
createDoorApiNodeHandler,
|
|
15432
16341
|
createDoorApiRouter,
|
|
15433
16342
|
createDoorEventHub,
|
|
15434
16343
|
createDoorHealthPublisher,
|
|
15435
16344
|
createEventsApiRouter,
|
|
16345
|
+
createLaunchApiRouter,
|
|
15436
16346
|
createLaunchEventPublisher,
|
|
15437
16347
|
createLeafCache,
|
|
16348
|
+
createLifecycleApiRouter,
|
|
15438
16349
|
createProfile,
|
|
15439
16350
|
createQuotaExpiringPublisher,
|
|
15440
16351
|
createRcApiNodeHandler,
|
|
@@ -15542,7 +16453,9 @@ init_ownCli();
|
|
|
15542
16453
|
requirePool,
|
|
15543
16454
|
resolveAgentShimHome,
|
|
15544
16455
|
resolveClaudeHome,
|
|
16456
|
+
resolveClaudeLaunch,
|
|
15545
16457
|
resolveDecisions,
|
|
16458
|
+
resolveLaunch,
|
|
15546
16459
|
resolveLaunchSelection,
|
|
15547
16460
|
resolveLayoutPaths,
|
|
15548
16461
|
resolveSupervisorConfig,
|