claude-use 9.5.1 → 9.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/cli.cjs +40802 -23017
- package/dist/index.cjs +1327 -414
- package/dist/index.mjs +1271 -405
- package/dist/types/index.d.ts +6095 -1756
- package/package.json +2 -1
package/dist/index.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.0",
|
|
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>",
|
|
@@ -2676,6 +2690,7 @@ var init_package = __esm({
|
|
|
2676
2690
|
dependencies: {
|
|
2677
2691
|
"@anthropic-ai/claude-agent-sdk": "0.3.292",
|
|
2678
2692
|
"@clack/prompts": "^1.8.0",
|
|
2693
|
+
"@modelcontextprotocol/sdk": "1.32.0",
|
|
2679
2694
|
"@orpc/client": "2.0.0-beta.41",
|
|
2680
2695
|
"@orpc/openapi": "2.0.0-beta.41",
|
|
2681
2696
|
"@orpc/server": "2.0.0-beta.41",
|
|
@@ -3027,8 +3042,8 @@ function verifyHeadroomSocket(socketPath, ports) {
|
|
|
3027
3042
|
}
|
|
3028
3043
|
const uid = ports.currentUid();
|
|
3029
3044
|
const directory = path12.dirname(socketPath);
|
|
3030
|
-
const
|
|
3031
|
-
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 };
|
|
3032
3047
|
}
|
|
3033
3048
|
function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
3034
3049
|
const unsupported = platformRefusal(ports.platform);
|
|
@@ -3046,8 +3061,8 @@ function prepareHeadroomSocket(fs12, ports, paths, supervisorPid) {
|
|
|
3046
3061
|
return { refused: `the headroom socket directory ${paths.headroomSocketDir} is a symlink; it must be the real directory` };
|
|
3047
3062
|
}
|
|
3048
3063
|
fs12.mkdirPrivate(paths.headroomSocketDir);
|
|
3049
|
-
const
|
|
3050
|
-
return
|
|
3064
|
+
const refusal2 = ownerOnlyRefusal("socket directory", paths.headroomSocketDir, ports.lstat(paths.headroomSocketDir), "dir", ports.currentUid());
|
|
3065
|
+
return refusal2 === void 0 ? { socketPath } : { refused: refusal2 };
|
|
3051
3066
|
}
|
|
3052
3067
|
function pruneStaleHeadroomSockets(fs12, paths, isRunning) {
|
|
3053
3068
|
const removed = [];
|
|
@@ -4559,14 +4574,14 @@ function capacityOf(plan) {
|
|
|
4559
4574
|
return plan.kind === "subscription" ? plan.capacity : 1;
|
|
4560
4575
|
}
|
|
4561
4576
|
function assessRefusedNested(member, nested, nowMs) {
|
|
4562
|
-
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 };
|
|
4563
4578
|
return {
|
|
4564
4579
|
candidate: {
|
|
4565
4580
|
identity: member.identity,
|
|
4566
4581
|
class: "ineligible",
|
|
4567
|
-
...
|
|
4582
|
+
...refusal2.blockedUntilMs === void 0 ? {} : { blockedUntilMs: refusal2.blockedUntilMs },
|
|
4568
4583
|
plan: planOf(member.account),
|
|
4569
|
-
reasons: [
|
|
4584
|
+
reasons: [refusal2.reason]
|
|
4570
4585
|
}
|
|
4571
4586
|
};
|
|
4572
4587
|
}
|
|
@@ -4657,7 +4672,7 @@ function rankPool(input) {
|
|
|
4657
4672
|
const assessments = members.map((member) => ({ member, ...assess(member, nowMs) }));
|
|
4658
4673
|
const demands = assessments.flatMap(({ candidate, burn }) => burn === void 0 ? [] : [burn * capacityOf(candidate.plan)]);
|
|
4659
4674
|
const sharedDemand = demands.length === 0 ? void 0 : Math.max(...demands);
|
|
4660
|
-
const
|
|
4675
|
+
const guarded2 = assessments.map((assessment) => {
|
|
4661
4676
|
const { candidate } = assessment;
|
|
4662
4677
|
if (candidate.class === "ineligible" || assessment.member.policy === void 0) {
|
|
4663
4678
|
return assessment;
|
|
@@ -4672,7 +4687,7 @@ function rankPool(input) {
|
|
|
4672
4687
|
}
|
|
4673
4688
|
return { ...assessment, candidate: { ...candidate, class: "ineligible", reasons: [`skipped by policy (${verdict.checked.join(", ")}: did not hold)`, ...candidate.reasons] } };
|
|
4674
4689
|
});
|
|
4675
|
-
const candidates =
|
|
4690
|
+
const candidates = guarded2.map((assessment) => {
|
|
4676
4691
|
const { candidate, fiveHour, burn } = assessment;
|
|
4677
4692
|
const pace = burn ?? (sharedDemand === void 0 ? void 0 : sharedDemand / capacityOf(candidate.plan));
|
|
4678
4693
|
const { sevenDay, sevenDayBurn } = assessment;
|
|
@@ -5742,7 +5757,7 @@ function cascadeProviderName(cascade) {
|
|
|
5742
5757
|
}
|
|
5743
5758
|
return name;
|
|
5744
5759
|
}
|
|
5745
|
-
function
|
|
5760
|
+
function selectProvider(params) {
|
|
5746
5761
|
const cliName = params.cliProvider !== void 0 && params.cliProvider !== "" ? params.cliProvider : void 0;
|
|
5747
5762
|
const name = cliName ?? (params.cascade === void 0 ? void 0 : cascadeProviderName(params.cascade));
|
|
5748
5763
|
if (name === void 0) {
|
|
@@ -5757,6 +5772,14 @@ function resolveProvider(params) {
|
|
|
5757
5772
|
message: `agent-shim: no provider named "${name}". ` + (known.length > 0 ? `Known providers: ${known.join(", ")}.` : "No providers are defined yet; run `agent-shim provider add`.")
|
|
5758
5773
|
};
|
|
5759
5774
|
}
|
|
5775
|
+
return { ok: true, provider: { name, definition } };
|
|
5776
|
+
}
|
|
5777
|
+
function resolveProvider(params) {
|
|
5778
|
+
const selection = selectProvider(params);
|
|
5779
|
+
if (selection?.ok !== true) {
|
|
5780
|
+
return selection;
|
|
5781
|
+
}
|
|
5782
|
+
const { name, definition } = selection.provider;
|
|
5760
5783
|
if (params.credentials === void 0) {
|
|
5761
5784
|
return { ok: false, status: 1, message: `agent-shim: provider ${name} needs its credential resolved, but this launcher has no credential port wired` };
|
|
5762
5785
|
}
|
|
@@ -6037,6 +6060,51 @@ var init_claudeShim = __esm({
|
|
|
6037
6060
|
}
|
|
6038
6061
|
});
|
|
6039
6062
|
|
|
6063
|
+
// src/update/update.ts
|
|
6064
|
+
function compareVersions3(left, right) {
|
|
6065
|
+
const parse = (version) => {
|
|
6066
|
+
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
|
|
6067
|
+
if (match === null) {
|
|
6068
|
+
throw new Error(`not a plain release version: ${version}`);
|
|
6069
|
+
}
|
|
6070
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
6071
|
+
};
|
|
6072
|
+
const leftParts = parse(left);
|
|
6073
|
+
const rightParts = parse(right);
|
|
6074
|
+
return leftParts.map((part, index) => part - (rightParts[index] ?? 0)).find((difference) => difference !== 0) ?? 0;
|
|
6075
|
+
}
|
|
6076
|
+
function releaseTagFromUrl(url) {
|
|
6077
|
+
const segment = url.split("?")[0]?.split("/").at(-1);
|
|
6078
|
+
const candidate = segment?.startsWith("v") === true ? segment.slice(1) : void 0;
|
|
6079
|
+
return candidate !== void 0 && /^\d+\.\d+\.\d+$/.test(candidate) ? candidate : void 0;
|
|
6080
|
+
}
|
|
6081
|
+
var LATEST_RELEASE_URL, UpdateChannelError, UpdateConflictError, UpdateDownloadError;
|
|
6082
|
+
var init_update = __esm({
|
|
6083
|
+
"src/update/update.ts"() {
|
|
6084
|
+
"use strict";
|
|
6085
|
+
init_cliError();
|
|
6086
|
+
LATEST_RELEASE_URL = "https://github.com/ExaDev/agent-shim/releases/latest";
|
|
6087
|
+
UpdateChannelError = class extends CliError {
|
|
6088
|
+
constructor(message) {
|
|
6089
|
+
super(message);
|
|
6090
|
+
this.name = "UpdateChannelError";
|
|
6091
|
+
}
|
|
6092
|
+
};
|
|
6093
|
+
UpdateConflictError = class extends CliError {
|
|
6094
|
+
constructor(message) {
|
|
6095
|
+
super(message);
|
|
6096
|
+
this.name = "UpdateConflictError";
|
|
6097
|
+
}
|
|
6098
|
+
};
|
|
6099
|
+
UpdateDownloadError = class extends CliError {
|
|
6100
|
+
constructor(message) {
|
|
6101
|
+
super(message);
|
|
6102
|
+
this.name = "UpdateDownloadError";
|
|
6103
|
+
}
|
|
6104
|
+
};
|
|
6105
|
+
}
|
|
6106
|
+
});
|
|
6107
|
+
|
|
6040
6108
|
// src/frontdoor/ensure.ts
|
|
6041
6109
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6042
6110
|
function ensureFrontDoor(params) {
|
|
@@ -6442,7 +6510,7 @@ var init_headers = __esm({
|
|
|
6442
6510
|
});
|
|
6443
6511
|
|
|
6444
6512
|
// src/launcher/flags.ts
|
|
6445
|
-
import
|
|
6513
|
+
import path32 from "node:path";
|
|
6446
6514
|
function resolveLaunchFlags(params) {
|
|
6447
6515
|
return {
|
|
6448
6516
|
skipPermissions: params.flags?.skipPermissions ?? parseEnvBool("AGENT_SHIM_SKIP_PERMISSIONS", params.env.AGENT_SHIM_SKIP_PERMISSIONS) ?? params.cascade?.skipPermissions ?? false,
|
|
@@ -6473,7 +6541,7 @@ function buildEnv(params) {
|
|
|
6473
6541
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
6474
6542
|
let providerCustomHeaders;
|
|
6475
6543
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
6476
|
-
env.CLAUDE_CONFIG_DIR =
|
|
6544
|
+
env.CLAUDE_CONFIG_DIR = path32.join(params.identitiesDir, params.resolvedIdentityName);
|
|
6477
6545
|
}
|
|
6478
6546
|
if (params.provider !== void 0) {
|
|
6479
6547
|
const providerEnv = params.provider.definition.env ?? {};
|
|
@@ -6596,7 +6664,9 @@ function resolvePoolLaunch(params) {
|
|
|
6596
6664
|
}
|
|
6597
6665
|
const { pick, earliestReturn, movedOff } = graph.ranking;
|
|
6598
6666
|
if (pick !== void 0) {
|
|
6599
|
-
|
|
6667
|
+
if (params.recordPick) {
|
|
6668
|
+
recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
|
|
6669
|
+
}
|
|
6600
6670
|
const move = movedOff === void 0 ? "" : `moved off ${movedOff.identity} (${movedOff.reason}); `;
|
|
6601
6671
|
return {
|
|
6602
6672
|
ok: true,
|
|
@@ -6662,33 +6732,6 @@ var init_spawn = __esm({
|
|
|
6662
6732
|
}
|
|
6663
6733
|
});
|
|
6664
6734
|
|
|
6665
|
-
// src/update/update.ts
|
|
6666
|
-
function compareVersions3(left, right) {
|
|
6667
|
-
const parse = (version) => {
|
|
6668
|
-
const match = /^(\d+)\.(\d+)\.(\d+)$/.exec(version);
|
|
6669
|
-
if (match === null) {
|
|
6670
|
-
throw new Error(`not a plain release version: ${version}`);
|
|
6671
|
-
}
|
|
6672
|
-
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
6673
|
-
};
|
|
6674
|
-
const leftParts = parse(left);
|
|
6675
|
-
const rightParts = parse(right);
|
|
6676
|
-
return leftParts.map((part, index) => part - (rightParts[index] ?? 0)).find((difference) => difference !== 0) ?? 0;
|
|
6677
|
-
}
|
|
6678
|
-
function releaseTagFromUrl(url) {
|
|
6679
|
-
const segment = url.split("?")[0]?.split("/").at(-1);
|
|
6680
|
-
const candidate = segment?.startsWith("v") === true ? segment.slice(1) : void 0;
|
|
6681
|
-
return candidate !== void 0 && /^\d+\.\d+\.\d+$/.test(candidate) ? candidate : void 0;
|
|
6682
|
-
}
|
|
6683
|
-
var LATEST_RELEASE_URL;
|
|
6684
|
-
var init_update = __esm({
|
|
6685
|
-
"src/update/update.ts"() {
|
|
6686
|
-
"use strict";
|
|
6687
|
-
init_cliError();
|
|
6688
|
-
LATEST_RELEASE_URL = "https://github.com/ExaDev/agent-shim/releases/latest";
|
|
6689
|
-
}
|
|
6690
|
-
});
|
|
6691
|
-
|
|
6692
6735
|
// src/update/launchHook.ts
|
|
6693
6736
|
function resolveUpdateMode(globalConfig) {
|
|
6694
6737
|
return globalConfig?.update?.mode ?? "off";
|
|
@@ -6760,7 +6803,7 @@ var init_launchHook = __esm({
|
|
|
6760
6803
|
|
|
6761
6804
|
// src/launcher.ts
|
|
6762
6805
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
6763
|
-
import
|
|
6806
|
+
import path33 from "node:path";
|
|
6764
6807
|
function resolveIdentityCredential(identity, credential, env, port) {
|
|
6765
6808
|
if (port === void 0) {
|
|
6766
6809
|
return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
|
|
@@ -6768,7 +6811,7 @@ function resolveIdentityCredential(identity, credential, env, port) {
|
|
|
6768
6811
|
const resolution = resolveCredential({ credential, env, port, subject: `identity ${identity}` });
|
|
6769
6812
|
return resolution.ok ? resolution : { ok: false, status: CREDENTIAL_UNAVAILABLE_EXIT, message: resolution.message };
|
|
6770
6813
|
}
|
|
6771
|
-
function pickFromPool(decided, params, parsedArgv) {
|
|
6814
|
+
function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
6772
6815
|
const { paths, fs: fs12, proc, log } = params;
|
|
6773
6816
|
if (decided.pool === void 0) {
|
|
6774
6817
|
return { identityDecision: decided };
|
|
@@ -6789,7 +6832,9 @@ function pickFromPool(decided, params, parsedArgv) {
|
|
|
6789
6832
|
now: farmRuntime.now,
|
|
6790
6833
|
sleep: farmRuntime.lock.sleep,
|
|
6791
6834
|
passthrough: parsedArgv.rest,
|
|
6792
|
-
|
|
6835
|
+
// A read-only decision never sleeps for a refused pool and never records its pick, so asking what a launch would pick leaves the next real launch's keep-warm preference as it was.
|
|
6836
|
+
wait: !readOnly && parsedArgv.wait === true,
|
|
6837
|
+
recordPick: !readOnly,
|
|
6793
6838
|
log
|
|
6794
6839
|
});
|
|
6795
6840
|
if (!resolution.ok) {
|
|
@@ -6802,7 +6847,7 @@ function pickFromPool(decided, params, parsedArgv) {
|
|
|
6802
6847
|
poolPick: { name: decided.pool, reasons: resolution.reasons, ...resolution.movedOff === void 0 ? {} : { movedOff: resolution.movedOff } }
|
|
6803
6848
|
};
|
|
6804
6849
|
}
|
|
6805
|
-
function
|
|
6850
|
+
function decideLaunch(params, readOnly) {
|
|
6806
6851
|
const { paths, fs: fs12, proc, log } = params;
|
|
6807
6852
|
const { env, argv } = proc;
|
|
6808
6853
|
const parsedArgv = parseLauncherArgv(argv);
|
|
@@ -6826,10 +6871,10 @@ function prepareLaunch(params) {
|
|
|
6826
6871
|
return trimmed === "" ? void 0 : trimmed;
|
|
6827
6872
|
}
|
|
6828
6873
|
});
|
|
6829
|
-
const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv);
|
|
6874
|
+
const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv, readOnly);
|
|
6830
6875
|
const farmIdentity = configDirEscapeHatchApplies ? void 0 : identityDecision.name;
|
|
6831
6876
|
const farm = farmIdentity === void 0 ? void 0 : params.farm;
|
|
6832
|
-
if (farm !== void 0 && farmIdentity !== void 0) {
|
|
6877
|
+
if (!readOnly && farm !== void 0 && farmIdentity !== void 0) {
|
|
6833
6878
|
let recovery;
|
|
6834
6879
|
try {
|
|
6835
6880
|
recovery = recoverFarm({
|
|
@@ -6868,33 +6913,44 @@ function prepareLaunch(params) {
|
|
|
6868
6913
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
6869
6914
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
6870
6915
|
});
|
|
6871
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(
|
|
6916
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(path33.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
6872
6917
|
log.error(
|
|
6873
6918
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
6874
6919
|
);
|
|
6875
6920
|
proc.exit(1);
|
|
6876
6921
|
}
|
|
6877
6922
|
const farmContext = farm !== void 0 && farmIdentity !== void 0 ? { farm, identity: farmIdentity, cascade: farm.loadCascade(configProfileDecision.name, cliOverride) } : void 0;
|
|
6878
|
-
const
|
|
6923
|
+
const providerParams = {
|
|
6879
6924
|
paths,
|
|
6880
6925
|
port: fs12,
|
|
6881
|
-
|
|
6882
|
-
...params.credentials === void 0 ? {} : { credentials: params.credentials },
|
|
6883
|
-
...parsedArgv.provider === void 0 ? {} : { cliProvider: parsedArgv.provider },
|
|
6926
|
+
...parsedArgv.provider === void 0 || parsedArgv.provider === false ? {} : { cliProvider: parsedArgv.provider },
|
|
6884
6927
|
...farmContext === void 0 ? {} : { cascade: farmContext.cascade }
|
|
6885
|
-
}
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6928
|
+
};
|
|
6929
|
+
let selectedProvider;
|
|
6930
|
+
let resolvedProvider;
|
|
6931
|
+
if (parsedArgv.provider !== false && readOnly) {
|
|
6932
|
+
const selection = selectProvider(providerParams);
|
|
6933
|
+
if (selection !== void 0 && !selection.ok) {
|
|
6934
|
+
log.error(selection.message);
|
|
6935
|
+
proc.exit(selection.status);
|
|
6936
|
+
}
|
|
6937
|
+
selectedProvider = selection?.ok === true ? selection.provider : void 0;
|
|
6938
|
+
} else if (parsedArgv.provider !== false) {
|
|
6939
|
+
const provider = resolveProvider({ ...providerParams, env, ...params.credentials === void 0 ? {} : { credentials: params.credentials } });
|
|
6940
|
+
if (provider !== void 0 && !provider.ok) {
|
|
6941
|
+
log.error(provider.message);
|
|
6942
|
+
proc.exit(provider.status);
|
|
6943
|
+
}
|
|
6944
|
+
resolvedProvider = provider?.ok === true ? provider.provider : void 0;
|
|
6945
|
+
selectedProvider = resolvedProvider;
|
|
6946
|
+
for (const warning of provider?.ok === true ? provider.warnings : []) {
|
|
6947
|
+
log.warn(warning);
|
|
6948
|
+
}
|
|
6893
6949
|
}
|
|
6894
6950
|
if (farm !== void 0 && farmIdentity !== void 0) {
|
|
6895
6951
|
try {
|
|
6896
6952
|
const snapshot = readUsageSnapshot(farm.fs, paths.usageSnapshotsDir, farmIdentity);
|
|
6897
|
-
for (const warning of quotaWarnings(snapshot,
|
|
6953
|
+
for (const warning of quotaWarnings(snapshot, selectedProvider?.name ?? ANTHROPIC_PROVIDER, farm.now())) {
|
|
6898
6954
|
log.warn(warning);
|
|
6899
6955
|
}
|
|
6900
6956
|
} catch (error) {
|
|
@@ -6904,8 +6960,8 @@ function prepareLaunch(params) {
|
|
|
6904
6960
|
log.warn(`agent-shim: ${error.message}`);
|
|
6905
6961
|
}
|
|
6906
6962
|
}
|
|
6907
|
-
const identityCredentialBlock = loadedIdentity?.config.credential;
|
|
6908
|
-
const identityResolution =
|
|
6963
|
+
const identityCredentialBlock = selectedProvider === void 0 && farmIdentity !== void 0 ? loadedIdentity?.config.credential : void 0;
|
|
6964
|
+
const identityResolution = !readOnly && identityCredentialBlock !== void 0 && farmIdentity !== void 0 ? resolveIdentityCredential(farmIdentity, identityCredentialBlock, env, params.credentials) : void 0;
|
|
6909
6965
|
if (identityResolution !== void 0 && !identityResolution.ok) {
|
|
6910
6966
|
log.error(identityResolution.message);
|
|
6911
6967
|
proc.exit(identityResolution.status);
|
|
@@ -6919,25 +6975,97 @@ function prepareLaunch(params) {
|
|
|
6919
6975
|
allowAmbientCredential: loadedIdentity?.config.allowAmbientCredential ?? false,
|
|
6920
6976
|
allowAmbientCredentialOverride: parseEnvBool("AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL", env.AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL) === true,
|
|
6921
6977
|
identityName: identityDecision.name,
|
|
6922
|
-
providerSelected:
|
|
6978
|
+
providerSelected: selectedProvider !== void 0,
|
|
6923
6979
|
...identityCredential === void 0 ? {} : { injectedCredential: { variable: CREDENTIAL_TARGET_VARS[identityCredential.target], token: identityCredential.token } }
|
|
6924
6980
|
});
|
|
6925
6981
|
if (!guardResult.ok) {
|
|
6926
|
-
|
|
6927
|
-
|
|
6982
|
+
if (readOnly && identityCredentialBlock !== void 0) {
|
|
6983
|
+
log.warn(`${guardResult.message} (not resolved here: the launch proceeds only if that value is the identity's own injected credential)`);
|
|
6984
|
+
} else {
|
|
6985
|
+
log.error(guardResult.message);
|
|
6986
|
+
proc.exit(1);
|
|
6987
|
+
}
|
|
6988
|
+
}
|
|
6989
|
+
const launchCascade = farmContext?.cascade ?? (params.farm === void 0 ? void 0 : params.farm.loadCascade(configProfileDecision.name, cliOverride));
|
|
6990
|
+
let cascadeLaunch;
|
|
6991
|
+
if (launchCascade !== void 0 && params.farm !== void 0) {
|
|
6992
|
+
const assembled = assembleCascade(launchCascade);
|
|
6993
|
+
const flattened = flattenLayers(assembled.layers, { home: params.farm.home });
|
|
6994
|
+
cascadeLaunch = flattened.launch;
|
|
6995
|
+
if (readOnly) {
|
|
6996
|
+
for (const diagnostic of [...assembled.diagnostics, ...flattened.diagnostics]) {
|
|
6997
|
+
if (diagnostic.severity !== "info") {
|
|
6998
|
+
log.warn(`agent-shim: ${diagnostic.code}: ${diagnostic.message}`);
|
|
6999
|
+
}
|
|
7000
|
+
}
|
|
7001
|
+
}
|
|
6928
7002
|
}
|
|
7003
|
+
const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
|
|
7004
|
+
const discovered = params.resolveClaudeBinary(pinnedVersion === void 0 ? void 0 : { version: pinnedVersion.version });
|
|
7005
|
+
const flags = resolveLaunchFlags({
|
|
7006
|
+
env,
|
|
7007
|
+
// A pool pick reads the usage the front door records, so a pool launch records its own unless something says otherwise.
|
|
7008
|
+
...poolExplanation === void 0 ? {} : { trackUsageDefault: true },
|
|
7009
|
+
...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
|
|
7010
|
+
flags: {
|
|
7011
|
+
...parsedArgv.skipPermissions === void 0 ? {} : { skipPermissions: parsedArgv.skipPermissions },
|
|
7012
|
+
...parsedArgv.remoteControl === void 0 ? {} : { remoteControl: parsedArgv.remoteControl },
|
|
7013
|
+
...parsedArgv.headroom === void 0 ? {} : { headroom: parsedArgv.headroom },
|
|
7014
|
+
...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
|
|
7015
|
+
}
|
|
7016
|
+
});
|
|
7017
|
+
const args = buildArgv({
|
|
7018
|
+
toolFlags: buildFlagArgs(flags),
|
|
7019
|
+
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
7020
|
+
passthrough: parsedArgv.rest
|
|
7021
|
+
});
|
|
7022
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path33.join(paths.identitiesDir, identityDecision.name);
|
|
7023
|
+
const decision = {
|
|
7024
|
+
identitySource: identityDecision.source,
|
|
7025
|
+
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
7026
|
+
configProfileSource: configProfileDecision.source,
|
|
7027
|
+
...identityDecision.name === void 0 ? {} : { identity: identityDecision.name },
|
|
7028
|
+
...poolPick === void 0 ? {} : { pool: poolPick },
|
|
7029
|
+
...configDir === void 0 || configDir === "" ? {} : { configDir },
|
|
7030
|
+
...configProfileDecision.name === void 0 ? {} : { configProfile: configProfileDecision.name },
|
|
7031
|
+
...selectedProvider === void 0 ? {} : { provider: selectedProvider.name }
|
|
7032
|
+
};
|
|
7033
|
+
return {
|
|
7034
|
+
parsedArgv,
|
|
7035
|
+
identityDecision,
|
|
7036
|
+
poolExplanation,
|
|
7037
|
+
poolPick,
|
|
7038
|
+
configDirEscapeHatch: configDirEscapeHatchApplies,
|
|
7039
|
+
farmIdentity,
|
|
7040
|
+
farmContext,
|
|
7041
|
+
configProfileDecision,
|
|
7042
|
+
provider: selectedProvider,
|
|
7043
|
+
resolvedProvider,
|
|
7044
|
+
identityCredentialBlock,
|
|
7045
|
+
identityCredential,
|
|
7046
|
+
pinnedVersion,
|
|
7047
|
+
flags,
|
|
7048
|
+
bin: discovered.path,
|
|
7049
|
+
args,
|
|
7050
|
+
decision
|
|
7051
|
+
};
|
|
7052
|
+
}
|
|
7053
|
+
function prepareLaunch(params) {
|
|
7054
|
+
const { paths, proc, log } = params;
|
|
7055
|
+
const { env } = proc;
|
|
7056
|
+
const decided = decideLaunch(params, false);
|
|
7057
|
+
const { identityDecision, configProfileDecision, resolvedProvider, identityCredential, poolExplanation, flags: resolvedFlags, args: finalArgv, configDirEscapeHatch: configDirEscapeHatchApplies, decision } = decided;
|
|
6929
7058
|
log.info(
|
|
6930
7059
|
`agent-shim: identity ${identityDecision.name ?? "(none)"} (${identityDecision.source}${poolExplanation === void 0 ? "" : `, ${poolExplanation}`}), config profile ${configProfileDecision.name ?? "(none)"} (${configProfileDecision.source})` + (resolvedProvider === void 0 ? "" : `, provider ${resolvedProvider.name} (credential ${resolvedProvider.credential.target} from ${describeSource(resolvedProvider.credential.source)})`) + (identityCredential === void 0 ? "" : `, identity credential ${identityCredential.target} from ${describeSource(identityCredential.source)}`)
|
|
6931
7060
|
);
|
|
6932
7061
|
const updateCheck = runLaunchUpdateCheck({
|
|
6933
7062
|
mode: params.updateMode ?? "off",
|
|
6934
|
-
checkPath:
|
|
7063
|
+
checkPath: path33.join(paths.root, "update.check"),
|
|
6935
7064
|
currentVersion: package_default.version,
|
|
6936
7065
|
port: params.update
|
|
6937
7066
|
});
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = farmContext;
|
|
7067
|
+
if (decided.farmContext !== void 0) {
|
|
7068
|
+
const { farm: resyncFarmRuntime, identity: resyncIdentity, cascade } = decided.farmContext;
|
|
6941
7069
|
let result;
|
|
6942
7070
|
try {
|
|
6943
7071
|
result = resyncFarm({
|
|
@@ -6974,27 +7102,10 @@ function prepareLaunch(params) {
|
|
|
6974
7102
|
log.info(
|
|
6975
7103
|
result.noOp ? `agent-shim: farm at ${result.farmRoot} already matches the resolved cascade` : `agent-shim: farm at ${result.farmRoot} resynced (${String(result.manifest.links.length)} link(s), ${String(result.manifest.materialised.length)} built director(ies)${result.adopted.length === 0 ? "" : `, ${String(result.adopted.length)} adopted into ${resyncFarmRuntime.claudeHome}`})`
|
|
6976
7104
|
);
|
|
6977
|
-
cascadeLaunch = result.resolved.flattened.launch;
|
|
6978
|
-
} else if (params.farm !== void 0) {
|
|
6979
|
-
cascadeLaunch = flattenLayers(assembleCascade(params.farm.loadCascade(configProfileDecision.name, cliOverride)).layers, { home: params.farm.home }).launch;
|
|
6980
7105
|
}
|
|
6981
|
-
|
|
6982
|
-
|
|
6983
|
-
if (pinnedVersion !== void 0) {
|
|
6984
|
-
log.info(`agent-shim: Claude Code ${pinnedVersion.version} (pinned by ${pinnedVersion.source})`);
|
|
7106
|
+
if (decided.pinnedVersion !== void 0) {
|
|
7107
|
+
log.info(`agent-shim: Claude Code ${decided.pinnedVersion.version} (pinned by ${decided.pinnedVersion.source})`);
|
|
6985
7108
|
}
|
|
6986
|
-
const resolvedFlags = resolveLaunchFlags({
|
|
6987
|
-
env,
|
|
6988
|
-
// A pool pick reads the usage the front door records, so a pool launch records its own unless something says otherwise.
|
|
6989
|
-
...poolExplanation === void 0 ? {} : { trackUsageDefault: true },
|
|
6990
|
-
...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
|
|
6991
|
-
flags: {
|
|
6992
|
-
...parsedArgv.skipPermissions === void 0 ? {} : { skipPermissions: parsedArgv.skipPermissions },
|
|
6993
|
-
...parsedArgv.remoteControl === void 0 ? {} : { remoteControl: parsedArgv.remoteControl },
|
|
6994
|
-
...parsedArgv.headroom === void 0 ? {} : { headroom: parsedArgv.headroom },
|
|
6995
|
-
...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
|
|
6996
|
-
}
|
|
6997
|
-
});
|
|
6998
7109
|
const frontDoorPort = params.frontdoor;
|
|
6999
7110
|
const frontDoorEngaged = resolvedProvider !== void 0 || resolvedFlags.headroom || resolvedFlags.trackUsage;
|
|
7000
7111
|
if (frontDoorEngaged && frontDoorPort === void 0) {
|
|
@@ -7018,11 +7129,6 @@ function prepareLaunch(params) {
|
|
|
7018
7129
|
log.info(`agent-shim: routing through the front door on 127.0.0.1:${String(frontDoor.port)}${resolvedProvider === void 0 ? ` (OAuth via the door's CONNECT surface on 127.0.0.1:${String(frontDoor.connectPort)}, usage recorded)` : ` (provider ${resolvedProvider.name})`}`);
|
|
7019
7130
|
}
|
|
7020
7131
|
const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
|
|
7021
|
-
const finalArgv = buildArgv({
|
|
7022
|
-
toolFlags: buildFlagArgs(resolvedFlags),
|
|
7023
|
-
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
7024
|
-
passthrough: parsedArgv.rest
|
|
7025
|
-
});
|
|
7026
7132
|
const finalEnv = buildEnv({
|
|
7027
7133
|
baseEnv: env,
|
|
7028
7134
|
configDirEscapeHatch: configDirEscapeHatchApplies,
|
|
@@ -7040,18 +7146,35 @@ function prepareLaunch(params) {
|
|
|
7040
7146
|
registered();
|
|
7041
7147
|
}
|
|
7042
7148
|
};
|
|
7043
|
-
|
|
7044
|
-
|
|
7045
|
-
|
|
7046
|
-
|
|
7047
|
-
|
|
7048
|
-
|
|
7049
|
-
|
|
7050
|
-
|
|
7051
|
-
|
|
7052
|
-
|
|
7149
|
+
return { bin: decided.bin, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
|
|
7150
|
+
}
|
|
7151
|
+
function resolveLaunch(params) {
|
|
7152
|
+
const decided = decideLaunch(params, true);
|
|
7153
|
+
const { env } = params.proc;
|
|
7154
|
+
const frontDoor = decided.provider !== void 0 || decided.flags.headroom || decided.flags.trackUsage;
|
|
7155
|
+
const built = buildEnv({
|
|
7156
|
+
baseEnv: env,
|
|
7157
|
+
configDirEscapeHatch: decided.configDirEscapeHatch,
|
|
7158
|
+
resolvedIdentityName: decided.identityDecision.name,
|
|
7159
|
+
identitiesDir: params.paths.identitiesDir,
|
|
7160
|
+
...decided.provider === void 0 ? {} : { provider: decided.provider },
|
|
7161
|
+
...frontDoor ? { frontdoor: { port: 0, connectPort: 0, trustBundlePath: "", sessionToken: "" } } : {},
|
|
7162
|
+
...decided.flags.headroom ? { headroom: { socketPath: "", projectId: "" } } : {},
|
|
7163
|
+
sessionId: ""
|
|
7164
|
+
});
|
|
7165
|
+
const credentialNames = decided.identityCredentialBlock === void 0 ? [] : Object.keys(credentialVariables(decided.identityCredentialBlock.target ?? "bearer", ""));
|
|
7166
|
+
const environment = [.../* @__PURE__ */ new Set([...Object.keys(built).filter((name) => built[name] !== env[name]), ...credentialNames])].sort();
|
|
7167
|
+
const credential = decided.provider !== void 0 ? { subject: "provider", name: decided.provider.name, summary: summariseCredential(decided.provider.definition.credential) } : decided.identityCredentialBlock !== void 0 && decided.farmIdentity !== void 0 ? { subject: "identity", name: decided.farmIdentity, summary: summariseCredential(decided.identityCredentialBlock) } : void 0;
|
|
7168
|
+
return {
|
|
7169
|
+
decision: decided.decision,
|
|
7170
|
+
flags: decided.flags,
|
|
7171
|
+
...decided.pinnedVersion === void 0 ? {} : { claudeVersion: decided.pinnedVersion },
|
|
7172
|
+
bin: decided.bin,
|
|
7173
|
+
args: decided.args,
|
|
7174
|
+
...credential === void 0 ? {} : { credential },
|
|
7175
|
+
routing: { frontDoor, headroom: decided.flags.headroom },
|
|
7176
|
+
environment
|
|
7053
7177
|
};
|
|
7054
|
-
return { bin: discovered.path, args: finalArgv, env: finalEnv, release, markChildStarted: updateCheck.markChildStarted, decision };
|
|
7055
7178
|
}
|
|
7056
7179
|
function runLaunchPlan(plan, spawn2) {
|
|
7057
7180
|
try {
|
|
@@ -7097,12 +7220,12 @@ var init_launcher = __esm({
|
|
|
7097
7220
|
});
|
|
7098
7221
|
|
|
7099
7222
|
// src/ownCli.ts
|
|
7100
|
-
import
|
|
7223
|
+
import path34 from "node:path";
|
|
7101
7224
|
function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
|
|
7102
7225
|
if (distDir === void 0) {
|
|
7103
7226
|
throw new OwnCliPathUnknownError();
|
|
7104
7227
|
}
|
|
7105
|
-
return
|
|
7228
|
+
return path34.join(distDir, OWN_CLI_FILE_NAME);
|
|
7106
7229
|
}
|
|
7107
7230
|
var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
7108
7231
|
var init_ownCli = __esm({
|
|
@@ -7191,10 +7314,10 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
|
|
|
7191
7314
|
|
|
7192
7315
|
// src/frontdoor/trust.ts
|
|
7193
7316
|
import { createHash as createHash6 } from "node:crypto";
|
|
7194
|
-
import
|
|
7317
|
+
import path35 from "node:path";
|
|
7195
7318
|
function resolveTrustBundle(params) {
|
|
7196
7319
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
|
|
7197
|
-
if (inherited === void 0 || inherited === "" ||
|
|
7320
|
+
if (inherited === void 0 || inherited === "" || path35.resolve(inherited) === path35.resolve(caCertFile)) {
|
|
7198
7321
|
return { path: caCertFile };
|
|
7199
7322
|
}
|
|
7200
7323
|
const caPem = fs12.readFileUtf8(caCertFile);
|
|
@@ -7212,7 +7335,7 @@ function resolveTrustBundle(params) {
|
|
|
7212
7335
|
}
|
|
7213
7336
|
const combined = `${inheritedPem.trimEnd()}
|
|
7214
7337
|
${caPem}`;
|
|
7215
|
-
const bundle =
|
|
7338
|
+
const bundle = path35.join(bundlesDir, `${createHash6("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
7216
7339
|
if (!fs12.exists(bundle)) {
|
|
7217
7340
|
fs12.mkdirp(bundlesDir);
|
|
7218
7341
|
fs12.writeFileAtomic(bundle, combined);
|
|
@@ -7369,6 +7492,31 @@ function prepareClaudeLaunch(options) {
|
|
|
7369
7492
|
const spawnDaemon = daemonSpawnerFor(options.agentShim);
|
|
7370
7493
|
return prepareLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) }));
|
|
7371
7494
|
}
|
|
7495
|
+
function resolveClaudeLaunch(options) {
|
|
7496
|
+
const paths = options.paths ?? resolveLayoutPaths();
|
|
7497
|
+
const refusals = [];
|
|
7498
|
+
const warnings = [];
|
|
7499
|
+
const log = {
|
|
7500
|
+
info: () => void 0,
|
|
7501
|
+
warn: (message) => {
|
|
7502
|
+
warnings.push(message);
|
|
7503
|
+
},
|
|
7504
|
+
error: (message) => {
|
|
7505
|
+
refusals.push(message);
|
|
7506
|
+
}
|
|
7507
|
+
};
|
|
7508
|
+
const proc = {
|
|
7509
|
+
env: options.env,
|
|
7510
|
+
argv: options.argv,
|
|
7511
|
+
exit: (code) => {
|
|
7512
|
+
throw new LaunchRefusedError(refusals.join("\n") || `the launch was refused (exit ${String(code)})`, code);
|
|
7513
|
+
}
|
|
7514
|
+
};
|
|
7515
|
+
const spawnDaemon = () => {
|
|
7516
|
+
throw new Error("resolving a launch starts no daemon");
|
|
7517
|
+
};
|
|
7518
|
+
return { resolution: resolveLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) })), warnings };
|
|
7519
|
+
}
|
|
7372
7520
|
var LaunchRefusedError;
|
|
7373
7521
|
var init_launchWiring = __esm({
|
|
7374
7522
|
"src/launchWiring.ts"() {
|
|
@@ -7535,7 +7683,7 @@ var init_anthropicUsageRefresh = __esm({
|
|
|
7535
7683
|
});
|
|
7536
7684
|
|
|
7537
7685
|
// src/usage/providerQuota.ts
|
|
7538
|
-
import { z as
|
|
7686
|
+
import { z as z23 } from "zod";
|
|
7539
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;
|
|
7540
7688
|
var init_providerQuota = __esm({
|
|
7541
7689
|
"src/usage/providerQuota.ts"() {
|
|
@@ -7553,35 +7701,35 @@ var init_providerQuota = __esm({
|
|
|
7553
7701
|
[ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
|
|
7554
7702
|
[ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7]
|
|
7555
7703
|
]);
|
|
7556
|
-
ZaiLimitSchema =
|
|
7557
|
-
type:
|
|
7558
|
-
unit:
|
|
7559
|
-
number:
|
|
7560
|
-
percentage:
|
|
7561
|
-
nextResetTime:
|
|
7562
|
-
usage:
|
|
7563
|
-
currentValue:
|
|
7564
|
-
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()
|
|
7565
7713
|
});
|
|
7566
|
-
ZaiResponseSchema =
|
|
7567
|
-
success:
|
|
7568
|
-
msg:
|
|
7569
|
-
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) })
|
|
7570
7718
|
});
|
|
7571
7719
|
OPENROUTER_HOST = "openrouter.ai";
|
|
7572
7720
|
OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
7573
7721
|
OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
7574
7722
|
MS_PER_DAY3 = HOURS_PER_DAY3 * SECONDS_PER_HOUR * MS_PER_SECOND7;
|
|
7575
|
-
OpenRouterKeySchema =
|
|
7576
|
-
data:
|
|
7577
|
-
limit:
|
|
7578
|
-
limit_remaining:
|
|
7579
|
-
limit_reset:
|
|
7580
|
-
is_free_tier:
|
|
7581
|
-
free_model_daily_requests:
|
|
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()
|
|
7582
7730
|
})
|
|
7583
7731
|
});
|
|
7584
|
-
OpenRouterCreditsSchema =
|
|
7732
|
+
OpenRouterCreditsSchema = z23.object({ data: z23.object({ total_credits: z23.number().nonnegative(), total_usage: z23.number().nonnegative() }) });
|
|
7585
7733
|
}
|
|
7586
7734
|
});
|
|
7587
7735
|
|
|
@@ -8197,8 +8345,8 @@ function parseConnectTarget(authority) {
|
|
|
8197
8345
|
function isInterceptedHost(host, interceptHosts) {
|
|
8198
8346
|
return interceptHosts.includes(host);
|
|
8199
8347
|
}
|
|
8200
|
-
function servedByPipeline(
|
|
8201
|
-
return
|
|
8348
|
+
function servedByPipeline(path36) {
|
|
8349
|
+
return path36?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
8202
8350
|
}
|
|
8203
8351
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
8204
8352
|
"connection",
|
|
@@ -8559,6 +8707,7 @@ var HTTP_STATUS = {
|
|
|
8559
8707
|
forbidden: 403,
|
|
8560
8708
|
notFound: 404,
|
|
8561
8709
|
methodNotAllowed: 405,
|
|
8710
|
+
conflict: 409,
|
|
8562
8711
|
payloadTooLarge: 413,
|
|
8563
8712
|
tooManyRequests: 429,
|
|
8564
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. */
|
|
@@ -8732,11 +8881,11 @@ function createRcSessionTracker(deps) {
|
|
|
8732
8881
|
};
|
|
8733
8882
|
const observeExchange = (request4) => {
|
|
8734
8883
|
const method = (request4.method ?? "").toUpperCase();
|
|
8735
|
-
const
|
|
8736
|
-
if (!
|
|
8884
|
+
const path36 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
8885
|
+
if (!path36.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
8737
8886
|
return void 0;
|
|
8738
8887
|
}
|
|
8739
|
-
const tail =
|
|
8888
|
+
const tail = path36.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
8740
8889
|
const facts = {
|
|
8741
8890
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
8742
8891
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -9118,8 +9267,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
9118
9267
|
function isRcReadFileEncoding(value) {
|
|
9119
9268
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
9120
9269
|
}
|
|
9121
|
-
function buildRcReadFilePayload(requestId,
|
|
9122
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
9270
|
+
function buildRcReadFilePayload(requestId, path36, options) {
|
|
9271
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path36, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
9123
9272
|
}
|
|
9124
9273
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
9125
9274
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -9221,15 +9370,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
9221
9370
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
9222
9371
|
return result.ok ? { ...result, requestId } : result;
|
|
9223
9372
|
}
|
|
9224
|
-
async function readRcSessionFile(deps, sessionId,
|
|
9225
|
-
if (
|
|
9373
|
+
async function readRcSessionFile(deps, sessionId, path36, options) {
|
|
9374
|
+
if (path36 === "") {
|
|
9226
9375
|
return { ok: false, message: "a read-file write needs a non-empty path: the SDK's own field names the file the worker resolves against the session's cwd, and an empty string names none" };
|
|
9227
9376
|
}
|
|
9228
9377
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
9229
9378
|
return { ok: false, message: "a read-file write's max-bytes is a positive whole number of bytes: the SDK's own field caps the read, and a zero or negative cap reads nothing" };
|
|
9230
9379
|
}
|
|
9231
9380
|
const requestId = deps.newUuid();
|
|
9232
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
9381
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path36, options), `read ${path36} from session ${sessionId}`);
|
|
9233
9382
|
return result.ok ? { ...result, requestId } : result;
|
|
9234
9383
|
}
|
|
9235
9384
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -9398,11 +9547,11 @@ function createRcControlHandler(deps) {
|
|
|
9398
9547
|
path: "read-file",
|
|
9399
9548
|
read: (body) => {
|
|
9400
9549
|
const session = bodyString(body, "session");
|
|
9401
|
-
const
|
|
9550
|
+
const path36 = bodyString(body, "path");
|
|
9402
9551
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
9403
9552
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
9404
|
-
const refused2 = session === void 0 ||
|
|
9405
|
-
return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session,
|
|
9553
|
+
const refused2 = session === void 0 || path36 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
9554
|
+
return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path36, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
|
|
9406
9555
|
}
|
|
9407
9556
|
},
|
|
9408
9557
|
{
|
|
@@ -9712,9 +9861,9 @@ function requestIdOfBody(body) {
|
|
|
9712
9861
|
}
|
|
9713
9862
|
function frontDoorRcControl(transport, token) {
|
|
9714
9863
|
const headers = { authorization: `Bearer ${token}` };
|
|
9715
|
-
const listAnswerOf = async (
|
|
9864
|
+
const listAnswerOf = async (path36, what) => {
|
|
9716
9865
|
try {
|
|
9717
|
-
return await transport.request({ method: "GET", path:
|
|
9866
|
+
return await transport.request({ method: "GET", path: path36, headers });
|
|
9718
9867
|
} catch (error) {
|
|
9719
9868
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
9720
9869
|
}
|
|
@@ -9786,10 +9935,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
9786
9935
|
}
|
|
9787
9936
|
return pending;
|
|
9788
9937
|
};
|
|
9789
|
-
const writeOf = async (
|
|
9938
|
+
const writeOf = async (path36, body, describeFailure) => {
|
|
9790
9939
|
let answer;
|
|
9791
9940
|
try {
|
|
9792
|
-
answer = await transport.request({ method: "POST", path:
|
|
9941
|
+
answer = await transport.request({ method: "POST", path: path36, headers: { ...headers, "content-type": "application/json" }, body });
|
|
9793
9942
|
} catch (error) {
|
|
9794
9943
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
9795
9944
|
}
|
|
@@ -9820,10 +9969,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
9820
9969
|
endSession: async (sessionId, reason) => await writeOf(`${CONTROL_PATH_PREFIX}/end-session`, JSON.stringify({ session: sessionId, ...reason === void 0 ? {} : { reason } }), (status, message) => `ending ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
9821
9970
|
getUsage: async (sessionId, skipBehaviors) => await writeOf(`${CONTROL_PATH_PREFIX}/get-usage`, JSON.stringify({ session: sessionId, ...skipBehaviors === void 0 ? {} : { skipBehaviors } }), (status, message) => `requesting the usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
9822
9971
|
getContextUsage: async (sessionId, detail) => await writeOf(`${CONTROL_PATH_PREFIX}/get-context-usage`, JSON.stringify({ session: sessionId, ...detail === void 0 ? {} : { detail } }), (status, message) => `requesting the context usage of ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
9823
|
-
readFile: async (sessionId,
|
|
9972
|
+
readFile: async (sessionId, path36, options) => await writeOf(
|
|
9824
9973
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
9825
|
-
JSON.stringify({ session: sessionId, path:
|
|
9826
|
-
(status, message) => `reading ${
|
|
9974
|
+
JSON.stringify({ session: sessionId, path: path36, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
9975
|
+
(status, message) => `reading ${path36} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
9827
9976
|
),
|
|
9828
9977
|
fileSuggestions: async (sessionId, query) => await writeOf(`${CONTROL_PATH_PREFIX}/file-suggestions`, JSON.stringify({ session: sessionId, query }), (status, message) => `requesting file suggestions from ${sessionId} failed (HTTP ${String(status)}): ${message}`),
|
|
9829
9978
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -9982,12 +10131,12 @@ function tlsFacts(options) {
|
|
|
9982
10131
|
}
|
|
9983
10132
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
9984
10133
|
const agent = new ExemptTlsAgent();
|
|
9985
|
-
const post = async (
|
|
10134
|
+
const post = async (path36, headers, body) => await new Promise((resolve, reject) => {
|
|
9986
10135
|
const options = {
|
|
9987
10136
|
host: target.host,
|
|
9988
10137
|
port: target.port,
|
|
9989
10138
|
method: "POST",
|
|
9990
|
-
path:
|
|
10139
|
+
path: path36,
|
|
9991
10140
|
// The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
|
|
9992
10141
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
9993
10142
|
agent
|
|
@@ -10052,12 +10201,12 @@ function lateRcStreamDial(resolve) {
|
|
|
10052
10201
|
}
|
|
10053
10202
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10054
10203
|
const agent = new ExemptTlsAgent();
|
|
10055
|
-
const request4 = async (method,
|
|
10204
|
+
const request4 = async (method, path36, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
10056
10205
|
const options = {
|
|
10057
10206
|
host: target.host,
|
|
10058
10207
|
port: target.port,
|
|
10059
10208
|
method,
|
|
10060
|
-
path:
|
|
10209
|
+
path: path36,
|
|
10061
10210
|
// The Host header names the host whose API this is, not the address dialled: a redirected test dials a loopback stand-in while still speaking to the API host by name, exactly as the forwarded paths present their SNI.
|
|
10062
10211
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
10063
10212
|
agent,
|
|
@@ -10099,9 +10248,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
10099
10248
|
return { status, body: await readAll(response) };
|
|
10100
10249
|
},
|
|
10101
10250
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
10102
|
-
const
|
|
10251
|
+
const path36 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
|
|
10103
10252
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
10104
|
-
const { status, response } = await request4("GET",
|
|
10253
|
+
const { status, response } = await request4("GET", path36, streamHeaders, void 0, signal);
|
|
10105
10254
|
if (!isSuccessful2(status)) {
|
|
10106
10255
|
await readAll(response);
|
|
10107
10256
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -10684,9 +10833,9 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
10684
10833
|
if (request4.method === "GET" && request4.url === `${RC_ORPC_PATH_PREFIX}${RC_OPENAPI_DOC_PATH}`) {
|
|
10685
10834
|
const token = doorApiBearer(request4.headers);
|
|
10686
10835
|
if (token === void 0 || !isLiveCapability(token, [expectedToken])) {
|
|
10687
|
-
const
|
|
10836
|
+
const refusal2 = new ORPCError("UNAUTHORIZED", { message: "the front door's OpenAPI document demands this generation's control token as a Bearer credential" });
|
|
10688
10837
|
response.writeHead(HTTP_STATUS.unauthorized, { "content-type": "application/json" });
|
|
10689
|
-
response.end(JSON.stringify(
|
|
10838
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
10690
10839
|
return { matched: true };
|
|
10691
10840
|
}
|
|
10692
10841
|
try {
|
|
@@ -10694,17 +10843,21 @@ function doorApiNodeHandlerOf(router, expectedToken) {
|
|
|
10694
10843
|
response.writeHead(HTTP_STATUS.ok, { "content-type": "application/json" });
|
|
10695
10844
|
response.end(JSON.stringify(doc));
|
|
10696
10845
|
} catch (error) {
|
|
10697
|
-
const
|
|
10846
|
+
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)}` });
|
|
10698
10847
|
response.writeHead(HTTP_STATUS.internalServerError, { "content-type": "application/json" });
|
|
10699
|
-
response.end(JSON.stringify(
|
|
10848
|
+
response.end(JSON.stringify(refusal2.toJSON()));
|
|
10700
10849
|
}
|
|
10701
10850
|
return { matched: true };
|
|
10702
10851
|
}
|
|
10703
|
-
const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers
|
|
10852
|
+
const rest = await restHandler.handle(request4, response, { context: { headers: request4.headers, afterResponse: (action) => {
|
|
10853
|
+
response.once("finish", action);
|
|
10854
|
+
} }, prefix: RC_ORPC_PATH_PREFIX });
|
|
10704
10855
|
if (rest.matched) {
|
|
10705
10856
|
return rest;
|
|
10706
10857
|
}
|
|
10707
|
-
return await rpcHandler.handle(request4, response, { context: { headers: request4.headers
|
|
10858
|
+
return await rpcHandler.handle(request4, response, { context: { headers: request4.headers, afterResponse: (action) => {
|
|
10859
|
+
response.once("finish", action);
|
|
10860
|
+
} }, prefix: RC_ORPC_PATH_PREFIX });
|
|
10708
10861
|
}
|
|
10709
10862
|
};
|
|
10710
10863
|
}
|
|
@@ -10741,8 +10894,8 @@ init_cliError();
|
|
|
10741
10894
|
init_realPorts();
|
|
10742
10895
|
|
|
10743
10896
|
// src/frontdoor/controlApi.ts
|
|
10744
|
-
import { createORPCClient as createORPCClient2, ORPCError as
|
|
10745
|
-
import { openapi as
|
|
10897
|
+
import { createORPCClient as createORPCClient2, ORPCError as ORPCError6 } from "@orpc/client";
|
|
10898
|
+
import { openapi as openapi7 } from "@orpc/openapi";
|
|
10746
10899
|
|
|
10747
10900
|
// src/checkReport.ts
|
|
10748
10901
|
init_classify();
|
|
@@ -10926,6 +11079,48 @@ function removeProfile(paths, name) {
|
|
|
10926
11079
|
requireProfileExists(paths, name);
|
|
10927
11080
|
fs4.rmSync(profileJsonPath(paths, name));
|
|
10928
11081
|
}
|
|
11082
|
+
function applyProfileChange(paths, name, change) {
|
|
11083
|
+
let touched = false;
|
|
11084
|
+
if (change.category !== void 0) {
|
|
11085
|
+
setProfileCategories(paths, name, change.category);
|
|
11086
|
+
touched = true;
|
|
11087
|
+
}
|
|
11088
|
+
if (change.entry !== void 0) {
|
|
11089
|
+
setProfileEntries(paths, name, change.entry);
|
|
11090
|
+
touched = true;
|
|
11091
|
+
}
|
|
11092
|
+
if (change.extends !== void 0 || change.description !== void 0) {
|
|
11093
|
+
setProfileMetadata(paths, name, {
|
|
11094
|
+
...change.extends === void 0 ? {} : { extends: change.extends === false ? [] : change.extends },
|
|
11095
|
+
...change.description === void 0 ? {} : { description: change.description }
|
|
11096
|
+
});
|
|
11097
|
+
touched = true;
|
|
11098
|
+
}
|
|
11099
|
+
const launchPatch = {};
|
|
11100
|
+
if (change.launchSkipPermissions !== void 0) {
|
|
11101
|
+
launchPatch.skipPermissions = change.launchSkipPermissions;
|
|
11102
|
+
}
|
|
11103
|
+
if (change.launchRemoteControl !== void 0) {
|
|
11104
|
+
launchPatch.remoteControl = change.launchRemoteControl;
|
|
11105
|
+
}
|
|
11106
|
+
if (change.launchHeadroom !== void 0) {
|
|
11107
|
+
launchPatch.headroom = change.launchHeadroom;
|
|
11108
|
+
}
|
|
11109
|
+
if (change.launchTrackUsage !== void 0) {
|
|
11110
|
+
launchPatch.trackUsage = change.launchTrackUsage;
|
|
11111
|
+
}
|
|
11112
|
+
if (change.launchProvider !== void 0) {
|
|
11113
|
+
launchPatch.provider = change.launchProvider === false ? void 0 : change.launchProvider;
|
|
11114
|
+
}
|
|
11115
|
+
if (change.launchClaudeVersion !== void 0) {
|
|
11116
|
+
launchPatch.claudeVersion = change.launchClaudeVersion === false ? void 0 : change.launchClaudeVersion;
|
|
11117
|
+
}
|
|
11118
|
+
if (Object.keys(launchPatch).length > 0) {
|
|
11119
|
+
setProfileLaunchFlags(paths, name, launchPatch);
|
|
11120
|
+
touched = true;
|
|
11121
|
+
}
|
|
11122
|
+
return touched;
|
|
11123
|
+
}
|
|
10929
11124
|
|
|
10930
11125
|
// src/poolStore.ts
|
|
10931
11126
|
init_store();
|
|
@@ -10969,19 +11164,19 @@ function writePools(paths, pools) {
|
|
|
10969
11164
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
10970
11165
|
}
|
|
10971
11166
|
function poolCycleOf(pools, name) {
|
|
10972
|
-
const walk = (current,
|
|
11167
|
+
const walk = (current, path36) => {
|
|
10973
11168
|
for (const entry of pools[current]?.identities ?? []) {
|
|
10974
11169
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
10975
11170
|
if (nested === void 0) {
|
|
10976
11171
|
continue;
|
|
10977
11172
|
}
|
|
10978
11173
|
if (nested === name) {
|
|
10979
|
-
return [...
|
|
11174
|
+
return [...path36, nested];
|
|
10980
11175
|
}
|
|
10981
|
-
if (
|
|
11176
|
+
if (path36.includes(nested)) {
|
|
10982
11177
|
continue;
|
|
10983
11178
|
}
|
|
10984
|
-
const found = walk(nested, [...
|
|
11179
|
+
const found = walk(nested, [...path36, nested]);
|
|
10985
11180
|
if (found !== void 0) {
|
|
10986
11181
|
return found;
|
|
10987
11182
|
}
|
|
@@ -11699,6 +11894,14 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
11699
11894
|
function identityJsonPath(paths, name) {
|
|
11700
11895
|
return path27.join(paths.identitiesDir, name, "identity.json");
|
|
11701
11896
|
}
|
|
11897
|
+
function requireIdentityNames(paths, names) {
|
|
11898
|
+
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
11899
|
+
for (const name of names) {
|
|
11900
|
+
if (poolNameOf(name) === void 0 && !existing.has(name)) {
|
|
11901
|
+
throw new IdentityNotFoundError(name);
|
|
11902
|
+
}
|
|
11903
|
+
}
|
|
11904
|
+
}
|
|
11702
11905
|
function identityExists(paths, name) {
|
|
11703
11906
|
return fs9.existsSync(identityJsonPath(paths, name));
|
|
11704
11907
|
}
|
|
@@ -12552,103 +12755,813 @@ var DoctorRunOutputSchema = z19.strictObject({
|
|
|
12552
12755
|
ok: z19.boolean(),
|
|
12553
12756
|
findings: z19.readonly(z19.array(DoctorFindingSchema))
|
|
12554
12757
|
});
|
|
12555
|
-
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
12559
|
-
|
|
12560
|
-
|
|
12561
|
-
|
|
12562
|
-
|
|
12563
|
-
|
|
12564
|
-
var
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
var DoorEventSchema = z20.strictObject({
|
|
12569
|
-
source: z20.string().min(1),
|
|
12570
|
-
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
12571
|
-
sequence: z20.number().int().positive(),
|
|
12572
|
-
payload: z20.unknown()
|
|
12573
|
-
});
|
|
12574
|
-
var DoorEventSourceQuerySchema = z20.strictObject({
|
|
12575
|
-
sources: z20.array(z20.string().min(1)).min(1).optional()
|
|
12576
|
-
});
|
|
12577
|
-
var LaunchLifecycleEventSchema = z20.strictObject({
|
|
12578
|
-
kind: z20.enum(["registered", "pruned", "ended"]),
|
|
12579
|
-
pid: z20.number().int().positive(),
|
|
12580
|
-
startedAt: z20.number(),
|
|
12581
|
-
observedAt: z20.number()
|
|
12582
|
-
});
|
|
12583
|
-
var DoorHealthEventSchema = z20.discriminatedUnion("kind", [
|
|
12584
|
-
z20.strictObject({ kind: z20.literal("generation"), pid: z20.number().int().positive(), providerPort: z20.number().int().positive(), connectPort: z20.number().int().positive(), directPort: z20.number().int().positive(), observedAt: z20.number() }),
|
|
12585
|
-
z20.strictObject({ kind: z20.literal("listenerFailed"), pid: z20.number().int().positive(), listener: z20.enum(["provider", "connect", "direct"]), message: z20.string(), observedAt: z20.number() }),
|
|
12586
|
-
z20.strictObject({ kind: z20.literal("binaryTurnover"), pid: z20.number().int().positive(), observedAt: z20.number() }),
|
|
12587
|
-
z20.strictObject({ kind: z20.literal("idleShutdown"), pid: z20.number().int().positive(), observedAt: z20.number() })
|
|
12758
|
+
var FrontDoorRestartOutputSchema = z19.strictObject({
|
|
12759
|
+
action: z19.literal("restarting"),
|
|
12760
|
+
previousPid: z19.int().positive()
|
|
12761
|
+
});
|
|
12762
|
+
var UpdateCheckOutputSchema = z19.strictObject({
|
|
12763
|
+
current: z19.string(),
|
|
12764
|
+
latest: z19.string(),
|
|
12765
|
+
action: z19.enum(["current", "available", "updated"])
|
|
12766
|
+
});
|
|
12767
|
+
var CodexSignInSchema = z19.discriminatedUnion("state", [
|
|
12768
|
+
z19.strictObject({ state: z19.literal("none") }),
|
|
12769
|
+
z19.strictObject({ state: z19.literal("signed-in"), email: z19.string().optional(), planScope: z19.boolean(), accessTokenExpiresAt: z19.number() }),
|
|
12770
|
+
z19.strictObject({ state: z19.literal("unreadable"), message: z19.string() })
|
|
12588
12771
|
]);
|
|
12589
|
-
var
|
|
12590
|
-
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12594
|
-
|
|
12595
|
-
|
|
12596
|
-
observedAt: z20.number()
|
|
12772
|
+
var CodexStatusOutputSchema = z19.strictObject({
|
|
12773
|
+
signIn: CodexSignInSchema,
|
|
12774
|
+
codexProviders: z19.readonly(z19.array(z19.string()))
|
|
12775
|
+
});
|
|
12776
|
+
var CodexLogoutOutputSchema = z19.strictObject({
|
|
12777
|
+
hadGrant: z19.boolean(),
|
|
12778
|
+
revoked: z19.boolean()
|
|
12597
12779
|
});
|
|
12598
12780
|
|
|
12599
|
-
// src/frontdoor/
|
|
12600
|
-
|
|
12601
|
-
|
|
12781
|
+
// src/frontdoor/codexApi.ts
|
|
12782
|
+
import { openapi as openapi2 } from "@orpc/openapi";
|
|
12783
|
+
var CODEX_API_TAG = "codex";
|
|
12784
|
+
function createCodexApiRouter(deps) {
|
|
12602
12785
|
const authed = doorApiAuth(deps.expectedToken);
|
|
12603
12786
|
return {
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
throw new ORPCError2("NOT_FOUND", { message: `the door publishes no event source named ${unknown.map((source) => `"${source}"`).join(", ")}; the live sources are ${live.map((source) => `"${source}"`).join(", ")}` });
|
|
12611
|
-
}
|
|
12612
|
-
}
|
|
12613
|
-
const stream = deps.events.stream(input.sources);
|
|
12614
|
-
const ended = new Promise((resolve) => {
|
|
12615
|
-
signal?.addEventListener("abort", () => {
|
|
12616
|
-
resolve();
|
|
12617
|
-
}, { once: true });
|
|
12618
|
-
});
|
|
12619
|
-
try {
|
|
12620
|
-
for (; ; ) {
|
|
12621
|
-
signal?.throwIfAborted();
|
|
12622
|
-
const next = await Promise.race([stream.next(), ended.then(() => ({ value: void 0, done: true }))]);
|
|
12623
|
-
if (next.done === true) {
|
|
12624
|
-
signal?.throwIfAborted();
|
|
12625
|
-
return;
|
|
12626
|
-
}
|
|
12627
|
-
yield withEventMeta2(next.value, { id: String(next.value.sequence) });
|
|
12628
|
-
}
|
|
12629
|
-
} finally {
|
|
12630
|
-
stream.close();
|
|
12631
|
-
}
|
|
12632
|
-
})
|
|
12787
|
+
codex: {
|
|
12788
|
+
status: authed.meta(openapi2({ method: "GET", path: "/rest/codex/status", summary: "Read the Codex sign-in and the codex providers", tags: [CODEX_API_TAG] })).output(CodexStatusOutputSchema).handler(() => {
|
|
12789
|
+
const status = deps.codexStatus();
|
|
12790
|
+
return { signIn: status.signIn, codexProviders: status.codexProviders };
|
|
12791
|
+
}),
|
|
12792
|
+
logout: authed.meta(openapi2({ method: "POST", path: "/rest/codex/logout", summary: "Revoke the Sign in with ChatGPT login and remove it", tags: [CODEX_API_TAG] })).output(CodexLogoutOutputSchema).handler(async () => await deps.codexLogout())
|
|
12633
12793
|
}
|
|
12634
12794
|
};
|
|
12635
12795
|
}
|
|
12636
12796
|
|
|
12637
|
-
// src/frontdoor/
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12797
|
+
// src/frontdoor/configApi.ts
|
|
12798
|
+
init_cliError();
|
|
12799
|
+
init_schema();
|
|
12800
|
+
import { ORPCError as ORPCError2 } from "@orpc/client";
|
|
12801
|
+
import { openapi as openapi3 } from "@orpc/openapi";
|
|
12802
|
+
init_credential();
|
|
12803
|
+
|
|
12804
|
+
// src/credentialCacheChange.ts
|
|
12805
|
+
init_cliError();
|
|
12806
|
+
init_schema();
|
|
12807
|
+
function mergeCredentialCache(request4, existing) {
|
|
12808
|
+
if (request4.enabled === false) {
|
|
12809
|
+
return false;
|
|
12810
|
+
}
|
|
12811
|
+
if (request4.ttl === void 0 && request4.store === void 0 && request4.enabled !== true) {
|
|
12812
|
+
return void 0;
|
|
12813
|
+
}
|
|
12814
|
+
const parsed = CredentialCacheSchema.safeParse({
|
|
12815
|
+
...existing,
|
|
12816
|
+
...request4.ttl === void 0 ? {} : { ttl: request4.ttl },
|
|
12817
|
+
...request4.store === void 0 ? {} : { store: request4.store }
|
|
12818
|
+
});
|
|
12819
|
+
if (!parsed.success) {
|
|
12820
|
+
throw new UsageError(parsed.error.issues.map((issue) => issue.message).join("; "));
|
|
12821
|
+
}
|
|
12822
|
+
return parsed.data;
|
|
12823
|
+
}
|
|
12824
|
+
|
|
12825
|
+
// src/directoryRulesStore.ts
|
|
12826
|
+
init_store();
|
|
12827
|
+
init_load();
|
|
12828
|
+
init_schema();
|
|
12829
|
+
init_cliError();
|
|
12830
|
+
var DirectoryRuleNotFoundError = class extends CliError {
|
|
12831
|
+
constructor(rulePath) {
|
|
12832
|
+
super(`No directory rule found for path "${rulePath}".`);
|
|
12833
|
+
this.rulePath = rulePath;
|
|
12834
|
+
this.name = "DirectoryRuleNotFoundError";
|
|
12835
|
+
}
|
|
12836
|
+
rulePath;
|
|
12837
|
+
};
|
|
12838
|
+
var DirectoryRuleMissingTargetError = class extends CliError {
|
|
12839
|
+
constructor() {
|
|
12840
|
+
super("A directory rule must set at least one of --config-profile or --identity.");
|
|
12841
|
+
this.name = "DirectoryRuleMissingTargetError";
|
|
12842
|
+
}
|
|
12843
|
+
};
|
|
12844
|
+
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
12845
|
+
constructor(rulePath) {
|
|
12846
|
+
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
12847
|
+
this.rulePath = rulePath;
|
|
12848
|
+
this.name = "DirectoryRuleAlreadyExistsError";
|
|
12849
|
+
}
|
|
12850
|
+
rulePath;
|
|
12851
|
+
};
|
|
12852
|
+
function readDirectoryRules(paths) {
|
|
12853
|
+
return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
|
|
12854
|
+
}
|
|
12855
|
+
function writeDirectoryRules(paths, rules) {
|
|
12856
|
+
const parsed = DirectoryRulesSchema.safeParse(rules);
|
|
12857
|
+
if (!parsed.success) {
|
|
12858
|
+
throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
|
|
12859
|
+
}
|
|
12860
|
+
writeJsonAtomic(paths.directoryRulesFile, parsed.data);
|
|
12861
|
+
}
|
|
12862
|
+
function listDirectoryRules(paths) {
|
|
12863
|
+
return readDirectoryRules(paths).rules;
|
|
12864
|
+
}
|
|
12865
|
+
function addDirectoryRule(paths, rulePath, options) {
|
|
12866
|
+
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
12867
|
+
throw new DirectoryRuleMissingTargetError();
|
|
12868
|
+
}
|
|
12869
|
+
const current = readDirectoryRules(paths);
|
|
12870
|
+
if (current.rules.some((rule) => rule.path === rulePath)) {
|
|
12871
|
+
throw new DirectoryRuleAlreadyExistsError(rulePath);
|
|
12872
|
+
}
|
|
12873
|
+
const created = buildNewRule(rulePath, options);
|
|
12874
|
+
writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
|
|
12875
|
+
return created;
|
|
12876
|
+
}
|
|
12877
|
+
function ruleHasEffect(rule) {
|
|
12878
|
+
return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
|
|
12879
|
+
}
|
|
12880
|
+
function updateDirectoryRule(paths, rulePath, options) {
|
|
12881
|
+
const current = readDirectoryRules(paths);
|
|
12882
|
+
const index = current.rules.findIndex((rule) => rule.path === rulePath);
|
|
12883
|
+
const existing = index === -1 ? void 0 : current.rules[index];
|
|
12884
|
+
if (existing === void 0) {
|
|
12885
|
+
throw new DirectoryRuleNotFoundError(rulePath);
|
|
12886
|
+
}
|
|
12887
|
+
const { configProfile, identity, ...rest } = existing;
|
|
12888
|
+
const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
|
|
12889
|
+
const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
|
|
12890
|
+
const updated = {
|
|
12891
|
+
...rest,
|
|
12892
|
+
...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
|
|
12893
|
+
...nextIdentity === void 0 ? {} : { identity: nextIdentity }
|
|
12894
|
+
};
|
|
12895
|
+
if (!ruleHasEffect(updated)) {
|
|
12896
|
+
throw new DirectoryRuleMissingTargetError();
|
|
12897
|
+
}
|
|
12898
|
+
const nextRules = [...current.rules];
|
|
12899
|
+
nextRules[index] = updated;
|
|
12900
|
+
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
12901
|
+
return updated;
|
|
12902
|
+
}
|
|
12903
|
+
function buildNewRule(rulePath, options) {
|
|
12904
|
+
return {
|
|
12905
|
+
path: rulePath,
|
|
12906
|
+
...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
|
|
12907
|
+
...options.identity !== void 0 ? { identity: options.identity } : {}
|
|
12908
|
+
};
|
|
12909
|
+
}
|
|
12910
|
+
function removeDirectoryRule(paths, rulePath) {
|
|
12911
|
+
const current = readDirectoryRules(paths);
|
|
12912
|
+
const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
|
|
12913
|
+
if (nextRules.length === current.rules.length) {
|
|
12914
|
+
throw new DirectoryRuleNotFoundError(rulePath);
|
|
12915
|
+
}
|
|
12916
|
+
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
12917
|
+
}
|
|
12918
|
+
function requireRuleSelector(paths, selector) {
|
|
12919
|
+
if (selector.startsWith(POOL_SELECTOR_PREFIX)) {
|
|
12920
|
+
const poolName = selector.slice(POOL_SELECTOR_PREFIX.length);
|
|
12921
|
+
if (readPools(paths)[poolName] === void 0) {
|
|
12922
|
+
throw new PoolNotFoundError(poolName);
|
|
12923
|
+
}
|
|
12924
|
+
} else if (readIdentity(paths, selector) === void 0) {
|
|
12925
|
+
throw new IdentityNotFoundError(selector);
|
|
12926
|
+
}
|
|
12927
|
+
}
|
|
12928
|
+
|
|
12929
|
+
// src/frontdoor/configApi.ts
|
|
12930
|
+
init_identity();
|
|
12931
|
+
init_providersStore();
|
|
12932
|
+
|
|
12933
|
+
// src/frontdoor/configSchemas.ts
|
|
12934
|
+
init_schema();
|
|
12935
|
+
import { z as z20 } from "zod";
|
|
12936
|
+
var RemovalConfirmationSchema = z20.boolean();
|
|
12937
|
+
var CredentialWriteSchema = (targets) => z20.strictObject({
|
|
12938
|
+
sources: z20.array(RemoteCredentialSourceSchema).min(1).optional(),
|
|
12939
|
+
target: z20.enum(targets).optional(),
|
|
12940
|
+
cache: z20.union([z20.literal(false), CredentialCacheSchema]).optional()
|
|
12941
|
+
});
|
|
12942
|
+
var CredentialSummarySchema2 = z20.strictObject({
|
|
12943
|
+
target: z20.enum(CREDENTIAL_TARGETS),
|
|
12944
|
+
sources: z20.readonly(z20.array(
|
|
12945
|
+
z20.discriminatedUnion("kind", [
|
|
12946
|
+
z20.strictObject({ kind: z20.literal("env"), variable: z20.string() }),
|
|
12947
|
+
z20.strictObject({ kind: z20.literal("file"), path: z20.string() }),
|
|
12948
|
+
z20.strictObject({ kind: z20.literal("command"), program: z20.string() }),
|
|
12949
|
+
z20.strictObject({ kind: z20.literal("op"), reference: z20.string() }),
|
|
12950
|
+
z20.strictObject({ kind: z20.literal("keychain"), service: z20.string(), account: z20.string().optional() }),
|
|
12951
|
+
z20.strictObject({ kind: z20.literal("literal") })
|
|
12952
|
+
])
|
|
12953
|
+
)),
|
|
12954
|
+
cache: CredentialCacheSchema.optional()
|
|
12955
|
+
});
|
|
12956
|
+
var mutationOutput = (kind, action) => z20.strictObject({ action: z20.literal(action), kind: z20.literal(kind), name: z20.string() });
|
|
12957
|
+
var storedMutationOutput = (kind, action, value) => z20.strictObject({ action: z20.literal(action), kind: z20.literal(kind), name: z20.string(), value });
|
|
12958
|
+
var IdentityValueSchema = z20.strictObject({
|
|
12959
|
+
name: z20.string(),
|
|
12960
|
+
defaultConfigProfile: z20.string().optional(),
|
|
12961
|
+
allowAmbientCredential: z20.boolean(),
|
|
12962
|
+
credential: CredentialSummarySchema2.optional()
|
|
12963
|
+
});
|
|
12964
|
+
var ProfileValueSchema = ConfigProfileSchema.omit({ $schema: true });
|
|
12965
|
+
var ProviderValueSchema = z20.strictObject({
|
|
12966
|
+
name: z20.string(),
|
|
12967
|
+
kind: z20.enum(PROVIDER_KINDS),
|
|
12968
|
+
displayName: z20.string(),
|
|
12969
|
+
baseUrl: z20.string().optional(),
|
|
12970
|
+
codex: CodexProviderConfigSchema.optional(),
|
|
12971
|
+
credential: CredentialSummarySchema2,
|
|
12972
|
+
env: z20.record(z20.string(), z20.string()).optional()
|
|
12973
|
+
});
|
|
12974
|
+
var ConfigNameInputSchema = z20.strictObject({ name: z20.string().min(1) });
|
|
12975
|
+
var ConfigIdentityAddOutputSchema = storedMutationOutput("identity", "created", IdentityValueSchema);
|
|
12976
|
+
var ConfigIdentitySetInputSchema = z20.strictObject({
|
|
12977
|
+
name: z20.string().min(1),
|
|
12978
|
+
defaultConfigProfile: z20.union([z20.string().min(1), z20.literal(false)]).optional(),
|
|
12979
|
+
allowAmbientCredential: z20.boolean().optional(),
|
|
12980
|
+
credential: z20.union([z20.literal(false), CredentialWriteSchema(CREDENTIAL_TARGETS)]).optional()
|
|
12981
|
+
});
|
|
12982
|
+
var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
|
|
12983
|
+
var ConfigIdentityRemoveInputSchema = z20.strictObject({ name: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
12984
|
+
var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
|
|
12985
|
+
var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
|
|
12986
|
+
var ConfigProfileAddInputSchema = z20.strictObject({
|
|
12987
|
+
name: z20.string().min(1),
|
|
12988
|
+
extends: z20.array(z20.string().min(1)).optional(),
|
|
12989
|
+
description: z20.string().optional()
|
|
12990
|
+
});
|
|
12991
|
+
var ConfigProfileAddOutputSchema = storedMutationOutput("profile", "created", ProfileValueSchema);
|
|
12992
|
+
var ConfigProfileSetInputSchema = z20.strictObject({
|
|
12993
|
+
name: z20.string().min(1),
|
|
12994
|
+
category: z20.record(z20.string(), z20.boolean()).optional(),
|
|
12995
|
+
entry: z20.record(z20.string(), z20.boolean()).optional(),
|
|
12996
|
+
extends: z20.union([z20.array(z20.string().min(1)), z20.literal(false)]).optional(),
|
|
12997
|
+
description: z20.union([z20.string(), z20.literal(false)]).optional(),
|
|
12998
|
+
launch: z20.strictObject({
|
|
12999
|
+
skipPermissions: z20.boolean().optional(),
|
|
13000
|
+
remoteControl: z20.boolean().optional(),
|
|
13001
|
+
headroom: z20.boolean().optional(),
|
|
13002
|
+
trackUsage: z20.boolean().optional(),
|
|
13003
|
+
provider: z20.union([z20.string().min(1), z20.literal(false)]).optional(),
|
|
13004
|
+
claudeVersion: z20.union([z20.string().min(1), z20.literal(false)]).optional()
|
|
13005
|
+
}).optional()
|
|
13006
|
+
});
|
|
13007
|
+
var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
|
|
13008
|
+
var ConfigProfileRemoveInputSchema = z20.strictObject({ name: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13009
|
+
var ConfigProfileRemoveOutputSchema = mutationOutput("profile", "removed");
|
|
13010
|
+
var ConfigProfileUseOutputSchema = mutationOutput("profile", "selected");
|
|
13011
|
+
var PoolMembersInputSchema = z20.array(z20.string().min(1)).min(1);
|
|
13012
|
+
var ConfigPoolAddInputSchema = z20.strictObject({
|
|
13013
|
+
name: z20.string().min(1),
|
|
13014
|
+
identities: PoolMembersInputSchema,
|
|
13015
|
+
preference: z20.enum(POOL_PREFERENCES).optional()
|
|
13016
|
+
});
|
|
13017
|
+
var ConfigPoolAddOutputSchema = storedMutationOutput("pool", "created", PoolSchema);
|
|
13018
|
+
var ConfigPoolSetInputSchema = z20.strictObject({
|
|
13019
|
+
name: z20.string().min(1),
|
|
13020
|
+
identities: PoolMembersInputSchema.optional(),
|
|
13021
|
+
preference: z20.union([z20.enum(POOL_PREFERENCES), z20.literal(false)]).optional()
|
|
13022
|
+
});
|
|
13023
|
+
var ConfigPoolSetOutputSchema = storedMutationOutput("pool", "updated", PoolSchema);
|
|
13024
|
+
var ConfigPoolRemoveInputSchema = z20.strictObject({ name: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13025
|
+
var ConfigPoolRemoveOutputSchema = mutationOutput("pool", "removed");
|
|
13026
|
+
var ConfigPoolUseOutputSchema = mutationOutput("pool", "selected");
|
|
13027
|
+
var ConfigProviderAddInputSchema = z20.strictObject({
|
|
13028
|
+
name: z20.string().min(1),
|
|
13029
|
+
kind: z20.enum(PROVIDER_KINDS).optional(),
|
|
13030
|
+
displayName: z20.string().min(1),
|
|
13031
|
+
baseUrl: z20.string().min(1).optional(),
|
|
13032
|
+
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).required({ sources: true }),
|
|
13033
|
+
codex: CodexProviderConfigSchema.optional()
|
|
13034
|
+
});
|
|
13035
|
+
var ConfigProviderAddOutputSchema = storedMutationOutput("provider", "created", ProviderValueSchema);
|
|
13036
|
+
var ConfigProviderSetInputSchema = z20.strictObject({
|
|
13037
|
+
name: z20.string().min(1),
|
|
13038
|
+
displayName: z20.string().min(1).optional(),
|
|
13039
|
+
baseUrl: z20.string().min(1).optional(),
|
|
13040
|
+
credential: CredentialWriteSchema(PROVIDER_CREDENTIAL_TARGETS).optional(),
|
|
13041
|
+
codex: CodexProviderConfigSchema.optional()
|
|
13042
|
+
});
|
|
13043
|
+
var ConfigProviderSetOutputSchema = storedMutationOutput("provider", "updated", ProviderValueSchema);
|
|
13044
|
+
var ConfigProviderRemoveInputSchema = z20.strictObject({ name: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13045
|
+
var ConfigProviderRemoveOutputSchema = mutationOutput("provider", "removed");
|
|
13046
|
+
var ConfigRuleAddInputSchema = z20.strictObject({
|
|
13047
|
+
path: z20.string().min(1),
|
|
13048
|
+
configProfile: z20.string().min(1).optional(),
|
|
13049
|
+
identity: z20.string().min(1).optional()
|
|
13050
|
+
});
|
|
13051
|
+
var ConfigRuleAddOutputSchema = storedMutationOutput("rule", "created", DirectoryRuleSchema);
|
|
13052
|
+
var ConfigRuleSetInputSchema = z20.strictObject({
|
|
13053
|
+
path: z20.string().min(1),
|
|
13054
|
+
configProfile: z20.union([z20.string().min(1), z20.literal(false)]).optional(),
|
|
13055
|
+
identity: z20.union([z20.string().min(1), z20.literal(false)]).optional()
|
|
13056
|
+
});
|
|
13057
|
+
var ConfigRuleSetOutputSchema = storedMutationOutput("rule", "updated", DirectoryRuleSchema);
|
|
13058
|
+
var ConfigRuleRemoveInputSchema = z20.strictObject({ path: z20.string().min(1), confirm: RemovalConfirmationSchema });
|
|
13059
|
+
var ConfigRuleRemoveOutputSchema = mutationOutput("rule", "removed");
|
|
13060
|
+
|
|
13061
|
+
// src/frontdoor/configApi.ts
|
|
13062
|
+
var CONFIG_API_TAG = "config";
|
|
13063
|
+
function refusal(error) {
|
|
13064
|
+
if (error instanceof IdentityNotFoundError || error instanceof ProfileNotFoundError || error instanceof PoolNotFoundError || error instanceof ProviderNotFoundError || error instanceof DirectoryRuleNotFoundError) {
|
|
13065
|
+
throw new ORPCError2("NOT_FOUND", { message: error.message });
|
|
13066
|
+
}
|
|
13067
|
+
if (error instanceof IdentityAlreadyExistsError || error instanceof ProfileAlreadyExistsError || error instanceof PoolAlreadyExistsError || error instanceof ProviderAlreadyExistsError || error instanceof DirectoryRuleAlreadyExistsError) {
|
|
13068
|
+
throw new ORPCError2("CONFLICT", { message: error.message });
|
|
13069
|
+
}
|
|
13070
|
+
if (error instanceof CliError) {
|
|
13071
|
+
throw new ORPCError2("BAD_REQUEST", { message: error.message });
|
|
13072
|
+
}
|
|
13073
|
+
throw error;
|
|
13074
|
+
}
|
|
13075
|
+
function guarded(write) {
|
|
13076
|
+
try {
|
|
13077
|
+
return write();
|
|
13078
|
+
} catch (error) {
|
|
13079
|
+
return refusal(error);
|
|
13080
|
+
}
|
|
13081
|
+
}
|
|
13082
|
+
function requireConfirmation(confirm, what) {
|
|
13083
|
+
if (!confirm) {
|
|
13084
|
+
throw new ORPCError2("BAD_REQUEST", { message: `removing ${what} needs confirm: true, the API's form of the CLI's --yes` });
|
|
13085
|
+
}
|
|
13086
|
+
}
|
|
13087
|
+
function requireChange(given, fields) {
|
|
13088
|
+
if (!given) {
|
|
13089
|
+
throw new ORPCError2("BAD_REQUEST", { message: `Nothing to change: pass ${fields}.` });
|
|
13090
|
+
}
|
|
13091
|
+
}
|
|
13092
|
+
function identityValue(name, paths) {
|
|
13093
|
+
const identity = readIdentity(paths, name);
|
|
13094
|
+
if (identity === void 0) {
|
|
13095
|
+
throw new IdentityNotFoundError(name);
|
|
13096
|
+
}
|
|
13097
|
+
return {
|
|
13098
|
+
name: identity.name,
|
|
13099
|
+
...identity.defaultConfigProfile === void 0 ? {} : { defaultConfigProfile: identity.defaultConfigProfile },
|
|
13100
|
+
allowAmbientCredential: identity.allowAmbientCredential,
|
|
13101
|
+
...identity.credential === void 0 ? {} : { credential: summariseCredential(identity.credential) }
|
|
13102
|
+
};
|
|
13103
|
+
}
|
|
13104
|
+
function providerValue(name, provider) {
|
|
13105
|
+
return {
|
|
13106
|
+
name,
|
|
13107
|
+
kind: provider.kind ?? "http",
|
|
13108
|
+
displayName: provider.displayName,
|
|
13109
|
+
...isCodexProvider(provider) ? provider.codex === void 0 ? {} : { codex: provider.codex } : { baseUrl: provider.baseUrl },
|
|
13110
|
+
credential: summariseCredential(provider.credential),
|
|
13111
|
+
...provider.env === void 0 ? {} : { env: provider.env }
|
|
13112
|
+
};
|
|
13113
|
+
}
|
|
13114
|
+
function profileValue(name, paths) {
|
|
13115
|
+
const profile = { ...readProfile(paths, name) };
|
|
13116
|
+
delete profile.$schema;
|
|
13117
|
+
return profile;
|
|
13118
|
+
}
|
|
13119
|
+
function createConfigApiRouter(deps) {
|
|
13120
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13121
|
+
const { paths } = deps;
|
|
13122
|
+
const route = (path36, summary) => authed.meta(openapi3({ method: "POST", path: path36, summary, tags: [CONFIG_API_TAG] }));
|
|
13123
|
+
return {
|
|
13124
|
+
config: {
|
|
13125
|
+
identity: {
|
|
13126
|
+
add: route("/rest/config/identity/add", "Create an identity").input(ConfigNameInputSchema).output(ConfigIdentityAddOutputSchema).handler(
|
|
13127
|
+
({ input }) => guarded(() => {
|
|
13128
|
+
addIdentity(paths, input.name);
|
|
13129
|
+
return { action: "created", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
13130
|
+
})
|
|
13131
|
+
),
|
|
13132
|
+
set: route("/rest/config/identity/set", "Update an identity's default profile, ambient-credential setting or credential").input(ConfigIdentitySetInputSchema).output(ConfigIdentitySetOutputSchema).handler(
|
|
13133
|
+
({ input }) => guarded(() => {
|
|
13134
|
+
requireChange(input.defaultConfigProfile !== void 0 || input.allowAmbientCredential !== void 0 || input.credential !== void 0, "defaultConfigProfile, allowAmbientCredential or credential");
|
|
13135
|
+
if (!identityExists(paths, input.name)) {
|
|
13136
|
+
throw new IdentityNotFoundError(input.name);
|
|
13137
|
+
}
|
|
13138
|
+
if (typeof input.defaultConfigProfile === "string") {
|
|
13139
|
+
requireProfileExists(paths, input.defaultConfigProfile);
|
|
13140
|
+
}
|
|
13141
|
+
if (input.defaultConfigProfile !== void 0) {
|
|
13142
|
+
setDefaultConfigProfile(paths, input.name, input.defaultConfigProfile === false ? void 0 : input.defaultConfigProfile);
|
|
13143
|
+
}
|
|
13144
|
+
if (input.allowAmbientCredential !== void 0) {
|
|
13145
|
+
setAllowAmbientCredential(paths, input.name, input.allowAmbientCredential);
|
|
13146
|
+
}
|
|
13147
|
+
if (input.credential === false) {
|
|
13148
|
+
setIdentityCredential(paths, input.name, false);
|
|
13149
|
+
} else if (input.credential !== void 0) {
|
|
13150
|
+
const { sources, target, cache } = input.credential;
|
|
13151
|
+
const merged = cache === void 0 ? void 0 : mergeCredentialCache(cache === false ? { enabled: false } : { ...cache, enabled: true }, readIdentity(paths, input.name)?.credential?.cache);
|
|
13152
|
+
const change = {
|
|
13153
|
+
...sources === void 0 ? {} : { sources },
|
|
13154
|
+
...target === void 0 ? {} : { target },
|
|
13155
|
+
...merged === void 0 ? {} : { cache: merged }
|
|
13156
|
+
};
|
|
13157
|
+
setIdentityCredential(paths, input.name, change);
|
|
13158
|
+
}
|
|
13159
|
+
return { action: "updated", kind: "identity", name: input.name, value: identityValue(input.name, paths) };
|
|
13160
|
+
})
|
|
13161
|
+
),
|
|
13162
|
+
remove: route("/rest/config/identity/remove", "Delete an identity and its directory").input(ConfigIdentityRemoveInputSchema).output(ConfigIdentityRemoveOutputSchema).handler(({ input }) => {
|
|
13163
|
+
requireConfirmation(input.confirm, `identity "${input.name}" and its directory`);
|
|
13164
|
+
return guarded(() => {
|
|
13165
|
+
removeIdentity(paths, input.name);
|
|
13166
|
+
return { action: "removed", kind: "identity", name: input.name };
|
|
13167
|
+
});
|
|
13168
|
+
}),
|
|
13169
|
+
use: route("/rest/config/identity/use", "Select the active identity").input(ConfigNameInputSchema).output(ConfigIdentityUseOutputSchema).handler(
|
|
13170
|
+
({ input }) => guarded(() => {
|
|
13171
|
+
if (poolNameOf(input.name) === void 0 && !identityExists(paths, input.name)) {
|
|
13172
|
+
throw new IdentityNotFoundError(input.name);
|
|
13173
|
+
}
|
|
13174
|
+
useIdentity(paths, input.name);
|
|
13175
|
+
return { action: "selected", kind: "identity", name: input.name };
|
|
13176
|
+
})
|
|
13177
|
+
)
|
|
13178
|
+
},
|
|
13179
|
+
profile: {
|
|
13180
|
+
add: route("/rest/config/profile/add", "Create a configuration profile").input(ConfigProfileAddInputSchema).output(ConfigProfileAddOutputSchema).handler(
|
|
13181
|
+
({ input }) => guarded(() => {
|
|
13182
|
+
createProfile(paths, input.name, input.extends, input.description);
|
|
13183
|
+
return { action: "created", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
|
|
13184
|
+
})
|
|
13185
|
+
),
|
|
13186
|
+
set: route("/rest/config/profile/set", "Update a configuration profile's categories, entries, extends list, description or launch settings").input(ConfigProfileSetInputSchema).output(ConfigProfileSetOutputSchema).handler(
|
|
13187
|
+
({ input }) => guarded(() => {
|
|
13188
|
+
const { launch } = input;
|
|
13189
|
+
requireChange(
|
|
13190
|
+
input.category !== void 0 || input.entry !== void 0 || input.extends !== void 0 || input.description !== void 0 || launch !== void 0,
|
|
13191
|
+
"category, entry, extends, description or launch"
|
|
13192
|
+
);
|
|
13193
|
+
requireProfileExists(paths, input.name);
|
|
13194
|
+
applyProfileChange(paths, input.name, {
|
|
13195
|
+
...input.category === void 0 ? {} : { category: input.category },
|
|
13196
|
+
...input.entry === void 0 ? {} : { entry: input.entry },
|
|
13197
|
+
...input.extends === void 0 ? {} : { extends: input.extends },
|
|
13198
|
+
...input.description === void 0 ? {} : { description: input.description },
|
|
13199
|
+
...launch?.skipPermissions === void 0 ? {} : { launchSkipPermissions: launch.skipPermissions },
|
|
13200
|
+
...launch?.remoteControl === void 0 ? {} : { launchRemoteControl: launch.remoteControl },
|
|
13201
|
+
...launch?.headroom === void 0 ? {} : { launchHeadroom: launch.headroom },
|
|
13202
|
+
...launch?.trackUsage === void 0 ? {} : { launchTrackUsage: launch.trackUsage },
|
|
13203
|
+
...launch?.provider === void 0 ? {} : { launchProvider: launch.provider },
|
|
13204
|
+
...launch?.claudeVersion === void 0 ? {} : { launchClaudeVersion: launch.claudeVersion }
|
|
13205
|
+
});
|
|
13206
|
+
return { action: "updated", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
|
|
13207
|
+
})
|
|
13208
|
+
),
|
|
13209
|
+
remove: route("/rest/config/profile/remove", "Delete a configuration profile").input(ConfigProfileRemoveInputSchema).output(ConfigProfileRemoveOutputSchema).handler(({ input }) => {
|
|
13210
|
+
requireConfirmation(input.confirm, `configuration profile "${input.name}"`);
|
|
13211
|
+
return guarded(() => {
|
|
13212
|
+
removeProfile(paths, input.name);
|
|
13213
|
+
return { action: "removed", kind: "profile", name: input.name };
|
|
13214
|
+
});
|
|
13215
|
+
}),
|
|
13216
|
+
use: route("/rest/config/profile/use", "Make a configuration profile the global default").input(ConfigNameInputSchema).output(ConfigProfileUseOutputSchema).handler(
|
|
13217
|
+
({ input }) => guarded(() => {
|
|
13218
|
+
requireProfileExists(paths, input.name);
|
|
13219
|
+
setGlobalDefaultProfile(paths, input.name);
|
|
13220
|
+
return { action: "selected", kind: "profile", name: input.name };
|
|
13221
|
+
})
|
|
13222
|
+
)
|
|
13223
|
+
},
|
|
13224
|
+
pool: {
|
|
13225
|
+
add: route("/rest/config/pool/add", "Define a pool").input(ConfigPoolAddInputSchema).output(ConfigPoolAddOutputSchema).handler(
|
|
13226
|
+
({ input }) => guarded(() => {
|
|
13227
|
+
requireIdentityNames(paths, input.identities);
|
|
13228
|
+
const created = addPool(paths, input.name, input.identities, input.preference);
|
|
13229
|
+
return { action: "created", kind: "pool", name: input.name, value: created };
|
|
13230
|
+
})
|
|
13231
|
+
),
|
|
13232
|
+
set: route("/rest/config/pool/set", "Replace a pool's members, its preference or both").input(ConfigPoolSetInputSchema).output(ConfigPoolSetOutputSchema).handler(
|
|
13233
|
+
({ input }) => guarded(() => {
|
|
13234
|
+
requireChange(input.identities !== void 0 || input.preference !== void 0, "identities or preference");
|
|
13235
|
+
const existing = requirePool(paths, input.name);
|
|
13236
|
+
if (input.identities !== void 0) {
|
|
13237
|
+
requireIdentityNames(paths, input.identities);
|
|
13238
|
+
}
|
|
13239
|
+
const members = input.identities ?? existing.identities;
|
|
13240
|
+
const preference = input.preference === void 0 ? existing.preference : input.preference === false ? void 0 : input.preference;
|
|
13241
|
+
return { action: "updated", kind: "pool", name: input.name, value: setPool(paths, input.name, members, preference) };
|
|
13242
|
+
})
|
|
13243
|
+
),
|
|
13244
|
+
remove: route("/rest/config/pool/remove", "Delete a pool").input(ConfigPoolRemoveInputSchema).output(ConfigPoolRemoveOutputSchema).handler(({ input }) => {
|
|
13245
|
+
requireConfirmation(input.confirm, `pool "${input.name}"`);
|
|
13246
|
+
return guarded(() => {
|
|
13247
|
+
removePool(paths, input.name);
|
|
13248
|
+
return { action: "removed", kind: "pool", name: input.name };
|
|
13249
|
+
});
|
|
13250
|
+
}),
|
|
13251
|
+
use: route("/rest/config/pool/use", "Make launches with no other selection pick a member of a pool").input(ConfigNameInputSchema).output(ConfigPoolUseOutputSchema).handler(
|
|
13252
|
+
({ input }) => guarded(() => {
|
|
13253
|
+
if (readPools(paths)[input.name] === void 0) {
|
|
13254
|
+
throw new PoolNotFoundError(input.name);
|
|
13255
|
+
}
|
|
13256
|
+
useIdentity(paths, `pool:${input.name}`);
|
|
13257
|
+
return { action: "selected", kind: "pool", name: input.name };
|
|
13258
|
+
})
|
|
13259
|
+
)
|
|
13260
|
+
},
|
|
13261
|
+
provider: {
|
|
13262
|
+
add: route("/rest/config/provider/add", "Create an API provider definition").input(ConfigProviderAddInputSchema).output(ConfigProviderAddOutputSchema).handler(
|
|
13263
|
+
({ input }) => guarded(() => {
|
|
13264
|
+
const created = addProvider(paths, input.name, {
|
|
13265
|
+
...input.kind === void 0 ? {} : { kind: input.kind },
|
|
13266
|
+
displayName: input.displayName,
|
|
13267
|
+
...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
|
|
13268
|
+
sources: input.credential.sources,
|
|
13269
|
+
...input.credential.target === void 0 ? {} : { target: input.credential.target },
|
|
13270
|
+
...input.codex === void 0 ? {} : { codex: input.codex }
|
|
13271
|
+
});
|
|
13272
|
+
const cache = input.credential.cache;
|
|
13273
|
+
const stored = cache === void 0 || cache === false ? created : updateProvider(paths, input.name, { cache });
|
|
13274
|
+
return { action: "created", kind: "provider", name: input.name, value: providerValue(input.name, stored) };
|
|
13275
|
+
})
|
|
13276
|
+
),
|
|
13277
|
+
set: route("/rest/config/provider/set", "Update an API provider definition").input(ConfigProviderSetInputSchema).output(ConfigProviderSetOutputSchema).handler(
|
|
13278
|
+
({ input }) => guarded(() => {
|
|
13279
|
+
requireChange(input.displayName !== void 0 || input.baseUrl !== void 0 || input.credential !== void 0 || input.codex !== void 0, "displayName, baseUrl, credential or codex");
|
|
13280
|
+
const existing = readProvider(paths, input.name);
|
|
13281
|
+
if (existing === void 0) {
|
|
13282
|
+
throw new ProviderNotFoundError(input.name);
|
|
13283
|
+
}
|
|
13284
|
+
const credential = input.credential;
|
|
13285
|
+
if (input.baseUrl !== void 0 && !isCodexProvider(existing) && input.baseUrl !== existing.baseUrl && credential?.sources === void 0) {
|
|
13286
|
+
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.` });
|
|
13287
|
+
}
|
|
13288
|
+
const cache = credential?.cache === void 0 ? void 0 : mergeCredentialCache(credential.cache === false ? { enabled: false } : { ...credential.cache, enabled: true }, existing.credential.cache);
|
|
13289
|
+
const updated = updateProvider(paths, input.name, {
|
|
13290
|
+
...input.displayName === void 0 ? {} : { displayName: input.displayName },
|
|
13291
|
+
...input.baseUrl === void 0 ? {} : { baseUrl: input.baseUrl },
|
|
13292
|
+
...credential?.sources === void 0 ? {} : { sources: credential.sources },
|
|
13293
|
+
...credential?.target === void 0 ? {} : { target: credential.target },
|
|
13294
|
+
...cache === void 0 ? {} : { cache },
|
|
13295
|
+
...input.codex === void 0 ? {} : { codex: input.codex }
|
|
13296
|
+
});
|
|
13297
|
+
return { action: "updated", kind: "provider", name: input.name, value: providerValue(input.name, updated) };
|
|
13298
|
+
})
|
|
13299
|
+
),
|
|
13300
|
+
remove: route("/rest/config/provider/remove", "Delete an API provider definition").input(ConfigProviderRemoveInputSchema).output(ConfigProviderRemoveOutputSchema).handler(({ input }) => {
|
|
13301
|
+
requireConfirmation(input.confirm, `provider "${input.name}"`);
|
|
13302
|
+
return guarded(() => {
|
|
13303
|
+
if (!providerExists(paths, input.name)) {
|
|
13304
|
+
throw new ProviderNotFoundError(input.name);
|
|
13305
|
+
}
|
|
13306
|
+
removeProvider(paths, input.name);
|
|
13307
|
+
return { action: "removed", kind: "provider", name: input.name };
|
|
13308
|
+
});
|
|
13309
|
+
})
|
|
13310
|
+
},
|
|
13311
|
+
rule: {
|
|
13312
|
+
add: route("/rest/config/rule/add", "Add a directory rule for a path").input(ConfigRuleAddInputSchema).output(ConfigRuleAddOutputSchema).handler(
|
|
13313
|
+
({ input }) => guarded(() => {
|
|
13314
|
+
if (input.identity !== void 0) {
|
|
13315
|
+
requireRuleSelector(paths, input.identity);
|
|
13316
|
+
}
|
|
13317
|
+
if (input.configProfile !== void 0) {
|
|
13318
|
+
requireProfileExists(paths, input.configProfile);
|
|
13319
|
+
}
|
|
13320
|
+
const created = addDirectoryRule(paths, input.path, {
|
|
13321
|
+
...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
|
|
13322
|
+
...input.identity === void 0 ? {} : { identity: input.identity }
|
|
13323
|
+
});
|
|
13324
|
+
return { action: "created", kind: "rule", name: input.path, value: created };
|
|
13325
|
+
})
|
|
13326
|
+
),
|
|
13327
|
+
set: route("/rest/config/rule/set", "Update the directory rule for a path").input(ConfigRuleSetInputSchema).output(ConfigRuleSetOutputSchema).handler(
|
|
13328
|
+
({ input }) => guarded(() => {
|
|
13329
|
+
requireChange(input.configProfile !== void 0 || input.identity !== void 0, "configProfile or identity");
|
|
13330
|
+
if (typeof input.identity === "string") {
|
|
13331
|
+
requireRuleSelector(paths, input.identity);
|
|
13332
|
+
}
|
|
13333
|
+
if (typeof input.configProfile === "string") {
|
|
13334
|
+
requireProfileExists(paths, input.configProfile);
|
|
13335
|
+
}
|
|
13336
|
+
const updated = updateDirectoryRule(paths, input.path, {
|
|
13337
|
+
...input.configProfile === void 0 ? {} : { configProfile: input.configProfile },
|
|
13338
|
+
...input.identity === void 0 ? {} : { identity: input.identity }
|
|
13339
|
+
});
|
|
13340
|
+
return { action: "updated", kind: "rule", name: input.path, value: updated };
|
|
13341
|
+
})
|
|
13342
|
+
),
|
|
13343
|
+
remove: route("/rest/config/rule/remove", "Remove the directory rule for a path").input(ConfigRuleRemoveInputSchema).output(ConfigRuleRemoveOutputSchema).handler(({ input }) => {
|
|
13344
|
+
requireConfirmation(input.confirm, `the directory rule for "${input.path}"`);
|
|
13345
|
+
return guarded(() => {
|
|
13346
|
+
if (!listDirectoryRules(paths).some((entry) => entry.path === input.path)) {
|
|
13347
|
+
throw new DirectoryRuleNotFoundError(input.path);
|
|
13348
|
+
}
|
|
13349
|
+
removeDirectoryRule(paths, input.path);
|
|
13350
|
+
return { action: "removed", kind: "rule", name: input.path };
|
|
13351
|
+
});
|
|
13352
|
+
})
|
|
13353
|
+
}
|
|
13354
|
+
}
|
|
13355
|
+
};
|
|
13356
|
+
}
|
|
13357
|
+
|
|
13358
|
+
// src/frontdoor/eventsApi.ts
|
|
13359
|
+
import { ORPCError as ORPCError3 } from "@orpc/client";
|
|
13360
|
+
import { openapi as openapi4 } from "@orpc/openapi";
|
|
13361
|
+
import { eventIterator as eventIterator2, withEventMeta as withEventMeta2 } from "@orpc/server";
|
|
13362
|
+
|
|
13363
|
+
// src/frontdoor/eventSchemas.ts
|
|
13364
|
+
import { z as z21 } from "zod";
|
|
13365
|
+
var DOOR_EVENT_SOURCE_RC = "rc";
|
|
13366
|
+
var LAUNCH_EVENT_SOURCE = "launch";
|
|
13367
|
+
var USAGE_EVENT_SOURCE = "usage";
|
|
13368
|
+
var DOOR_HEALTH_EVENT_SOURCE = "door";
|
|
13369
|
+
var QUOTA_EXPIRING_EVENT_SOURCE = "quota-expiring";
|
|
13370
|
+
var DoorEventSchema = z21.strictObject({
|
|
13371
|
+
source: z21.string().min(1),
|
|
13372
|
+
/** A positive integer because the backbone's counters start at one and only ever increase. */
|
|
13373
|
+
sequence: z21.number().int().positive(),
|
|
13374
|
+
payload: z21.unknown()
|
|
13375
|
+
});
|
|
13376
|
+
var DoorEventSourceQuerySchema = z21.strictObject({
|
|
13377
|
+
sources: z21.array(z21.string().min(1)).min(1).optional()
|
|
13378
|
+
});
|
|
13379
|
+
var LaunchLifecycleEventSchema = z21.strictObject({
|
|
13380
|
+
kind: z21.enum(["registered", "pruned", "ended"]),
|
|
13381
|
+
pid: z21.number().int().positive(),
|
|
13382
|
+
startedAt: z21.number(),
|
|
13383
|
+
observedAt: z21.number()
|
|
13384
|
+
});
|
|
13385
|
+
var DoorHealthEventSchema = z21.discriminatedUnion("kind", [
|
|
13386
|
+
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() }),
|
|
13387
|
+
z21.strictObject({ kind: z21.literal("listenerFailed"), pid: z21.number().int().positive(), listener: z21.enum(["provider", "connect", "direct"]), message: z21.string(), observedAt: z21.number() }),
|
|
13388
|
+
z21.strictObject({ kind: z21.literal("binaryTurnover"), pid: z21.number().int().positive(), observedAt: z21.number() }),
|
|
13389
|
+
z21.strictObject({ kind: z21.literal("idleShutdown"), pid: z21.number().int().positive(), observedAt: z21.number() })
|
|
13390
|
+
]);
|
|
13391
|
+
var QuotaExpiringEventSchema = z21.strictObject({
|
|
13392
|
+
identity: z21.string().min(1),
|
|
13393
|
+
provider: z21.string().min(1),
|
|
13394
|
+
window: z21.enum(["fiveHour", "sevenDay"]),
|
|
13395
|
+
/** 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. */
|
|
13396
|
+
utilization: z21.number().min(0).max(1),
|
|
13397
|
+
resetsAt: z21.iso.datetime(),
|
|
13398
|
+
observedAt: z21.number()
|
|
13399
|
+
});
|
|
13400
|
+
|
|
13401
|
+
// src/frontdoor/eventsApi.ts
|
|
13402
|
+
var EVENTS_API_TAG = "events";
|
|
13403
|
+
function createEventsApiRouter(deps) {
|
|
13404
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13405
|
+
return {
|
|
13406
|
+
events: {
|
|
13407
|
+
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 }) {
|
|
13408
|
+
if (input.sources !== void 0) {
|
|
13409
|
+
const live = deps.events.sources();
|
|
13410
|
+
const unknown = input.sources.filter((source) => !live.includes(source));
|
|
13411
|
+
if (unknown.length > 0) {
|
|
13412
|
+
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(", ")}` });
|
|
13413
|
+
}
|
|
13414
|
+
}
|
|
13415
|
+
const stream = deps.events.stream(input.sources);
|
|
13416
|
+
const ended = new Promise((resolve) => {
|
|
13417
|
+
signal?.addEventListener("abort", () => {
|
|
13418
|
+
resolve();
|
|
13419
|
+
}, { once: true });
|
|
13420
|
+
});
|
|
13421
|
+
try {
|
|
13422
|
+
for (; ; ) {
|
|
13423
|
+
signal?.throwIfAborted();
|
|
13424
|
+
const next = await Promise.race([stream.next(), ended.then(() => ({ value: void 0, done: true }))]);
|
|
13425
|
+
if (next.done === true) {
|
|
13426
|
+
signal?.throwIfAborted();
|
|
13427
|
+
return;
|
|
13428
|
+
}
|
|
13429
|
+
yield withEventMeta2(next.value, { id: String(next.value.sequence) });
|
|
13430
|
+
}
|
|
13431
|
+
} finally {
|
|
13432
|
+
stream.close();
|
|
13433
|
+
}
|
|
13434
|
+
})
|
|
13435
|
+
}
|
|
13436
|
+
};
|
|
13437
|
+
}
|
|
13438
|
+
|
|
13439
|
+
// src/frontdoor/lifecycleApi.ts
|
|
13440
|
+
init_update();
|
|
13441
|
+
import { ORPCError as ORPCError4 } from "@orpc/client";
|
|
13442
|
+
import { openapi as openapi5 } from "@orpc/openapi";
|
|
13443
|
+
var FRONTDOOR_API_TAG = "frontdoor";
|
|
13444
|
+
var UPDATE_API_TAG = "update";
|
|
13445
|
+
function createLifecycleApiRouter(deps) {
|
|
13446
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13447
|
+
return {
|
|
13448
|
+
frontdoor: {
|
|
13449
|
+
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 }) => {
|
|
13450
|
+
context.afterResponse(deps.restartDoor);
|
|
13451
|
+
return { action: "restarting", previousPid: deps.doorPid };
|
|
13452
|
+
})
|
|
13453
|
+
},
|
|
13454
|
+
update: {
|
|
13455
|
+
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 () => {
|
|
13456
|
+
try {
|
|
13457
|
+
return await deps.checkForUpdate();
|
|
13458
|
+
} catch (error) {
|
|
13459
|
+
if (error instanceof UpdateChannelError) {
|
|
13460
|
+
throw new ORPCError4("PRECONDITION_FAILED", { message: error.message });
|
|
13461
|
+
}
|
|
13462
|
+
if (error instanceof UpdateConflictError) {
|
|
13463
|
+
throw new ORPCError4("CONFLICT", { message: error.message });
|
|
13464
|
+
}
|
|
13465
|
+
if (error instanceof UpdateDownloadError) {
|
|
13466
|
+
throw new ORPCError4("BAD_GATEWAY", { message: error.message });
|
|
13467
|
+
}
|
|
13468
|
+
throw error;
|
|
13469
|
+
}
|
|
13470
|
+
})
|
|
13471
|
+
}
|
|
13472
|
+
};
|
|
13473
|
+
}
|
|
13474
|
+
|
|
13475
|
+
// src/frontdoor/launchApi.ts
|
|
13476
|
+
init_cliError();
|
|
13477
|
+
import { ORPCError as ORPCError5 } from "@orpc/client";
|
|
13478
|
+
import { openapi as openapi6 } from "@orpc/openapi";
|
|
13479
|
+
|
|
13480
|
+
// src/frontdoor/launchSchemas.ts
|
|
13481
|
+
import path30 from "node:path";
|
|
13482
|
+
import { z as z22 } from "zod";
|
|
13483
|
+
init_claudeVersion();
|
|
13484
|
+
init_identity();
|
|
13485
|
+
var LaunchResolveInputSchema = z22.strictObject({
|
|
13486
|
+
path: z22.string().min(1),
|
|
13487
|
+
/** `@name`, launch flags, then the arguments for `claude`; empty for a bare launch. */
|
|
13488
|
+
argv: z22.readonly(z22.array(z22.string())).optional(),
|
|
13489
|
+
/** 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. */
|
|
13490
|
+
env: z22.record(z22.string(), z22.string()).optional()
|
|
13491
|
+
}).refine((input) => path30.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
13492
|
+
var LaunchPoolDecisionSchema = z22.strictObject({
|
|
13493
|
+
name: z22.string(),
|
|
13494
|
+
reasons: z22.readonly(z22.array(z22.string())),
|
|
13495
|
+
movedOff: z22.strictObject({ identity: z22.string(), reason: z22.string() }).optional()
|
|
13496
|
+
});
|
|
13497
|
+
var LaunchDecisionSchema = z22.strictObject({
|
|
13498
|
+
identity: z22.string().optional(),
|
|
13499
|
+
identitySource: z22.enum(IDENTITY_DECISION_SOURCES),
|
|
13500
|
+
pool: LaunchPoolDecisionSchema.optional(),
|
|
13501
|
+
configDirEscapeHatch: z22.boolean(),
|
|
13502
|
+
configDir: z22.string().optional(),
|
|
13503
|
+
configProfile: z22.string().optional(),
|
|
13504
|
+
configProfileSource: z22.enum(CONFIG_PROFILE_DECISION_SOURCES),
|
|
13505
|
+
provider: z22.string().optional()
|
|
13506
|
+
});
|
|
13507
|
+
var LaunchFlagsSchema = z22.strictObject({
|
|
13508
|
+
skipPermissions: z22.boolean(),
|
|
13509
|
+
remoteControl: z22.boolean(),
|
|
13510
|
+
headroom: z22.boolean(),
|
|
13511
|
+
trackUsage: z22.boolean()
|
|
13512
|
+
});
|
|
13513
|
+
var LaunchResolveOutputSchema = z22.strictObject({
|
|
13514
|
+
decision: LaunchDecisionSchema,
|
|
13515
|
+
flags: LaunchFlagsSchema,
|
|
13516
|
+
claudeVersion: z22.strictObject({ version: z22.string(), source: z22.enum(CLAUDE_VERSION_SOURCES) }).optional(),
|
|
13517
|
+
/** The real `claude` binary the launch would spawn, on the door's host. */
|
|
13518
|
+
bin: z22.string(),
|
|
13519
|
+
/** The arguments the launch would pass it: the tool's own flags, then `CLAUDE_EXTRA_FLAGS`, then the caller's own. */
|
|
13520
|
+
args: z22.readonly(z22.array(z22.string())),
|
|
13521
|
+
/** The credential the launch would authenticate with, by target and source kinds. Absent when none applies. */
|
|
13522
|
+
credential: z22.strictObject({ subject: z22.enum(["provider", "identity"]), name: z22.string(), summary: CredentialSummarySchema }).optional(),
|
|
13523
|
+
routing: z22.strictObject({ frontDoor: z22.boolean(), headroom: z22.boolean() }),
|
|
13524
|
+
/** The names of the environment variables the launch would set or unset, sorted. Values are not reported. */
|
|
13525
|
+
environment: z22.readonly(z22.array(z22.string())),
|
|
13526
|
+
warnings: z22.readonly(z22.array(z22.string()))
|
|
13527
|
+
});
|
|
13528
|
+
|
|
13529
|
+
// src/frontdoor/launchApi.ts
|
|
13530
|
+
var LAUNCH_API_TAG = "launch";
|
|
13531
|
+
function createLaunchApiRouter(deps) {
|
|
13532
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
13533
|
+
return {
|
|
13534
|
+
launch: {
|
|
13535
|
+
resolve: authed.meta(openapi6({ method: "POST", path: "/rest/launch/resolve", summary: "Resolve what a launch from one directory would do, without performing it", tags: [LAUNCH_API_TAG] })).input(LaunchResolveInputSchema).output(LaunchResolveOutputSchema).handler(({ input }) => {
|
|
13536
|
+
try {
|
|
13537
|
+
const { resolution, warnings } = deps.resolveLaunch({ path: input.path, argv: input.argv ?? [], env: input.env ?? {} });
|
|
13538
|
+
return { ...resolution, warnings };
|
|
13539
|
+
} catch (error) {
|
|
13540
|
+
if (error instanceof CliError) {
|
|
13541
|
+
throw new ORPCError5("BAD_REQUEST", { message: error.message });
|
|
13542
|
+
}
|
|
13543
|
+
throw error;
|
|
13544
|
+
}
|
|
13545
|
+
})
|
|
13546
|
+
}
|
|
13547
|
+
};
|
|
13548
|
+
}
|
|
13549
|
+
|
|
13550
|
+
// src/frontdoor/controlApi.ts
|
|
13551
|
+
var USAGE_API_TAG = "usage";
|
|
13552
|
+
var FRONTDOOR_API_TAG2 = "frontdoor";
|
|
13553
|
+
var CHECK_API_TAG = "check";
|
|
13554
|
+
var DOCTOR_API_TAG = "doctor";
|
|
13555
|
+
var POOL_API_TAG = "pool";
|
|
13556
|
+
function createControlApiRouter(deps) {
|
|
13557
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
12645
13558
|
return {
|
|
12646
13559
|
usage: {
|
|
12647
|
-
list: authed.meta(
|
|
12648
|
-
effectiveWindow: authed.meta(
|
|
13560
|
+
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() })),
|
|
13561
|
+
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 }) => {
|
|
12649
13562
|
const snapshot = deps.usageSnapshotOf(input.identity);
|
|
12650
13563
|
if (snapshot === void 0) {
|
|
12651
|
-
throw new
|
|
13564
|
+
throw new ORPCError6("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
|
|
12652
13565
|
}
|
|
12653
13566
|
const provider = input.provider ?? ANTHROPIC_PROVIDER;
|
|
12654
13567
|
const rateLimit = snapshot.providers[provider]?.rateLimit;
|
|
@@ -12662,34 +13575,34 @@ function createControlApiRouter(deps) {
|
|
|
12662
13575
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
12663
13576
|
};
|
|
12664
13577
|
}),
|
|
12665
|
-
live: authed.meta(
|
|
13578
|
+
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 }) => {
|
|
12666
13579
|
const sessions = deps.liveRateLimits(input.session);
|
|
12667
13580
|
if (input.session !== void 0 && sessions.length === 0) {
|
|
12668
13581
|
if (deps.list().some((session) => session.id === input.session)) {
|
|
12669
|
-
throw new
|
|
13582
|
+
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` });
|
|
12670
13583
|
}
|
|
12671
|
-
throw new
|
|
13584
|
+
throw new ORPCError6("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
12672
13585
|
}
|
|
12673
13586
|
return { latest: deps.latestRateLimit(), sessions };
|
|
12674
13587
|
})
|
|
12675
13588
|
},
|
|
12676
13589
|
frontdoor: {
|
|
12677
|
-
status: authed.meta(
|
|
12678
|
-
sessions: authed.meta(
|
|
13590
|
+
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()),
|
|
13591
|
+
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 }))
|
|
12679
13592
|
},
|
|
12680
13593
|
check: {
|
|
12681
13594
|
// 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.
|
|
12682
|
-
run: authed.meta(
|
|
13595
|
+
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)))
|
|
12683
13596
|
},
|
|
12684
13597
|
doctor: {
|
|
12685
|
-
run: authed.meta(
|
|
13598
|
+
run: authed.meta(openapi7({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
|
|
12686
13599
|
},
|
|
12687
13600
|
pool: {
|
|
12688
|
-
pick: authed.meta(
|
|
13601
|
+
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 }) => {
|
|
12689
13602
|
const report = deps.poolPick(input.pool, input.path);
|
|
12690
13603
|
if (report === void 0) {
|
|
12691
13604
|
const live = deps.poolNames();
|
|
12692
|
-
throw new
|
|
13605
|
+
throw new ORPCError6("NOT_FOUND", {
|
|
12693
13606
|
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(", ")}`
|
|
12694
13607
|
});
|
|
12695
13608
|
}
|
|
@@ -12699,7 +13612,9 @@ function createControlApiRouter(deps) {
|
|
|
12699
13612
|
};
|
|
12700
13613
|
}
|
|
12701
13614
|
function createDoorApiRouter(deps) {
|
|
12702
|
-
|
|
13615
|
+
const control = createControlApiRouter(deps);
|
|
13616
|
+
const lifecycle = createLifecycleApiRouter(deps);
|
|
13617
|
+
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
12703
13618
|
}
|
|
12704
13619
|
function createDoorApiNodeHandler(deps) {
|
|
12705
13620
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
@@ -13511,9 +14426,9 @@ async function serveRcCompatSessions(ctx, pathname, compatPath) {
|
|
|
13511
14426
|
const slash = rest.indexOf("/");
|
|
13512
14427
|
const address = slash === -1 ? rest : rest.slice(0, slash);
|
|
13513
14428
|
const compatTail = slash === -1 ? "" : rest.slice(slash + 1);
|
|
13514
|
-
const
|
|
13515
|
-
if (
|
|
13516
|
-
await ctx.unauthorized(response,
|
|
14429
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14430
|
+
if (refusal2 !== void 0) {
|
|
14431
|
+
await ctx.unauthorized(response, refusal2);
|
|
13517
14432
|
return;
|
|
13518
14433
|
}
|
|
13519
14434
|
const session = ctx.sessions.get(address) ?? ctx.sessions.get(`cse_${address}`);
|
|
@@ -13591,9 +14506,9 @@ function conversationRow(conversation) {
|
|
|
13591
14506
|
}
|
|
13592
14507
|
async function serveRcConversations(ctx, pathname, method) {
|
|
13593
14508
|
const { request: request4, response, conversations } = ctx;
|
|
13594
|
-
const
|
|
13595
|
-
if (
|
|
13596
|
-
await ctx.unauthorized(response,
|
|
14509
|
+
const refusal2 = ctx.credentialRefusal(request4.headers);
|
|
14510
|
+
if (refusal2 !== void 0) {
|
|
14511
|
+
await ctx.unauthorized(response, refusal2);
|
|
13597
14512
|
return;
|
|
13598
14513
|
}
|
|
13599
14514
|
if (pathname === RC_CONVERSATIONS_PATH_PREFIX) {
|
|
@@ -13917,9 +14832,9 @@ async function fetchThroughWebProxy(url, deps) {
|
|
|
13917
14832
|
try {
|
|
13918
14833
|
let redirects = 0;
|
|
13919
14834
|
for (; ; ) {
|
|
13920
|
-
const
|
|
13921
|
-
if (
|
|
13922
|
-
return
|
|
14835
|
+
const refusal2 = await checkTarget(current, deps);
|
|
14836
|
+
if (refusal2 !== void 0) {
|
|
14837
|
+
return refusal2;
|
|
13923
14838
|
}
|
|
13924
14839
|
let hop;
|
|
13925
14840
|
try {
|
|
@@ -14289,8 +15204,8 @@ data: ${JSON.stringify(envelope)}
|
|
|
14289
15204
|
"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",
|
|
14290
15205
|
unrecognised: "the self-hosted Remote Control surface did not recognise the presented credential"
|
|
14291
15206
|
};
|
|
14292
|
-
const unauthorized = async (response,
|
|
14293
|
-
await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[
|
|
15207
|
+
const unauthorized = async (response, refusal2) => {
|
|
15208
|
+
await answerJson2(response, HTTP_STATUS.unauthorized, { type: "error", error: { type: "authentication_error", message: refusalMessages[refusal2] } });
|
|
14294
15209
|
};
|
|
14295
15210
|
const serveSessionPath = async (session, tail, request4, response) => {
|
|
14296
15211
|
const method = request4.method.toUpperCase();
|
|
@@ -14301,9 +15216,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14301
15216
|
session.lastTrafficAt = deps.now();
|
|
14302
15217
|
if (tail === "") {
|
|
14303
15218
|
if (method === "PATCH" || method === "PUT") {
|
|
14304
|
-
const
|
|
14305
|
-
if (
|
|
14306
|
-
await unauthorized(response,
|
|
15219
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15220
|
+
if (refusal2 !== void 0) {
|
|
15221
|
+
await unauthorized(response, refusal2);
|
|
14307
15222
|
return;
|
|
14308
15223
|
}
|
|
14309
15224
|
const body = parseJsonObject5(await readBody2(request4.body, CONTROL_BODY_CAP_BYTES));
|
|
@@ -14326,9 +15241,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14326
15241
|
return;
|
|
14327
15242
|
}
|
|
14328
15243
|
if (tail === "bridge" && method === "POST") {
|
|
14329
|
-
const
|
|
14330
|
-
if (
|
|
14331
|
-
await unauthorized(response,
|
|
15244
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15245
|
+
if (refusal2 !== void 0) {
|
|
15246
|
+
await unauthorized(response, refusal2);
|
|
14332
15247
|
return;
|
|
14333
15248
|
}
|
|
14334
15249
|
const workerJwt = mintWorkerJwt(deps.randomToken, deps.now());
|
|
@@ -14338,9 +15253,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14338
15253
|
return;
|
|
14339
15254
|
}
|
|
14340
15255
|
if (tail === "archive" && method === "POST") {
|
|
14341
|
-
const
|
|
14342
|
-
if (
|
|
14343
|
-
await unauthorized(response,
|
|
15256
|
+
const refusal2 = credentialRefusal(request4.headers);
|
|
15257
|
+
if (refusal2 !== void 0) {
|
|
15258
|
+
await unauthorized(response, refusal2);
|
|
14344
15259
|
return;
|
|
14345
15260
|
}
|
|
14346
15261
|
retireSession(session);
|
|
@@ -14351,9 +15266,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
14351
15266
|
if (tail === "worker" || tail.startsWith("worker/")) {
|
|
14352
15267
|
const workerTail = tail === "worker" ? "" : tail.slice("worker/".length);
|
|
14353
15268
|
const webProxy = workerTail === "web-fetch" || workerTail === "web-search";
|
|
14354
|
-
const
|
|
14355
|
-
if (
|
|
14356
|
-
await unauthorized(response,
|
|
15269
|
+
const refusal2 = webProxy ? workerOrCredentialRefusal(request4.headers, session) : workerRefusal(request4.headers, session);
|
|
15270
|
+
if (refusal2 !== void 0) {
|
|
15271
|
+
await unauthorized(response, refusal2);
|
|
14357
15272
|
return;
|
|
14358
15273
|
}
|
|
14359
15274
|
if (workerTail === "" && method === "GET") {
|
|
@@ -14660,7 +15575,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
14660
15575
|
|
|
14661
15576
|
// src/frontdoor/rcSelfHostMint.ts
|
|
14662
15577
|
init_account();
|
|
14663
|
-
import
|
|
15578
|
+
import path31 from "node:path";
|
|
14664
15579
|
var CREDENTIALS_FILE = ".credentials.json";
|
|
14665
15580
|
var CLAUDE_JSON2 = ".claude.json";
|
|
14666
15581
|
var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
|
|
@@ -14684,7 +15599,7 @@ function readJsonObject(fs12, file) {
|
|
|
14684
15599
|
return isRecord11(parsed) ? parsed : void 0;
|
|
14685
15600
|
}
|
|
14686
15601
|
function readRcSelfHostRecord(fs12, frontdoorDir) {
|
|
14687
|
-
const parsed = readJsonObject(fs12,
|
|
15602
|
+
const parsed = readJsonObject(fs12, path31.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
14688
15603
|
if (parsed === void 0) {
|
|
14689
15604
|
return void 0;
|
|
14690
15605
|
}
|
|
@@ -14698,11 +15613,11 @@ function mintRcSelfHostCredential(deps) {
|
|
|
14698
15613
|
if (!isIdentityName(deps.identity)) {
|
|
14699
15614
|
throw new Error(`"${deps.identity}" is not a valid identity name.`);
|
|
14700
15615
|
}
|
|
14701
|
-
const identityDir =
|
|
14702
|
-
const credentialsFile =
|
|
14703
|
-
const claudeJsonFile =
|
|
14704
|
-
const recordDir =
|
|
14705
|
-
const recordFile =
|
|
15616
|
+
const identityDir = path31.join(deps.identitiesDir, deps.identity);
|
|
15617
|
+
const credentialsFile = path31.join(identityDir, CREDENTIALS_FILE);
|
|
15618
|
+
const claudeJsonFile = path31.join(identityDir, CLAUDE_JSON2);
|
|
15619
|
+
const recordDir = path31.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
|
|
15620
|
+
const recordFile = path31.join(recordDir, RC_SELF_HOST_RECORD_FILE);
|
|
14706
15621
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
14707
15622
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
14708
15623
|
const existingOauth = isRecord11(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
@@ -14718,7 +15633,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
14718
15633
|
const organizationUuid = deps.newUuid();
|
|
14719
15634
|
const accountUuid = deps.newUuid();
|
|
14720
15635
|
const mintedAt = new Date(deps.now()).toISOString();
|
|
14721
|
-
deps.fs.mkdirPrivate(
|
|
15636
|
+
deps.fs.mkdirPrivate(path31.dirname(credentialsFile));
|
|
14722
15637
|
deps.fs.writeFilePrivate(credentialsFile, `${JSON.stringify({ ...existingCredentials, claudeAiOauth: { accessToken, refreshToken, expiresAt: null, scopes: [...RC_SELF_HOST_SCOPE_LIST], subscriptionType: SELF_HOST_SUBSCRIPTION_TYPE, rateLimitTier: null } }, null, 2)}
|
|
14723
15638
|
`);
|
|
14724
15639
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|
|
@@ -14766,102 +15681,6 @@ init_paths();
|
|
|
14766
15681
|
init_cliError();
|
|
14767
15682
|
init_schema();
|
|
14768
15683
|
init_providersStore();
|
|
14769
|
-
|
|
14770
|
-
// src/directoryRulesStore.ts
|
|
14771
|
-
init_store();
|
|
14772
|
-
init_load();
|
|
14773
|
-
init_schema();
|
|
14774
|
-
init_cliError();
|
|
14775
|
-
var DirectoryRuleNotFoundError = class extends CliError {
|
|
14776
|
-
constructor(rulePath) {
|
|
14777
|
-
super(`No directory rule found for path "${rulePath}".`);
|
|
14778
|
-
this.rulePath = rulePath;
|
|
14779
|
-
this.name = "DirectoryRuleNotFoundError";
|
|
14780
|
-
}
|
|
14781
|
-
rulePath;
|
|
14782
|
-
};
|
|
14783
|
-
var DirectoryRuleMissingTargetError = class extends CliError {
|
|
14784
|
-
constructor() {
|
|
14785
|
-
super("A directory rule must set at least one of --config-profile or --identity.");
|
|
14786
|
-
this.name = "DirectoryRuleMissingTargetError";
|
|
14787
|
-
}
|
|
14788
|
-
};
|
|
14789
|
-
var DirectoryRuleAlreadyExistsError = class extends CliError {
|
|
14790
|
-
constructor(rulePath) {
|
|
14791
|
-
super(`A directory rule for path "${rulePath}" already exists. Use \`agent-shim rule set\` to change it.`);
|
|
14792
|
-
this.rulePath = rulePath;
|
|
14793
|
-
this.name = "DirectoryRuleAlreadyExistsError";
|
|
14794
|
-
}
|
|
14795
|
-
rulePath;
|
|
14796
|
-
};
|
|
14797
|
-
function readDirectoryRules(paths) {
|
|
14798
|
-
return readJson(paths.directoryRulesFile, DirectoryRulesSchema) ?? { rules: [] };
|
|
14799
|
-
}
|
|
14800
|
-
function writeDirectoryRules(paths, rules) {
|
|
14801
|
-
const parsed = DirectoryRulesSchema.safeParse(rules);
|
|
14802
|
-
if (!parsed.success) {
|
|
14803
|
-
throw new ConfigValidationError(paths.directoryRulesFile, parsed.error.issues);
|
|
14804
|
-
}
|
|
14805
|
-
writeJsonAtomic(paths.directoryRulesFile, parsed.data);
|
|
14806
|
-
}
|
|
14807
|
-
function listDirectoryRules(paths) {
|
|
14808
|
-
return readDirectoryRules(paths).rules;
|
|
14809
|
-
}
|
|
14810
|
-
function addDirectoryRule(paths, rulePath, options) {
|
|
14811
|
-
if (options.configProfile === void 0 && options.identity === void 0) {
|
|
14812
|
-
throw new DirectoryRuleMissingTargetError();
|
|
14813
|
-
}
|
|
14814
|
-
const current = readDirectoryRules(paths);
|
|
14815
|
-
if (current.rules.some((rule) => rule.path === rulePath)) {
|
|
14816
|
-
throw new DirectoryRuleAlreadyExistsError(rulePath);
|
|
14817
|
-
}
|
|
14818
|
-
const created = buildNewRule(rulePath, options);
|
|
14819
|
-
writeDirectoryRules(paths, { ...current, rules: [...current.rules, created] });
|
|
14820
|
-
return created;
|
|
14821
|
-
}
|
|
14822
|
-
function ruleHasEffect(rule) {
|
|
14823
|
-
return rule.configProfile !== void 0 || rule.identity !== void 0 || rule.categories !== void 0 || rule.entries !== void 0 || rule.launch !== void 0;
|
|
14824
|
-
}
|
|
14825
|
-
function updateDirectoryRule(paths, rulePath, options) {
|
|
14826
|
-
const current = readDirectoryRules(paths);
|
|
14827
|
-
const index = current.rules.findIndex((rule) => rule.path === rulePath);
|
|
14828
|
-
const existing = index === -1 ? void 0 : current.rules[index];
|
|
14829
|
-
if (existing === void 0) {
|
|
14830
|
-
throw new DirectoryRuleNotFoundError(rulePath);
|
|
14831
|
-
}
|
|
14832
|
-
const { configProfile, identity, ...rest } = existing;
|
|
14833
|
-
const nextConfigProfile = options.configProfile === void 0 ? configProfile : options.configProfile === false ? void 0 : options.configProfile;
|
|
14834
|
-
const nextIdentity = options.identity === void 0 ? identity : options.identity === false ? void 0 : options.identity;
|
|
14835
|
-
const updated = {
|
|
14836
|
-
...rest,
|
|
14837
|
-
...nextConfigProfile === void 0 ? {} : { configProfile: nextConfigProfile },
|
|
14838
|
-
...nextIdentity === void 0 ? {} : { identity: nextIdentity }
|
|
14839
|
-
};
|
|
14840
|
-
if (!ruleHasEffect(updated)) {
|
|
14841
|
-
throw new DirectoryRuleMissingTargetError();
|
|
14842
|
-
}
|
|
14843
|
-
const nextRules = [...current.rules];
|
|
14844
|
-
nextRules[index] = updated;
|
|
14845
|
-
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
14846
|
-
return updated;
|
|
14847
|
-
}
|
|
14848
|
-
function buildNewRule(rulePath, options) {
|
|
14849
|
-
return {
|
|
14850
|
-
path: rulePath,
|
|
14851
|
-
...options.configProfile !== void 0 ? { configProfile: options.configProfile } : {},
|
|
14852
|
-
...options.identity !== void 0 ? { identity: options.identity } : {}
|
|
14853
|
-
};
|
|
14854
|
-
}
|
|
14855
|
-
function removeDirectoryRule(paths, rulePath) {
|
|
14856
|
-
const current = readDirectoryRules(paths);
|
|
14857
|
-
const nextRules = current.rules.filter((rule) => rule.path !== rulePath);
|
|
14858
|
-
if (nextRules.length === current.rules.length) {
|
|
14859
|
-
throw new DirectoryRuleNotFoundError(rulePath);
|
|
14860
|
-
}
|
|
14861
|
-
writeDirectoryRules(paths, { ...current, rules: nextRules });
|
|
14862
|
-
}
|
|
14863
|
-
|
|
14864
|
-
// src/index.ts
|
|
14865
15684
|
init_launcher();
|
|
14866
15685
|
init_spawn();
|
|
14867
15686
|
init_launchWiring();
|
|
@@ -14972,10 +15791,47 @@ export {
|
|
|
14972
15791
|
CheckReportJsonSchema,
|
|
14973
15792
|
CheckRunInputSchema,
|
|
14974
15793
|
CliError,
|
|
15794
|
+
CodexLogoutOutputSchema,
|
|
15795
|
+
CodexSignInSchema,
|
|
15796
|
+
CodexStatusOutputSchema,
|
|
15797
|
+
ConfigIdentityAddOutputSchema,
|
|
15798
|
+
ConfigIdentityRemoveInputSchema,
|
|
15799
|
+
ConfigIdentityRemoveOutputSchema,
|
|
15800
|
+
ConfigIdentitySetInputSchema,
|
|
15801
|
+
ConfigIdentitySetOutputSchema,
|
|
15802
|
+
ConfigIdentityUseOutputSchema,
|
|
15803
|
+
ConfigNameInputSchema,
|
|
15804
|
+
ConfigPoolAddInputSchema,
|
|
15805
|
+
ConfigPoolAddOutputSchema,
|
|
15806
|
+
ConfigPoolRemoveInputSchema,
|
|
15807
|
+
ConfigPoolRemoveOutputSchema,
|
|
15808
|
+
ConfigPoolSetInputSchema,
|
|
15809
|
+
ConfigPoolSetOutputSchema,
|
|
15810
|
+
ConfigPoolUseOutputSchema,
|
|
15811
|
+
ConfigProfileAddInputSchema,
|
|
15812
|
+
ConfigProfileAddOutputSchema,
|
|
15813
|
+
ConfigProfileRemoveInputSchema,
|
|
15814
|
+
ConfigProfileRemoveOutputSchema,
|
|
14975
15815
|
ConfigProfileSchema,
|
|
15816
|
+
ConfigProfileSetInputSchema,
|
|
15817
|
+
ConfigProfileSetOutputSchema,
|
|
15818
|
+
ConfigProfileUseOutputSchema,
|
|
15819
|
+
ConfigProviderAddInputSchema,
|
|
15820
|
+
ConfigProviderAddOutputSchema,
|
|
15821
|
+
ConfigProviderRemoveInputSchema,
|
|
15822
|
+
ConfigProviderRemoveOutputSchema,
|
|
15823
|
+
ConfigProviderSetInputSchema,
|
|
15824
|
+
ConfigProviderSetOutputSchema,
|
|
15825
|
+
ConfigRuleAddInputSchema,
|
|
15826
|
+
ConfigRuleAddOutputSchema,
|
|
15827
|
+
ConfigRuleRemoveInputSchema,
|
|
15828
|
+
ConfigRuleRemoveOutputSchema,
|
|
15829
|
+
ConfigRuleSetInputSchema,
|
|
15830
|
+
ConfigRuleSetOutputSchema,
|
|
14976
15831
|
CredentialCacheSchema,
|
|
14977
15832
|
CredentialSchema,
|
|
14978
15833
|
CredentialSourceSchema,
|
|
15834
|
+
CredentialSummarySchema2 as CredentialSummarySchema,
|
|
14979
15835
|
DOOR_EVENT_BUFFER_EVENTS,
|
|
14980
15836
|
DOOR_EVENT_SOURCE_RC,
|
|
14981
15837
|
DOOR_HEALTH_EVENT_SOURCE,
|
|
@@ -14996,6 +15852,7 @@ export {
|
|
|
14996
15852
|
FARM_MANIFEST_FILENAME,
|
|
14997
15853
|
FrontDoorControlMaterialError,
|
|
14998
15854
|
FrontDoorNotServingError,
|
|
15855
|
+
FrontDoorRestartOutputSchema,
|
|
14999
15856
|
FrontDoorSessionStatusSchema,
|
|
15000
15857
|
FrontDoorSessionsOutputSchema,
|
|
15001
15858
|
FrontDoorStartError,
|
|
@@ -15013,6 +15870,8 @@ export {
|
|
|
15013
15870
|
LAUNCH_EVENT_SOURCE,
|
|
15014
15871
|
LaunchLifecycleEventSchema,
|
|
15015
15872
|
LaunchRefusedError,
|
|
15873
|
+
LaunchResolveInputSchema,
|
|
15874
|
+
LaunchResolveOutputSchema,
|
|
15016
15875
|
LegacyProviderFileError,
|
|
15017
15876
|
OWN_CLI_FILE_NAME,
|
|
15018
15877
|
PROMPT_CACHE_TTL_MS,
|
|
@@ -15059,6 +15918,7 @@ export {
|
|
|
15059
15918
|
RcStreamEnvelopeSchema,
|
|
15060
15919
|
RcStreamEventSchema,
|
|
15061
15920
|
USAGE_EVENT_SOURCE,
|
|
15921
|
+
UpdateCheckOutputSchema,
|
|
15062
15922
|
UsageError,
|
|
15063
15923
|
UsageListOutputSchema,
|
|
15064
15924
|
UsageLiveOutputSchema,
|
|
@@ -15101,14 +15961,18 @@ export {
|
|
|
15101
15961
|
collectDoctorReport,
|
|
15102
15962
|
collectFrontDoorStatus,
|
|
15103
15963
|
collectPoolPick,
|
|
15964
|
+
createCodexApiRouter,
|
|
15965
|
+
createConfigApiRouter,
|
|
15104
15966
|
createControlApiRouter,
|
|
15105
15967
|
createDoorApiNodeHandler,
|
|
15106
15968
|
createDoorApiRouter,
|
|
15107
15969
|
createDoorEventHub,
|
|
15108
15970
|
createDoorHealthPublisher,
|
|
15109
15971
|
createEventsApiRouter,
|
|
15972
|
+
createLaunchApiRouter,
|
|
15110
15973
|
createLaunchEventPublisher,
|
|
15111
15974
|
createLeafCache,
|
|
15975
|
+
createLifecycleApiRouter,
|
|
15112
15976
|
createProfile,
|
|
15113
15977
|
createQuotaExpiringPublisher,
|
|
15114
15978
|
createRcApiNodeHandler,
|
|
@@ -15216,7 +16080,9 @@ export {
|
|
|
15216
16080
|
requirePool,
|
|
15217
16081
|
resolveAgentShimHome,
|
|
15218
16082
|
resolveClaudeHome,
|
|
16083
|
+
resolveClaudeLaunch,
|
|
15219
16084
|
resolveDecisions,
|
|
16085
|
+
resolveLaunch,
|
|
15220
16086
|
resolveLaunchSelection,
|
|
15221
16087
|
resolveLayoutPaths,
|
|
15222
16088
|
resolveSupervisorConfig,
|