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.mjs
CHANGED
|
@@ -209,7 +209,7 @@ function isCodexProvider(provider) {
|
|
|
209
209
|
function poolMemberIdentity(member) {
|
|
210
210
|
return typeof member === "string" ? member : member.identity;
|
|
211
211
|
}
|
|
212
|
-
var 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;
|
|
212
|
+
var 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;
|
|
213
213
|
var init_schema = __esm({
|
|
214
214
|
"src/config/schema.ts"() {
|
|
215
215
|
"use strict";
|
|
@@ -262,20 +262,33 @@ var init_schema = __esm({
|
|
|
262
262
|
/** 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. */
|
|
263
263
|
timeoutMs: z.int().positive().optional()
|
|
264
264
|
};
|
|
265
|
+
EnvCredentialSourceSchema = z.strictObject({ env: z.string().min(1) });
|
|
266
|
+
FileCredentialSourceSchema = z.strictObject({
|
|
267
|
+
file: z.string().min(1).refine((filePath) => filePath.startsWith("~/") || path2.isAbsolute(filePath), {
|
|
268
|
+
message: "a credential file must be an absolute or ~-rooted path, since a launch can start in any directory"
|
|
269
|
+
})
|
|
270
|
+
});
|
|
271
|
+
CommandCredentialSourceSchema = z.strictObject({ command: ArgvSchema, ...CommandSourceOptions });
|
|
272
|
+
OpCredentialSourceSchema = z.strictObject({ op: z.string().startsWith("op://"), ...CommandSourceOptions });
|
|
273
|
+
KeychainCredentialSourceSchema = z.strictObject({
|
|
274
|
+
keychain: z.strictObject({ service: z.string().min(1), account: z.string().min(1).optional() }),
|
|
275
|
+
...CommandSourceOptions
|
|
276
|
+
});
|
|
277
|
+
LiteralCredentialSourceSchema = z.strictObject({ literal: z.string().min(1) });
|
|
265
278
|
CredentialSourceSchema = z.union([
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
+
EnvCredentialSourceSchema,
|
|
280
|
+
FileCredentialSourceSchema,
|
|
281
|
+
CommandCredentialSourceSchema,
|
|
282
|
+
OpCredentialSourceSchema,
|
|
283
|
+
KeychainCredentialSourceSchema,
|
|
284
|
+
LiteralCredentialSourceSchema
|
|
285
|
+
]);
|
|
286
|
+
RemoteCredentialSourceSchema = z.union([
|
|
287
|
+
EnvCredentialSourceSchema,
|
|
288
|
+
FileCredentialSourceSchema,
|
|
289
|
+
OpCredentialSourceSchema,
|
|
290
|
+
KeychainCredentialSourceSchema,
|
|
291
|
+
LiteralCredentialSourceSchema
|
|
279
292
|
]);
|
|
280
293
|
CREDENTIAL_CACHE_STORES = ["keychain", "file"];
|
|
281
294
|
CredentialCacheSchema = z.strictObject({
|
|
@@ -292,6 +305,7 @@ var init_schema = __esm({
|
|
|
292
305
|
ProviderEnvSchema = z.record(z.string().min(1), z.string()).refine((env) => !Object.keys(env).some((key) => RESERVED_PROVIDER_ENV_KEYS.includes(key)), {
|
|
293
306
|
message: `env may not set ${RESERVED_PROVIDER_ENV_KEYS.join(", ")}: the credential block's target sets one and agent-shim removes the others`
|
|
294
307
|
});
|
|
308
|
+
PROVIDER_KINDS = ["http", "codex"];
|
|
295
309
|
CODEX_EFFORTS = ["none", "low", "medium", "high"];
|
|
296
310
|
CODEX_LOGINS = ["codex-cli", "chatgpt-sign-in"];
|
|
297
311
|
CODEX_DEFAULT_TIER_MODELS = Object.freeze({
|
|
@@ -2625,7 +2639,7 @@ var init_package = __esm({
|
|
|
2625
2639
|
"package.json"() {
|
|
2626
2640
|
package_default = {
|
|
2627
2641
|
name: "claude-use",
|
|
2628
|
-
version: "9.
|
|
2642
|
+
version: "9.7.1",
|
|
2629
2643
|
description: "A profile manager and launcher for Claude Code that lets one person run multiple logins from one machine while controlling what gets shared between them.",
|
|
2630
2644
|
license: "MIT",
|
|
2631
2645
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -3028,8 +3042,8 @@ function verifyHeadroomSocket(socketPath, ports) {
|
|
|
3028
3042
|
}
|
|
3029
3043
|
const uid = ports.currentUid();
|
|
3030
3044
|
const directory = path12.dirname(socketPath);
|
|
3031
|
-
const
|
|
3032
|
-
return
|
|
3045
|
+
const refusal2 = ownerOnlyRefusal("socket directory", directory, ports.lstat(directory), "dir", uid) ?? ownerOnlyRefusal("socket", socketPath, ports.lstat(socketPath), "socket", uid);
|
|
3046
|
+
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
3033
3047
|
}
|
|
3034
3048
|
function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
3035
3049
|
const unsupported = platformRefusal(ports.platform);
|
|
@@ -3047,8 +3061,8 @@ function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
|
3047
3061
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
3048
3062
|
}
|
|
3049
3063
|
fs12.mkdirPrivate(paths.headroomSocketDir);
|
|
3050
|
-
const
|
|
3051
|
-
return
|
|
3064
|
+
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
3065
|
+
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
3052
3066
|
}
|
|
3053
3067
|
function pruneStaleHeadroomSockets(fs12, paths, isRunning) {
|
|
3054
3068
|
const removed = [];
|
|
@@ -4560,14 +4574,14 @@ function capacityOf(plan) {
|
|
|
4560
4574
|
return plan.kind === "subscription" ? plan.capacity : 1;
|
|
4561
4575
|
}
|
|
4562
4576
|
function assessRefusedNested(member, nested, nowMs) {
|
|
4563
|
-
const
|
|
4577
|
+
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 };
|
|
4564
4578
|
return {
|
|
4565
4579
|
candidate: {
|
|
4566
4580
|
identity: member.identity,
|
|
4567
4581
|
class: "ineligible",
|
|
4568
|
-
...
|
|
4582
|
+
...refusal2.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal2.blockedUntilMs },
|
|
4569
4583
|
plan: planOf(member.account),
|
|
4570
|
-
reasons: [
|
|
4584
|
+
reasons: [refusal2.reason]
|
|
4571
4585
|
}
|
|
4572
4586
|
};
|
|
4573
4587
|
}
|
|
@@ -4658,7 +4672,7 @@ function rankPool(input) {
|
|
|
4658
4672
|
const assessments = members.map((member) => ({ member, ...assess(member, nowMs) }));
|
|
4659
4673
|
const demands = assessments.flatMap(({ candidate, burn }) => burn === void 0 ? [] : [burn * capacityOf(candidate.plan)]);
|
|
4660
4674
|
const sharedDemand = demands.length === 0 ? void 0 : Math.max(...demands);
|
|
4661
|
-
const
|
|
4675
|
+
const guarded2 = assessments.map((assessment) => {
|
|
4662
4676
|
const { candidate } = assessment;
|
|
4663
4677
|
if (candidate.class === "ineligible" || assessment.member.policy === void 0) {
|
|
4664
4678
|
return assessment;
|
|
@@ -4673,7 +4687,7 @@ function rankPool(input) {
|
|
|
4673
4687
|
}
|
|
4674
4688
|
return { ...assessment, candidate: { ...candidate, class: "ineligible", reasons: [`skipped by policy (${verdict.checked.join(", ")}: did not hold)`, ...candidate.reasons] } };
|
|
4675
4689
|
});
|
|
4676
|
-
const candidates =
|
|
4690
|
+
const candidates = guarded2.map((assessment) => {
|
|
4677
4691
|
const { candidate, fiveHour, burn } = assessment;
|
|
4678
4692
|
const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
|
|
4679
4693
|
const { sevenDay, sevenDayBurn } = assessment;
|
|
@@ -7669,7 +7683,7 @@ var init_anthropicUsageRefresh = __esm({
|
|
|
7669
7683
|
});
|
|
7670
7684
|
|
|
7671
7685
|
// src/usage/providerQuota.ts
|
|
7672
|
-
import { z as
|
|
7686
|
+
import { z as z23 } from "zod";
|
|
7673
7687
|
var MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY3, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema;
|
|
7674
7688
|
var init_providerQuota = __esm({
|
|
7675
7689
|
"src/usage/providerQuota.ts"() {
|
|
@@ -7687,35 +7701,35 @@ var init_providerQuota = __esm({
|
|
|
7687
7701
|
[ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
|
|
7688
7702
|
[ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7]
|
|
7689
7703
|
]);
|
|
7690
|
-
ZaiLimitSchema =
|
|
7691
|
-
type:
|
|
7692
|
-
unit:
|
|
7693
|
-
number:
|
|
7694
|
-
percentage:
|
|
7695
|
-
nextResetTime:
|
|
7696
|
-
usage:
|
|
7697
|
-
currentValue:
|
|
7698
|
-
remaining:
|
|
7704
|
+
ZaiLimitSchema = z23.object({
|
|
7705
|
+
type: z23.string(),
|
|
7706
|
+
unit: z23.number().int(),
|
|
7707
|
+
number: z23.number().int().positive(),
|
|
7708
|
+
percentage: z23.number().nonnegative(),
|
|
7709
|
+
nextResetTime: z23.number().positive().optional(),
|
|
7710
|
+
usage: z23.number().nonnegative().optional(),
|
|
7711
|
+
currentValue: z23.number().nonnegative().optional(),
|
|
7712
|
+
remaining: z23.number().nonnegative().optional()
|
|
7699
7713
|
});
|
|
7700
|
-
ZaiResponseSchema =
|
|
7701
|
-
success:
|
|
7702
|
-
msg:
|
|
7703
|
-
data:
|
|
7714
|
+
ZaiResponseSchema = z23.object({
|
|
7715
|
+
success: z23.boolean(),
|
|
7716
|
+
msg: z23.string().optional(),
|
|
7717
|
+
data: z23.object({ level: z23.string().optional(), limits: z23.array(ZaiLimitSchema) })
|
|
7704
7718
|
});
|
|
7705
7719
|
OPENROUTER_HOST = "openrouter.ai";
|
|
7706
7720
|
OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
7707
7721
|
OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
7708
7722
|
MS_PER_DAY3 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7;
|
|
7709
|
-
OpenRouterKeySchema =
|
|
7710
|
-
data:
|
|
7711
|
-
limit:
|
|
7712
|
-
limit_remaining:
|
|
7713
|
-
limit_reset:
|
|
7714
|
-
is_free_tier:
|
|
7715
|
-
free_model_daily_requests:
|
|
7723
|
+
OpenRouterKeySchema = z23.object({
|
|
7724
|
+
data: z23.object({
|
|
7725
|
+
limit: z23.number().nonnegative().nullable(),
|
|
7726
|
+
limit_remaining: z23.number().nullable(),
|
|
7727
|
+
limit_reset: z23.string().nullable(),
|
|
7728
|
+
is_free_tier: z23.boolean().optional(),
|
|
7729
|
+
free_model_daily_requests: z23.object({ used: z23.number().nonnegative(), limit: z23.number().nonnegative(), remaining: z23.number() }).optional()
|
|
7716
7730
|
})
|
|
7717
7731
|
});
|
|
7718
|
-
OpenRouterCreditsSchema =
|
|
7732
|
+
OpenRouterCreditsSchema = z23.object({ data: z23.object({ total_credits: z23.number().nonnegative(), total_usage: z23.number().nonnegative() }) });
|
|
7719
7733
|
}
|
|
7720
7734
|
});
|
|
7721
7735
|
|
|
@@ -8693,6 +8707,7 @@ var HTTP_STATUS = {
|
|
|
8693
8707
|
forbidden: 403,
|
|
8694
8708
|
notFound: 404,
|
|
8695
8709
|
methodNotAllowed: 405,
|
|
8710
|
+
conflict: 409,
|
|
8696
8711
|
payloadTooLarge: 413,
|
|
8697
8712
|
tooManyRequests: 429,
|
|
8698
8713
|
/** 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. */
|
|
@@ -10701,6 +10716,7 @@ var RcAnswerOutputSchema = z4.strictObject({
|
|
|
10701
10716
|
var RC_ORPC_PATH_PREFIX = "/__agent-shim/orpc";
|
|
10702
10717
|
var RC_OPENAPI_DOC_PATH = "/openapi.json";
|
|
10703
10718
|
var RC_SUBSCRIBER_BUFFER_EVENTS = 100;
|
|
10719
|
+
var READ_ONLY_OPERATION_EXTENSION = "x-agent-shim-read-only";
|
|
10704
10720
|
function doorApiBearer(headers) {
|
|
10705
10721
|
const presented = headers.authorization;
|
|
10706
10722
|
const bearerPrefix = "bearer ".length;
|
|
@@ -10818,9 +10834,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
10818
10834
|
if (request4.method === "GET" && request4.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
|
|
10819
10835
|
const token = doorApiBearer(request4.headers);
|
|
10820
10836
|
if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
|
|
10821
|
-
const
|
|
10837
|
+
const refusal2 = new ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
|
|
10822
10838
|
response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
|
|
10823
|
-
response.end(JSON.stringify(
|
|
10839
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
10824
10840
|
return { matched: true };
|
|
10825
10841
|
}
|
|
10826
10842
|
try {
|
|
@@ -10828,9 +10844,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
10828
10844
|
response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
|
|
10829
10845
|
response.end(JSON.stringify(doc));
|
|
10830
10846
|
} catch (error) {
|
|
10831
|
-
const
|
|
10847
|
+
const refusal2 = new 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)}` });
|
|
10832
10848
|
response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
|
|
10833
|
-
response.end(JSON.stringify(
|
|
10849
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
10834
10850
|
}
|
|
10835
10851
|
return { matched: true };
|
|
10836
10852
|
}
|
|
@@ -10879,8 +10895,8 @@ init_cliError();
|
|
|
10879
10895
|
init_realPorts();
|
|
10880
10896
|
|
|
10881
10897
|
// src/frontdoor/controlApi.ts
|
|
10882
|
-
import { createORPCClient as createORPCClient2, ORPCError as
|
|
10883
|
-
import { openapi as
|
|
10898
|
+
import { createORPCClient as createORPCClient2, ORPCError as ORPCError6 } from "@orpc/client";
|
|
10899
|
+
import { openapi as openapi7 } from "@orpc/openapi";
|
|
10884
10900
|
|
|
10885
10901
|
// src/checkReport.ts
|
|
10886
10902
|
init_classify();
|
|
@@ -11064,6 +11080,48 @@ function removeProfile(paths, name) {
|
|
|
11064
11080
|
requireProfileExists(paths, name);
|
|
11065
11081
|
fs4.rmSync(profileJsonPath(paths, name));
|
|
11066
11082
|
}
|
|
11083
|
+
function applyProfileChange(paths, name, change) {
|
|
11084
|
+
let touched = false;
|
|
11085
|
+
if (change.category !== void 0) {
|
|
11086
|
+
setProfileCategories(paths, name, change.category);
|
|
11087
|
+
touched = true;
|
|
11088
|
+
}
|
|
11089
|
+
if (change.entry !== void 0) {
|
|
11090
|
+
setProfileEntries(paths, name, change.entry);
|
|
11091
|
+
touched = true;
|
|
11092
|
+
}
|
|
11093
|
+
if (change.extends !== void 0 || change.description !== void 0) {
|
|
11094
|
+
setProfileMetadata(paths, name, {
|
|
11095
|
+
...change.extends === void 0 ? {} : { extends: change.extends === false ? [] : change.extends },
|
|
11096
|
+
...change.description === void 0 ? {} : { description: change.description }
|
|
11097
|
+
});
|
|
11098
|
+
touched = true;
|
|
11099
|
+
}
|
|
11100
|
+
const launchPatch = {};
|
|
11101
|
+
if (change.launchSkipPermissions !== void 0) {
|
|
11102
|
+
launchPatch.skipPermissions = change.launchSkipPermissions;
|
|
11103
|
+
}
|
|
11104
|
+
if (change.launchRemoteControl !== void 0) {
|
|
11105
|
+
launchPatch.remoteControl = change.launchRemoteControl;
|
|
11106
|
+
}
|
|
11107
|
+
if (change.launchHeadroom !== void 0) {
|
|
11108
|
+
launchPatch.headroom = change.launchHeadroom;
|
|
11109
|
+
}
|
|
11110
|
+
if (change.launchTrackUsage !== void 0) {
|
|
11111
|
+
launchPatch.trackUsage = change.launchTrackUsage;
|
|
11112
|
+
}
|
|
11113
|
+
if (change.launchProvider !== void 0) {
|
|
11114
|
+
launchPatch.provider = change.launchProvider === false ? void 0 : change.launchProvider;
|
|
11115
|
+
}
|
|
11116
|
+
if (change.launchClaudeVersion !== void 0) {
|
|
11117
|
+
launchPatch.claudeVersion = change.launchClaudeVersion === false ? void 0 : change.launchClaudeVersion;
|
|
11118
|
+
}
|
|
11119
|
+
if (Object.keys(launchPatch).length > 0) {
|
|
11120
|
+
setProfileLaunchFlags(paths, name, launchPatch);
|
|
11121
|
+
touched = true;
|
|
11122
|
+
}
|
|
11123
|
+
return touched;
|
|
11124
|
+
}
|
|
11067
11125
|
|
|
11068
11126
|
// src/poolStore.ts
|
|
11069
11127
|
init_store();
|
|
@@ -11837,6 +11895,14 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
11837
11895
|
function identityJsonPath(paths, name) {
|
|
11838
11896
|
return path27.join(paths.identitiesDir, name, "identity.json");
|
|
11839
11897
|
}
|
|
11898
|
+
function requireIdentityNames(paths, names) {
|
|
11899
|
+
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
11900
|
+
for (const name of names) {
|
|
11901
|
+
if (poolNameOf(name) === void 0 && !existing.has(name)) {
|
|
11902
|
+
throw new IdentityNotFoundError(name);
|
|
11903
|
+
}
|
|
11904
|
+
}
|
|
11905
|
+
}
|
|
11840
11906
|
function identityExists(paths, name) {
|
|
11841
11907
|
return fs9.existsSync(identityJsonPath(paths, name));
|
|
11842
11908
|
}
|
|
@@ -12729,47 +12795,608 @@ function createCodexApiRouter(deps) {
|
|
|
12729
12795
|
};
|
|
12730
12796
|
}
|
|
12731
12797
|
|
|
12732
|
-
// src/frontdoor/
|
|
12798
|
+
// src/frontdoor/configApi.ts
|
|
12799
|
+
init_cliError();
|
|
12800
|
+
init_schema();
|
|
12733
12801
|
import { ORPCError as ORPCError2 } from "@orpc/client";
|
|
12734
12802
|
import { openapi as openapi3 } from "@orpc/openapi";
|
|
12803
|
+
init_credential();
|
|
12804
|
+
|
|
12805
|
+
// src/credentialCacheChange.ts
|
|
12806
|
+
init_cliError();
|
|
12807
|
+
init_schema();
|
|
12808
|
+
function mergeCredentialCache(request4, existing) {
|
|
12809
|
+
if (request4.enabled === false) {
|
|
12810
|
+
return false;
|
|
12811
|
+
}
|
|
12812
|
+
if (request4.ttl === void 0 && request4.store === void 0 && request4.enabled !== true) {
|
|
12813
|
+
return void 0;
|
|
12814
|
+
}
|
|
12815
|
+
const parsed = CredentialCacheSchema.safeParse({
|
|
12816
|
+
...existing,
|
|
12817
|
+
...request4.ttl === void 0 ? {} : { ttl: request4.ttl },
|
|
12818
|
+
...request4.store === void 0 ? {} : { store: request4.store }
|
|
12819
|
+
});
|
|
12820
|
+
if (!parsed.success) {
|
|
12821
|
+
throw new UsageError(parsed.error.issues.map((issue) => issue.message).join("; "));
|
|
12822
|
+
}
|
|
12823
|
+
return parsed.data;
|
|
12824
|
+
}
|
|
12825
|
+
|
|
12826
|
+
// src/directoryRulesStore.ts
|
|
12827
|
+
init_store();
|
|
12828
|
+
init_load();
|
|
12829
|
+
init_schema();
|
|
12830
|
+
init_cliError();
|
|
12831
|
+
var DirectoryRuleNotFoundError = class extends CliError {
|
|
12832
|
+
constructor(rulePath) {
|
|
12833
|
+
super(`No directory rule found for path "${rulePath}".`);
|
|
12834
|
+
this.rulePath = rulePath;
|
|
12835
|
+
this.name = "DirectoryRuleNotFoundError";
|
|
12836
|
+
}
|
|
12837
|
+
rulePath;
|
|
12838
|
+
};
|
|
12839
|
+
var DirectoryRuleMissingTargetError = class extends CliError {
|
|
12840
|
+
constructor() {
|
|
12841
|
+
super("A directory rule must set at least one of --config-profile or --identity.");
|
|
12842
|
+
this.name = "DirectoryRuleMissingTargetError";
|
|
12843
|
+
}
|
|
12844
|
+
};
|
|
12845
|
+
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
12846
|
+
constructor(rulePath) {
|
|
12847
|
+
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
12848
|
+
this.rulePath = rulePath;
|
|
12849
|
+
this.name = "DirectoryRuleAlreadyExistsError";
|
|
12850
|
+
}
|
|
12851
|
+
rulePath;
|
|
12852
|
+
};
|
|
12853
|
+
function readDirectoryRules(paths) {
|
|
12854
|
+
return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
|
|
12855
|
+
}
|
|
12856
|
+
function writeDirectoryRules(paths, rules) {
|
|
12857
|
+
const parsed = DirectoryRulesSchema.safeParse(rules);
|
|
12858
|
+
if (!parsed.success) {
|
|
12859
|
+
throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
|
|
12860
|
+
}
|
|
12861
|
+
writeJsonAtomic(paths.directoryRulesFile, parsed.data);
|
|
12862
|
+
}
|
|
12863
|
+
function listDirectoryRules(paths) {
|
|
12864
|
+
return readDirectoryRules(paths).rules;
|
|
12865
|
+
}
|
|
12866
|
+
function addDirectoryRule(paths, rulePath, options) {
|
|
12867
|
+
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
12868
|
+
throw new DirectoryRuleMissingTargetError();
|
|
12869
|
+
}
|
|
12870
|
+
const current = readDirectoryRules(paths);
|
|
12871
|
+
if (current.rules.some((rule) => rule.path === rulePath)) {
|
|
12872
|
+
throw new DirectoryRuleAlreadyExistsError(rulePath);
|
|
12873
|
+
}
|
|
12874
|
+
const created = buildNewRule(rulePath, options);
|
|
12875
|
+
writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
|
|
12876
|
+
return created;
|
|
12877
|
+
}
|
|
12878
|
+
function ruleHasEffect(rule) {
|
|
12879
|
+
return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
|
|
12880
|
+
}
|
|
12881
|
+
function updateDirectoryRule(paths, rulePath, options) {
|
|
12882
|
+
const current = readDirectoryRules(paths);
|
|
12883
|
+
const index = current.rules.findIndex((rule) => rule.path === rulePath);
|
|
12884
|
+
const existing = index === -1 ? void 0 : current.rules[index];
|
|
12885
|
+
if (existing === void 0) {
|
|
12886
|
+
throw new DirectoryRuleNotFoundError(rulePath);
|
|
12887
|
+
}
|
|
12888
|
+
const { configProfile, identity, ...rest } = existing;
|
|
12889
|
+
const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
|
|
12890
|
+
const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
|
|
12891
|
+
const updated = {
|
|
12892
|
+
...rest,
|
|
12893
|
+
...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
|
|
12894
|
+
...nextIdentity === void 0 ? {} : { identity: nextIdentity }
|
|
12895
|
+
};
|
|
12896
|
+
if (!ruleHasEffect(updated)) {
|
|
12897
|
+
throw new DirectoryRuleMissingTargetError();
|
|
12898
|
+
}
|
|
12899
|
+
const nextRules = [...current.rules];
|
|
12900
|
+
nextRules[index] = updated;
|
|
12901
|
+
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
12902
|
+
return updated;
|
|
12903
|
+
}
|
|
12904
|
+
function buildNewRule(rulePath, options) {
|
|
12905
|
+
return {
|
|
12906
|
+
path: rulePath,
|
|
12907
|
+
...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
|
|
12908
|
+
...options.identity !== void 0 ? { identity: options.identity } : {}
|
|
12909
|
+
};
|
|
12910
|
+
}
|
|
12911
|
+
function removeDirectoryRule(paths, rulePath) {
|
|
12912
|
+
const current = readDirectoryRules(paths);
|
|
12913
|
+
const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
|
|
12914
|
+
if (nextRules.length === current.rules.length) {
|
|
12915
|
+
throw new DirectoryRuleNotFoundError(rulePath);
|
|
12916
|
+
}
|
|
12917
|
+
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
12918
|
+
}
|
|
12919
|
+
function requireRuleSelector(paths, selector) {
|
|
12920
|
+
if (selector.startsWith(POOL_SELECTOR_PREFIX)) {
|
|
12921
|
+
const poolName = selector.slice(POOL_SELECTOR_PREFIX.length);
|
|
12922
|
+
if (readPools(paths)[poolName] === void 0) {
|
|
12923
|
+
throw new PoolNotFoundError(poolName);
|
|
12924
|
+
}
|
|
12925
|
+
} else if (readIdentity(paths, selector) === void 0) {
|
|
12926
|
+
throw new IdentityNotFoundError(selector);
|
|
12927
|
+
}
|
|
12928
|
+
}
|
|
12929
|
+
|
|
12930
|
+
// src/frontdoor/configApi.ts
|
|
12931
|
+
init_identity();
|
|
12932
|
+
init_providersStore();
|
|
12933
|
+
|
|
12934
|
+
// src/frontdoor/configSchemas.ts
|
|
12935
|
+
init_schema();
|
|
12936
|
+
import { z as z20 } from "zod";
|
|
12937
|
+
var RemovalConfirmationSchema = z20.boolean();
|
|
12938
|
+
var CredentialWriteSchema = (targets) => z20.strictObject({
|
|
12939
|
+
sources: z20.array(RemoteCredentialSourceSchema).min(1).optional(),
|
|
12940
|
+
target: z20.enum(targets).optional(),
|
|
12941
|
+
cache: z20.union([z20.literal(false), CredentialCacheSchema]).optional()
|
|
12942
|
+
});
|
|
12943
|
+
var CredentialSummarySchema2 = z20.strictObject({
|
|
12944
|
+
target: z20.enum(CREDENTIAL_TARGETS),
|
|
12945
|
+
sources: z20.readonly(z20.array(
|
|
12946
|
+
z20.discriminatedUnion("kind", [
|
|
12947
|
+
z20.strictObject({ kind: z20.literal("env"), variable: z20.string() }),
|
|
12948
|
+
z20.strictObject({ kind: z20.literal("file"), path: z20.string() }),
|
|
12949
|
+
z20.strictObject({ kind: z20.literal("command"), program: z20.string() }),
|
|
12950
|
+
z20.strictObject({ kind: z20.literal("op"), reference: z20.string() }),
|
|
12951
|
+
z20.strictObject({ kind: z20.literal("keychain"), service: z20.string(), account: z20.string().optional() }),
|
|
12952
|
+
z20.strictObject({ kind: z20.literal("literal") })
|
|
12953
|
+
])
|
|
12954
|
+
)),
|
|
12955
|
+
cache: CredentialCacheSchema.optional()
|
|
12956
|
+
});
|
|
12957
|
+
var mutationOutput = (kind, action) => z20.strictObject({ action: z20.literal(action), kind: z20.literal(kind), name: z20.string() });
|
|
12958
|
+
var storedMutationOutput = (kind, action, value) => z20.strictObject({ action: z20.literal(action), kind: z20.literal(kind), name: z20.string(), value });
|
|
12959
|
+
var IdentityValueSchema = z20.strictObject({
|
|
12960
|
+
name: z20.string(),
|
|
12961
|
+
defaultConfigProfile: z20.string().optional(),
|
|
12962
|
+
allowAmbientCredential: z20.boolean(),
|
|
12963
|
+
credential: CredentialSummarySchema2.optional()
|
|
12964
|
+
});
|
|
12965
|
+
var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
|
|
12966
|
+
var ProviderValueSchema = z20.strictObject({
|
|
12967
|
+
name: z20.string(),
|
|
12968
|
+
kind: z20.enum(PROVIDER_KINDS),
|
|
12969
|
+
displayName: z20.string(),
|
|
12970
|
+
baseUrl: z20.string().optional(),
|
|
12971
|
+
codex: CodexProviderConfigSchema.optional(),
|
|
12972
|
+
credential: CredentialSummarySchema2,
|
|
12973
|
+
env: z20.record(z20.string(), z20.string()).optional()
|
|
12974
|
+
});
|
|
12975
|
+
var ConfigNameInputSchema = z20.strictObject({ name: z20.string().min(1) });
|
|
12976
|
+
var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
|
|
12977
|
+
var ConfigIdentitySetInputSchema = z20.strictObject({
|
|
12978
|
+
name: z20.string().min(1),
|
|
12979
|
+
defaultConfigProfile: z20.union([z20.string().min(1), z20.literal(false)]).optional(),
|
|
12980
|
+
allowAmbientCredential: z20.boolean().optional(),
|
|
12981
|
+
credential: z20.union([z20.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
|
|
12982
|
+
});
|
|
12983
|
+
var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
|
|
12984
|
+
var ConfigIdentityRemoveInputSchema = z20.strictObject({ name: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
12985
|
+
var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
|
|
12986
|
+
var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
|
|
12987
|
+
var ConfigProfileAddInputSchema = z20.strictObject({
|
|
12988
|
+
name: z20.string().min(1),
|
|
12989
|
+
extends: z20.array(z20.string().min(1)).optional(),
|
|
12990
|
+
description: z20.string().optional()
|
|
12991
|
+
});
|
|
12992
|
+
var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
|
|
12993
|
+
var ConfigProfileSetInputSchema = z20.strictObject({
|
|
12994
|
+
name: z20.string().min(1),
|
|
12995
|
+
category: z20.record(z20.string(), z20.boolean()).optional(),
|
|
12996
|
+
entry: z20.record(z20.string(), z20.boolean()).optional(),
|
|
12997
|
+
extends: z20.union([z20.array(z20.string().min(1)), z20.literal(false)]).optional(),
|
|
12998
|
+
description: z20.union([z20.string(), z20.literal(false)]).optional(),
|
|
12999
|
+
launch: z20.strictObject({
|
|
13000
|
+
skipPermissions: z20.boolean().optional(),
|
|
13001
|
+
remoteControl: z20.boolean().optional(),
|
|
13002
|
+
headroom: z20.boolean().optional(),
|
|
13003
|
+
trackUsage: z20.boolean().optional(),
|
|
13004
|
+
provider: z20.union([z20.string().min(1), z20.literal(false)]).optional(),
|
|
13005
|
+
claudeVersion: z20.union([z20.string().min(1), z20.literal(false)]).optional()
|
|
13006
|
+
}).optional()
|
|
13007
|
+
});
|
|
13008
|
+
var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
|
|
13009
|
+
var ConfigProfileRemoveInputSchema = z20.strictObject({ name: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13010
|
+
var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
|
|
13011
|
+
var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
|
|
13012
|
+
var PoolMembersInputSchema = z20.array(z20.string().min(1)).min(1);
|
|
13013
|
+
var ConfigPoolAddInputSchema = z20.strictObject({
|
|
13014
|
+
name: z20.string().min(1),
|
|
13015
|
+
identities: PoolMembersInputSchema,
|
|
13016
|
+
preference: z20.enum(POOL_PREFERENCES).optional()
|
|
13017
|
+
});
|
|
13018
|
+
var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
|
|
13019
|
+
var ConfigPoolSetInputSchema = z20.strictObject({
|
|
13020
|
+
name: z20.string().min(1),
|
|
13021
|
+
identities: PoolMembersInputSchema.optional(),
|
|
13022
|
+
preference: z20.union([z20.enum(POOL_PREFERENCES), z20.literal(false)]).optional()
|
|
13023
|
+
});
|
|
13024
|
+
var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
|
|
13025
|
+
var ConfigPoolRemoveInputSchema = z20.strictObject({ name: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13026
|
+
var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
|
|
13027
|
+
var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
|
|
13028
|
+
var ConfigProviderAddInputSchema = z20.strictObject({
|
|
13029
|
+
name: z20.string().min(1),
|
|
13030
|
+
kind: z20.enum(PROVIDER_KINDS).optional(),
|
|
13031
|
+
displayName: z20.string().min(1),
|
|
13032
|
+
baseUrl: z20.string().min(1).optional(),
|
|
13033
|
+
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
|
|
13034
|
+
codex: CodexProviderConfigSchema.optional()
|
|
13035
|
+
});
|
|
13036
|
+
var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
|
|
13037
|
+
var ConfigProviderSetInputSchema = z20.strictObject({
|
|
13038
|
+
name: z20.string().min(1),
|
|
13039
|
+
displayName: z20.string().min(1).optional(),
|
|
13040
|
+
baseUrl: z20.string().min(1).optional(),
|
|
13041
|
+
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
|
|
13042
|
+
codex: CodexProviderConfigSchema.optional()
|
|
13043
|
+
});
|
|
13044
|
+
var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
|
|
13045
|
+
var ConfigProviderRemoveInputSchema = z20.strictObject({ name: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13046
|
+
var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
|
|
13047
|
+
var ConfigRuleAddInputSchema = z20.strictObject({
|
|
13048
|
+
path: z20.string().min(1),
|
|
13049
|
+
configProfile: z20.string().min(1).optional(),
|
|
13050
|
+
identity: z20.string().min(1).optional()
|
|
13051
|
+
});
|
|
13052
|
+
var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
|
|
13053
|
+
var ConfigRuleSetInputSchema = z20.strictObject({
|
|
13054
|
+
path: z20.string().min(1),
|
|
13055
|
+
configProfile: z20.union([z20.string().min(1), z20.literal(false)]).optional(),
|
|
13056
|
+
identity: z20.union([z20.string().min(1), z20.literal(false)]).optional()
|
|
13057
|
+
});
|
|
13058
|
+
var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
|
|
13059
|
+
var ConfigRuleRemoveInputSchema = z20.strictObject({ path: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13060
|
+
var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
|
|
13061
|
+
|
|
13062
|
+
// src/frontdoor/configApi.ts
|
|
13063
|
+
var CONFIG_API_TAG = "config";
|
|
13064
|
+
function refusal(error) {
|
|
13065
|
+
if (error instanceof IdentityNotFoundError || error instanceof ProfileNotFoundError || error instanceof PoolNotFoundError || error instanceof ProviderNotFoundError || error instanceof DirectoryRuleNotFoundError) {
|
|
13066
|
+
throw new ORPCError2("NOT_FOUND", { message: error.message });
|
|
13067
|
+
}
|
|
13068
|
+
if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError) {
|
|
13069
|
+
throw new ORPCError2("CONFLICT", { message: error.message });
|
|
13070
|
+
}
|
|
13071
|
+
if (error instanceof CliError) {
|
|
13072
|
+
throw new ORPCError2("BAD_REQUEST", { message: error.message });
|
|
13073
|
+
}
|
|
13074
|
+
throw error;
|
|
13075
|
+
}
|
|
13076
|
+
function guarded(write) {
|
|
13077
|
+
try {
|
|
13078
|
+
return write();
|
|
13079
|
+
} catch (error) {
|
|
13080
|
+
return refusal(error);
|
|
13081
|
+
}
|
|
13082
|
+
}
|
|
13083
|
+
function requireConfirmation(confirm, what) {
|
|
13084
|
+
if (!confirm) {
|
|
13085
|
+
throw new ORPCError2("BAD_REQUEST", { message: `removing ${what} needs confirm: true, the API's form of the CLI's --yes` });
|
|
13086
|
+
}
|
|
13087
|
+
}
|
|
13088
|
+
function requireChange(given, fields) {
|
|
13089
|
+
if (!given) {
|
|
13090
|
+
throw new ORPCError2("BAD_REQUEST", { message: `Nothing to change: pass ${fields}.` });
|
|
13091
|
+
}
|
|
13092
|
+
}
|
|
13093
|
+
function identityValue(name, paths) {
|
|
13094
|
+
const identity = readIdentity(paths, name);
|
|
13095
|
+
if (identity === void 0) {
|
|
13096
|
+
throw new IdentityNotFoundError(name);
|
|
13097
|
+
}
|
|
13098
|
+
return {
|
|
13099
|
+
name: identity.name,
|
|
13100
|
+
...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
|
|
13101
|
+
allowAmbientCredential: identity.allowAmbientCredential,
|
|
13102
|
+
...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
|
|
13103
|
+
};
|
|
13104
|
+
}
|
|
13105
|
+
function providerValue(name, provider) {
|
|
13106
|
+
return {
|
|
13107
|
+
name,
|
|
13108
|
+
kind: provider.kind ?? "http",
|
|
13109
|
+
displayName: provider.displayName,
|
|
13110
|
+
...isCodexProvider(provider) ? provider.codex === void 0 ? {} : { codex: provider.codex } : { baseUrl: provider.baseUrl },
|
|
13111
|
+
credential: summariseCredential(provider.credential),
|
|
13112
|
+
...provider.env === void 0 ? {} : { env: provider.env }
|
|
13113
|
+
};
|
|
13114
|
+
}
|
|
13115
|
+
function profileValue(name, paths) {
|
|
13116
|
+
const profile = { ...readProfile(paths, name) };
|
|
13117
|
+
delete profile.$schema;
|
|
13118
|
+
return profile;
|
|
13119
|
+
}
|
|
13120
|
+
function createConfigApiRouter(deps) {
|
|
13121
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13122
|
+
const { paths } = deps;
|
|
13123
|
+
const route = (path36, summary) => authed.meta(openapi3({ method: "POST", path: path36, summary, tags: [CONFIG_API_TAG] }));
|
|
13124
|
+
return {
|
|
13125
|
+
config: {
|
|
13126
|
+
identity: {
|
|
13127
|
+
add: route("/rest/config/identity/add", "Create an identity").input(ConfigNameInputSchema).output(ConfigIdentityAddOutputSchema).handler(
|
|
13128
|
+
({ input }) => guarded(() => {
|
|
13129
|
+
addIdentity(paths, input.name);
|
|
13130
|
+
return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
13131
|
+
})
|
|
13132
|
+
),
|
|
13133
|
+
set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
|
|
13134
|
+
({ input }) => guarded(() => {
|
|
13135
|
+
requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
|
|
13136
|
+
if (!identityExists(paths, input.name)) {
|
|
13137
|
+
throw new IdentityNotFoundError(input.name);
|
|
13138
|
+
}
|
|
13139
|
+
if (typeof input.defaultConfigProfile === "string") {
|
|
13140
|
+
requireProfileExists(paths, input.defaultConfigProfile);
|
|
13141
|
+
}
|
|
13142
|
+
if (input.defaultConfigProfile !== void 0) {
|
|
13143
|
+
setDefaultConfigProfile(paths, input.name, input.defaultConfigProfile === false ? void 0 : input.defaultConfigProfile);
|
|
13144
|
+
}
|
|
13145
|
+
if (input.allowAmbientCredential !== void 0) {
|
|
13146
|
+
setAllowAmbientCredential(paths, input.name, input.allowAmbientCredential);
|
|
13147
|
+
}
|
|
13148
|
+
if (input.credential === false) {
|
|
13149
|
+
setIdentityCredential(paths, input.name, false);
|
|
13150
|
+
} else if (input.credential !== void 0) {
|
|
13151
|
+
const { sources, target, cache } = input.credential;
|
|
13152
|
+
const merged = cache === void 0 ? void 0 : mergeCredentialCache(cache === false ? { enabled: false } : { ...cache, enabled: true }, readIdentity(paths, input.name)?.credential?.cache);
|
|
13153
|
+
const change = {
|
|
13154
|
+
...sources === void 0 ? {} : { sources },
|
|
13155
|
+
...target === void 0 ? {} : { target },
|
|
13156
|
+
...merged === void 0 ? {} : { cache: merged }
|
|
13157
|
+
};
|
|
13158
|
+
setIdentityCredential(paths, input.name, change);
|
|
13159
|
+
}
|
|
13160
|
+
return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
13161
|
+
})
|
|
13162
|
+
),
|
|
13163
|
+
remove: route("/rest/config/identity/remove", "Delete an identity and its directory").input(ConfigIdentityRemoveInputSchema).output(ConfigIdentityRemoveOutputSchema).handler(({ input }) => {
|
|
13164
|
+
requireConfirmation(input.confirm, `identity "${input.name}" and its directory`);
|
|
13165
|
+
return guarded(() => {
|
|
13166
|
+
removeIdentity(paths, input.name);
|
|
13167
|
+
return { action: "removed", kind: "identity", name: input.name };
|
|
13168
|
+
});
|
|
13169
|
+
}),
|
|
13170
|
+
use: route("/rest/config/identity/use", "Select the active identity").input(ConfigNameInputSchema).output(ConfigIdentityUseOutputSchema).handler(
|
|
13171
|
+
({ input }) => guarded(() => {
|
|
13172
|
+
if (poolNameOf(input.name) === void 0 && !identityExists(paths, input.name)) {
|
|
13173
|
+
throw new IdentityNotFoundError(input.name);
|
|
13174
|
+
}
|
|
13175
|
+
useIdentity(paths, input.name);
|
|
13176
|
+
return { action: "selected", kind: "identity", name: input.name };
|
|
13177
|
+
})
|
|
13178
|
+
)
|
|
13179
|
+
},
|
|
13180
|
+
profile: {
|
|
13181
|
+
add: route("/rest/config/profile/add", "Create a configuration profile").input(ConfigProfileAddInputSchema).output(ConfigProfileAddOutputSchema).handler(
|
|
13182
|
+
({ input }) => guarded(() => {
|
|
13183
|
+
createProfile(paths, input.name, input.extends, input.description);
|
|
13184
|
+
return { action: "created", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
|
|
13185
|
+
})
|
|
13186
|
+
),
|
|
13187
|
+
set: route("/rest/config/profile/set", "Update a configuration profile's categories, entries, extends list, description or launch settings").input(ConfigProfileSetInputSchema).output(ConfigProfileSetOutputSchema).handler(
|
|
13188
|
+
({ input }) => guarded(() => {
|
|
13189
|
+
const { launch } = input;
|
|
13190
|
+
requireChange(
|
|
13191
|
+
input.category !== void 0 || input.entry !== void 0 || input.extends !== void 0 || input.description !== void 0 || launch !== void 0,
|
|
13192
|
+
"category, entry, extends, description or launch"
|
|
13193
|
+
);
|
|
13194
|
+
requireProfileExists(paths, input.name);
|
|
13195
|
+
applyProfileChange(paths, input.name, {
|
|
13196
|
+
...input.category === void 0 ? {} : { category: input.category },
|
|
13197
|
+
...input.entry === void 0 ? {} : { entry: input.entry },
|
|
13198
|
+
...input.extends === void 0 ? {} : { extends: input.extends },
|
|
13199
|
+
...input.description === void 0 ? {} : { description: input.description },
|
|
13200
|
+
...launch?.skipPermissions === void 0 ? {} : { launchSkipPermissions: launch.skipPermissions },
|
|
13201
|
+
...launch?.remoteControl === void 0 ? {} : { launchRemoteControl: launch.remoteControl },
|
|
13202
|
+
...launch?.headroom === void 0 ? {} : { launchHeadroom: launch.headroom },
|
|
13203
|
+
...launch?.trackUsage === void 0 ? {} : { launchTrackUsage: launch.trackUsage },
|
|
13204
|
+
...launch?.provider === void 0 ? {} : { launchProvider: launch.provider },
|
|
13205
|
+
...launch?.claudeVersion === void 0 ? {} : { launchClaudeVersion: launch.claudeVersion }
|
|
13206
|
+
});
|
|
13207
|
+
return { action: "updated", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
|
|
13208
|
+
})
|
|
13209
|
+
),
|
|
13210
|
+
remove: route("/rest/config/profile/remove", "Delete a configuration profile").input(ConfigProfileRemoveInputSchema).output(ConfigProfileRemoveOutputSchema).handler(({ input }) => {
|
|
13211
|
+
requireConfirmation(input.confirm, `configuration profile "${input.name}"`);
|
|
13212
|
+
return guarded(() => {
|
|
13213
|
+
removeProfile(paths, input.name);
|
|
13214
|
+
return { action: "removed", kind: "profile", name: input.name };
|
|
13215
|
+
});
|
|
13216
|
+
}),
|
|
13217
|
+
use: route("/rest/config/profile/use", "Make a configuration profile the global default").input(ConfigNameInputSchema).output(ConfigProfileUseOutputSchema).handler(
|
|
13218
|
+
({ input }) => guarded(() => {
|
|
13219
|
+
requireProfileExists(paths, input.name);
|
|
13220
|
+
setGlobalDefaultProfile(paths, input.name);
|
|
13221
|
+
return { action: "selected", kind: "profile", name: input.name };
|
|
13222
|
+
})
|
|
13223
|
+
)
|
|
13224
|
+
},
|
|
13225
|
+
pool: {
|
|
13226
|
+
add: route("/rest/config/pool/add", "Define a pool").input(ConfigPoolAddInputSchema).output(ConfigPoolAddOutputSchema).handler(
|
|
13227
|
+
({ input }) => guarded(() => {
|
|
13228
|
+
requireIdentityNames(paths, input.identities);
|
|
13229
|
+
const created = addPool(paths, input.name, input.identities, input.preference);
|
|
13230
|
+
return { action: "created", kind: "pool", name: input.name, value: created };
|
|
13231
|
+
})
|
|
13232
|
+
),
|
|
13233
|
+
set: route("/rest/config/pool/set", "Replace a pool's members, its preference or both").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
|
|
13234
|
+
({ input }) => guarded(() => {
|
|
13235
|
+
requireChange(input.identities !== void 0 || input.preference !== void 0, "identities or preference");
|
|
13236
|
+
const existing = requirePool(paths, input.name);
|
|
13237
|
+
if (input.identities !== void 0) {
|
|
13238
|
+
requireIdentityNames(paths, input.identities);
|
|
13239
|
+
}
|
|
13240
|
+
const members = input.identities ?? existing.identities;
|
|
13241
|
+
const preference = input.preference === void 0 ? existing.preference : input.preference === false ? void 0 : input.preference;
|
|
13242
|
+
return { action: "updated", kind: "pool", name: input.name, value: setPool(paths, input.name, members, preference) };
|
|
13243
|
+
})
|
|
13244
|
+
),
|
|
13245
|
+
remove: route("/rest/config/pool/remove", "Delete a pool").input(ConfigPoolRemoveInputSchema).output(ConfigPoolRemoveOutputSchema).handler(({ input }) => {
|
|
13246
|
+
requireConfirmation(input.confirm, `pool "${input.name}"`);
|
|
13247
|
+
return guarded(() => {
|
|
13248
|
+
removePool(paths, input.name);
|
|
13249
|
+
return { action: "removed", kind: "pool", name: input.name };
|
|
13250
|
+
});
|
|
13251
|
+
}),
|
|
13252
|
+
use: route("/rest/config/pool/use", "Make launches with no other selection pick a member of a pool").input(ConfigNameInputSchema).output(ConfigPoolUseOutputSchema).handler(
|
|
13253
|
+
({ input }) => guarded(() => {
|
|
13254
|
+
if (readPools(paths)[input.name] === void 0) {
|
|
13255
|
+
throw new PoolNotFoundError(input.name);
|
|
13256
|
+
}
|
|
13257
|
+
useIdentity(paths, `pool:${input.name}`);
|
|
13258
|
+
return { action: "selected", kind: "pool", name: input.name };
|
|
13259
|
+
})
|
|
13260
|
+
)
|
|
13261
|
+
},
|
|
13262
|
+
provider: {
|
|
13263
|
+
add: route("/rest/config/provider/add", "Create an API provider definition").input(ConfigProviderAddInputSchema).output(ConfigProviderAddOutputSchema).handler(
|
|
13264
|
+
({ input }) => guarded(() => {
|
|
13265
|
+
const created = addProvider(paths, input.name, {
|
|
13266
|
+
...input.kind === void 0 ? {} : { kind: input.kind },
|
|
13267
|
+
displayName: input.displayName,
|
|
13268
|
+
...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
|
|
13269
|
+
sources: input.credential.sources,
|
|
13270
|
+
...input.credential.target === void 0 ? {} : { target: input.credential.target },
|
|
13271
|
+
...input.codex === void 0 ? {} : { codex: input.codex }
|
|
13272
|
+
});
|
|
13273
|
+
const cache = input.credential.cache;
|
|
13274
|
+
const stored = cache === void 0 || cache === false ? created : updateProvider(paths, input.name, { cache });
|
|
13275
|
+
return { action: "created", kind: "provider", name: input.name, value: providerValue(input.name, stored) };
|
|
13276
|
+
})
|
|
13277
|
+
),
|
|
13278
|
+
set: route("/rest/config/provider/set", "Update an API provider definition").input(ConfigProviderSetInputSchema).output(ConfigProviderSetOutputSchema).handler(
|
|
13279
|
+
({ input }) => guarded(() => {
|
|
13280
|
+
requireChange(input.displayName !== void 0 || input.baseUrl !== void 0 || input.credential !== void 0 || input.codex !== void 0, "displayName, baseUrl, credential or codex");
|
|
13281
|
+
const existing = readProvider(paths, input.name);
|
|
13282
|
+
if (existing === void 0) {
|
|
13283
|
+
throw new ProviderNotFoundError(input.name);
|
|
13284
|
+
}
|
|
13285
|
+
const credential = input.credential;
|
|
13286
|
+
if (input.baseUrl !== void 0 && !isCodexProvider(existing) && input.baseUrl !== existing.baseUrl && credential?.sources === void 0) {
|
|
13287
|
+
throw new ORPCError2("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.` });
|
|
13288
|
+
}
|
|
13289
|
+
const cache = credential?.cache === void 0 ? void 0 : mergeCredentialCache(credential.cache === false ? { enabled: false } : { ...credential.cache, enabled: true }, existing.credential.cache);
|
|
13290
|
+
const updated = updateProvider(paths, input.name, {
|
|
13291
|
+
...input.displayName === void 0 ? {} : { displayName: input.displayName },
|
|
13292
|
+
...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
|
|
13293
|
+
...credential?.sources === void 0 ? {} : { sources: credential.sources },
|
|
13294
|
+
...credential?.target === void 0 ? {} : { target: credential.target },
|
|
13295
|
+
...cache === void 0 ? {} : { cache },
|
|
13296
|
+
...input.codex === void 0 ? {} : { codex: input.codex }
|
|
13297
|
+
});
|
|
13298
|
+
return { action: "updated", kind: "provider", name: input.name, value: providerValue(input.name, updated) };
|
|
13299
|
+
})
|
|
13300
|
+
),
|
|
13301
|
+
remove: route("/rest/config/provider/remove", "Delete an API provider definition").input(ConfigProviderRemoveInputSchema).output(ConfigProviderRemoveOutputSchema).handler(({ input }) => {
|
|
13302
|
+
requireConfirmation(input.confirm, `provider "${input.name}"`);
|
|
13303
|
+
return guarded(() => {
|
|
13304
|
+
if (!providerExists(paths, input.name)) {
|
|
13305
|
+
throw new ProviderNotFoundError(input.name);
|
|
13306
|
+
}
|
|
13307
|
+
removeProvider(paths, input.name);
|
|
13308
|
+
return { action: "removed", kind: "provider", name: input.name };
|
|
13309
|
+
});
|
|
13310
|
+
})
|
|
13311
|
+
},
|
|
13312
|
+
rule: {
|
|
13313
|
+
add: route("/rest/config/rule/add", "Add a directory rule for a path").input(ConfigRuleAddInputSchema).output(ConfigRuleAddOutputSchema).handler(
|
|
13314
|
+
({ input }) => guarded(() => {
|
|
13315
|
+
if (input.identity !== void 0) {
|
|
13316
|
+
requireRuleSelector(paths, input.identity);
|
|
13317
|
+
}
|
|
13318
|
+
if (input.configProfile !== void 0) {
|
|
13319
|
+
requireProfileExists(paths, input.configProfile);
|
|
13320
|
+
}
|
|
13321
|
+
const created = addDirectoryRule(paths, input.path, {
|
|
13322
|
+
...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
|
|
13323
|
+
...input.identity === void 0 ? {} : { identity: input.identity }
|
|
13324
|
+
});
|
|
13325
|
+
return { action: "created", kind: "rule", name: input.path, value: created };
|
|
13326
|
+
})
|
|
13327
|
+
),
|
|
13328
|
+
set: route("/rest/config/rule/set", "Update the directory rule for a path").input(ConfigRuleSetInputSchema).output(ConfigRuleSetOutputSchema).handler(
|
|
13329
|
+
({ input }) => guarded(() => {
|
|
13330
|
+
requireChange(input.configProfile !== void 0 || input.identity !== void 0, "configProfile or identity");
|
|
13331
|
+
if (typeof input.identity === "string") {
|
|
13332
|
+
requireRuleSelector(paths, input.identity);
|
|
13333
|
+
}
|
|
13334
|
+
if (typeof input.configProfile === "string") {
|
|
13335
|
+
requireProfileExists(paths, input.configProfile);
|
|
13336
|
+
}
|
|
13337
|
+
const updated = updateDirectoryRule(paths, input.path, {
|
|
13338
|
+
...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
|
|
13339
|
+
...input.identity === void 0 ? {} : { identity: input.identity }
|
|
13340
|
+
});
|
|
13341
|
+
return { action: "updated", kind: "rule", name: input.path, value: updated };
|
|
13342
|
+
})
|
|
13343
|
+
),
|
|
13344
|
+
remove: route("/rest/config/rule/remove", "Remove the directory rule for a path").input(ConfigRuleRemoveInputSchema).output(ConfigRuleRemoveOutputSchema).handler(({ input }) => {
|
|
13345
|
+
requireConfirmation(input.confirm, `the directory rule for "${input.path}"`);
|
|
13346
|
+
return guarded(() => {
|
|
13347
|
+
if (!listDirectoryRules(paths).some((entry) => entry.path === input.path)) {
|
|
13348
|
+
throw new DirectoryRuleNotFoundError(input.path);
|
|
13349
|
+
}
|
|
13350
|
+
removeDirectoryRule(paths, input.path);
|
|
13351
|
+
return { action: "removed", kind: "rule", name: input.path };
|
|
13352
|
+
});
|
|
13353
|
+
})
|
|
13354
|
+
}
|
|
13355
|
+
}
|
|
13356
|
+
};
|
|
13357
|
+
}
|
|
13358
|
+
|
|
13359
|
+
// src/frontdoor/eventsApi.ts
|
|
13360
|
+
import { ORPCError as ORPCError3 } from "@orpc/client";
|
|
13361
|
+
import { openapi as openapi4 } from "@orpc/openapi";
|
|
12735
13362
|
import { eventIterator as eventIterator2, withEventMeta as withEventMeta2 } from "@orpc/server";
|
|
12736
13363
|
|
|
12737
13364
|
// src/frontdoor/eventSchemas.ts
|
|
12738
|
-
import { z as
|
|
13365
|
+
import { z as z21 } from "zod";
|
|
12739
13366
|
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
12740
13367
|
var LAUNCH_EVENT_SOURCE = "launch";
|
|
12741
13368
|
var USAGE_EVENT_SOURCE = "usage";
|
|
12742
13369
|
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
12743
13370
|
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
12744
|
-
var DoorEventSchema =
|
|
12745
|
-
source:
|
|
13371
|
+
var DoorEventSchema = z21.strictObject({
|
|
13372
|
+
source: z21.string().min(1),
|
|
12746
13373
|
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
12747
|
-
sequence:
|
|
12748
|
-
payload:
|
|
12749
|
-
});
|
|
12750
|
-
var DoorEventSourceQuerySchema =
|
|
12751
|
-
sources:
|
|
12752
|
-
});
|
|
12753
|
-
var LaunchLifecycleEventSchema =
|
|
12754
|
-
kind:
|
|
12755
|
-
pid:
|
|
12756
|
-
startedAt:
|
|
12757
|
-
observedAt:
|
|
12758
|
-
});
|
|
12759
|
-
var DoorHealthEventSchema =
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
13374
|
+
sequence: z21.number().int().positive(),
|
|
13375
|
+
payload: z21.unknown()
|
|
13376
|
+
});
|
|
13377
|
+
var DoorEventSourceQuerySchema = z21.strictObject({
|
|
13378
|
+
sources: z21.array(z21.string().min(1)).min(1).optional()
|
|
13379
|
+
});
|
|
13380
|
+
var LaunchLifecycleEventSchema = z21.strictObject({
|
|
13381
|
+
kind: z21.enum(["registered", "pruned", "ended"]),
|
|
13382
|
+
pid: z21.number().int().positive(),
|
|
13383
|
+
startedAt: z21.number(),
|
|
13384
|
+
observedAt: z21.number()
|
|
13385
|
+
});
|
|
13386
|
+
var DoorHealthEventSchema = z21.discriminatedUnion("kind", [
|
|
13387
|
+
z21.strictObject({ kind: z21.literal("generation"), pid: z21.number().int().positive(), providerPort: z21.number().int().positive(), connectPort: z21.number().int().positive(), directPort: z21.number().int().positive(), observedAt: z21.number() }),
|
|
13388
|
+
z21.strictObject({ kind: z21.literal("listenerFailed"), pid: z21.number().int().positive(), listener: z21.enum(["provider", "connect", "direct"]), message: z21.string(), observedAt: z21.number() }),
|
|
13389
|
+
z21.strictObject({ kind: z21.literal("binaryTurnover"), pid: z21.number().int().positive(), observedAt: z21.number() }),
|
|
13390
|
+
z21.strictObject({ kind: z21.literal("idleShutdown"), pid: z21.number().int().positive(), observedAt: z21.number() })
|
|
12764
13391
|
]);
|
|
12765
|
-
var QuotaExpiringEventSchema =
|
|
12766
|
-
identity:
|
|
12767
|
-
provider:
|
|
12768
|
-
window:
|
|
13392
|
+
var QuotaExpiringEventSchema = z21.strictObject({
|
|
13393
|
+
identity: z21.string().min(1),
|
|
13394
|
+
provider: z21.string().min(1),
|
|
13395
|
+
window: z21.enum(["fiveHour", "sevenDay"]),
|
|
12769
13396
|
/** 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. */
|
|
12770
|
-
utilization:
|
|
12771
|
-
resetsAt:
|
|
12772
|
-
observedAt:
|
|
13397
|
+
utilization: z21.number().min(0).max(1),
|
|
13398
|
+
resetsAt: z21.iso.datetime(),
|
|
13399
|
+
observedAt: z21.number()
|
|
12773
13400
|
});
|
|
12774
13401
|
|
|
12775
13402
|
// src/frontdoor/eventsApi.ts
|
|
@@ -12778,12 +13405,12 @@ function createEventsApiRouter(deps) {
|
|
|
12778
13405
|
const authed = doorApiAuth(deps.expectedToken);
|
|
12779
13406
|
return {
|
|
12780
13407
|
events: {
|
|
12781
|
-
subscribe: authed.meta(
|
|
13408
|
+
subscribe: authed.meta(openapi4({ method: "GET", path: "/rest/events", summary: "Stream the door's every event source (SSE)", tags: [EVENTS_API_TAG] })).input(DoorEventSourceQuerySchema).output(eventIterator2(DoorEventSchema)).handler(async function* ({ input, signal }) {
|
|
12782
13409
|
if (input.sources !== void 0) {
|
|
12783
13410
|
const live = deps.events.sources();
|
|
12784
13411
|
const unknown = input.sources.filter((source) => !live.includes(source));
|
|
12785
13412
|
if (unknown.length > 0) {
|
|
12786
|
-
throw new
|
|
13413
|
+
throw new ORPCError3("NOT_FOUND", { message: `the door publishes no event source named ${unknown.map((source) => `"${source}"`).join(", ")}; the live sources are ${live.map((source) => `"${source}"`).join(", ")}` });
|
|
12787
13414
|
}
|
|
12788
13415
|
}
|
|
12789
13416
|
const stream = deps.events.stream(input.sources);
|
|
@@ -12812,32 +13439,32 @@ function createEventsApiRouter(deps) {
|
|
|
12812
13439
|
|
|
12813
13440
|
// src/frontdoor/lifecycleApi.ts
|
|
12814
13441
|
init_update();
|
|
12815
|
-
import { ORPCError as
|
|
12816
|
-
import { openapi as
|
|
13442
|
+
import { ORPCError as ORPCError4 } from "@orpc/client";
|
|
13443
|
+
import { openapi as openapi5 } from "@orpc/openapi";
|
|
12817
13444
|
var FRONTDOOR_API_TAG = "frontdoor";
|
|
12818
13445
|
var UPDATE_API_TAG = "update";
|
|
12819
13446
|
function createLifecycleApiRouter(deps) {
|
|
12820
13447
|
const authed = doorApiAuth(deps.expectedToken);
|
|
12821
13448
|
return {
|
|
12822
13449
|
frontdoor: {
|
|
12823
|
-
restart: authed.meta(
|
|
13450
|
+
restart: authed.meta(openapi5({ method: "POST", path: "/rest/frontdoor/restart", summary: "Replace the serving front door in place", description: "Answers with the pid of the door being replaced, then replaces it. The replacement is a new generation with its own control token: the caller reopens its client from the state root once the door's supervisor pid differs from the one returned.", tags: [FRONTDOOR_API_TAG] })).output(FrontDoorRestartOutputSchema).handler(({ context }) => {
|
|
12824
13451
|
context.afterResponse(deps.restartDoor);
|
|
12825
13452
|
return { action: "restarting", previousPid: deps.doorPid };
|
|
12826
13453
|
})
|
|
12827
13454
|
},
|
|
12828
13455
|
update: {
|
|
12829
|
-
check: authed.meta(
|
|
13456
|
+
check: authed.meta(openapi5({ method: "GET", path: "/rest/update/check", summary: "Check whether a newer release exists", tags: [UPDATE_API_TAG] })).output(UpdateCheckOutputSchema).handler(async () => {
|
|
12830
13457
|
try {
|
|
12831
13458
|
return await deps.checkForUpdate();
|
|
12832
13459
|
} catch (error) {
|
|
12833
13460
|
if (error instanceof UpdateChannelError) {
|
|
12834
|
-
throw new
|
|
13461
|
+
throw new ORPCError4("PRECONDITION_FAILED", { message: error.message });
|
|
12835
13462
|
}
|
|
12836
13463
|
if (error instanceof UpdateConflictError) {
|
|
12837
|
-
throw new
|
|
13464
|
+
throw new ORPCError4("CONFLICT", { message: error.message });
|
|
12838
13465
|
}
|
|
12839
13466
|
if (error instanceof UpdateDownloadError) {
|
|
12840
|
-
throw new
|
|
13467
|
+
throw new ORPCError4("BAD_GATEWAY", { message: error.message });
|
|
12841
13468
|
}
|
|
12842
13469
|
throw error;
|
|
12843
13470
|
}
|
|
@@ -12848,56 +13475,56 @@ function createLifecycleApiRouter(deps) {
|
|
|
12848
13475
|
|
|
12849
13476
|
// src/frontdoor/launchApi.ts
|
|
12850
13477
|
init_cliError();
|
|
12851
|
-
import { ORPCError as
|
|
12852
|
-
import { openapi as
|
|
13478
|
+
import { ORPCError as ORPCError5 } from "@orpc/client";
|
|
13479
|
+
import { openapi as openapi6 } from "@orpc/openapi";
|
|
12853
13480
|
|
|
12854
13481
|
// src/frontdoor/launchSchemas.ts
|
|
12855
13482
|
import path30 from "node:path";
|
|
12856
|
-
import { z as
|
|
13483
|
+
import { z as z22 } from "zod";
|
|
12857
13484
|
init_claudeVersion();
|
|
12858
13485
|
init_identity();
|
|
12859
|
-
var LaunchResolveInputSchema =
|
|
12860
|
-
path:
|
|
13486
|
+
var LaunchResolveInputSchema = z22.strictObject({
|
|
13487
|
+
path: z22.string().min(1),
|
|
12861
13488
|
/** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
|
|
12862
|
-
argv:
|
|
13489
|
+
argv: z22.readonly(z22.array(z22.string())).optional(),
|
|
12863
13490
|
/** The launch's inherited environment. Absent means an empty one: the door's own environment is never a substitute for the caller's, so a caller that wants `AGENT_SHIM_*` switches or a `CLAUDE_CONFIG_DIR` considered names them here. Values are read, never reported. */
|
|
12864
|
-
env:
|
|
13491
|
+
env: z22.record(z22.string(), z22.string()).optional()
|
|
12865
13492
|
}).refine((input) => path30.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
12866
|
-
var LaunchPoolDecisionSchema =
|
|
12867
|
-
name:
|
|
12868
|
-
reasons:
|
|
12869
|
-
movedOff:
|
|
12870
|
-
});
|
|
12871
|
-
var LaunchDecisionSchema =
|
|
12872
|
-
identity:
|
|
12873
|
-
identitySource:
|
|
13493
|
+
var LaunchPoolDecisionSchema = z22.strictObject({
|
|
13494
|
+
name: z22.string(),
|
|
13495
|
+
reasons: z22.readonly(z22.array(z22.string())),
|
|
13496
|
+
movedOff: z22.strictObject({ identity: z22.string(), reason: z22.string() }).optional()
|
|
13497
|
+
});
|
|
13498
|
+
var LaunchDecisionSchema = z22.strictObject({
|
|
13499
|
+
identity: z22.string().optional(),
|
|
13500
|
+
identitySource: z22.enum(IDENTITY_DECISION_SOURCES),
|
|
12874
13501
|
pool: LaunchPoolDecisionSchema.optional(),
|
|
12875
|
-
configDirEscapeHatch:
|
|
12876
|
-
configDir:
|
|
12877
|
-
configProfile:
|
|
12878
|
-
configProfileSource:
|
|
12879
|
-
provider:
|
|
12880
|
-
});
|
|
12881
|
-
var LaunchFlagsSchema =
|
|
12882
|
-
skipPermissions:
|
|
12883
|
-
remoteControl:
|
|
12884
|
-
headroom:
|
|
12885
|
-
trackUsage:
|
|
12886
|
-
});
|
|
12887
|
-
var LaunchResolveOutputSchema =
|
|
13502
|
+
configDirEscapeHatch: z22.boolean(),
|
|
13503
|
+
configDir: z22.string().optional(),
|
|
13504
|
+
configProfile: z22.string().optional(),
|
|
13505
|
+
configProfileSource: z22.enum(CONFIG_PROFILE_DECISION_SOURCES),
|
|
13506
|
+
provider: z22.string().optional()
|
|
13507
|
+
});
|
|
13508
|
+
var LaunchFlagsSchema = z22.strictObject({
|
|
13509
|
+
skipPermissions: z22.boolean(),
|
|
13510
|
+
remoteControl: z22.boolean(),
|
|
13511
|
+
headroom: z22.boolean(),
|
|
13512
|
+
trackUsage: z22.boolean()
|
|
13513
|
+
});
|
|
13514
|
+
var LaunchResolveOutputSchema = z22.strictObject({
|
|
12888
13515
|
decision: LaunchDecisionSchema,
|
|
12889
13516
|
flags: LaunchFlagsSchema,
|
|
12890
|
-
claudeVersion:
|
|
13517
|
+
claudeVersion: z22.strictObject({ version: z22.string(), source: z22.enum(CLAUDE_VERSION_SOURCES) }).optional(),
|
|
12891
13518
|
/** The real `claude` binary the launch would spawn, on the door's host. */
|
|
12892
|
-
bin:
|
|
13519
|
+
bin: z22.string(),
|
|
12893
13520
|
/** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
|
|
12894
|
-
args:
|
|
13521
|
+
args: z22.readonly(z22.array(z22.string())),
|
|
12895
13522
|
/** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
|
|
12896
|
-
credential:
|
|
12897
|
-
routing:
|
|
13523
|
+
credential: z22.strictObject({ subject: z22.enum(["provider", "identity"]), name: z22.string(), summary: CredentialSummarySchema }).optional(),
|
|
13524
|
+
routing: z22.strictObject({ frontDoor: z22.boolean(), headroom: z22.boolean() }),
|
|
12898
13525
|
/** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
|
|
12899
|
-
environment:
|
|
12900
|
-
warnings:
|
|
13526
|
+
environment: z22.readonly(z22.array(z22.string())),
|
|
13527
|
+
warnings: z22.readonly(z22.array(z22.string()))
|
|
12901
13528
|
});
|
|
12902
13529
|
|
|
12903
13530
|
// src/frontdoor/launchApi.ts
|
|
@@ -12906,13 +13533,22 @@ function createLaunchApiRouter(deps) {
|
|
|
12906
13533
|
const authed = doorApiAuth(deps.expectedToken);
|
|
12907
13534
|
return {
|
|
12908
13535
|
launch: {
|
|
12909
|
-
resolve: authed.meta(
|
|
13536
|
+
resolve: authed.meta(
|
|
13537
|
+
openapi6({
|
|
13538
|
+
method: "POST",
|
|
13539
|
+
path: "/rest/launch/resolve",
|
|
13540
|
+
summary: "Resolve what a launch from one directory would do, without performing it",
|
|
13541
|
+
tags: [LAUNCH_API_TAG],
|
|
13542
|
+
// A POST because the launch's environment and arguments are a body, but the answer changes nothing.
|
|
13543
|
+
spec: (current) => ({ ...current, [READ_ONLY_OPERATION_EXTENSION]: true })
|
|
13544
|
+
})
|
|
13545
|
+
).input(LaunchResolveInputSchema).output(LaunchResolveOutputSchema).handler(({ input }) => {
|
|
12910
13546
|
try {
|
|
12911
13547
|
const { resolution, warnings } = deps.resolveLaunch({ path: input.path, argv: input.argv ?? [], env: input.env ?? {} });
|
|
12912
13548
|
return { ...resolution, warnings };
|
|
12913
13549
|
} catch (error) {
|
|
12914
13550
|
if (error instanceof CliError) {
|
|
12915
|
-
throw new
|
|
13551
|
+
throw new ORPCError5("BAD_REQUEST", { message: error.message });
|
|
12916
13552
|
}
|
|
12917
13553
|
throw error;
|
|
12918
13554
|
}
|
|
@@ -12931,11 +13567,11 @@ function createControlApiRouter(deps) {
|
|
|
12931
13567
|
const authed = doorApiAuth(deps.expectedToken);
|
|
12932
13568
|
return {
|
|
12933
13569
|
usage: {
|
|
12934
|
-
list: authed.meta(
|
|
12935
|
-
effectiveWindow: authed.meta(
|
|
13570
|
+
list: authed.meta(openapi7({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
|
|
13571
|
+
effectiveWindow: authed.meta(openapi7({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
|
|
12936
13572
|
const snapshot = deps.usageSnapshotOf(input.identity);
|
|
12937
13573
|
if (snapshot === void 0) {
|
|
12938
|
-
throw new
|
|
13574
|
+
throw new ORPCError6("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
|
|
12939
13575
|
}
|
|
12940
13576
|
const provider = input.provider ?? ANTHROPIC_PROVIDER;
|
|
12941
13577
|
const rateLimit = snapshot.providers[provider]?.rateLimit;
|
|
@@ -12949,34 +13585,34 @@ function createControlApiRouter(deps) {
|
|
|
12949
13585
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
12950
13586
|
};
|
|
12951
13587
|
}),
|
|
12952
|
-
live: authed.meta(
|
|
13588
|
+
live: authed.meta(openapi7({ 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 }) => {
|
|
12953
13589
|
const sessions = deps.liveRateLimits(input.session);
|
|
12954
13590
|
if (input.session !== void 0 && sessions.length === 0) {
|
|
12955
13591
|
if (deps.list().some((session) => session.id === input.session)) {
|
|
12956
|
-
throw new
|
|
13592
|
+
throw new ORPCError6("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` });
|
|
12957
13593
|
}
|
|
12958
|
-
throw new
|
|
13594
|
+
throw new ORPCError6("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
12959
13595
|
}
|
|
12960
13596
|
return { latest: deps.latestRateLimit(), sessions };
|
|
12961
13597
|
})
|
|
12962
13598
|
},
|
|
12963
13599
|
frontdoor: {
|
|
12964
|
-
status: authed.meta(
|
|
12965
|
-
sessions: authed.meta(
|
|
13600
|
+
status: authed.meta(openapi7({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
|
|
13601
|
+
sessions: authed.meta(openapi7({ 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 }))
|
|
12966
13602
|
},
|
|
12967
13603
|
check: {
|
|
12968
13604
|
// 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.
|
|
12969
|
-
run: authed.meta(
|
|
13605
|
+
run: authed.meta(openapi7({ 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)))
|
|
12970
13606
|
},
|
|
12971
13607
|
doctor: {
|
|
12972
|
-
run: authed.meta(
|
|
13608
|
+
run: authed.meta(openapi7({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
|
|
12973
13609
|
},
|
|
12974
13610
|
pool: {
|
|
12975
|
-
pick: authed.meta(
|
|
13611
|
+
pick: authed.meta(openapi7({ 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 }) => {
|
|
12976
13612
|
const report = deps.poolPick(input.pool, input.path);
|
|
12977
13613
|
if (report === void 0) {
|
|
12978
13614
|
const live = deps.poolNames();
|
|
12979
|
-
throw new
|
|
13615
|
+
throw new ORPCError6("NOT_FOUND", {
|
|
12980
13616
|
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(", ")}`
|
|
12981
13617
|
});
|
|
12982
13618
|
}
|
|
@@ -12988,7 +13624,7 @@ function createControlApiRouter(deps) {
|
|
|
12988
13624
|
function createDoorApiRouter(deps) {
|
|
12989
13625
|
const control = createControlApiRouter(deps);
|
|
12990
13626
|
const lifecycle = createLifecycleApiRouter(deps);
|
|
12991
|
-
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
13627
|
+
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
12992
13628
|
}
|
|
12993
13629
|
function createDoorApiNodeHandler(deps) {
|
|
12994
13630
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
@@ -13800,9 +14436,9 @@ async function serveRcCompatSessions(ctx, pathname, compatPath) {
|
|
|
13800
14436
|
const slash = rest.indexOf("/");
|
|
13801
14437
|
const address = slash === -1 ? rest : rest.slice(0, slash);
|
|
13802
14438
|
const compatTail = slash === -1 ? "" : rest.slice(slash + 1);
|
|
13803
|
-
const
|
|
13804
|
-
if (
|
|
13805
|
-
await ctx.unauthorized(response,
|
|
14439
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14440
|
+
if (refusal2 !== void 0) {
|
|
14441
|
+
await ctx.unauthorized(response, refusal2);
|
|
13806
14442
|
return;
|
|
13807
14443
|
}
|
|
13808
14444
|
const session = ctx.sessions.get(address) ?? ctx.sessions.get(`cse_${address}`);
|
|
@@ -13880,9 +14516,9 @@ function conversationRow(conversation) {
|
|
|
13880
14516
|
}
|
|
13881
14517
|
async function serveRcConversations(ctx, pathname, method) {
|
|
13882
14518
|
const { request: request4, response, conversations } = ctx;
|
|
13883
|
-
const
|
|
13884
|
-
if (
|
|
13885
|
-
await ctx.unauthorized(response,
|
|
14519
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14520
|
+
if (refusal2 !== void 0) {
|
|
14521
|
+
await ctx.unauthorized(response, refusal2);
|
|
13886
14522
|
return;
|
|
13887
14523
|
}
|
|
13888
14524
|
if (pathname === RC_CONVERSATIONS_PATH_PREFIX) {
|
|
@@ -14206,9 +14842,9 @@ async function fetchThroughWebProxy(url, deps) {
|
|
|
14206
14842
|
try {
|
|
14207
14843
|
let redirects = 0;
|
|
14208
14844
|
for (; ; ) {
|
|
14209
|
-
const
|
|
14210
|
-
if (
|
|
14211
|
-
return
|
|
14845
|
+
const refusal2 = await checkTarget(current, deps);
|
|
14846
|
+
if (refusal2 !== void 0) {
|
|
14847
|
+
return refusal2;
|
|
14212
14848
|
}
|
|
14213
14849
|
let hop;
|
|
14214
14850
|
try {
|
|
@@ -14578,8 +15214,8 @@ data: ${JSON.stringify(envelope)}
|
|
|
14578
15214
|
"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",
|
|
14579
15215
|
unrecognised: "the self-hosted Remote Control surface did not recognise the presented credential"
|
|
14580
15216
|
};
|
|
14581
|
-
const unauthorized = async (response,
|
|
14582
|
-
await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[
|
|
15217
|
+
const unauthorized = async (response, refusal2) => {
|
|
15218
|
+
await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[refusal2] } });
|
|
14583
15219
|
};
|
|
14584
15220
|
const serveSessionPath = async (session, tail, request4, response) => {
|
|
14585
15221
|
const method = request4.method.toUpperCase();
|
|
@@ -14590,9 +15226,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14590
15226
|
session.lastTrafficAt = deps.now();
|
|
14591
15227
|
if (tail === "") {
|
|
14592
15228
|
if (method === "PATCH" || method === "PUT") {
|
|
14593
|
-
const
|
|
14594
|
-
if (
|
|
14595
|
-
await unauthorized(response,
|
|
15229
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15230
|
+
if (refusal2 !== void 0) {
|
|
15231
|
+
await unauthorized(response, refusal2);
|
|
14596
15232
|
return;
|
|
14597
15233
|
}
|
|
14598
15234
|
const body = parseJsonObject5(await readBody2(request4.body, CONTROL_BODY_CAP_BYTES));
|
|
@@ -14615,9 +15251,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14615
15251
|
return;
|
|
14616
15252
|
}
|
|
14617
15253
|
if (tail === "bridge" && method === "POST") {
|
|
14618
|
-
const
|
|
14619
|
-
if (
|
|
14620
|
-
await unauthorized(response,
|
|
15254
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15255
|
+
if (refusal2 !== void 0) {
|
|
15256
|
+
await unauthorized(response, refusal2);
|
|
14621
15257
|
return;
|
|
14622
15258
|
}
|
|
14623
15259
|
const workerJwt = mintWorkerJwt(deps.randomToken, deps.now());
|
|
@@ -14627,9 +15263,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14627
15263
|
return;
|
|
14628
15264
|
}
|
|
14629
15265
|
if (tail === "archive" && method === "POST") {
|
|
14630
|
-
const
|
|
14631
|
-
if (
|
|
14632
|
-
await unauthorized(response,
|
|
15266
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15267
|
+
if (refusal2 !== void 0) {
|
|
15268
|
+
await unauthorized(response, refusal2);
|
|
14633
15269
|
return;
|
|
14634
15270
|
}
|
|
14635
15271
|
retireSession(session);
|
|
@@ -14640,9 +15276,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14640
15276
|
if (tail === "worker" || tail.startsWith("worker/")) {
|
|
14641
15277
|
const workerTail = tail === "worker" ? "" : tail.slice("worker/".length);
|
|
14642
15278
|
const webProxy = workerTail === "web-fetch" || workerTail === "web-search";
|
|
14643
|
-
const
|
|
14644
|
-
if (
|
|
14645
|
-
await unauthorized(response,
|
|
15279
|
+
const refusal2 = webProxy ? workerOrCredentialRefusal(request4.headers, session) : workerRefusal(request4.headers, session);
|
|
15280
|
+
if (refusal2 !== void 0) {
|
|
15281
|
+
await unauthorized(response, refusal2);
|
|
14646
15282
|
return;
|
|
14647
15283
|
}
|
|
14648
15284
|
if (workerTail === "" && method === "GET") {
|
|
@@ -15055,102 +15691,6 @@ init_paths();
|
|
|
15055
15691
|
init_cliError();
|
|
15056
15692
|
init_schema();
|
|
15057
15693
|
init_providersStore();
|
|
15058
|
-
|
|
15059
|
-
// src/directoryRulesStore.ts
|
|
15060
|
-
init_store();
|
|
15061
|
-
init_load();
|
|
15062
|
-
init_schema();
|
|
15063
|
-
init_cliError();
|
|
15064
|
-
var DirectoryRuleNotFoundError = class extends CliError {
|
|
15065
|
-
constructor(rulePath) {
|
|
15066
|
-
super(`No directory rule found for path "${rulePath}".`);
|
|
15067
|
-
this.rulePath = rulePath;
|
|
15068
|
-
this.name = "DirectoryRuleNotFoundError";
|
|
15069
|
-
}
|
|
15070
|
-
rulePath;
|
|
15071
|
-
};
|
|
15072
|
-
var DirectoryRuleMissingTargetError = class extends CliError {
|
|
15073
|
-
constructor() {
|
|
15074
|
-
super("A directory rule must set at least one of --config-profile or --identity.");
|
|
15075
|
-
this.name = "DirectoryRuleMissingTargetError";
|
|
15076
|
-
}
|
|
15077
|
-
};
|
|
15078
|
-
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
15079
|
-
constructor(rulePath) {
|
|
15080
|
-
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
15081
|
-
this.rulePath = rulePath;
|
|
15082
|
-
this.name = "DirectoryRuleAlreadyExistsError";
|
|
15083
|
-
}
|
|
15084
|
-
rulePath;
|
|
15085
|
-
};
|
|
15086
|
-
function readDirectoryRules(paths) {
|
|
15087
|
-
return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
|
|
15088
|
-
}
|
|
15089
|
-
function writeDirectoryRules(paths, rules) {
|
|
15090
|
-
const parsed = DirectoryRulesSchema.safeParse(rules);
|
|
15091
|
-
if (!parsed.success) {
|
|
15092
|
-
throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
|
|
15093
|
-
}
|
|
15094
|
-
writeJsonAtomic(paths.directoryRulesFile, parsed.data);
|
|
15095
|
-
}
|
|
15096
|
-
function listDirectoryRules(paths) {
|
|
15097
|
-
return readDirectoryRules(paths).rules;
|
|
15098
|
-
}
|
|
15099
|
-
function addDirectoryRule(paths, rulePath, options) {
|
|
15100
|
-
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
15101
|
-
throw new DirectoryRuleMissingTargetError();
|
|
15102
|
-
}
|
|
15103
|
-
const current = readDirectoryRules(paths);
|
|
15104
|
-
if (current.rules.some((rule) => rule.path === rulePath)) {
|
|
15105
|
-
throw new DirectoryRuleAlreadyExistsError(rulePath);
|
|
15106
|
-
}
|
|
15107
|
-
const created = buildNewRule(rulePath, options);
|
|
15108
|
-
writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
|
|
15109
|
-
return created;
|
|
15110
|
-
}
|
|
15111
|
-
function ruleHasEffect(rule) {
|
|
15112
|
-
return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
|
|
15113
|
-
}
|
|
15114
|
-
function updateDirectoryRule(paths, rulePath, options) {
|
|
15115
|
-
const current = readDirectoryRules(paths);
|
|
15116
|
-
const index = current.rules.findIndex((rule) => rule.path === rulePath);
|
|
15117
|
-
const existing = index === -1 ? void 0 : current.rules[index];
|
|
15118
|
-
if (existing === void 0) {
|
|
15119
|
-
throw new DirectoryRuleNotFoundError(rulePath);
|
|
15120
|
-
}
|
|
15121
|
-
const { configProfile, identity, ...rest } = existing;
|
|
15122
|
-
const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
|
|
15123
|
-
const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
|
|
15124
|
-
const updated = {
|
|
15125
|
-
...rest,
|
|
15126
|
-
...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
|
|
15127
|
-
...nextIdentity === void 0 ? {} : { identity: nextIdentity }
|
|
15128
|
-
};
|
|
15129
|
-
if (!ruleHasEffect(updated)) {
|
|
15130
|
-
throw new DirectoryRuleMissingTargetError();
|
|
15131
|
-
}
|
|
15132
|
-
const nextRules = [...current.rules];
|
|
15133
|
-
nextRules[index] = updated;
|
|
15134
|
-
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
15135
|
-
return updated;
|
|
15136
|
-
}
|
|
15137
|
-
function buildNewRule(rulePath, options) {
|
|
15138
|
-
return {
|
|
15139
|
-
path: rulePath,
|
|
15140
|
-
...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
|
|
15141
|
-
...options.identity !== void 0 ? { identity: options.identity } : {}
|
|
15142
|
-
};
|
|
15143
|
-
}
|
|
15144
|
-
function removeDirectoryRule(paths, rulePath) {
|
|
15145
|
-
const current = readDirectoryRules(paths);
|
|
15146
|
-
const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
|
|
15147
|
-
if (nextRules.length === current.rules.length) {
|
|
15148
|
-
throw new DirectoryRuleNotFoundError(rulePath);
|
|
15149
|
-
}
|
|
15150
|
-
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
15151
|
-
}
|
|
15152
|
-
|
|
15153
|
-
// src/index.ts
|
|
15154
15694
|
init_launcher();
|
|
15155
15695
|
init_spawn();
|
|
15156
15696
|
init_launchWiring();
|
|
@@ -15264,10 +15804,44 @@ export {
|
|
|
15264
15804
|
CodexLogoutOutputSchema,
|
|
15265
15805
|
CodexSignInSchema,
|
|
15266
15806
|
CodexStatusOutputSchema,
|
|
15807
|
+
ConfigIdentityAddOutputSchema,
|
|
15808
|
+
ConfigIdentityRemoveInputSchema,
|
|
15809
|
+
ConfigIdentityRemoveOutputSchema,
|
|
15810
|
+
ConfigIdentitySetInputSchema,
|
|
15811
|
+
ConfigIdentitySetOutputSchema,
|
|
15812
|
+
ConfigIdentityUseOutputSchema,
|
|
15813
|
+
ConfigNameInputSchema,
|
|
15814
|
+
ConfigPoolAddInputSchema,
|
|
15815
|
+
ConfigPoolAddOutputSchema,
|
|
15816
|
+
ConfigPoolRemoveInputSchema,
|
|
15817
|
+
ConfigPoolRemoveOutputSchema,
|
|
15818
|
+
ConfigPoolSetInputSchema,
|
|
15819
|
+
ConfigPoolSetOutputSchema,
|
|
15820
|
+
ConfigPoolUseOutputSchema,
|
|
15821
|
+
ConfigProfileAddInputSchema,
|
|
15822
|
+
ConfigProfileAddOutputSchema,
|
|
15823
|
+
ConfigProfileRemoveInputSchema,
|
|
15824
|
+
ConfigProfileRemoveOutputSchema,
|
|
15267
15825
|
ConfigProfileSchema,
|
|
15826
|
+
ConfigProfileSetInputSchema,
|
|
15827
|
+
ConfigProfileSetOutputSchema,
|
|
15828
|
+
ConfigProfileUseOutputSchema,
|
|
15829
|
+
ConfigProviderAddInputSchema,
|
|
15830
|
+
ConfigProviderAddOutputSchema,
|
|
15831
|
+
ConfigProviderRemoveInputSchema,
|
|
15832
|
+
ConfigProviderRemoveOutputSchema,
|
|
15833
|
+
ConfigProviderSetInputSchema,
|
|
15834
|
+
ConfigProviderSetOutputSchema,
|
|
15835
|
+
ConfigRuleAddInputSchema,
|
|
15836
|
+
ConfigRuleAddOutputSchema,
|
|
15837
|
+
ConfigRuleRemoveInputSchema,
|
|
15838
|
+
ConfigRuleRemoveOutputSchema,
|
|
15839
|
+
ConfigRuleSetInputSchema,
|
|
15840
|
+
ConfigRuleSetOutputSchema,
|
|
15268
15841
|
CredentialCacheSchema,
|
|
15269
15842
|
CredentialSchema,
|
|
15270
15843
|
CredentialSourceSchema,
|
|
15844
|
+
CredentialSummarySchema2 as CredentialSummarySchema,
|
|
15271
15845
|
DOOR_EVENT_BUFFER_EVENTS,
|
|
15272
15846
|
DOOR_EVENT_SOURCE_RC,
|
|
15273
15847
|
DOOR_HEALTH_EVENT_SOURCE,
|
|
@@ -15398,6 +15972,7 @@ export {
|
|
|
15398
15972
|
collectFrontDoorStatus,
|
|
15399
15973
|
collectPoolPick,
|
|
15400
15974
|
createCodexApiRouter,
|
|
15975
|
+
createConfigApiRouter,
|
|
15401
15976
|
createControlApiRouter,
|
|
15402
15977
|
createDoorApiNodeHandler,
|
|
15403
15978
|
createDoorApiRouter,
|