claude-use 9.6.0 → 9.7.1
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 +611 -131
- package/dist/index.cjs +870 -260
- package/dist/index.mjs +833 -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.1",
|
|
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. */
|
|
@@ -11038,6 +11088,7 @@ var RcAnswerOutputSchema = import_zod4.z.strictObject({
|
|
|
11038
11088
|
var RC_ORPC_PATH_PREFIX = "/__agent-shim/orpc";
|
|
11039
11089
|
var RC_OPENAPI_DOC_PATH = "/openapi.json";
|
|
11040
11090
|
var RC_SUBSCRIBER_BUFFER_EVENTS = 100;
|
|
11091
|
+
var READ_ONLY_OPERATION_EXTENSION = "x-agent-shim-read-only";
|
|
11041
11092
|
function doorApiBearer(headers) {
|
|
11042
11093
|
const presented = headers.authorization;
|
|
11043
11094
|
const bearerPrefix = "bearer ".length;
|
|
@@ -11155,9 +11206,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
11155
11206
|
if (request4.method === "GET" && request4.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
|
|
11156
11207
|
const token = doorApiBearer(request4.headers);
|
|
11157
11208
|
if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
|
|
11158
|
-
const
|
|
11209
|
+
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
11210
|
response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
|
|
11160
|
-
response.end(JSON.stringify(
|
|
11211
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
11161
11212
|
return { matched: true };
|
|
11162
11213
|
}
|
|
11163
11214
|
try {
|
|
@@ -11165,9 +11216,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
11165
11216
|
response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
|
|
11166
11217
|
response.end(JSON.stringify(doc));
|
|
11167
11218
|
} catch (error) {
|
|
11168
|
-
const
|
|
11219
|
+
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
11220
|
response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
|
|
11170
|
-
response.end(JSON.stringify(
|
|
11221
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
11171
11222
|
}
|
|
11172
11223
|
return { matched: true };
|
|
11173
11224
|
}
|
|
@@ -11216,8 +11267,8 @@ init_cliError();
|
|
|
11216
11267
|
init_realPorts();
|
|
11217
11268
|
|
|
11218
11269
|
// src/frontdoor/controlApi.ts
|
|
11219
|
-
var
|
|
11220
|
-
var
|
|
11270
|
+
var import_client6 = require("@orpc/client");
|
|
11271
|
+
var import_openapi7 = require("@orpc/openapi");
|
|
11221
11272
|
|
|
11222
11273
|
// src/checkReport.ts
|
|
11223
11274
|
var import_node_os5 = __toESM(require("node:os"), 1);
|
|
@@ -11401,6 +11452,48 @@ function removeProfile(paths, name) {
|
|
|
11401
11452
|
requireProfileExists(paths, name);
|
|
11402
11453
|
import_node_fs3.default.rmSync(profileJsonPath(paths, name));
|
|
11403
11454
|
}
|
|
11455
|
+
function applyProfileChange(paths, name, change) {
|
|
11456
|
+
let touched = false;
|
|
11457
|
+
if (change.category !== void 0) {
|
|
11458
|
+
setProfileCategories(paths, name, change.category);
|
|
11459
|
+
touched = true;
|
|
11460
|
+
}
|
|
11461
|
+
if (change.entry !== void 0) {
|
|
11462
|
+
setProfileEntries(paths, name, change.entry);
|
|
11463
|
+
touched = true;
|
|
11464
|
+
}
|
|
11465
|
+
if (change.extends !== void 0 || change.description !== void 0) {
|
|
11466
|
+
setProfileMetadata(paths, name, {
|
|
11467
|
+
...change.extends === void 0 ? {} : { extends: change.extends === false ? [] : change.extends },
|
|
11468
|
+
...change.description === void 0 ? {} : { description: change.description }
|
|
11469
|
+
});
|
|
11470
|
+
touched = true;
|
|
11471
|
+
}
|
|
11472
|
+
const launchPatch = {};
|
|
11473
|
+
if (change.launchSkipPermissions !== void 0) {
|
|
11474
|
+
launchPatch.skipPermissions = change.launchSkipPermissions;
|
|
11475
|
+
}
|
|
11476
|
+
if (change.launchRemoteControl !== void 0) {
|
|
11477
|
+
launchPatch.remoteControl = change.launchRemoteControl;
|
|
11478
|
+
}
|
|
11479
|
+
if (change.launchHeadroom !== void 0) {
|
|
11480
|
+
launchPatch.headroom = change.launchHeadroom;
|
|
11481
|
+
}
|
|
11482
|
+
if (change.launchTrackUsage !== void 0) {
|
|
11483
|
+
launchPatch.trackUsage = change.launchTrackUsage;
|
|
11484
|
+
}
|
|
11485
|
+
if (change.launchProvider !== void 0) {
|
|
11486
|
+
launchPatch.provider = change.launchProvider === false ? void 0 : change.launchProvider;
|
|
11487
|
+
}
|
|
11488
|
+
if (change.launchClaudeVersion !== void 0) {
|
|
11489
|
+
launchPatch.claudeVersion = change.launchClaudeVersion === false ? void 0 : change.launchClaudeVersion;
|
|
11490
|
+
}
|
|
11491
|
+
if (Object.keys(launchPatch).length > 0) {
|
|
11492
|
+
setProfileLaunchFlags(paths, name, launchPatch);
|
|
11493
|
+
touched = true;
|
|
11494
|
+
}
|
|
11495
|
+
return touched;
|
|
11496
|
+
}
|
|
11404
11497
|
|
|
11405
11498
|
// src/poolStore.ts
|
|
11406
11499
|
init_store();
|
|
@@ -12174,6 +12267,14 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
12174
12267
|
function identityJsonPath(paths, name) {
|
|
12175
12268
|
return import_node_path27.default.join(paths.identitiesDir, name, "identity.json");
|
|
12176
12269
|
}
|
|
12270
|
+
function requireIdentityNames(paths, names) {
|
|
12271
|
+
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
12272
|
+
for (const name of names) {
|
|
12273
|
+
if (poolNameOf(name) === void 0 && !existing.has(name)) {
|
|
12274
|
+
throw new IdentityNotFoundError(name);
|
|
12275
|
+
}
|
|
12276
|
+
}
|
|
12277
|
+
}
|
|
12177
12278
|
function identityExists(paths, name) {
|
|
12178
12279
|
return import_node_fs8.default.existsSync(identityJsonPath(paths, name));
|
|
12179
12280
|
}
|
|
@@ -13066,47 +13167,608 @@ function createCodexApiRouter(deps) {
|
|
|
13066
13167
|
};
|
|
13067
13168
|
}
|
|
13068
13169
|
|
|
13069
|
-
// src/frontdoor/
|
|
13170
|
+
// src/frontdoor/configApi.ts
|
|
13070
13171
|
var import_client2 = require("@orpc/client");
|
|
13071
13172
|
var import_openapi3 = require("@orpc/openapi");
|
|
13173
|
+
init_cliError();
|
|
13174
|
+
init_schema();
|
|
13175
|
+
init_credential();
|
|
13176
|
+
|
|
13177
|
+
// src/credentialCacheChange.ts
|
|
13178
|
+
init_cliError();
|
|
13179
|
+
init_schema();
|
|
13180
|
+
function mergeCredentialCache(request4, existing) {
|
|
13181
|
+
if (request4.enabled === false) {
|
|
13182
|
+
return false;
|
|
13183
|
+
}
|
|
13184
|
+
if (request4.ttl === void 0 && request4.store === void 0 && request4.enabled !== true) {
|
|
13185
|
+
return void 0;
|
|
13186
|
+
}
|
|
13187
|
+
const parsed = CredentialCacheSchema.safeParse({
|
|
13188
|
+
...existing,
|
|
13189
|
+
...request4.ttl === void 0 ? {} : { ttl: request4.ttl },
|
|
13190
|
+
...request4.store === void 0 ? {} : { store: request4.store }
|
|
13191
|
+
});
|
|
13192
|
+
if (!parsed.success) {
|
|
13193
|
+
throw new UsageError(parsed.error.issues.map((issue) => issue.message).join("; "));
|
|
13194
|
+
}
|
|
13195
|
+
return parsed.data;
|
|
13196
|
+
}
|
|
13197
|
+
|
|
13198
|
+
// src/directoryRulesStore.ts
|
|
13199
|
+
init_store();
|
|
13200
|
+
init_load();
|
|
13201
|
+
init_schema();
|
|
13202
|
+
init_cliError();
|
|
13203
|
+
var DirectoryRuleNotFoundError = class extends CliError {
|
|
13204
|
+
constructor(rulePath) {
|
|
13205
|
+
super(`No directory rule found for path "${rulePath}".`);
|
|
13206
|
+
this.rulePath = rulePath;
|
|
13207
|
+
this.name = "DirectoryRuleNotFoundError";
|
|
13208
|
+
}
|
|
13209
|
+
rulePath;
|
|
13210
|
+
};
|
|
13211
|
+
var DirectoryRuleMissingTargetError = class extends CliError {
|
|
13212
|
+
constructor() {
|
|
13213
|
+
super("A directory rule must set at least one of --config-profile or --identity.");
|
|
13214
|
+
this.name = "DirectoryRuleMissingTargetError";
|
|
13215
|
+
}
|
|
13216
|
+
};
|
|
13217
|
+
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
13218
|
+
constructor(rulePath) {
|
|
13219
|
+
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
13220
|
+
this.rulePath = rulePath;
|
|
13221
|
+
this.name = "DirectoryRuleAlreadyExistsError";
|
|
13222
|
+
}
|
|
13223
|
+
rulePath;
|
|
13224
|
+
};
|
|
13225
|
+
function readDirectoryRules(paths) {
|
|
13226
|
+
return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
|
|
13227
|
+
}
|
|
13228
|
+
function writeDirectoryRules(paths, rules) {
|
|
13229
|
+
const parsed = DirectoryRulesSchema.safeParse(rules);
|
|
13230
|
+
if (!parsed.success) {
|
|
13231
|
+
throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
|
|
13232
|
+
}
|
|
13233
|
+
writeJsonAtomic(paths.directoryRulesFile, parsed.data);
|
|
13234
|
+
}
|
|
13235
|
+
function listDirectoryRules(paths) {
|
|
13236
|
+
return readDirectoryRules(paths).rules;
|
|
13237
|
+
}
|
|
13238
|
+
function addDirectoryRule(paths, rulePath, options) {
|
|
13239
|
+
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
13240
|
+
throw new DirectoryRuleMissingTargetError();
|
|
13241
|
+
}
|
|
13242
|
+
const current = readDirectoryRules(paths);
|
|
13243
|
+
if (current.rules.some((rule) => rule.path === rulePath)) {
|
|
13244
|
+
throw new DirectoryRuleAlreadyExistsError(rulePath);
|
|
13245
|
+
}
|
|
13246
|
+
const created = buildNewRule(rulePath, options);
|
|
13247
|
+
writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
|
|
13248
|
+
return created;
|
|
13249
|
+
}
|
|
13250
|
+
function ruleHasEffect(rule) {
|
|
13251
|
+
return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
|
|
13252
|
+
}
|
|
13253
|
+
function updateDirectoryRule(paths, rulePath, options) {
|
|
13254
|
+
const current = readDirectoryRules(paths);
|
|
13255
|
+
const index = current.rules.findIndex((rule) => rule.path === rulePath);
|
|
13256
|
+
const existing = index === -1 ? void 0 : current.rules[index];
|
|
13257
|
+
if (existing === void 0) {
|
|
13258
|
+
throw new DirectoryRuleNotFoundError(rulePath);
|
|
13259
|
+
}
|
|
13260
|
+
const { configProfile, identity, ...rest } = existing;
|
|
13261
|
+
const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
|
|
13262
|
+
const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
|
|
13263
|
+
const updated = {
|
|
13264
|
+
...rest,
|
|
13265
|
+
...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
|
|
13266
|
+
...nextIdentity === void 0 ? {} : { identity: nextIdentity }
|
|
13267
|
+
};
|
|
13268
|
+
if (!ruleHasEffect(updated)) {
|
|
13269
|
+
throw new DirectoryRuleMissingTargetError();
|
|
13270
|
+
}
|
|
13271
|
+
const nextRules = [...current.rules];
|
|
13272
|
+
nextRules[index] = updated;
|
|
13273
|
+
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
13274
|
+
return updated;
|
|
13275
|
+
}
|
|
13276
|
+
function buildNewRule(rulePath, options) {
|
|
13277
|
+
return {
|
|
13278
|
+
path: rulePath,
|
|
13279
|
+
...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
|
|
13280
|
+
...options.identity !== void 0 ? { identity: options.identity } : {}
|
|
13281
|
+
};
|
|
13282
|
+
}
|
|
13283
|
+
function removeDirectoryRule(paths, rulePath) {
|
|
13284
|
+
const current = readDirectoryRules(paths);
|
|
13285
|
+
const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
|
|
13286
|
+
if (nextRules.length === current.rules.length) {
|
|
13287
|
+
throw new DirectoryRuleNotFoundError(rulePath);
|
|
13288
|
+
}
|
|
13289
|
+
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
13290
|
+
}
|
|
13291
|
+
function requireRuleSelector(paths, selector) {
|
|
13292
|
+
if (selector.startsWith(POOL_SELECTOR_PREFIX)) {
|
|
13293
|
+
const poolName = selector.slice(POOL_SELECTOR_PREFIX.length);
|
|
13294
|
+
if (readPools(paths)[poolName] === void 0) {
|
|
13295
|
+
throw new PoolNotFoundError(poolName);
|
|
13296
|
+
}
|
|
13297
|
+
} else if (readIdentity(paths, selector) === void 0) {
|
|
13298
|
+
throw new IdentityNotFoundError(selector);
|
|
13299
|
+
}
|
|
13300
|
+
}
|
|
13301
|
+
|
|
13302
|
+
// src/frontdoor/configApi.ts
|
|
13303
|
+
init_identity();
|
|
13304
|
+
init_providersStore();
|
|
13305
|
+
|
|
13306
|
+
// src/frontdoor/configSchemas.ts
|
|
13307
|
+
var import_zod20 = require("zod");
|
|
13308
|
+
init_schema();
|
|
13309
|
+
var RemovalConfirmationSchema = import_zod20.z.boolean();
|
|
13310
|
+
var CredentialWriteSchema = (targets) => import_zod20.z.strictObject({
|
|
13311
|
+
sources: import_zod20.z.array(RemoteCredentialSourceSchema).min(1).optional(),
|
|
13312
|
+
target: import_zod20.z.enum(targets).optional(),
|
|
13313
|
+
cache: import_zod20.z.union([import_zod20.z.literal(false), CredentialCacheSchema]).optional()
|
|
13314
|
+
});
|
|
13315
|
+
var CredentialSummarySchema2 = import_zod20.z.strictObject({
|
|
13316
|
+
target: import_zod20.z.enum(CREDENTIAL_TARGETS),
|
|
13317
|
+
sources: import_zod20.z.readonly(import_zod20.z.array(
|
|
13318
|
+
import_zod20.z.discriminatedUnion("kind", [
|
|
13319
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("env"), variable: import_zod20.z.string() }),
|
|
13320
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("file"), path: import_zod20.z.string() }),
|
|
13321
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("command"), program: import_zod20.z.string() }),
|
|
13322
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("op"), reference: import_zod20.z.string() }),
|
|
13323
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("keychain"), service: import_zod20.z.string(), account: import_zod20.z.string().optional() }),
|
|
13324
|
+
import_zod20.z.strictObject({ kind: import_zod20.z.literal("literal") })
|
|
13325
|
+
])
|
|
13326
|
+
)),
|
|
13327
|
+
cache: CredentialCacheSchema.optional()
|
|
13328
|
+
});
|
|
13329
|
+
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() });
|
|
13330
|
+
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 });
|
|
13331
|
+
var IdentityValueSchema = import_zod20.z.strictObject({
|
|
13332
|
+
name: import_zod20.z.string(),
|
|
13333
|
+
defaultConfigProfile: import_zod20.z.string().optional(),
|
|
13334
|
+
allowAmbientCredential: import_zod20.z.boolean(),
|
|
13335
|
+
credential: CredentialSummarySchema2.optional()
|
|
13336
|
+
});
|
|
13337
|
+
var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
|
|
13338
|
+
var ProviderValueSchema = import_zod20.z.strictObject({
|
|
13339
|
+
name: import_zod20.z.string(),
|
|
13340
|
+
kind: import_zod20.z.enum(PROVIDER_KINDS),
|
|
13341
|
+
displayName: import_zod20.z.string(),
|
|
13342
|
+
baseUrl: import_zod20.z.string().optional(),
|
|
13343
|
+
codex: CodexProviderConfigSchema.optional(),
|
|
13344
|
+
credential: CredentialSummarySchema2,
|
|
13345
|
+
env: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.string()).optional()
|
|
13346
|
+
});
|
|
13347
|
+
var ConfigNameInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1) });
|
|
13348
|
+
var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
|
|
13349
|
+
var ConfigIdentitySetInputSchema = import_zod20.z.strictObject({
|
|
13350
|
+
name: import_zod20.z.string().min(1),
|
|
13351
|
+
defaultConfigProfile: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
|
|
13352
|
+
allowAmbientCredential: import_zod20.z.boolean().optional(),
|
|
13353
|
+
credential: import_zod20.z.union([import_zod20.z.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
|
|
13354
|
+
});
|
|
13355
|
+
var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
|
|
13356
|
+
var ConfigIdentityRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13357
|
+
var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
|
|
13358
|
+
var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
|
|
13359
|
+
var ConfigProfileAddInputSchema = import_zod20.z.strictObject({
|
|
13360
|
+
name: import_zod20.z.string().min(1),
|
|
13361
|
+
extends: import_zod20.z.array(import_zod20.z.string().min(1)).optional(),
|
|
13362
|
+
description: import_zod20.z.string().optional()
|
|
13363
|
+
});
|
|
13364
|
+
var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
|
|
13365
|
+
var ConfigProfileSetInputSchema = import_zod20.z.strictObject({
|
|
13366
|
+
name: import_zod20.z.string().min(1),
|
|
13367
|
+
category: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.boolean()).optional(),
|
|
13368
|
+
entry: import_zod20.z.record(import_zod20.z.string(), import_zod20.z.boolean()).optional(),
|
|
13369
|
+
extends: import_zod20.z.union([import_zod20.z.array(import_zod20.z.string().min(1)), import_zod20.z.literal(false)]).optional(),
|
|
13370
|
+
description: import_zod20.z.union([import_zod20.z.string(), import_zod20.z.literal(false)]).optional(),
|
|
13371
|
+
launch: import_zod20.z.strictObject({
|
|
13372
|
+
skipPermissions: import_zod20.z.boolean().optional(),
|
|
13373
|
+
remoteControl: import_zod20.z.boolean().optional(),
|
|
13374
|
+
headroom: import_zod20.z.boolean().optional(),
|
|
13375
|
+
trackUsage: import_zod20.z.boolean().optional(),
|
|
13376
|
+
provider: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
|
|
13377
|
+
claudeVersion: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional()
|
|
13378
|
+
}).optional()
|
|
13379
|
+
});
|
|
13380
|
+
var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
|
|
13381
|
+
var ConfigProfileRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13382
|
+
var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
|
|
13383
|
+
var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
|
|
13384
|
+
var PoolMembersInputSchema = import_zod20.z.array(import_zod20.z.string().min(1)).min(1);
|
|
13385
|
+
var ConfigPoolAddInputSchema = import_zod20.z.strictObject({
|
|
13386
|
+
name: import_zod20.z.string().min(1),
|
|
13387
|
+
identities: PoolMembersInputSchema,
|
|
13388
|
+
preference: import_zod20.z.enum(POOL_PREFERENCES).optional()
|
|
13389
|
+
});
|
|
13390
|
+
var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
|
|
13391
|
+
var ConfigPoolSetInputSchema = import_zod20.z.strictObject({
|
|
13392
|
+
name: import_zod20.z.string().min(1),
|
|
13393
|
+
identities: PoolMembersInputSchema.optional(),
|
|
13394
|
+
preference: import_zod20.z.union([import_zod20.z.enum(POOL_PREFERENCES), import_zod20.z.literal(false)]).optional()
|
|
13395
|
+
});
|
|
13396
|
+
var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
|
|
13397
|
+
var ConfigPoolRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13398
|
+
var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
|
|
13399
|
+
var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
|
|
13400
|
+
var ConfigProviderAddInputSchema = import_zod20.z.strictObject({
|
|
13401
|
+
name: import_zod20.z.string().min(1),
|
|
13402
|
+
kind: import_zod20.z.enum(PROVIDER_KINDS).optional(),
|
|
13403
|
+
displayName: import_zod20.z.string().min(1),
|
|
13404
|
+
baseUrl: import_zod20.z.string().min(1).optional(),
|
|
13405
|
+
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
|
|
13406
|
+
codex: CodexProviderConfigSchema.optional()
|
|
13407
|
+
});
|
|
13408
|
+
var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
|
|
13409
|
+
var ConfigProviderSetInputSchema = import_zod20.z.strictObject({
|
|
13410
|
+
name: import_zod20.z.string().min(1),
|
|
13411
|
+
displayName: import_zod20.z.string().min(1).optional(),
|
|
13412
|
+
baseUrl: import_zod20.z.string().min(1).optional(),
|
|
13413
|
+
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
|
|
13414
|
+
codex: CodexProviderConfigSchema.optional()
|
|
13415
|
+
});
|
|
13416
|
+
var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
|
|
13417
|
+
var ConfigProviderRemoveInputSchema = import_zod20.z.strictObject({ name: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13418
|
+
var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
|
|
13419
|
+
var ConfigRuleAddInputSchema = import_zod20.z.strictObject({
|
|
13420
|
+
path: import_zod20.z.string().min(1),
|
|
13421
|
+
configProfile: import_zod20.z.string().min(1).optional(),
|
|
13422
|
+
identity: import_zod20.z.string().min(1).optional()
|
|
13423
|
+
});
|
|
13424
|
+
var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
|
|
13425
|
+
var ConfigRuleSetInputSchema = import_zod20.z.strictObject({
|
|
13426
|
+
path: import_zod20.z.string().min(1),
|
|
13427
|
+
configProfile: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional(),
|
|
13428
|
+
identity: import_zod20.z.union([import_zod20.z.string().min(1), import_zod20.z.literal(false)]).optional()
|
|
13429
|
+
});
|
|
13430
|
+
var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
|
|
13431
|
+
var ConfigRuleRemoveInputSchema = import_zod20.z.strictObject({ path: import_zod20.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13432
|
+
var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
|
|
13433
|
+
|
|
13434
|
+
// src/frontdoor/configApi.ts
|
|
13435
|
+
var CONFIG_API_TAG = "config";
|
|
13436
|
+
function refusal(error) {
|
|
13437
|
+
if (error instanceof IdentityNotFoundError || error instanceof ProfileNotFoundError || error instanceof PoolNotFoundError || error instanceof ProviderNotFoundError || error instanceof DirectoryRuleNotFoundError) {
|
|
13438
|
+
throw new import_client2.ORPCError("NOT_FOUND", { message: error.message });
|
|
13439
|
+
}
|
|
13440
|
+
if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError) {
|
|
13441
|
+
throw new import_client2.ORPCError("CONFLICT", { message: error.message });
|
|
13442
|
+
}
|
|
13443
|
+
if (error instanceof CliError) {
|
|
13444
|
+
throw new import_client2.ORPCError("BAD_REQUEST", { message: error.message });
|
|
13445
|
+
}
|
|
13446
|
+
throw error;
|
|
13447
|
+
}
|
|
13448
|
+
function guarded(write) {
|
|
13449
|
+
try {
|
|
13450
|
+
return write();
|
|
13451
|
+
} catch (error) {
|
|
13452
|
+
return refusal(error);
|
|
13453
|
+
}
|
|
13454
|
+
}
|
|
13455
|
+
function requireConfirmation(confirm, what) {
|
|
13456
|
+
if (!confirm) {
|
|
13457
|
+
throw new import_client2.ORPCError("BAD_REQUEST", { message: `removing ${what} needs confirm: true, the API's form of the CLI's --yes` });
|
|
13458
|
+
}
|
|
13459
|
+
}
|
|
13460
|
+
function requireChange(given, fields) {
|
|
13461
|
+
if (!given) {
|
|
13462
|
+
throw new import_client2.ORPCError("BAD_REQUEST", { message: `Nothing to change: pass ${fields}.` });
|
|
13463
|
+
}
|
|
13464
|
+
}
|
|
13465
|
+
function identityValue(name, paths) {
|
|
13466
|
+
const identity = readIdentity(paths, name);
|
|
13467
|
+
if (identity === void 0) {
|
|
13468
|
+
throw new IdentityNotFoundError(name);
|
|
13469
|
+
}
|
|
13470
|
+
return {
|
|
13471
|
+
name: identity.name,
|
|
13472
|
+
...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
|
|
13473
|
+
allowAmbientCredential: identity.allowAmbientCredential,
|
|
13474
|
+
...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
|
|
13475
|
+
};
|
|
13476
|
+
}
|
|
13477
|
+
function providerValue(name, provider) {
|
|
13478
|
+
return {
|
|
13479
|
+
name,
|
|
13480
|
+
kind: provider.kind ?? "http",
|
|
13481
|
+
displayName: provider.displayName,
|
|
13482
|
+
...isCodexProvider(provider) ? provider.codex === void 0 ? {} : { codex: provider.codex } : { baseUrl: provider.baseUrl },
|
|
13483
|
+
credential: summariseCredential(provider.credential),
|
|
13484
|
+
...provider.env === void 0 ? {} : { env: provider.env }
|
|
13485
|
+
};
|
|
13486
|
+
}
|
|
13487
|
+
function profileValue(name, paths) {
|
|
13488
|
+
const profile = { ...readProfile(paths, name) };
|
|
13489
|
+
delete profile.$schema;
|
|
13490
|
+
return profile;
|
|
13491
|
+
}
|
|
13492
|
+
function createConfigApiRouter(deps) {
|
|
13493
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13494
|
+
const { paths } = deps;
|
|
13495
|
+
const route = (path36, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path36, summary, tags: [CONFIG_API_TAG] }));
|
|
13496
|
+
return {
|
|
13497
|
+
config: {
|
|
13498
|
+
identity: {
|
|
13499
|
+
add: route("/rest/config/identity/add", "Create an identity").input(ConfigNameInputSchema).output(ConfigIdentityAddOutputSchema).handler(
|
|
13500
|
+
({ input }) => guarded(() => {
|
|
13501
|
+
addIdentity(paths, input.name);
|
|
13502
|
+
return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
13503
|
+
})
|
|
13504
|
+
),
|
|
13505
|
+
set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
|
|
13506
|
+
({ input }) => guarded(() => {
|
|
13507
|
+
requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
|
|
13508
|
+
if (!identityExists(paths, input.name)) {
|
|
13509
|
+
throw new IdentityNotFoundError(input.name);
|
|
13510
|
+
}
|
|
13511
|
+
if (typeof input.defaultConfigProfile === "string") {
|
|
13512
|
+
requireProfileExists(paths, input.defaultConfigProfile);
|
|
13513
|
+
}
|
|
13514
|
+
if (input.defaultConfigProfile !== void 0) {
|
|
13515
|
+
setDefaultConfigProfile(paths, input.name, input.defaultConfigProfile === false ? void 0 : input.defaultConfigProfile);
|
|
13516
|
+
}
|
|
13517
|
+
if (input.allowAmbientCredential !== void 0) {
|
|
13518
|
+
setAllowAmbientCredential(paths, input.name, input.allowAmbientCredential);
|
|
13519
|
+
}
|
|
13520
|
+
if (input.credential === false) {
|
|
13521
|
+
setIdentityCredential(paths, input.name, false);
|
|
13522
|
+
} else if (input.credential !== void 0) {
|
|
13523
|
+
const { sources, target, cache } = input.credential;
|
|
13524
|
+
const merged = cache === void 0 ? void 0 : mergeCredentialCache(cache === false ? { enabled: false } : { ...cache, enabled: true }, readIdentity(paths, input.name)?.credential?.cache);
|
|
13525
|
+
const change = {
|
|
13526
|
+
...sources === void 0 ? {} : { sources },
|
|
13527
|
+
...target === void 0 ? {} : { target },
|
|
13528
|
+
...merged === void 0 ? {} : { cache: merged }
|
|
13529
|
+
};
|
|
13530
|
+
setIdentityCredential(paths, input.name, change);
|
|
13531
|
+
}
|
|
13532
|
+
return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
13533
|
+
})
|
|
13534
|
+
),
|
|
13535
|
+
remove: route("/rest/config/identity/remove", "Delete an identity and its directory").input(ConfigIdentityRemoveInputSchema).output(ConfigIdentityRemoveOutputSchema).handler(({ input }) => {
|
|
13536
|
+
requireConfirmation(input.confirm, `identity "${input.name}" and its directory`);
|
|
13537
|
+
return guarded(() => {
|
|
13538
|
+
removeIdentity(paths, input.name);
|
|
13539
|
+
return { action: "removed", kind: "identity", name: input.name };
|
|
13540
|
+
});
|
|
13541
|
+
}),
|
|
13542
|
+
use: route("/rest/config/identity/use", "Select the active identity").input(ConfigNameInputSchema).output(ConfigIdentityUseOutputSchema).handler(
|
|
13543
|
+
({ input }) => guarded(() => {
|
|
13544
|
+
if (poolNameOf(input.name) === void 0 && !identityExists(paths, input.name)) {
|
|
13545
|
+
throw new IdentityNotFoundError(input.name);
|
|
13546
|
+
}
|
|
13547
|
+
useIdentity(paths, input.name);
|
|
13548
|
+
return { action: "selected", kind: "identity", name: input.name };
|
|
13549
|
+
})
|
|
13550
|
+
)
|
|
13551
|
+
},
|
|
13552
|
+
profile: {
|
|
13553
|
+
add: route("/rest/config/profile/add", "Create a configuration profile").input(ConfigProfileAddInputSchema).output(ConfigProfileAddOutputSchema).handler(
|
|
13554
|
+
({ input }) => guarded(() => {
|
|
13555
|
+
createProfile(paths, input.name, input.extends, input.description);
|
|
13556
|
+
return { action: "created", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
|
|
13557
|
+
})
|
|
13558
|
+
),
|
|
13559
|
+
set: route("/rest/config/profile/set", "Update a configuration profile's categories, entries, extends list, description or launch settings").input(ConfigProfileSetInputSchema).output(ConfigProfileSetOutputSchema).handler(
|
|
13560
|
+
({ input }) => guarded(() => {
|
|
13561
|
+
const { launch } = input;
|
|
13562
|
+
requireChange(
|
|
13563
|
+
input.category !== void 0 || input.entry !== void 0 || input.extends !== void 0 || input.description !== void 0 || launch !== void 0,
|
|
13564
|
+
"category, entry, extends, description or launch"
|
|
13565
|
+
);
|
|
13566
|
+
requireProfileExists(paths, input.name);
|
|
13567
|
+
applyProfileChange(paths, input.name, {
|
|
13568
|
+
...input.category === void 0 ? {} : { category: input.category },
|
|
13569
|
+
...input.entry === void 0 ? {} : { entry: input.entry },
|
|
13570
|
+
...input.extends === void 0 ? {} : { extends: input.extends },
|
|
13571
|
+
...input.description === void 0 ? {} : { description: input.description },
|
|
13572
|
+
...launch?.skipPermissions === void 0 ? {} : { launchSkipPermissions: launch.skipPermissions },
|
|
13573
|
+
...launch?.remoteControl === void 0 ? {} : { launchRemoteControl: launch.remoteControl },
|
|
13574
|
+
...launch?.headroom === void 0 ? {} : { launchHeadroom: launch.headroom },
|
|
13575
|
+
...launch?.trackUsage === void 0 ? {} : { launchTrackUsage: launch.trackUsage },
|
|
13576
|
+
...launch?.provider === void 0 ? {} : { launchProvider: launch.provider },
|
|
13577
|
+
...launch?.claudeVersion === void 0 ? {} : { launchClaudeVersion: launch.claudeVersion }
|
|
13578
|
+
});
|
|
13579
|
+
return { action: "updated", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
|
|
13580
|
+
})
|
|
13581
|
+
),
|
|
13582
|
+
remove: route("/rest/config/profile/remove", "Delete a configuration profile").input(ConfigProfileRemoveInputSchema).output(ConfigProfileRemoveOutputSchema).handler(({ input }) => {
|
|
13583
|
+
requireConfirmation(input.confirm, `configuration profile "${input.name}"`);
|
|
13584
|
+
return guarded(() => {
|
|
13585
|
+
removeProfile(paths, input.name);
|
|
13586
|
+
return { action: "removed", kind: "profile", name: input.name };
|
|
13587
|
+
});
|
|
13588
|
+
}),
|
|
13589
|
+
use: route("/rest/config/profile/use", "Make a configuration profile the global default").input(ConfigNameInputSchema).output(ConfigProfileUseOutputSchema).handler(
|
|
13590
|
+
({ input }) => guarded(() => {
|
|
13591
|
+
requireProfileExists(paths, input.name);
|
|
13592
|
+
setGlobalDefaultProfile(paths, input.name);
|
|
13593
|
+
return { action: "selected", kind: "profile", name: input.name };
|
|
13594
|
+
})
|
|
13595
|
+
)
|
|
13596
|
+
},
|
|
13597
|
+
pool: {
|
|
13598
|
+
add: route("/rest/config/pool/add", "Define a pool").input(ConfigPoolAddInputSchema).output(ConfigPoolAddOutputSchema).handler(
|
|
13599
|
+
({ input }) => guarded(() => {
|
|
13600
|
+
requireIdentityNames(paths, input.identities);
|
|
13601
|
+
const created = addPool(paths, input.name, input.identities, input.preference);
|
|
13602
|
+
return { action: "created", kind: "pool", name: input.name, value: created };
|
|
13603
|
+
})
|
|
13604
|
+
),
|
|
13605
|
+
set: route("/rest/config/pool/set", "Replace a pool's members, its preference or both").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
|
|
13606
|
+
({ input }) => guarded(() => {
|
|
13607
|
+
requireChange(input.identities !== void 0 || input.preference !== void 0, "identities or preference");
|
|
13608
|
+
const existing = requirePool(paths, input.name);
|
|
13609
|
+
if (input.identities !== void 0) {
|
|
13610
|
+
requireIdentityNames(paths, input.identities);
|
|
13611
|
+
}
|
|
13612
|
+
const members = input.identities ?? existing.identities;
|
|
13613
|
+
const preference = input.preference === void 0 ? existing.preference : input.preference === false ? void 0 : input.preference;
|
|
13614
|
+
return { action: "updated", kind: "pool", name: input.name, value: setPool(paths, input.name, members, preference) };
|
|
13615
|
+
})
|
|
13616
|
+
),
|
|
13617
|
+
remove: route("/rest/config/pool/remove", "Delete a pool").input(ConfigPoolRemoveInputSchema).output(ConfigPoolRemoveOutputSchema).handler(({ input }) => {
|
|
13618
|
+
requireConfirmation(input.confirm, `pool "${input.name}"`);
|
|
13619
|
+
return guarded(() => {
|
|
13620
|
+
removePool(paths, input.name);
|
|
13621
|
+
return { action: "removed", kind: "pool", name: input.name };
|
|
13622
|
+
});
|
|
13623
|
+
}),
|
|
13624
|
+
use: route("/rest/config/pool/use", "Make launches with no other selection pick a member of a pool").input(ConfigNameInputSchema).output(ConfigPoolUseOutputSchema).handler(
|
|
13625
|
+
({ input }) => guarded(() => {
|
|
13626
|
+
if (readPools(paths)[input.name] === void 0) {
|
|
13627
|
+
throw new PoolNotFoundError(input.name);
|
|
13628
|
+
}
|
|
13629
|
+
useIdentity(paths, `pool:${input.name}`);
|
|
13630
|
+
return { action: "selected", kind: "pool", name: input.name };
|
|
13631
|
+
})
|
|
13632
|
+
)
|
|
13633
|
+
},
|
|
13634
|
+
provider: {
|
|
13635
|
+
add: route("/rest/config/provider/add", "Create an API provider definition").input(ConfigProviderAddInputSchema).output(ConfigProviderAddOutputSchema).handler(
|
|
13636
|
+
({ input }) => guarded(() => {
|
|
13637
|
+
const created = addProvider(paths, input.name, {
|
|
13638
|
+
...input.kind === void 0 ? {} : { kind: input.kind },
|
|
13639
|
+
displayName: input.displayName,
|
|
13640
|
+
...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
|
|
13641
|
+
sources: input.credential.sources,
|
|
13642
|
+
...input.credential.target === void 0 ? {} : { target: input.credential.target },
|
|
13643
|
+
...input.codex === void 0 ? {} : { codex: input.codex }
|
|
13644
|
+
});
|
|
13645
|
+
const cache = input.credential.cache;
|
|
13646
|
+
const stored = cache === void 0 || cache === false ? created : updateProvider(paths, input.name, { cache });
|
|
13647
|
+
return { action: "created", kind: "provider", name: input.name, value: providerValue(input.name, stored) };
|
|
13648
|
+
})
|
|
13649
|
+
),
|
|
13650
|
+
set: route("/rest/config/provider/set", "Update an API provider definition").input(ConfigProviderSetInputSchema).output(ConfigProviderSetOutputSchema).handler(
|
|
13651
|
+
({ input }) => guarded(() => {
|
|
13652
|
+
requireChange(input.displayName !== void 0 || input.baseUrl !== void 0 || input.credential !== void 0 || input.codex !== void 0, "displayName, baseUrl, credential or codex");
|
|
13653
|
+
const existing = readProvider(paths, input.name);
|
|
13654
|
+
if (existing === void 0) {
|
|
13655
|
+
throw new ProviderNotFoundError(input.name);
|
|
13656
|
+
}
|
|
13657
|
+
const credential = input.credential;
|
|
13658
|
+
if (input.baseUrl !== void 0 && !isCodexProvider(existing) && input.baseUrl !== existing.baseUrl && credential?.sources === void 0) {
|
|
13659
|
+
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.` });
|
|
13660
|
+
}
|
|
13661
|
+
const cache = credential?.cache === void 0 ? void 0 : mergeCredentialCache(credential.cache === false ? { enabled: false } : { ...credential.cache, enabled: true }, existing.credential.cache);
|
|
13662
|
+
const updated = updateProvider(paths, input.name, {
|
|
13663
|
+
...input.displayName === void 0 ? {} : { displayName: input.displayName },
|
|
13664
|
+
...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
|
|
13665
|
+
...credential?.sources === void 0 ? {} : { sources: credential.sources },
|
|
13666
|
+
...credential?.target === void 0 ? {} : { target: credential.target },
|
|
13667
|
+
...cache === void 0 ? {} : { cache },
|
|
13668
|
+
...input.codex === void 0 ? {} : { codex: input.codex }
|
|
13669
|
+
});
|
|
13670
|
+
return { action: "updated", kind: "provider", name: input.name, value: providerValue(input.name, updated) };
|
|
13671
|
+
})
|
|
13672
|
+
),
|
|
13673
|
+
remove: route("/rest/config/provider/remove", "Delete an API provider definition").input(ConfigProviderRemoveInputSchema).output(ConfigProviderRemoveOutputSchema).handler(({ input }) => {
|
|
13674
|
+
requireConfirmation(input.confirm, `provider "${input.name}"`);
|
|
13675
|
+
return guarded(() => {
|
|
13676
|
+
if (!providerExists(paths, input.name)) {
|
|
13677
|
+
throw new ProviderNotFoundError(input.name);
|
|
13678
|
+
}
|
|
13679
|
+
removeProvider(paths, input.name);
|
|
13680
|
+
return { action: "removed", kind: "provider", name: input.name };
|
|
13681
|
+
});
|
|
13682
|
+
})
|
|
13683
|
+
},
|
|
13684
|
+
rule: {
|
|
13685
|
+
add: route("/rest/config/rule/add", "Add a directory rule for a path").input(ConfigRuleAddInputSchema).output(ConfigRuleAddOutputSchema).handler(
|
|
13686
|
+
({ input }) => guarded(() => {
|
|
13687
|
+
if (input.identity !== void 0) {
|
|
13688
|
+
requireRuleSelector(paths, input.identity);
|
|
13689
|
+
}
|
|
13690
|
+
if (input.configProfile !== void 0) {
|
|
13691
|
+
requireProfileExists(paths, input.configProfile);
|
|
13692
|
+
}
|
|
13693
|
+
const created = addDirectoryRule(paths, input.path, {
|
|
13694
|
+
...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
|
|
13695
|
+
...input.identity === void 0 ? {} : { identity: input.identity }
|
|
13696
|
+
});
|
|
13697
|
+
return { action: "created", kind: "rule", name: input.path, value: created };
|
|
13698
|
+
})
|
|
13699
|
+
),
|
|
13700
|
+
set: route("/rest/config/rule/set", "Update the directory rule for a path").input(ConfigRuleSetInputSchema).output(ConfigRuleSetOutputSchema).handler(
|
|
13701
|
+
({ input }) => guarded(() => {
|
|
13702
|
+
requireChange(input.configProfile !== void 0 || input.identity !== void 0, "configProfile or identity");
|
|
13703
|
+
if (typeof input.identity === "string") {
|
|
13704
|
+
requireRuleSelector(paths, input.identity);
|
|
13705
|
+
}
|
|
13706
|
+
if (typeof input.configProfile === "string") {
|
|
13707
|
+
requireProfileExists(paths, input.configProfile);
|
|
13708
|
+
}
|
|
13709
|
+
const updated = updateDirectoryRule(paths, input.path, {
|
|
13710
|
+
...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
|
|
13711
|
+
...input.identity === void 0 ? {} : { identity: input.identity }
|
|
13712
|
+
});
|
|
13713
|
+
return { action: "updated", kind: "rule", name: input.path, value: updated };
|
|
13714
|
+
})
|
|
13715
|
+
),
|
|
13716
|
+
remove: route("/rest/config/rule/remove", "Remove the directory rule for a path").input(ConfigRuleRemoveInputSchema).output(ConfigRuleRemoveOutputSchema).handler(({ input }) => {
|
|
13717
|
+
requireConfirmation(input.confirm, `the directory rule for "${input.path}"`);
|
|
13718
|
+
return guarded(() => {
|
|
13719
|
+
if (!listDirectoryRules(paths).some((entry) => entry.path === input.path)) {
|
|
13720
|
+
throw new DirectoryRuleNotFoundError(input.path);
|
|
13721
|
+
}
|
|
13722
|
+
removeDirectoryRule(paths, input.path);
|
|
13723
|
+
return { action: "removed", kind: "rule", name: input.path };
|
|
13724
|
+
});
|
|
13725
|
+
})
|
|
13726
|
+
}
|
|
13727
|
+
}
|
|
13728
|
+
};
|
|
13729
|
+
}
|
|
13730
|
+
|
|
13731
|
+
// src/frontdoor/eventsApi.ts
|
|
13732
|
+
var import_client3 = require("@orpc/client");
|
|
13733
|
+
var import_openapi4 = require("@orpc/openapi");
|
|
13072
13734
|
var import_server3 = require("@orpc/server");
|
|
13073
13735
|
|
|
13074
13736
|
// src/frontdoor/eventSchemas.ts
|
|
13075
|
-
var
|
|
13737
|
+
var import_zod21 = require("zod");
|
|
13076
13738
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
13077
13739
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
13078
13740
|
var USAGE_EVENT_SOURCE = "usage";
|
|
13079
13741
|
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
13080
13742
|
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
13081
|
-
var DoorEventSchema =
|
|
13082
|
-
source:
|
|
13743
|
+
var DoorEventSchema = import_zod21.z.strictObject({
|
|
13744
|
+
source: import_zod21.z.string().min(1),
|
|
13083
13745
|
/** 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
|
-
|
|
13746
|
+
sequence: import_zod21.z.number().int().positive(),
|
|
13747
|
+
payload: import_zod21.z.unknown()
|
|
13748
|
+
});
|
|
13749
|
+
var DoorEventSourceQuerySchema = import_zod21.z.strictObject({
|
|
13750
|
+
sources: import_zod21.z.array(import_zod21.z.string().min(1)).min(1).optional()
|
|
13751
|
+
});
|
|
13752
|
+
var LaunchLifecycleEventSchema = import_zod21.z.strictObject({
|
|
13753
|
+
kind: import_zod21.z.enum(["registered", "pruned", "ended"]),
|
|
13754
|
+
pid: import_zod21.z.number().int().positive(),
|
|
13755
|
+
startedAt: import_zod21.z.number(),
|
|
13756
|
+
observedAt: import_zod21.z.number()
|
|
13757
|
+
});
|
|
13758
|
+
var DoorHealthEventSchema = import_zod21.z.discriminatedUnion("kind", [
|
|
13759
|
+
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() }),
|
|
13760
|
+
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() }),
|
|
13761
|
+
import_zod21.z.strictObject({ kind: import_zod21.z.literal("binaryTurnover"), pid: import_zod21.z.number().int().positive(), observedAt: import_zod21.z.number() }),
|
|
13762
|
+
import_zod21.z.strictObject({ kind: import_zod21.z.literal("idleShutdown"), pid: import_zod21.z.number().int().positive(), observedAt: import_zod21.z.number() })
|
|
13101
13763
|
]);
|
|
13102
|
-
var QuotaExpiringEventSchema =
|
|
13103
|
-
identity:
|
|
13104
|
-
provider:
|
|
13105
|
-
window:
|
|
13764
|
+
var QuotaExpiringEventSchema = import_zod21.z.strictObject({
|
|
13765
|
+
identity: import_zod21.z.string().min(1),
|
|
13766
|
+
provider: import_zod21.z.string().min(1),
|
|
13767
|
+
window: import_zod21.z.enum(["fiveHour", "sevenDay"]),
|
|
13106
13768
|
/** 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:
|
|
13769
|
+
utilization: import_zod21.z.number().min(0).max(1),
|
|
13770
|
+
resetsAt: import_zod21.z.iso.datetime(),
|
|
13771
|
+
observedAt: import_zod21.z.number()
|
|
13110
13772
|
});
|
|
13111
13773
|
|
|
13112
13774
|
// src/frontdoor/eventsApi.ts
|
|
@@ -13115,12 +13777,12 @@ function createEventsApiRouter(deps) {
|
|
|
13115
13777
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13116
13778
|
return {
|
|
13117
13779
|
events: {
|
|
13118
|
-
subscribe: authed.meta((0,
|
|
13780
|
+
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
13781
|
if (input.sources !== void 0) {
|
|
13120
13782
|
const live = deps.events.sources();
|
|
13121
13783
|
const unknown = input.sources.filter((source) => !live.includes(source));
|
|
13122
13784
|
if (unknown.length > 0) {
|
|
13123
|
-
throw new
|
|
13785
|
+
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
13786
|
}
|
|
13125
13787
|
}
|
|
13126
13788
|
const stream = deps.events.stream(input.sources);
|
|
@@ -13148,8 +13810,8 @@ function createEventsApiRouter(deps) {
|
|
|
13148
13810
|
}
|
|
13149
13811
|
|
|
13150
13812
|
// src/frontdoor/lifecycleApi.ts
|
|
13151
|
-
var
|
|
13152
|
-
var
|
|
13813
|
+
var import_client4 = require("@orpc/client");
|
|
13814
|
+
var import_openapi5 = require("@orpc/openapi");
|
|
13153
13815
|
init_update();
|
|
13154
13816
|
var FRONTDOOR_API_TAG = "frontdoor";
|
|
13155
13817
|
var UPDATE_API_TAG = "update";
|
|
@@ -13157,24 +13819,24 @@ function createLifecycleApiRouter(deps) {
|
|
|
13157
13819
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13158
13820
|
return {
|
|
13159
13821
|
frontdoor: {
|
|
13160
|
-
restart: authed.meta((0,
|
|
13822
|
+
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
13823
|
context.afterResponse(deps.restartDoor);
|
|
13162
13824
|
return { action: "restarting", previousPid: deps.doorPid };
|
|
13163
13825
|
})
|
|
13164
13826
|
},
|
|
13165
13827
|
update: {
|
|
13166
|
-
check: authed.meta((0,
|
|
13828
|
+
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
13829
|
try {
|
|
13168
13830
|
return await deps.checkForUpdate();
|
|
13169
13831
|
} catch (error) {
|
|
13170
13832
|
if (error instanceof UpdateChannelError) {
|
|
13171
|
-
throw new
|
|
13833
|
+
throw new import_client4.ORPCError("PRECONDITION_FAILED", { message: error.message });
|
|
13172
13834
|
}
|
|
13173
13835
|
if (error instanceof UpdateConflictError) {
|
|
13174
|
-
throw new
|
|
13836
|
+
throw new import_client4.ORPCError("CONFLICT", { message: error.message });
|
|
13175
13837
|
}
|
|
13176
13838
|
if (error instanceof UpdateDownloadError) {
|
|
13177
|
-
throw new
|
|
13839
|
+
throw new import_client4.ORPCError("BAD_GATEWAY", { message: error.message });
|
|
13178
13840
|
}
|
|
13179
13841
|
throw error;
|
|
13180
13842
|
}
|
|
@@ -13184,57 +13846,57 @@ function createLifecycleApiRouter(deps) {
|
|
|
13184
13846
|
}
|
|
13185
13847
|
|
|
13186
13848
|
// src/frontdoor/launchApi.ts
|
|
13187
|
-
var
|
|
13188
|
-
var
|
|
13849
|
+
var import_client5 = require("@orpc/client");
|
|
13850
|
+
var import_openapi6 = require("@orpc/openapi");
|
|
13189
13851
|
init_cliError();
|
|
13190
13852
|
|
|
13191
13853
|
// src/frontdoor/launchSchemas.ts
|
|
13192
13854
|
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
13193
|
-
var
|
|
13855
|
+
var import_zod22 = require("zod");
|
|
13194
13856
|
init_claudeVersion();
|
|
13195
13857
|
init_identity();
|
|
13196
|
-
var LaunchResolveInputSchema =
|
|
13197
|
-
path:
|
|
13858
|
+
var LaunchResolveInputSchema = import_zod22.z.strictObject({
|
|
13859
|
+
path: import_zod22.z.string().min(1),
|
|
13198
13860
|
/** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
|
|
13199
|
-
argv:
|
|
13861
|
+
argv: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())).optional(),
|
|
13200
13862
|
/** 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:
|
|
13863
|
+
env: import_zod22.z.record(import_zod22.z.string(), import_zod22.z.string()).optional()
|
|
13202
13864
|
}).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:
|
|
13865
|
+
var LaunchPoolDecisionSchema = import_zod22.z.strictObject({
|
|
13866
|
+
name: import_zod22.z.string(),
|
|
13867
|
+
reasons: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
|
|
13868
|
+
movedOff: import_zod22.z.strictObject({ identity: import_zod22.z.string(), reason: import_zod22.z.string() }).optional()
|
|
13869
|
+
});
|
|
13870
|
+
var LaunchDecisionSchema = import_zod22.z.strictObject({
|
|
13871
|
+
identity: import_zod22.z.string().optional(),
|
|
13872
|
+
identitySource: import_zod22.z.enum(IDENTITY_DECISION_SOURCES),
|
|
13211
13873
|
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 =
|
|
13874
|
+
configDirEscapeHatch: import_zod22.z.boolean(),
|
|
13875
|
+
configDir: import_zod22.z.string().optional(),
|
|
13876
|
+
configProfile: import_zod22.z.string().optional(),
|
|
13877
|
+
configProfileSource: import_zod22.z.enum(CONFIG_PROFILE_DECISION_SOURCES),
|
|
13878
|
+
provider: import_zod22.z.string().optional()
|
|
13879
|
+
});
|
|
13880
|
+
var LaunchFlagsSchema = import_zod22.z.strictObject({
|
|
13881
|
+
skipPermissions: import_zod22.z.boolean(),
|
|
13882
|
+
remoteControl: import_zod22.z.boolean(),
|
|
13883
|
+
headroom: import_zod22.z.boolean(),
|
|
13884
|
+
trackUsage: import_zod22.z.boolean()
|
|
13885
|
+
});
|
|
13886
|
+
var LaunchResolveOutputSchema = import_zod22.z.strictObject({
|
|
13225
13887
|
decision: LaunchDecisionSchema,
|
|
13226
13888
|
flags: LaunchFlagsSchema,
|
|
13227
|
-
claudeVersion:
|
|
13889
|
+
claudeVersion: import_zod22.z.strictObject({ version: import_zod22.z.string(), source: import_zod22.z.enum(CLAUDE_VERSION_SOURCES) }).optional(),
|
|
13228
13890
|
/** The real `claude` binary the launch would spawn, on the door's host. */
|
|
13229
|
-
bin:
|
|
13891
|
+
bin: import_zod22.z.string(),
|
|
13230
13892
|
/** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
|
|
13231
|
-
args:
|
|
13893
|
+
args: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
|
|
13232
13894
|
/** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
|
|
13233
|
-
credential:
|
|
13234
|
-
routing:
|
|
13895
|
+
credential: import_zod22.z.strictObject({ subject: import_zod22.z.enum(["provider", "identity"]), name: import_zod22.z.string(), summary: CredentialSummarySchema }).optional(),
|
|
13896
|
+
routing: import_zod22.z.strictObject({ frontDoor: import_zod22.z.boolean(), headroom: import_zod22.z.boolean() }),
|
|
13235
13897
|
/** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
|
|
13236
|
-
environment:
|
|
13237
|
-
warnings:
|
|
13898
|
+
environment: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
|
|
13899
|
+
warnings: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string()))
|
|
13238
13900
|
});
|
|
13239
13901
|
|
|
13240
13902
|
// src/frontdoor/launchApi.ts
|
|
@@ -13243,13 +13905,22 @@ function createLaunchApiRouter(deps) {
|
|
|
13243
13905
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13244
13906
|
return {
|
|
13245
13907
|
launch: {
|
|
13246
|
-
resolve: authed.meta(
|
|
13908
|
+
resolve: authed.meta(
|
|
13909
|
+
(0, import_openapi6.openapi)({
|
|
13910
|
+
method: "POST",
|
|
13911
|
+
path: "/rest/launch/resolve",
|
|
13912
|
+
summary: "Resolve what a launch from one directory would do, without performing it",
|
|
13913
|
+
tags: [LAUNCH_API_TAG],
|
|
13914
|
+
// A POST because the launch's environment and arguments are a body, but the answer changes nothing.
|
|
13915
|
+
spec: (current) => ({ ...current, [READ_ONLY_OPERATION_EXTENSION]: true })
|
|
13916
|
+
})
|
|
13917
|
+
).input(LaunchResolveInputSchema).output(LaunchResolveOutputSchema).handler(({ input }) => {
|
|
13247
13918
|
try {
|
|
13248
13919
|
const { resolution, warnings } = deps.resolveLaunch({ path: input.path, argv: input.argv ?? [], env: input.env ?? {} });
|
|
13249
13920
|
return { ...resolution, warnings };
|
|
13250
13921
|
} catch (error) {
|
|
13251
13922
|
if (error instanceof CliError) {
|
|
13252
|
-
throw new
|
|
13923
|
+
throw new import_client5.ORPCError("BAD_REQUEST", { message: error.message });
|
|
13253
13924
|
}
|
|
13254
13925
|
throw error;
|
|
13255
13926
|
}
|
|
@@ -13268,11 +13939,11 @@ function createControlApiRouter(deps) {
|
|
|
13268
13939
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13269
13940
|
return {
|
|
13270
13941
|
usage: {
|
|
13271
|
-
list: authed.meta((0,
|
|
13272
|
-
effectiveWindow: authed.meta((0,
|
|
13942
|
+
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() })),
|
|
13943
|
+
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
13944
|
const snapshot = deps.usageSnapshotOf(input.identity);
|
|
13274
13945
|
if (snapshot === void 0) {
|
|
13275
|
-
throw new
|
|
13946
|
+
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
13947
|
}
|
|
13277
13948
|
const provider = input.provider ?? ANTHROPIC_PROVIDER;
|
|
13278
13949
|
const rateLimit = snapshot.providers[provider]?.rateLimit;
|
|
@@ -13286,34 +13957,34 @@ function createControlApiRouter(deps) {
|
|
|
13286
13957
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
13287
13958
|
};
|
|
13288
13959
|
}),
|
|
13289
|
-
live: authed.meta((0,
|
|
13960
|
+
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
13961
|
const sessions = deps.liveRateLimits(input.session);
|
|
13291
13962
|
if (input.session !== void 0 && sessions.length === 0) {
|
|
13292
13963
|
if (deps.list().some((session) => session.id === input.session)) {
|
|
13293
|
-
throw new
|
|
13964
|
+
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
13965
|
}
|
|
13295
|
-
throw new
|
|
13966
|
+
throw new import_client6.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
13296
13967
|
}
|
|
13297
13968
|
return { latest: deps.latestRateLimit(), sessions };
|
|
13298
13969
|
})
|
|
13299
13970
|
},
|
|
13300
13971
|
frontdoor: {
|
|
13301
|
-
status: authed.meta((0,
|
|
13302
|
-
sessions: authed.meta((0,
|
|
13972
|
+
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()),
|
|
13973
|
+
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
13974
|
},
|
|
13304
13975
|
check: {
|
|
13305
13976
|
// 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,
|
|
13977
|
+
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
13978
|
},
|
|
13308
13979
|
doctor: {
|
|
13309
|
-
run: authed.meta((0,
|
|
13980
|
+
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
13981
|
},
|
|
13311
13982
|
pool: {
|
|
13312
|
-
pick: authed.meta((0,
|
|
13983
|
+
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
13984
|
const report = deps.poolPick(input.pool, input.path);
|
|
13314
13985
|
if (report === void 0) {
|
|
13315
13986
|
const live = deps.poolNames();
|
|
13316
|
-
throw new
|
|
13987
|
+
throw new import_client6.ORPCError("NOT_FOUND", {
|
|
13317
13988
|
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
13989
|
});
|
|
13319
13990
|
}
|
|
@@ -13325,13 +13996,13 @@ function createControlApiRouter(deps) {
|
|
|
13325
13996
|
function createDoorApiRouter(deps) {
|
|
13326
13997
|
const control = createControlApiRouter(deps);
|
|
13327
13998
|
const lifecycle = createLifecycleApiRouter(deps);
|
|
13328
|
-
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
13999
|
+
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
13329
14000
|
}
|
|
13330
14001
|
function createDoorApiNodeHandler(deps) {
|
|
13331
14002
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
13332
14003
|
}
|
|
13333
14004
|
function frontDoorApiClient(port, ca, token) {
|
|
13334
|
-
return (0,
|
|
14005
|
+
return (0, import_client6.createORPCClient)(frontDoorApiLink(port, ca, token));
|
|
13335
14006
|
}
|
|
13336
14007
|
|
|
13337
14008
|
// src/frontdoor/doorClient.ts
|
|
@@ -14137,9 +14808,9 @@ async function serveRcCompatSessions(ctx, pathname, compatPath) {
|
|
|
14137
14808
|
const slash = rest.indexOf("/");
|
|
14138
14809
|
const address = slash === -1 ? rest : rest.slice(0, slash);
|
|
14139
14810
|
const compatTail = slash === -1 ? "" : rest.slice(slash + 1);
|
|
14140
|
-
const
|
|
14141
|
-
if (
|
|
14142
|
-
await ctx.unauthorized(response,
|
|
14811
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14812
|
+
if (refusal2 !== void 0) {
|
|
14813
|
+
await ctx.unauthorized(response, refusal2);
|
|
14143
14814
|
return;
|
|
14144
14815
|
}
|
|
14145
14816
|
const session = ctx.sessions.get(address) ?? ctx.sessions.get(`cse_${address}`);
|
|
@@ -14217,9 +14888,9 @@ function conversationRow(conversation) {
|
|
|
14217
14888
|
}
|
|
14218
14889
|
async function serveRcConversations(ctx, pathname, method) {
|
|
14219
14890
|
const { request: request4, response, conversations } = ctx;
|
|
14220
|
-
const
|
|
14221
|
-
if (
|
|
14222
|
-
await ctx.unauthorized(response,
|
|
14891
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14892
|
+
if (refusal2 !== void 0) {
|
|
14893
|
+
await ctx.unauthorized(response, refusal2);
|
|
14223
14894
|
return;
|
|
14224
14895
|
}
|
|
14225
14896
|
if (pathname === RC_CONVERSATIONS_PATH_PREFIX) {
|
|
@@ -14543,9 +15214,9 @@ async function fetchThroughWebProxy(url, deps) {
|
|
|
14543
15214
|
try {
|
|
14544
15215
|
let redirects = 0;
|
|
14545
15216
|
for (; ; ) {
|
|
14546
|
-
const
|
|
14547
|
-
if (
|
|
14548
|
-
return
|
|
15217
|
+
const refusal2 = await checkTarget(current, deps);
|
|
15218
|
+
if (refusal2 !== void 0) {
|
|
15219
|
+
return refusal2;
|
|
14549
15220
|
}
|
|
14550
15221
|
let hop;
|
|
14551
15222
|
try {
|
|
@@ -14915,8 +15586,8 @@ data: ${JSON.stringify(envelope)}
|
|
|
14915
15586
|
"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
15587
|
unrecognised: "the self-hosted Remote Control surface did not recognise the presented credential"
|
|
14917
15588
|
};
|
|
14918
|
-
const unauthorized = async (response,
|
|
14919
|
-
await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[
|
|
15589
|
+
const unauthorized = async (response, refusal2) => {
|
|
15590
|
+
await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[refusal2] } });
|
|
14920
15591
|
};
|
|
14921
15592
|
const serveSessionPath = async (session, tail, request4, response) => {
|
|
14922
15593
|
const method = request4.method.toUpperCase();
|
|
@@ -14927,9 +15598,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14927
15598
|
session.lastTrafficAt = deps.now();
|
|
14928
15599
|
if (tail === "") {
|
|
14929
15600
|
if (method === "PATCH" || method === "PUT") {
|
|
14930
|
-
const
|
|
14931
|
-
if (
|
|
14932
|
-
await unauthorized(response,
|
|
15601
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15602
|
+
if (refusal2 !== void 0) {
|
|
15603
|
+
await unauthorized(response, refusal2);
|
|
14933
15604
|
return;
|
|
14934
15605
|
}
|
|
14935
15606
|
const body = parseJsonObject5(await readBody2(request4.body, CONTROL_BODY_CAP_BYTES));
|
|
@@ -14952,9 +15623,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14952
15623
|
return;
|
|
14953
15624
|
}
|
|
14954
15625
|
if (tail === "bridge" && method === "POST") {
|
|
14955
|
-
const
|
|
14956
|
-
if (
|
|
14957
|
-
await unauthorized(response,
|
|
15626
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15627
|
+
if (refusal2 !== void 0) {
|
|
15628
|
+
await unauthorized(response, refusal2);
|
|
14958
15629
|
return;
|
|
14959
15630
|
}
|
|
14960
15631
|
const workerJwt = mintWorkerJwt(deps.randomToken, deps.now());
|
|
@@ -14964,9 +15635,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14964
15635
|
return;
|
|
14965
15636
|
}
|
|
14966
15637
|
if (tail === "archive" && method === "POST") {
|
|
14967
|
-
const
|
|
14968
|
-
if (
|
|
14969
|
-
await unauthorized(response,
|
|
15638
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15639
|
+
if (refusal2 !== void 0) {
|
|
15640
|
+
await unauthorized(response, refusal2);
|
|
14970
15641
|
return;
|
|
14971
15642
|
}
|
|
14972
15643
|
retireSession(session);
|
|
@@ -14977,9 +15648,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14977
15648
|
if (tail === "worker" || tail.startsWith("worker/")) {
|
|
14978
15649
|
const workerTail = tail === "worker" ? "" : tail.slice("worker/".length);
|
|
14979
15650
|
const webProxy = workerTail === "web-fetch" || workerTail === "web-search";
|
|
14980
|
-
const
|
|
14981
|
-
if (
|
|
14982
|
-
await unauthorized(response,
|
|
15651
|
+
const refusal2 = webProxy ? workerOrCredentialRefusal(request4.headers, session) : workerRefusal(request4.headers, session);
|
|
15652
|
+
if (refusal2 !== void 0) {
|
|
15653
|
+
await unauthorized(response, refusal2);
|
|
14983
15654
|
return;
|
|
14984
15655
|
}
|
|
14985
15656
|
if (workerTail === "" && method === "GET") {
|
|
@@ -15392,102 +16063,6 @@ init_paths();
|
|
|
15392
16063
|
init_cliError();
|
|
15393
16064
|
init_schema();
|
|
15394
16065
|
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
16066
|
init_launcher();
|
|
15492
16067
|
init_spawn();
|
|
15493
16068
|
init_launchWiring();
|
|
@@ -15602,10 +16177,44 @@ init_ownCli();
|
|
|
15602
16177
|
CodexLogoutOutputSchema,
|
|
15603
16178
|
CodexSignInSchema,
|
|
15604
16179
|
CodexStatusOutputSchema,
|
|
16180
|
+
ConfigIdentityAddOutputSchema,
|
|
16181
|
+
ConfigIdentityRemoveInputSchema,
|
|
16182
|
+
ConfigIdentityRemoveOutputSchema,
|
|
16183
|
+
ConfigIdentitySetInputSchema,
|
|
16184
|
+
ConfigIdentitySetOutputSchema,
|
|
16185
|
+
ConfigIdentityUseOutputSchema,
|
|
16186
|
+
ConfigNameInputSchema,
|
|
16187
|
+
ConfigPoolAddInputSchema,
|
|
16188
|
+
ConfigPoolAddOutputSchema,
|
|
16189
|
+
ConfigPoolRemoveInputSchema,
|
|
16190
|
+
ConfigPoolRemoveOutputSchema,
|
|
16191
|
+
ConfigPoolSetInputSchema,
|
|
16192
|
+
ConfigPoolSetOutputSchema,
|
|
16193
|
+
ConfigPoolUseOutputSchema,
|
|
16194
|
+
ConfigProfileAddInputSchema,
|
|
16195
|
+
ConfigProfileAddOutputSchema,
|
|
16196
|
+
ConfigProfileRemoveInputSchema,
|
|
16197
|
+
ConfigProfileRemoveOutputSchema,
|
|
15605
16198
|
ConfigProfileSchema,
|
|
16199
|
+
ConfigProfileSetInputSchema,
|
|
16200
|
+
ConfigProfileSetOutputSchema,
|
|
16201
|
+
ConfigProfileUseOutputSchema,
|
|
16202
|
+
ConfigProviderAddInputSchema,
|
|
16203
|
+
ConfigProviderAddOutputSchema,
|
|
16204
|
+
ConfigProviderRemoveInputSchema,
|
|
16205
|
+
ConfigProviderRemoveOutputSchema,
|
|
16206
|
+
ConfigProviderSetInputSchema,
|
|
16207
|
+
ConfigProviderSetOutputSchema,
|
|
16208
|
+
ConfigRuleAddInputSchema,
|
|
16209
|
+
ConfigRuleAddOutputSchema,
|
|
16210
|
+
ConfigRuleRemoveInputSchema,
|
|
16211
|
+
ConfigRuleRemoveOutputSchema,
|
|
16212
|
+
ConfigRuleSetInputSchema,
|
|
16213
|
+
ConfigRuleSetOutputSchema,
|
|
15606
16214
|
CredentialCacheSchema,
|
|
15607
16215
|
CredentialSchema,
|
|
15608
16216
|
CredentialSourceSchema,
|
|
16217
|
+
CredentialSummarySchema,
|
|
15609
16218
|
DOOR_EVENT_BUFFER_EVENTS,
|
|
15610
16219
|
DOOR_EVENT_SOURCE_RC,
|
|
15611
16220
|
DOOR_HEALTH_EVENT_SOURCE,
|
|
@@ -15736,6 +16345,7 @@ init_ownCli();
|
|
|
15736
16345
|
collectFrontDoorStatus,
|
|
15737
16346
|
collectPoolPick,
|
|
15738
16347
|
createCodexApiRouter,
|
|
16348
|
+
createConfigApiRouter,
|
|
15739
16349
|
createControlApiRouter,
|
|
15740
16350
|
createDoorApiNodeHandler,
|
|
15741
16351
|
createDoorApiRouter,
|