claude-use 9.6.0 → 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/dist/cli.cjs +598 -129
- package/dist/index.cjs +860 -260
- package/dist/index.mjs +823 -258
- package/dist/types/index.d.ts +5573 -1838
- package/package.json +1 -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>",
|
|
@@ -3052,8 +3066,8 @@ function verifyHeadroomSocket(socketPath, ports) {
|
|
|
3052
3066
|
}
|
|
3053
3067
|
const uid = ports.currentUid();
|
|
3054
3068
|
const directory = import_node_path12.default.dirname(socketPath);
|
|
3055
|
-
const
|
|
3056
|
-
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 };
|
|
3057
3071
|
}
|
|
3058
3072
|
function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
3059
3073
|
const unsupported = platformRefusal(ports.platform);
|
|
@@ -3071,8 +3085,8 @@ function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
|
3071
3085
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
3072
3086
|
}
|
|
3073
3087
|
fs12.mkdirPrivate(paths.headroomSocketDir);
|
|
3074
|
-
const
|
|
3075
|
-
return
|
|
3088
|
+
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
3089
|
+
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
3076
3090
|
}
|
|
3077
3091
|
function pruneStaleHeadroomSockets(fs12, paths, isRunning) {
|
|
3078
3092
|
const removed = [];
|
|
@@ -4586,14 +4600,14 @@ function capacityOf(plan) {
|
|
|
4586
4600
|
return plan.kind === "subscription" ? plan.capacity : 1;
|
|
4587
4601
|
}
|
|
4588
4602
|
function assessRefusedNested(member, nested, nowMs) {
|
|
4589
|
-
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 };
|
|
4590
4604
|
return {
|
|
4591
4605
|
candidate: {
|
|
4592
4606
|
identity: member.identity,
|
|
4593
4607
|
class: "ineligible",
|
|
4594
|
-
...
|
|
4608
|
+
...refusal2.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal2.blockedUntilMs },
|
|
4595
4609
|
plan: planOf(member.account),
|
|
4596
|
-
reasons: [
|
|
4610
|
+
reasons: [refusal2.reason]
|
|
4597
4611
|
}
|
|
4598
4612
|
};
|
|
4599
4613
|
}
|
|
@@ -4684,7 +4698,7 @@ function rankPool(input) {
|
|
|
4684
4698
|
const assessments = members.map((member) => ({ member, ...assess(member, nowMs) }));
|
|
4685
4699
|
const demands = assessments.flatMap(({ candidate, burn }) => burn === void 0 ? [] : [burn * capacityOf(candidate.plan)]);
|
|
4686
4700
|
const sharedDemand = demands.length === 0 ? void 0 : Math.max(...demands);
|
|
4687
|
-
const
|
|
4701
|
+
const guarded2 = assessments.map((assessment) => {
|
|
4688
4702
|
const { candidate } = assessment;
|
|
4689
4703
|
if (candidate.class === "ineligible" || assessment.member.policy === void 0) {
|
|
4690
4704
|
return assessment;
|
|
@@ -4699,7 +4713,7 @@ function rankPool(input) {
|
|
|
4699
4713
|
}
|
|
4700
4714
|
return { ...assessment, candidate: { ...candidate, class: "ineligible", reasons: [`skipped by policy (${verdict.checked.join(", ")}: did not hold)`, ...candidate.reasons] } };
|
|
4701
4715
|
});
|
|
4702
|
-
const candidates =
|
|
4716
|
+
const candidates = guarded2.map((assessment) => {
|
|
4703
4717
|
const { candidate, fiveHour, burn } = assessment;
|
|
4704
4718
|
const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
|
|
4705
4719
|
const { sevenDay, sevenDayBurn } = assessment;
|
|
@@ -7697,11 +7711,11 @@ var init_anthropicUsageRefresh = __esm({
|
|
|
7697
7711
|
});
|
|
7698
7712
|
|
|
7699
7713
|
// src/usage/providerQuota.ts
|
|
7700
|
-
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;
|
|
7701
7715
|
var init_providerQuota = __esm({
|
|
7702
7716
|
"src/usage/providerQuota.ts"() {
|
|
7703
7717
|
"use strict";
|
|
7704
|
-
|
|
7718
|
+
import_zod23 = require("zod");
|
|
7705
7719
|
init_schema2();
|
|
7706
7720
|
MS_PER_SECOND7 = 1e3;
|
|
7707
7721
|
SECONDS_PER_HOUR = 3600;
|
|
@@ -7715,35 +7729,35 @@ var init_providerQuota = __esm({
|
|
|
7715
7729
|
[ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
|
|
7716
7730
|
[ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7]
|
|
7717
7731
|
]);
|
|
7718
|
-
ZaiLimitSchema =
|
|
7719
|
-
type:
|
|
7720
|
-
unit:
|
|
7721
|
-
number:
|
|
7722
|
-
percentage:
|
|
7723
|
-
nextResetTime:
|
|
7724
|
-
usage:
|
|
7725
|
-
currentValue:
|
|
7726
|
-
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()
|
|
7727
7741
|
});
|
|
7728
|
-
ZaiResponseSchema =
|
|
7729
|
-
success:
|
|
7730
|
-
msg:
|
|
7731
|
-
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) })
|
|
7732
7746
|
});
|
|
7733
7747
|
OPENROUTER_HOST = "openrouter.ai";
|
|
7734
7748
|
OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
7735
7749
|
OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
7736
7750
|
MS_PER_DAY3 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7;
|
|
7737
|
-
OpenRouterKeySchema =
|
|
7738
|
-
data:
|
|
7739
|
-
limit:
|
|
7740
|
-
limit_remaining:
|
|
7741
|
-
limit_reset:
|
|
7742
|
-
is_free_tier:
|
|
7743
|
-
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()
|
|
7744
7758
|
})
|
|
7745
7759
|
});
|
|
7746
|
-
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() }) });
|
|
7747
7761
|
}
|
|
7748
7762
|
});
|
|
7749
7763
|
|
|
@@ -7878,10 +7892,44 @@ __export(index_exports, {
|
|
|
7878
7892
|
CodexLogoutOutputSchema: () => CodexLogoutOutputSchema,
|
|
7879
7893
|
CodexSignInSchema: () => CodexSignInSchema,
|
|
7880
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,
|
|
7881
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,
|
|
7882
7929
|
CredentialCacheSchema: () => CredentialCacheSchema,
|
|
7883
7930
|
CredentialSchema: () => CredentialSchema,
|
|
7884
7931
|
CredentialSourceSchema: () => CredentialSourceSchema,
|
|
7932
|
+
CredentialSummarySchema: () => CredentialSummarySchema2,
|
|
7885
7933
|
DOOR_EVENT_BUFFER_EVENTS: () => DOOR_EVENT_BUFFER_EVENTS,
|
|
7886
7934
|
DOOR_EVENT_SOURCE_RC: () => DOOR_EVENT_SOURCE_RC,
|
|
7887
7935
|
DOOR_HEALTH_EVENT_SOURCE: () => DOOR_HEALTH_EVENT_SOURCE,
|
|
@@ -8012,6 +8060,7 @@ __export(index_exports, {
|
|
|
8012
8060
|
collectFrontDoorStatus: () => collectFrontDoorStatus,
|
|
8013
8061
|
collectPoolPick: () => collectPoolPick,
|
|
8014
8062
|
createCodexApiRouter: () => createCodexApiRouter,
|
|
8063
|
+
createConfigApiRouter: () => createConfigApiRouter,
|
|
8015
8064
|
createControlApiRouter: () => createControlApiRouter,
|
|
8016
8065
|
createDoorApiNodeHandler: () => createDoorApiNodeHandler,
|
|
8017
8066
|
createDoorApiRouter: () => createDoorApiRouter,
|
|
@@ -9030,6 +9079,7 @@ var HTTP_STATUS = {
|
|
|
9030
9079
|
forbidden: 403,
|
|
9031
9080
|
notFound: 404,
|
|
9032
9081
|
methodNotAllowed: 405,
|
|
9082
|
+
conflict: 409,
|
|
9033
9083
|
payloadTooLarge: 413,
|
|
9034
9084
|
tooManyRequests: 429,
|
|
9035
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. */
|
|
@@ -11155,9 +11205,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
11155
11205
|
if (request4.method === "GET" && request4.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
|
|
11156
11206
|
const token = doorApiBearer(request4.headers);
|
|
11157
11207
|
if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
|
|
11158
|
-
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" });
|
|
11159
11209
|
response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
|
|
11160
|
-
response.end(JSON.stringify(
|
|
11210
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
11161
11211
|
return { matched: true };
|
|
11162
11212
|
}
|
|
11163
11213
|
try {
|
|
@@ -11165,9 +11215,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
11165
11215
|
response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
|
|
11166
11216
|
response.end(JSON.stringify(doc));
|
|
11167
11217
|
} catch (error) {
|
|
11168
|
-
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)}` });
|
|
11169
11219
|
response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
|
|
11170
|
-
response.end(JSON.stringify(
|
|
11220
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
11171
11221
|
}
|
|
11172
11222
|
return { matched: true };
|
|
11173
11223
|
}
|
|
@@ -11216,8 +11266,8 @@ init_cliError();
|
|
|
11216
11266
|
init_realPorts();
|
|
11217
11267
|
|
|
11218
11268
|
// src/frontdoor/controlApi.ts
|
|
11219
|
-
var
|
|
11220
|
-
var
|
|
11269
|
+
var import_client6 = require("@orpc/client");
|
|
11270
|
+
var import_openapi7 = require("@orpc/openapi");
|
|
11221
11271
|
|
|
11222
11272
|
// src/checkReport.ts
|
|
11223
11273
|
var import_node_os5 = __toESM(require("node:os"), 1);
|
|
@@ -11401,6 +11451,48 @@ function removeProfile(paths, name) {
|
|
|
11401
11451
|
requireProfileExists(paths, name);
|
|
11402
11452
|
import_node_fs3.default.rmSync(profileJsonPath(paths, name));
|
|
11403
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
|
+
}
|
|
11404
11496
|
|
|
11405
11497
|
// src/poolStore.ts
|
|
11406
11498
|
init_store();
|
|
@@ -12174,6 +12266,14 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
12174
12266
|
function identityJsonPath(paths, name) {
|
|
12175
12267
|
return import_node_path27.default.join(paths.identitiesDir, name, "identity.json");
|
|
12176
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
|
+
}
|
|
12177
12277
|
function identityExists(paths, name) {
|
|
12178
12278
|
return import_node_fs8.default.existsSync(identityJsonPath(paths, name));
|
|
12179
12279
|
}
|
|
@@ -13066,47 +13166,608 @@ function createCodexApiRouter(deps) {
|
|
|
13066
13166
|
};
|
|
13067
13167
|
}
|
|
13068
13168
|
|
|
13069
|
-
// src/frontdoor/
|
|
13169
|
+
// src/frontdoor/configApi.ts
|
|
13070
13170
|
var import_client2 = require("@orpc/client");
|
|
13071
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");
|
|
13072
13733
|
var import_server3 = require("@orpc/server");
|
|
13073
13734
|
|
|
13074
13735
|
// src/frontdoor/eventSchemas.ts
|
|
13075
|
-
var
|
|
13736
|
+
var import_zod21 = require("zod");
|
|
13076
13737
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
13077
13738
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
13078
13739
|
var USAGE_EVENT_SOURCE = "usage";
|
|
13079
13740
|
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
13080
13741
|
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
13081
|
-
var DoorEventSchema =
|
|
13082
|
-
source:
|
|
13742
|
+
var DoorEventSchema = import_zod21.z.strictObject({
|
|
13743
|
+
source: import_zod21.z.string().min(1),
|
|
13083
13744
|
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
13084
|
-
sequence:
|
|
13085
|
-
payload:
|
|
13086
|
-
});
|
|
13087
|
-
var DoorEventSourceQuerySchema =
|
|
13088
|
-
sources:
|
|
13089
|
-
});
|
|
13090
|
-
var LaunchLifecycleEventSchema =
|
|
13091
|
-
kind:
|
|
13092
|
-
pid:
|
|
13093
|
-
startedAt:
|
|
13094
|
-
observedAt:
|
|
13095
|
-
});
|
|
13096
|
-
var DoorHealthEventSchema =
|
|
13097
|
-
|
|
13098
|
-
|
|
13099
|
-
|
|
13100
|
-
|
|
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() })
|
|
13101
13762
|
]);
|
|
13102
|
-
var QuotaExpiringEventSchema =
|
|
13103
|
-
identity:
|
|
13104
|
-
provider:
|
|
13105
|
-
window:
|
|
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"]),
|
|
13106
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. */
|
|
13107
|
-
utilization:
|
|
13108
|
-
resetsAt:
|
|
13109
|
-
observedAt:
|
|
13768
|
+
utilization: import_zod21.z.number().min(0).max(1),
|
|
13769
|
+
resetsAt: import_zod21.z.iso.datetime(),
|
|
13770
|
+
observedAt: import_zod21.z.number()
|
|
13110
13771
|
});
|
|
13111
13772
|
|
|
13112
13773
|
// src/frontdoor/eventsApi.ts
|
|
@@ -13115,12 +13776,12 @@ function createEventsApiRouter(deps) {
|
|
|
13115
13776
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13116
13777
|
return {
|
|
13117
13778
|
events: {
|
|
13118
|
-
subscribe: authed.meta((0,
|
|
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 }) {
|
|
13119
13780
|
if (input.sources !== void 0) {
|
|
13120
13781
|
const live = deps.events.sources();
|
|
13121
13782
|
const unknown = input.sources.filter((source) => !live.includes(source));
|
|
13122
13783
|
if (unknown.length > 0) {
|
|
13123
|
-
throw new
|
|
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(", ")}` });
|
|
13124
13785
|
}
|
|
13125
13786
|
}
|
|
13126
13787
|
const stream = deps.events.stream(input.sources);
|
|
@@ -13148,8 +13809,8 @@ function createEventsApiRouter(deps) {
|
|
|
13148
13809
|
}
|
|
13149
13810
|
|
|
13150
13811
|
// src/frontdoor/lifecycleApi.ts
|
|
13151
|
-
var
|
|
13152
|
-
var
|
|
13812
|
+
var import_client4 = require("@orpc/client");
|
|
13813
|
+
var import_openapi5 = require("@orpc/openapi");
|
|
13153
13814
|
init_update();
|
|
13154
13815
|
var FRONTDOOR_API_TAG = "frontdoor";
|
|
13155
13816
|
var UPDATE_API_TAG = "update";
|
|
@@ -13157,24 +13818,24 @@ function createLifecycleApiRouter(deps) {
|
|
|
13157
13818
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13158
13819
|
return {
|
|
13159
13820
|
frontdoor: {
|
|
13160
|
-
restart: authed.meta((0,
|
|
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 }) => {
|
|
13161
13822
|
context.afterResponse(deps.restartDoor);
|
|
13162
13823
|
return { action: "restarting", previousPid: deps.doorPid };
|
|
13163
13824
|
})
|
|
13164
13825
|
},
|
|
13165
13826
|
update: {
|
|
13166
|
-
check: authed.meta((0,
|
|
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 () => {
|
|
13167
13828
|
try {
|
|
13168
13829
|
return await deps.checkForUpdate();
|
|
13169
13830
|
} catch (error) {
|
|
13170
13831
|
if (error instanceof UpdateChannelError) {
|
|
13171
|
-
throw new
|
|
13832
|
+
throw new import_client4.ORPCError("PRECONDITION_FAILED", { message: error.message });
|
|
13172
13833
|
}
|
|
13173
13834
|
if (error instanceof UpdateConflictError) {
|
|
13174
|
-
throw new
|
|
13835
|
+
throw new import_client4.ORPCError("CONFLICT", { message: error.message });
|
|
13175
13836
|
}
|
|
13176
13837
|
if (error instanceof UpdateDownloadError) {
|
|
13177
|
-
throw new
|
|
13838
|
+
throw new import_client4.ORPCError("BAD_GATEWAY", { message: error.message });
|
|
13178
13839
|
}
|
|
13179
13840
|
throw error;
|
|
13180
13841
|
}
|
|
@@ -13184,57 +13845,57 @@ function createLifecycleApiRouter(deps) {
|
|
|
13184
13845
|
}
|
|
13185
13846
|
|
|
13186
13847
|
// src/frontdoor/launchApi.ts
|
|
13187
|
-
var
|
|
13188
|
-
var
|
|
13848
|
+
var import_client5 = require("@orpc/client");
|
|
13849
|
+
var import_openapi6 = require("@orpc/openapi");
|
|
13189
13850
|
init_cliError();
|
|
13190
13851
|
|
|
13191
13852
|
// src/frontdoor/launchSchemas.ts
|
|
13192
13853
|
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
13193
|
-
var
|
|
13854
|
+
var import_zod22 = require("zod");
|
|
13194
13855
|
init_claudeVersion();
|
|
13195
13856
|
init_identity();
|
|
13196
|
-
var LaunchResolveInputSchema =
|
|
13197
|
-
path:
|
|
13857
|
+
var LaunchResolveInputSchema = import_zod22.z.strictObject({
|
|
13858
|
+
path: import_zod22.z.string().min(1),
|
|
13198
13859
|
/** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
|
|
13199
|
-
argv:
|
|
13860
|
+
argv: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())).optional(),
|
|
13200
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. */
|
|
13201
|
-
env:
|
|
13862
|
+
env: import_zod22.z.record(import_zod22.z.string(), import_zod22.z.string()).optional()
|
|
13202
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" });
|
|
13203
|
-
var LaunchPoolDecisionSchema =
|
|
13204
|
-
name:
|
|
13205
|
-
reasons:
|
|
13206
|
-
movedOff:
|
|
13207
|
-
});
|
|
13208
|
-
var LaunchDecisionSchema =
|
|
13209
|
-
identity:
|
|
13210
|
-
identitySource:
|
|
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),
|
|
13211
13872
|
pool: LaunchPoolDecisionSchema.optional(),
|
|
13212
|
-
configDirEscapeHatch:
|
|
13213
|
-
configDir:
|
|
13214
|
-
configProfile:
|
|
13215
|
-
configProfileSource:
|
|
13216
|
-
provider:
|
|
13217
|
-
});
|
|
13218
|
-
var LaunchFlagsSchema =
|
|
13219
|
-
skipPermissions:
|
|
13220
|
-
remoteControl:
|
|
13221
|
-
headroom:
|
|
13222
|
-
trackUsage:
|
|
13223
|
-
});
|
|
13224
|
-
var LaunchResolveOutputSchema =
|
|
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({
|
|
13225
13886
|
decision: LaunchDecisionSchema,
|
|
13226
13887
|
flags: LaunchFlagsSchema,
|
|
13227
|
-
claudeVersion:
|
|
13888
|
+
claudeVersion: import_zod22.z.strictObject({ version: import_zod22.z.string(), source: import_zod22.z.enum(CLAUDE_VERSION_SOURCES) }).optional(),
|
|
13228
13889
|
/** The real `claude` binary the launch would spawn, on the door's host. */
|
|
13229
|
-
bin:
|
|
13890
|
+
bin: import_zod22.z.string(),
|
|
13230
13891
|
/** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
|
|
13231
|
-
args:
|
|
13892
|
+
args: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
|
|
13232
13893
|
/** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
|
|
13233
|
-
credential:
|
|
13234
|
-
routing:
|
|
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() }),
|
|
13235
13896
|
/** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
|
|
13236
|
-
environment:
|
|
13237
|
-
warnings:
|
|
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()))
|
|
13238
13899
|
});
|
|
13239
13900
|
|
|
13240
13901
|
// src/frontdoor/launchApi.ts
|
|
@@ -13243,13 +13904,13 @@ function createLaunchApiRouter(deps) {
|
|
|
13243
13904
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13244
13905
|
return {
|
|
13245
13906
|
launch: {
|
|
13246
|
-
resolve: authed.meta((0,
|
|
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 }) => {
|
|
13247
13908
|
try {
|
|
13248
13909
|
const { resolution, warnings } = deps.resolveLaunch({ path: input.path, argv: input.argv ?? [], env: input.env ?? {} });
|
|
13249
13910
|
return { ...resolution, warnings };
|
|
13250
13911
|
} catch (error) {
|
|
13251
13912
|
if (error instanceof CliError) {
|
|
13252
|
-
throw new
|
|
13913
|
+
throw new import_client5.ORPCError("BAD_REQUEST", { message: error.message });
|
|
13253
13914
|
}
|
|
13254
13915
|
throw error;
|
|
13255
13916
|
}
|
|
@@ -13268,11 +13929,11 @@ function createControlApiRouter(deps) {
|
|
|
13268
13929
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13269
13930
|
return {
|
|
13270
13931
|
usage: {
|
|
13271
|
-
list: authed.meta((0,
|
|
13272
|
-
effectiveWindow: authed.meta((0,
|
|
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 }) => {
|
|
13273
13934
|
const snapshot = deps.usageSnapshotOf(input.identity);
|
|
13274
13935
|
if (snapshot === void 0) {
|
|
13275
|
-
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` });
|
|
13276
13937
|
}
|
|
13277
13938
|
const provider = input.provider ?? ANTHROPIC_PROVIDER;
|
|
13278
13939
|
const rateLimit = snapshot.providers[provider]?.rateLimit;
|
|
@@ -13286,34 +13947,34 @@ function createControlApiRouter(deps) {
|
|
|
13286
13947
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
13287
13948
|
};
|
|
13288
13949
|
}),
|
|
13289
|
-
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 }) => {
|
|
13290
13951
|
const sessions = deps.liveRateLimits(input.session);
|
|
13291
13952
|
if (input.session !== void 0 && sessions.length === 0) {
|
|
13292
13953
|
if (deps.list().some((session) => session.id === input.session)) {
|
|
13293
|
-
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` });
|
|
13294
13955
|
}
|
|
13295
|
-
throw new
|
|
13956
|
+
throw new import_client6.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
13296
13957
|
}
|
|
13297
13958
|
return { latest: deps.latestRateLimit(), sessions };
|
|
13298
13959
|
})
|
|
13299
13960
|
},
|
|
13300
13961
|
frontdoor: {
|
|
13301
|
-
status: authed.meta((0,
|
|
13302
|
-
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 }))
|
|
13303
13964
|
},
|
|
13304
13965
|
check: {
|
|
13305
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.
|
|
13306
|
-
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)))
|
|
13307
13968
|
},
|
|
13308
13969
|
doctor: {
|
|
13309
|
-
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())
|
|
13310
13971
|
},
|
|
13311
13972
|
pool: {
|
|
13312
|
-
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 }) => {
|
|
13313
13974
|
const report = deps.poolPick(input.pool, input.path);
|
|
13314
13975
|
if (report === void 0) {
|
|
13315
13976
|
const live = deps.poolNames();
|
|
13316
|
-
throw new
|
|
13977
|
+
throw new import_client6.ORPCError("NOT_FOUND", {
|
|
13317
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(", ")}`
|
|
13318
13979
|
});
|
|
13319
13980
|
}
|
|
@@ -13325,13 +13986,13 @@ function createControlApiRouter(deps) {
|
|
|
13325
13986
|
function createDoorApiRouter(deps) {
|
|
13326
13987
|
const control = createControlApiRouter(deps);
|
|
13327
13988
|
const lifecycle = createLifecycleApiRouter(deps);
|
|
13328
|
-
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
13989
|
+
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
13329
13990
|
}
|
|
13330
13991
|
function createDoorApiNodeHandler(deps) {
|
|
13331
13992
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
13332
13993
|
}
|
|
13333
13994
|
function frontDoorApiClient(port, ca, token) {
|
|
13334
|
-
return (0,
|
|
13995
|
+
return (0, import_client6.createORPCClient)(frontDoorApiLink(port, ca, token));
|
|
13335
13996
|
}
|
|
13336
13997
|
|
|
13337
13998
|
// src/frontdoor/doorClient.ts
|
|
@@ -14137,9 +14798,9 @@ async function serveRcCompatSessions(ctx, pathname, compatPath) {
|
|
|
14137
14798
|
const slash = rest.indexOf("/");
|
|
14138
14799
|
const address = slash === -1 ? rest : rest.slice(0, slash);
|
|
14139
14800
|
const compatTail = slash === -1 ? "" : rest.slice(slash + 1);
|
|
14140
|
-
const
|
|
14141
|
-
if (
|
|
14142
|
-
await ctx.unauthorized(response,
|
|
14801
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14802
|
+
if (refusal2 !== void 0) {
|
|
14803
|
+
await ctx.unauthorized(response, refusal2);
|
|
14143
14804
|
return;
|
|
14144
14805
|
}
|
|
14145
14806
|
const session = ctx.sessions.get(address) ?? ctx.sessions.get(`cse_${address}`);
|
|
@@ -14217,9 +14878,9 @@ function conversationRow(conversation) {
|
|
|
14217
14878
|
}
|
|
14218
14879
|
async function serveRcConversations(ctx, pathname, method) {
|
|
14219
14880
|
const { request: request4, response, conversations } = ctx;
|
|
14220
|
-
const
|
|
14221
|
-
if (
|
|
14222
|
-
await ctx.unauthorized(response,
|
|
14881
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14882
|
+
if (refusal2 !== void 0) {
|
|
14883
|
+
await ctx.unauthorized(response, refusal2);
|
|
14223
14884
|
return;
|
|
14224
14885
|
}
|
|
14225
14886
|
if (pathname === RC_CONVERSATIONS_PATH_PREFIX) {
|
|
@@ -14543,9 +15204,9 @@ async function fetchThroughWebProxy(url, deps) {
|
|
|
14543
15204
|
try {
|
|
14544
15205
|
let redirects = 0;
|
|
14545
15206
|
for (; ; ) {
|
|
14546
|
-
const
|
|
14547
|
-
if (
|
|
14548
|
-
return
|
|
15207
|
+
const refusal2 = await checkTarget(current, deps);
|
|
15208
|
+
if (refusal2 !== void 0) {
|
|
15209
|
+
return refusal2;
|
|
14549
15210
|
}
|
|
14550
15211
|
let hop;
|
|
14551
15212
|
try {
|
|
@@ -14915,8 +15576,8 @@ data: ${JSON.stringify(envelope)}
|
|
|
14915
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",
|
|
14916
15577
|
unrecognised: "the self-hosted Remote Control surface did not recognise the presented credential"
|
|
14917
15578
|
};
|
|
14918
|
-
const unauthorized = async (response,
|
|
14919
|
-
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] } });
|
|
14920
15581
|
};
|
|
14921
15582
|
const serveSessionPath = async (session, tail, request4, response) => {
|
|
14922
15583
|
const method = request4.method.toUpperCase();
|
|
@@ -14927,9 +15588,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14927
15588
|
session.lastTrafficAt = deps.now();
|
|
14928
15589
|
if (tail === "") {
|
|
14929
15590
|
if (method === "PATCH" || method === "PUT") {
|
|
14930
|
-
const
|
|
14931
|
-
if (
|
|
14932
|
-
await unauthorized(response,
|
|
15591
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15592
|
+
if (refusal2 !== void 0) {
|
|
15593
|
+
await unauthorized(response, refusal2);
|
|
14933
15594
|
return;
|
|
14934
15595
|
}
|
|
14935
15596
|
const body = parseJsonObject5(await readBody2(request4.body, CONTROL_BODY_CAP_BYTES));
|
|
@@ -14952,9 +15613,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14952
15613
|
return;
|
|
14953
15614
|
}
|
|
14954
15615
|
if (tail === "bridge" && method === "POST") {
|
|
14955
|
-
const
|
|
14956
|
-
if (
|
|
14957
|
-
await unauthorized(response,
|
|
15616
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15617
|
+
if (refusal2 !== void 0) {
|
|
15618
|
+
await unauthorized(response, refusal2);
|
|
14958
15619
|
return;
|
|
14959
15620
|
}
|
|
14960
15621
|
const workerJwt = mintWorkerJwt(deps.randomToken, deps.now());
|
|
@@ -14964,9 +15625,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14964
15625
|
return;
|
|
14965
15626
|
}
|
|
14966
15627
|
if (tail === "archive" && method === "POST") {
|
|
14967
|
-
const
|
|
14968
|
-
if (
|
|
14969
|
-
await unauthorized(response,
|
|
15628
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15629
|
+
if (refusal2 !== void 0) {
|
|
15630
|
+
await unauthorized(response, refusal2);
|
|
14970
15631
|
return;
|
|
14971
15632
|
}
|
|
14972
15633
|
retireSession(session);
|
|
@@ -14977,9 +15638,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14977
15638
|
if (tail === "worker" || tail.startsWith("worker/")) {
|
|
14978
15639
|
const workerTail = tail === "worker" ? "" : tail.slice("worker/".length);
|
|
14979
15640
|
const webProxy = workerTail === "web-fetch" || workerTail === "web-search";
|
|
14980
|
-
const
|
|
14981
|
-
if (
|
|
14982
|
-
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);
|
|
14983
15644
|
return;
|
|
14984
15645
|
}
|
|
14985
15646
|
if (workerTail === "" && method === "GET") {
|
|
@@ -15392,102 +16053,6 @@ init_paths();
|
|
|
15392
16053
|
init_cliError();
|
|
15393
16054
|
init_schema();
|
|
15394
16055
|
init_providersStore();
|
|
15395
|
-
|
|
15396
|
-
// src/directoryRulesStore.ts
|
|
15397
|
-
init_store();
|
|
15398
|
-
init_load();
|
|
15399
|
-
init_schema();
|
|
15400
|
-
init_cliError();
|
|
15401
|
-
var DirectoryRuleNotFoundError = class extends CliError {
|
|
15402
|
-
constructor(rulePath) {
|
|
15403
|
-
super(`No directory rule found for path "${rulePath}".`);
|
|
15404
|
-
this.rulePath = rulePath;
|
|
15405
|
-
this.name = "DirectoryRuleNotFoundError";
|
|
15406
|
-
}
|
|
15407
|
-
rulePath;
|
|
15408
|
-
};
|
|
15409
|
-
var DirectoryRuleMissingTargetError = class extends CliError {
|
|
15410
|
-
constructor() {
|
|
15411
|
-
super("A directory rule must set at least one of --config-profile or --identity.");
|
|
15412
|
-
this.name = "DirectoryRuleMissingTargetError";
|
|
15413
|
-
}
|
|
15414
|
-
};
|
|
15415
|
-
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
15416
|
-
constructor(rulePath) {
|
|
15417
|
-
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
15418
|
-
this.rulePath = rulePath;
|
|
15419
|
-
this.name = "DirectoryRuleAlreadyExistsError";
|
|
15420
|
-
}
|
|
15421
|
-
rulePath;
|
|
15422
|
-
};
|
|
15423
|
-
function readDirectoryRules(paths) {
|
|
15424
|
-
return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
|
|
15425
|
-
}
|
|
15426
|
-
function writeDirectoryRules(paths, rules) {
|
|
15427
|
-
const parsed = DirectoryRulesSchema.safeParse(rules);
|
|
15428
|
-
if (!parsed.success) {
|
|
15429
|
-
throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
|
|
15430
|
-
}
|
|
15431
|
-
writeJsonAtomic(paths.directoryRulesFile, parsed.data);
|
|
15432
|
-
}
|
|
15433
|
-
function listDirectoryRules(paths) {
|
|
15434
|
-
return readDirectoryRules(paths).rules;
|
|
15435
|
-
}
|
|
15436
|
-
function addDirectoryRule(paths, rulePath, options) {
|
|
15437
|
-
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
15438
|
-
throw new DirectoryRuleMissingTargetError();
|
|
15439
|
-
}
|
|
15440
|
-
const current = readDirectoryRules(paths);
|
|
15441
|
-
if (current.rules.some((rule) => rule.path === rulePath)) {
|
|
15442
|
-
throw new DirectoryRuleAlreadyExistsError(rulePath);
|
|
15443
|
-
}
|
|
15444
|
-
const created = buildNewRule(rulePath, options);
|
|
15445
|
-
writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
|
|
15446
|
-
return created;
|
|
15447
|
-
}
|
|
15448
|
-
function ruleHasEffect(rule) {
|
|
15449
|
-
return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
|
|
15450
|
-
}
|
|
15451
|
-
function updateDirectoryRule(paths, rulePath, options) {
|
|
15452
|
-
const current = readDirectoryRules(paths);
|
|
15453
|
-
const index = current.rules.findIndex((rule) => rule.path === rulePath);
|
|
15454
|
-
const existing = index === -1 ? void 0 : current.rules[index];
|
|
15455
|
-
if (existing === void 0) {
|
|
15456
|
-
throw new DirectoryRuleNotFoundError(rulePath);
|
|
15457
|
-
}
|
|
15458
|
-
const { configProfile, identity, ...rest } = existing;
|
|
15459
|
-
const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
|
|
15460
|
-
const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
|
|
15461
|
-
const updated = {
|
|
15462
|
-
...rest,
|
|
15463
|
-
...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
|
|
15464
|
-
...nextIdentity === void 0 ? {} : { identity: nextIdentity }
|
|
15465
|
-
};
|
|
15466
|
-
if (!ruleHasEffect(updated)) {
|
|
15467
|
-
throw new DirectoryRuleMissingTargetError();
|
|
15468
|
-
}
|
|
15469
|
-
const nextRules = [...current.rules];
|
|
15470
|
-
nextRules[index] = updated;
|
|
15471
|
-
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
15472
|
-
return updated;
|
|
15473
|
-
}
|
|
15474
|
-
function buildNewRule(rulePath, options) {
|
|
15475
|
-
return {
|
|
15476
|
-
path: rulePath,
|
|
15477
|
-
...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
|
|
15478
|
-
...options.identity !== void 0 ? { identity: options.identity } : {}
|
|
15479
|
-
};
|
|
15480
|
-
}
|
|
15481
|
-
function removeDirectoryRule(paths, rulePath) {
|
|
15482
|
-
const current = readDirectoryRules(paths);
|
|
15483
|
-
const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
|
|
15484
|
-
if (nextRules.length === current.rules.length) {
|
|
15485
|
-
throw new DirectoryRuleNotFoundError(rulePath);
|
|
15486
|
-
}
|
|
15487
|
-
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
15488
|
-
}
|
|
15489
|
-
|
|
15490
|
-
// src/index.ts
|
|
15491
16056
|
init_launcher();
|
|
15492
16057
|
init_spawn();
|
|
15493
16058
|
init_launchWiring();
|
|
@@ -15602,10 +16167,44 @@ init_ownCli();
|
|
|
15602
16167
|
CodexLogoutOutputSchema,
|
|
15603
16168
|
CodexSignInSchema,
|
|
15604
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,
|
|
15605
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,
|
|
15606
16204
|
CredentialCacheSchema,
|
|
15607
16205
|
CredentialSchema,
|
|
15608
16206
|
CredentialSourceSchema,
|
|
16207
|
+
CredentialSummarySchema,
|
|
15609
16208
|
DOOR_EVENT_BUFFER_EVENTS,
|
|
15610
16209
|
DOOR_EVENT_SOURCE_RC,
|
|
15611
16210
|
DOOR_HEALTH_EVENT_SOURCE,
|
|
@@ -15736,6 +16335,7 @@ init_ownCli();
|
|
|
15736
16335
|
collectFrontDoorStatus,
|
|
15737
16336
|
collectPoolPick,
|
|
15738
16337
|
createCodexApiRouter,
|
|
16338
|
+
createConfigApiRouter,
|
|
15739
16339
|
createControlApiRouter,
|
|
15740
16340
|
createDoorApiNodeHandler,
|
|
15741
16341
|
createDoorApiRouter,
|