claude-use 9.16.0 → 9.18.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 +4 -2
- package/dist/cli.cjs +1133 -487
- package/dist/index.cjs +403 -188
- package/dist/index.mjs +379 -176
- package/dist/types/index.d.ts +384 -133
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2669,7 +2669,7 @@ var init_package = __esm({
|
|
|
2669
2669
|
"package.json"() {
|
|
2670
2670
|
package_default = {
|
|
2671
2671
|
name: "claude-use",
|
|
2672
|
-
version: "9.
|
|
2672
|
+
version: "9.18.0",
|
|
2673
2673
|
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.",
|
|
2674
2674
|
license: "MIT",
|
|
2675
2675
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -4791,22 +4791,25 @@ function rankPool(input) {
|
|
|
4791
4791
|
return { ...candidate, feasible: true };
|
|
4792
4792
|
}
|
|
4793
4793
|
const drySpots = [];
|
|
4794
|
+
const dryAfterMs = [];
|
|
4794
4795
|
if (fiveHour !== void 0 && pace !== void 0) {
|
|
4795
4796
|
const runsDryInMs = fiveHour.remaining / pace;
|
|
4796
4797
|
if (runsDryInMs < fiveHour.untilResetMs) {
|
|
4798
|
+
dryAfterMs.push(runsDryInMs);
|
|
4797
4799
|
drySpots.push(`5h window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(fiveHour.untilResetMs)}`);
|
|
4798
4800
|
}
|
|
4799
4801
|
}
|
|
4800
4802
|
if (sevenDay !== void 0 && sevenDayBurn !== void 0) {
|
|
4801
4803
|
const runsDryInMs = sevenDay.remaining / sevenDayBurn;
|
|
4802
4804
|
if (runsDryInMs < sevenDay.untilResetMs) {
|
|
4805
|
+
dryAfterMs.push(runsDryInMs);
|
|
4803
4806
|
drySpots.push(`7d window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(sevenDay.untilResetMs)}`);
|
|
4804
4807
|
}
|
|
4805
4808
|
}
|
|
4806
4809
|
if (drySpots.length === 0) {
|
|
4807
4810
|
return { ...candidate, feasible: true };
|
|
4808
4811
|
}
|
|
4809
|
-
return { ...candidate, feasible: false, reasons: [...drySpots, ...candidate.reasons] };
|
|
4812
|
+
return { ...candidate, feasible: false, runsDryAtMs: nowMs + Math.min(...dryAfterMs), reasons: [...drySpots, ...candidate.reasons] };
|
|
4810
4813
|
});
|
|
4811
4814
|
const ordered = input.preference === "listed" ? [...candidates] : [...candidates].sort(
|
|
4812
4815
|
(left, right) => CLASS_ORDER[left.class] - CLASS_ORDER[right.class] || Number(left.policyDemoted ?? false) - Number(right.policyDemoted ?? false) || Number(right.feasible) - Number(left.feasible) || (right.headroom ?? 1) - (left.headroom ?? 1) || (right.score ?? 0) - (left.score ?? 0) || left.identity.localeCompare(right.identity)
|
|
@@ -4828,11 +4831,13 @@ function rankPool(input) {
|
|
|
4828
4831
|
const pick = ordered.find((candidate) => candidate.class !== "ineligible");
|
|
4829
4832
|
const returns = ordered.flatMap((candidate) => candidate.blockedUntilMs === void 0 ? [] : [{ identity: candidate.identity, atMs: candidate.blockedUntilMs }]);
|
|
4830
4833
|
const earliestReturn = returns.length === 0 ? void 0 : returns.reduce((soonest, entry) => entry.atMs < soonest.atMs ? entry : soonest);
|
|
4834
|
+
const holdForReturn = pick?.runsDryAtMs === void 0 ? void 0 : returns.filter((entry) => entry.atMs < (pick.runsDryAtMs ?? 0)).reduce((soonest, entry) => soonest === void 0 || entry.atMs < soonest.atMs ? entry : soonest, void 0);
|
|
4831
4835
|
return {
|
|
4832
4836
|
candidates: ordered,
|
|
4833
4837
|
...pick === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick },
|
|
4834
4838
|
...movedOff === void 0 || pick === void 0 ? {} : { movedOff },
|
|
4835
|
-
...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } }
|
|
4839
|
+
...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } },
|
|
4840
|
+
...holdForReturn === void 0 ? {} : { holdForReturn }
|
|
4836
4841
|
};
|
|
4837
4842
|
}
|
|
4838
4843
|
var MS_PER_SECOND4, MS_PER_HOUR2, HOURS_PER_DAY2, FIVE_HOURS, PROMPT_CACHE_TTL_HOURS, PERCENT, SEVEN_DAYS, FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, PROMPT_CACHE_TTL_MS, CLASS_ORDER;
|
|
@@ -6630,7 +6635,7 @@ var init_headers = __esm({
|
|
|
6630
6635
|
});
|
|
6631
6636
|
|
|
6632
6637
|
// src/launcher/flags.ts
|
|
6633
|
-
import
|
|
6638
|
+
import path35 from "node:path";
|
|
6634
6639
|
function resolveLaunchFlags(params) {
|
|
6635
6640
|
return {
|
|
6636
6641
|
skipPermissions: params.flags?.skipPermissions ?? parseEnvBool("AGENT_SHIM_SKIP_PERMISSIONS", params.env.AGENT_SHIM_SKIP_PERMISSIONS) ?? params.cascade?.skipPermissions ?? false,
|
|
@@ -6661,7 +6666,7 @@ function buildEnv(params) {
|
|
|
6661
6666
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
6662
6667
|
let providerCustomHeaders;
|
|
6663
6668
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
6664
|
-
env.CLAUDE_CONFIG_DIR =
|
|
6669
|
+
env.CLAUDE_CONFIG_DIR = path35.join(params.identitiesDir, params.resolvedIdentityName);
|
|
6665
6670
|
}
|
|
6666
6671
|
if (params.provider !== void 0) {
|
|
6667
6672
|
const providerEnv = params.provider.definition.env ?? {};
|
|
@@ -6782,12 +6787,17 @@ function resolvePoolLaunch(params) {
|
|
|
6782
6787
|
if (graph.ranking.candidates.length === 0) {
|
|
6783
6788
|
return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
|
|
6784
6789
|
}
|
|
6785
|
-
const { pick, earliestReturn, movedOff, planReturn } = graph.ranking;
|
|
6790
|
+
const { pick, earliestReturn, movedOff, planReturn, holdForReturn } = graph.ranking;
|
|
6786
6791
|
if (pick !== void 0 && params.wait && planReturn !== void 0) {
|
|
6787
6792
|
log.info(`agent-shim: pool "${poolName}" would continue ${planReturn.identity} on extra usage; waiting until ${new Date(planReturn.atMs).toISOString()} for its plan window`);
|
|
6788
6793
|
params.sleep(Math.max(planReturn.atMs - nowMs, 0));
|
|
6789
6794
|
continue;
|
|
6790
6795
|
}
|
|
6796
|
+
if (pick !== void 0 && params.wait && holdForReturn !== void 0) {
|
|
6797
|
+
log.info(`agent-shim: pool "${poolName}" pick ${pick.identity} would run dry before its window resets; waiting until ${new Date(holdForReturn.atMs).toISOString()} for ${holdForReturn.identity}`);
|
|
6798
|
+
params.sleep(Math.max(holdForReturn.atMs - nowMs, 0));
|
|
6799
|
+
continue;
|
|
6800
|
+
}
|
|
6791
6801
|
if (pick !== void 0) {
|
|
6792
6802
|
if (params.recordPick) {
|
|
6793
6803
|
recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
|
|
@@ -6928,7 +6938,7 @@ var init_launchHook = __esm({
|
|
|
6928
6938
|
|
|
6929
6939
|
// src/launcher.ts
|
|
6930
6940
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
6931
|
-
import
|
|
6941
|
+
import path36 from "node:path";
|
|
6932
6942
|
function resolveIdentityCredential(identity, credential, env, port) {
|
|
6933
6943
|
if (port === void 0) {
|
|
6934
6944
|
return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
|
|
@@ -7038,7 +7048,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7038
7048
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
7039
7049
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
7040
7050
|
});
|
|
7041
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(
|
|
7051
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(path36.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
7042
7052
|
log.error(
|
|
7043
7053
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
7044
7054
|
);
|
|
@@ -7150,7 +7160,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7150
7160
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
7151
7161
|
passthrough: parsedArgv.rest
|
|
7152
7162
|
});
|
|
7153
|
-
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR :
|
|
7163
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path36.join(paths.identitiesDir, identityDecision.name);
|
|
7154
7164
|
const decision = {
|
|
7155
7165
|
identitySource: identityDecision.source,
|
|
7156
7166
|
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
@@ -7191,7 +7201,7 @@ function prepareLaunch(params) {
|
|
|
7191
7201
|
);
|
|
7192
7202
|
const updateCheck = runLaunchUpdateCheck({
|
|
7193
7203
|
mode: params.updateMode ?? "off",
|
|
7194
|
-
checkPath:
|
|
7204
|
+
checkPath: path36.join(paths.root, "update.check"),
|
|
7195
7205
|
currentVersion: package_default.version,
|
|
7196
7206
|
port: params.update
|
|
7197
7207
|
});
|
|
@@ -7351,12 +7361,12 @@ var init_launcher = __esm({
|
|
|
7351
7361
|
});
|
|
7352
7362
|
|
|
7353
7363
|
// src/ownCli.ts
|
|
7354
|
-
import
|
|
7364
|
+
import path37 from "node:path";
|
|
7355
7365
|
function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
|
|
7356
7366
|
if (distDir === void 0) {
|
|
7357
7367
|
throw new OwnCliPathUnknownError();
|
|
7358
7368
|
}
|
|
7359
|
-
return
|
|
7369
|
+
return path37.join(distDir, OWN_CLI_FILE_NAME);
|
|
7360
7370
|
}
|
|
7361
7371
|
var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
7362
7372
|
var init_ownCli = __esm({
|
|
@@ -7445,10 +7455,10 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
|
|
|
7445
7455
|
|
|
7446
7456
|
// src/frontdoor/trust.ts
|
|
7447
7457
|
import { createHash as createHash6 } from "node:crypto";
|
|
7448
|
-
import
|
|
7458
|
+
import path38 from "node:path";
|
|
7449
7459
|
function resolveTrustBundle(params) {
|
|
7450
7460
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
|
|
7451
|
-
if (inherited === void 0 || inherited === "" ||
|
|
7461
|
+
if (inherited === void 0 || inherited === "" || path38.resolve(inherited) === path38.resolve(caCertFile)) {
|
|
7452
7462
|
return { path: caCertFile };
|
|
7453
7463
|
}
|
|
7454
7464
|
const caPem = fs12.readFileUtf8(caCertFile);
|
|
@@ -7466,7 +7476,7 @@ function resolveTrustBundle(params) {
|
|
|
7466
7476
|
}
|
|
7467
7477
|
const combined = `${inheritedPem.trimEnd()}
|
|
7468
7478
|
${caPem}`;
|
|
7469
|
-
const bundle =
|
|
7479
|
+
const bundle = path38.join(bundlesDir, `${createHash6("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
7470
7480
|
if (!fs12.exists(bundle)) {
|
|
7471
7481
|
fs12.mkdirp(bundlesDir);
|
|
7472
7482
|
fs12.writeFileAtomic(bundle, combined);
|
|
@@ -7866,7 +7876,7 @@ var init_identityClaude = __esm({
|
|
|
7866
7876
|
});
|
|
7867
7877
|
|
|
7868
7878
|
// src/usage/providerQuota.ts
|
|
7869
|
-
import { z as
|
|
7879
|
+
import { z as z28 } from "zod";
|
|
7870
7880
|
var MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY4, 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;
|
|
7871
7881
|
var init_providerQuota = __esm({
|
|
7872
7882
|
"src/usage/providerQuota.ts"() {
|
|
@@ -7884,35 +7894,35 @@ var init_providerQuota = __esm({
|
|
|
7884
7894
|
[ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
|
|
7885
7895
|
[ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY4 * SECONDS_PER_HOUR * MS_PER_SECOND7]
|
|
7886
7896
|
]);
|
|
7887
|
-
ZaiLimitSchema =
|
|
7888
|
-
type:
|
|
7889
|
-
unit:
|
|
7890
|
-
number:
|
|
7891
|
-
percentage:
|
|
7892
|
-
nextResetTime:
|
|
7893
|
-
usage:
|
|
7894
|
-
currentValue:
|
|
7895
|
-
remaining:
|
|
7897
|
+
ZaiLimitSchema = z28.object({
|
|
7898
|
+
type: z28.string(),
|
|
7899
|
+
unit: z28.number().int(),
|
|
7900
|
+
number: z28.number().int().positive(),
|
|
7901
|
+
percentage: z28.number().nonnegative(),
|
|
7902
|
+
nextResetTime: z28.number().positive().optional(),
|
|
7903
|
+
usage: z28.number().nonnegative().optional(),
|
|
7904
|
+
currentValue: z28.number().nonnegative().optional(),
|
|
7905
|
+
remaining: z28.number().nonnegative().optional()
|
|
7896
7906
|
});
|
|
7897
|
-
ZaiResponseSchema =
|
|
7898
|
-
success:
|
|
7899
|
-
msg:
|
|
7900
|
-
data:
|
|
7907
|
+
ZaiResponseSchema = z28.object({
|
|
7908
|
+
success: z28.boolean(),
|
|
7909
|
+
msg: z28.string().optional(),
|
|
7910
|
+
data: z28.object({ level: z28.string().optional(), limits: z28.array(ZaiLimitSchema) })
|
|
7901
7911
|
});
|
|
7902
7912
|
OPENROUTER_HOST = "openrouter.ai";
|
|
7903
7913
|
OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
|
|
7904
7914
|
OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
|
|
7905
7915
|
MS_PER_DAY3 = HOURS_PER_DAY4 * SECONDS_PER_HOUR * MS_PER_SECOND7;
|
|
7906
|
-
OpenRouterKeySchema =
|
|
7907
|
-
data:
|
|
7908
|
-
limit:
|
|
7909
|
-
limit_remaining:
|
|
7910
|
-
limit_reset:
|
|
7911
|
-
is_free_tier:
|
|
7912
|
-
free_model_daily_requests:
|
|
7916
|
+
OpenRouterKeySchema = z28.object({
|
|
7917
|
+
data: z28.object({
|
|
7918
|
+
limit: z28.number().nonnegative().nullable(),
|
|
7919
|
+
limit_remaining: z28.number().nullable(),
|
|
7920
|
+
limit_reset: z28.string().nullable(),
|
|
7921
|
+
is_free_tier: z28.boolean().optional(),
|
|
7922
|
+
free_model_daily_requests: z28.object({ used: z28.number().nonnegative(), limit: z28.number().nonnegative(), remaining: z28.number() }).optional()
|
|
7913
7923
|
})
|
|
7914
7924
|
});
|
|
7915
|
-
OpenRouterCreditsSchema =
|
|
7925
|
+
OpenRouterCreditsSchema = z28.object({ data: z28.object({ total_credits: z28.number().nonnegative(), total_usage: z28.number().nonnegative() }) });
|
|
7916
7926
|
}
|
|
7917
7927
|
});
|
|
7918
7928
|
|
|
@@ -8525,8 +8535,8 @@ function parseConnectTarget(authority) {
|
|
|
8525
8535
|
function isInterceptedHost(host, interceptHosts) {
|
|
8526
8536
|
return interceptHosts.includes(host);
|
|
8527
8537
|
}
|
|
8528
|
-
function servedByPipeline(
|
|
8529
|
-
return
|
|
8538
|
+
function servedByPipeline(path39) {
|
|
8539
|
+
return path39?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
8530
8540
|
}
|
|
8531
8541
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
8532
8542
|
"connection",
|
|
@@ -9061,11 +9071,11 @@ function createRcSessionTracker(deps) {
|
|
|
9061
9071
|
};
|
|
9062
9072
|
const observeExchange = (request4) => {
|
|
9063
9073
|
const method = (request4.method ?? "").toUpperCase();
|
|
9064
|
-
const
|
|
9065
|
-
if (!
|
|
9074
|
+
const path39 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
9075
|
+
if (!path39.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
9066
9076
|
return void 0;
|
|
9067
9077
|
}
|
|
9068
|
-
const tail =
|
|
9078
|
+
const tail = path39.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
9069
9079
|
const facts = {
|
|
9070
9080
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
9071
9081
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -9447,8 +9457,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
9447
9457
|
function isRcReadFileEncoding(value) {
|
|
9448
9458
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
9449
9459
|
}
|
|
9450
|
-
function buildRcReadFilePayload(requestId,
|
|
9451
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
9460
|
+
function buildRcReadFilePayload(requestId, path39, options) {
|
|
9461
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path39, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
9452
9462
|
}
|
|
9453
9463
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
9454
9464
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -9550,15 +9560,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
9550
9560
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
9551
9561
|
return result.ok ? { ...result, requestId } : result;
|
|
9552
9562
|
}
|
|
9553
|
-
async function readRcSessionFile(deps, sessionId,
|
|
9554
|
-
if (
|
|
9563
|
+
async function readRcSessionFile(deps, sessionId, path39, options) {
|
|
9564
|
+
if (path39 === "") {
|
|
9555
9565
|
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" };
|
|
9556
9566
|
}
|
|
9557
9567
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
9558
9568
|
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" };
|
|
9559
9569
|
}
|
|
9560
9570
|
const requestId = deps.newUuid();
|
|
9561
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
9571
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path39, options), `read ${path39} from session ${sessionId}`);
|
|
9562
9572
|
return result.ok ? { ...result, requestId } : result;
|
|
9563
9573
|
}
|
|
9564
9574
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -9727,11 +9737,11 @@ function createRcControlHandler(deps) {
|
|
|
9727
9737
|
path: "read-file",
|
|
9728
9738
|
read: (body) => {
|
|
9729
9739
|
const session = bodyString(body, "session");
|
|
9730
|
-
const
|
|
9740
|
+
const path39 = bodyString(body, "path");
|
|
9731
9741
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
9732
9742
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
9733
|
-
const refused2 = session === void 0 ||
|
|
9734
|
-
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,
|
|
9743
|
+
const refused2 = session === void 0 || path39 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
9744
|
+
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, path39, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
|
|
9735
9745
|
}
|
|
9736
9746
|
},
|
|
9737
9747
|
{
|
|
@@ -10041,9 +10051,9 @@ function requestIdOfBody(body) {
|
|
|
10041
10051
|
}
|
|
10042
10052
|
function frontDoorRcControl(transport, token) {
|
|
10043
10053
|
const headers = { authorization: `Bearer ${token}` };
|
|
10044
|
-
const listAnswerOf = async (
|
|
10054
|
+
const listAnswerOf = async (path39, what) => {
|
|
10045
10055
|
try {
|
|
10046
|
-
return await transport.request({ method: "GET", path:
|
|
10056
|
+
return await transport.request({ method: "GET", path: path39, headers });
|
|
10047
10057
|
} catch (error) {
|
|
10048
10058
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
10049
10059
|
}
|
|
@@ -10115,10 +10125,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
10115
10125
|
}
|
|
10116
10126
|
return pending;
|
|
10117
10127
|
};
|
|
10118
|
-
const writeOf = async (
|
|
10128
|
+
const writeOf = async (path39, body, describeFailure2) => {
|
|
10119
10129
|
let answer;
|
|
10120
10130
|
try {
|
|
10121
|
-
answer = await transport.request({ method: "POST", path:
|
|
10131
|
+
answer = await transport.request({ method: "POST", path: path39, headers: { ...headers, "content-type": "application/json" }, body });
|
|
10122
10132
|
} catch (error) {
|
|
10123
10133
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
10124
10134
|
}
|
|
@@ -10149,10 +10159,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
10149
10159
|
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}`),
|
|
10150
10160
|
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}`),
|
|
10151
10161
|
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}`),
|
|
10152
|
-
readFile: async (sessionId,
|
|
10162
|
+
readFile: async (sessionId, path39, options) => await writeOf(
|
|
10153
10163
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
10154
|
-
JSON.stringify({ session: sessionId, path:
|
|
10155
|
-
(status, message) => `reading ${
|
|
10164
|
+
JSON.stringify({ session: sessionId, path: path39, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
10165
|
+
(status, message) => `reading ${path39} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
10156
10166
|
),
|
|
10157
10167
|
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}`),
|
|
10158
10168
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -10311,12 +10321,12 @@ function tlsFacts(options) {
|
|
|
10311
10321
|
}
|
|
10312
10322
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10313
10323
|
const agent = new ExemptTlsAgent();
|
|
10314
|
-
const post = async (
|
|
10324
|
+
const post = async (path39, headers, body) => await new Promise((resolve, reject) => {
|
|
10315
10325
|
const options = {
|
|
10316
10326
|
host: target.host,
|
|
10317
10327
|
port: target.port,
|
|
10318
10328
|
method: "POST",
|
|
10319
|
-
path:
|
|
10329
|
+
path: path39,
|
|
10320
10330
|
// 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.
|
|
10321
10331
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
10322
10332
|
agent
|
|
@@ -10381,12 +10391,12 @@ function lateRcStreamDial(resolve) {
|
|
|
10381
10391
|
}
|
|
10382
10392
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10383
10393
|
const agent = new ExemptTlsAgent();
|
|
10384
|
-
const request4 = async (method,
|
|
10394
|
+
const request4 = async (method, path39, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
10385
10395
|
const options = {
|
|
10386
10396
|
host: target.host,
|
|
10387
10397
|
port: target.port,
|
|
10388
10398
|
method,
|
|
10389
|
-
path:
|
|
10399
|
+
path: path39,
|
|
10390
10400
|
// 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.
|
|
10391
10401
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
10392
10402
|
agent,
|
|
@@ -10428,9 +10438,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
10428
10438
|
return { status, body: await readAll(response) };
|
|
10429
10439
|
},
|
|
10430
10440
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
10431
|
-
const
|
|
10441
|
+
const path39 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
|
|
10432
10442
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
10433
|
-
const { status, response } = await request4("GET",
|
|
10443
|
+
const { status, response } = await request4("GET", path39, streamHeaders, void 0, signal);
|
|
10434
10444
|
if (!isSuccessful2(status)) {
|
|
10435
10445
|
await readAll(response);
|
|
10436
10446
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -10897,6 +10907,7 @@ var RC_ORPC_PATH_PREFIX = "/__agent-shim/orpc";
|
|
|
10897
10907
|
var RC_OPENAPI_DOC_PATH = "/openapi.json";
|
|
10898
10908
|
var RC_SUBSCRIBER_BUFFER_EVENTS = 100;
|
|
10899
10909
|
var READ_ONLY_OPERATION_EXTENSION = "x-agent-shim-read-only";
|
|
10910
|
+
var SESSION_HISTORY_TAG = "agent-trees";
|
|
10900
10911
|
function doorApiBearer(headers) {
|
|
10901
10912
|
const presented = headers.authorization;
|
|
10902
10913
|
const bearerPrefix = "bearer ".length;
|
|
@@ -11311,8 +11322,8 @@ init_cliError();
|
|
|
11311
11322
|
init_realPorts();
|
|
11312
11323
|
|
|
11313
11324
|
// src/frontdoor/controlApi.ts
|
|
11314
|
-
import { createORPCClient as createORPCClient2, ORPCError as
|
|
11315
|
-
import { openapi as
|
|
11325
|
+
import { createORPCClient as createORPCClient2, ORPCError as ORPCError7 } from "@orpc/client";
|
|
11326
|
+
import { openapi as openapi8 } from "@orpc/openapi";
|
|
11316
11327
|
|
|
11317
11328
|
// src/checkReport.ts
|
|
11318
11329
|
init_classify();
|
|
@@ -11581,19 +11592,19 @@ function writePools(paths, pools) {
|
|
|
11581
11592
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
11582
11593
|
}
|
|
11583
11594
|
function poolCycleOf(pools, name) {
|
|
11584
|
-
const walk = (current,
|
|
11595
|
+
const walk = (current, path39) => {
|
|
11585
11596
|
for (const entry of pools[current]?.identities ?? []) {
|
|
11586
11597
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
11587
11598
|
if (nested === void 0) {
|
|
11588
11599
|
continue;
|
|
11589
11600
|
}
|
|
11590
11601
|
if (nested === name) {
|
|
11591
|
-
return [...
|
|
11602
|
+
return [...path39, nested];
|
|
11592
11603
|
}
|
|
11593
|
-
if (
|
|
11604
|
+
if (path39.includes(nested)) {
|
|
11594
11605
|
continue;
|
|
11595
11606
|
}
|
|
11596
|
-
const found = walk(nested, [...
|
|
11607
|
+
const found = walk(nested, [...path39, nested]);
|
|
11597
11608
|
if (found !== void 0) {
|
|
11598
11609
|
return found;
|
|
11599
11610
|
}
|
|
@@ -13727,7 +13738,7 @@ function profileValue(name, paths) {
|
|
|
13727
13738
|
function createConfigApiRouter(deps) {
|
|
13728
13739
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13729
13740
|
const { paths } = deps;
|
|
13730
|
-
const route = (
|
|
13741
|
+
const route = (path39, summary) => authed.meta(openapi3({ method: "POST", path: path39, summary, tags: [CONFIG_API_TAG] }));
|
|
13731
13742
|
return {
|
|
13732
13743
|
config: {
|
|
13733
13744
|
identity: {
|
|
@@ -14169,6 +14180,166 @@ function createLaunchApiRouter(deps) {
|
|
|
14169
14180
|
};
|
|
14170
14181
|
}
|
|
14171
14182
|
|
|
14183
|
+
// src/frontdoor/agentTreesApi.ts
|
|
14184
|
+
import { ORPCError as ORPCError6 } from "@orpc/client";
|
|
14185
|
+
import { openapi as openapi7 } from "@orpc/openapi";
|
|
14186
|
+
import { z as z26 } from "zod";
|
|
14187
|
+
|
|
14188
|
+
// src/agents/schema.ts
|
|
14189
|
+
import { z as z25 } from "zod";
|
|
14190
|
+
var AgentMetaSchema = z25.looseObject({
|
|
14191
|
+
agentType: z25.string(),
|
|
14192
|
+
isFork: z25.boolean().optional(),
|
|
14193
|
+
description: z25.string().optional(),
|
|
14194
|
+
name: z25.string().optional(),
|
|
14195
|
+
toolUseId: z25.string().optional(),
|
|
14196
|
+
spawnDepth: z25.number().int().nonnegative().optional(),
|
|
14197
|
+
parentAgentId: z25.string().optional(),
|
|
14198
|
+
model: z25.string().optional(),
|
|
14199
|
+
requestShape: z25.string().optional(),
|
|
14200
|
+
requestNonInteractive: z25.boolean().optional(),
|
|
14201
|
+
workflowPhase: z25.string().optional(),
|
|
14202
|
+
taskKind: z25.string().optional(),
|
|
14203
|
+
teamName: z25.string().optional(),
|
|
14204
|
+
worktreePath: z25.string().optional(),
|
|
14205
|
+
worktreeBranch: z25.string().optional(),
|
|
14206
|
+
stoppedByUser: z25.boolean().optional()
|
|
14207
|
+
});
|
|
14208
|
+
var AgentKindSchema = z25.enum(["subagent", "fork", "workflow-agent", "teammate"]);
|
|
14209
|
+
var AgentNodeSchema = z25.lazy(
|
|
14210
|
+
() => z25.strictObject({
|
|
14211
|
+
id: z25.string(),
|
|
14212
|
+
kind: AgentKindSchema,
|
|
14213
|
+
agentType: z25.string(),
|
|
14214
|
+
description: z25.string().optional(),
|
|
14215
|
+
name: z25.string().optional(),
|
|
14216
|
+
toolUseId: z25.string().optional(),
|
|
14217
|
+
spawnDepth: z25.number().int().nonnegative().optional(),
|
|
14218
|
+
model: z25.string().optional(),
|
|
14219
|
+
background: z25.boolean().optional(),
|
|
14220
|
+
workflowRunId: z25.string().optional(),
|
|
14221
|
+
workflowPhase: z25.string().optional(),
|
|
14222
|
+
teamName: z25.string().optional(),
|
|
14223
|
+
stoppedByUser: z25.boolean().optional(),
|
|
14224
|
+
transcript: z25.string(),
|
|
14225
|
+
children: z25.array(AgentNodeSchema)
|
|
14226
|
+
})
|
|
14227
|
+
);
|
|
14228
|
+
var TaskItemSchema = z25.strictObject({
|
|
14229
|
+
id: z25.string(),
|
|
14230
|
+
subject: z25.string(),
|
|
14231
|
+
description: z25.string().optional(),
|
|
14232
|
+
status: z25.string(),
|
|
14233
|
+
/** What a spinner shows while the task runs. */
|
|
14234
|
+
activeForm: z25.string().optional(),
|
|
14235
|
+
/** The teammate or agent name the task is assigned to, as Agent Teams writes it. */
|
|
14236
|
+
owner: z25.string().optional(),
|
|
14237
|
+
/** Free-form data the harness attaches to a task, kept as written. */
|
|
14238
|
+
metadata: z25.record(z25.string(), z25.unknown()).optional(),
|
|
14239
|
+
blocks: z25.array(z25.string()),
|
|
14240
|
+
blockedBy: z25.array(z25.string()),
|
|
14241
|
+
/** The id of the shared task list this task belongs to (a team's name, or a custom list id), absent for the session's own list. */
|
|
14242
|
+
taskList: z25.string().optional()
|
|
14243
|
+
});
|
|
14244
|
+
var WorkflowRunSchema = z25.strictObject({
|
|
14245
|
+
runId: z25.string(),
|
|
14246
|
+
workflowName: z25.string().optional(),
|
|
14247
|
+
status: z25.string().optional(),
|
|
14248
|
+
startTime: z25.number().optional(),
|
|
14249
|
+
phases: z25.array(z25.string()),
|
|
14250
|
+
summary: z25.string().optional()
|
|
14251
|
+
});
|
|
14252
|
+
var AgentTreeProblemSchema = z25.strictObject({
|
|
14253
|
+
/** Relative to the identity's configuration directory. */
|
|
14254
|
+
path: z25.string(),
|
|
14255
|
+
reason: z25.string()
|
|
14256
|
+
});
|
|
14257
|
+
var SessionSummarySchema = z25.strictObject({
|
|
14258
|
+
project: z25.string(),
|
|
14259
|
+
sessionId: z25.string(),
|
|
14260
|
+
superseded: z25.boolean(),
|
|
14261
|
+
/** The directory and transcript stem exactly as on disk, which differs from `sessionId` for a superseded session. */
|
|
14262
|
+
entry: z25.string(),
|
|
14263
|
+
agentCount: z25.number().int().nonnegative(),
|
|
14264
|
+
workflowRunCount: z25.number().int().nonnegative(),
|
|
14265
|
+
/** When the transcript was last written, as an ISO instant; absent when there is no transcript file. */
|
|
14266
|
+
updatedAt: z25.iso.datetime().optional(),
|
|
14267
|
+
identities: z25.array(z25.string())
|
|
14268
|
+
});
|
|
14269
|
+
var SessionAgentTreeSchema = z25.strictObject({
|
|
14270
|
+
project: z25.string(),
|
|
14271
|
+
sessionId: z25.string(),
|
|
14272
|
+
/** True for a session directory a resume superseded (`<session-id>.superseded-<epoch-ms>`). */
|
|
14273
|
+
superseded: z25.boolean(),
|
|
14274
|
+
/** The agents the session itself spawned, each with its descendants. */
|
|
14275
|
+
agents: z25.array(AgentNodeSchema),
|
|
14276
|
+
tasks: z25.array(TaskItemSchema),
|
|
14277
|
+
workflowRuns: z25.array(WorkflowRunSchema),
|
|
14278
|
+
problems: z25.array(AgentTreeProblemSchema)
|
|
14279
|
+
});
|
|
14280
|
+
|
|
14281
|
+
// src/frontdoor/agentTreesApi.ts
|
|
14282
|
+
init_cliError();
|
|
14283
|
+
var AgentTreesListInputSchema = z26.strictObject({
|
|
14284
|
+
/** Only this identity's sessions. */
|
|
14285
|
+
identity: z26.string().optional(),
|
|
14286
|
+
/** Include sessions that spawned no agent and ran no workflow. */
|
|
14287
|
+
all: z26.boolean().optional()
|
|
14288
|
+
});
|
|
14289
|
+
var AgentTreesListOutputSchema = z26.array(SessionSummarySchema);
|
|
14290
|
+
var AgentTreesShowInputSchema = z26.strictObject({
|
|
14291
|
+
/** A session id, or an unambiguous prefix of one. */
|
|
14292
|
+
session: z26.string().min(1),
|
|
14293
|
+
/** Look only in this identity. */
|
|
14294
|
+
identity: z26.string().optional()
|
|
14295
|
+
});
|
|
14296
|
+
var AgentTreesShowOutputSchema = z26.strictObject({ identities: z26.array(z26.string()), ...SessionAgentTreeSchema.shape });
|
|
14297
|
+
function asBadRequest(error) {
|
|
14298
|
+
if (error instanceof CliError) {
|
|
14299
|
+
throw new ORPCError6("BAD_REQUEST", { message: error.message });
|
|
14300
|
+
}
|
|
14301
|
+
throw error;
|
|
14302
|
+
}
|
|
14303
|
+
function createAgentTreesApiRouter(deps) {
|
|
14304
|
+
const authed = doorApiAuth(deps.expectedToken);
|
|
14305
|
+
return {
|
|
14306
|
+
agentTrees: {
|
|
14307
|
+
list: authed.meta(
|
|
14308
|
+
openapi7({
|
|
14309
|
+
method: "POST",
|
|
14310
|
+
path: "/rest/agent-trees/list",
|
|
14311
|
+
summary: "List the sessions that spawned agents or ran workflows, newest transcript first",
|
|
14312
|
+
tags: [SESSION_HISTORY_TAG],
|
|
14313
|
+
// A POST because the filters are a body, but the answer changes nothing.
|
|
14314
|
+
spec: (current) => ({ ...current, [READ_ONLY_OPERATION_EXTENSION]: true })
|
|
14315
|
+
})
|
|
14316
|
+
).input(AgentTreesListInputSchema).output(AgentTreesListOutputSchema).handler(({ input }) => {
|
|
14317
|
+
try {
|
|
14318
|
+
return deps.sessionList(input).map((session) => ({ ...session, identities: [...session.identities] }));
|
|
14319
|
+
} catch (error) {
|
|
14320
|
+
return asBadRequest(error);
|
|
14321
|
+
}
|
|
14322
|
+
}),
|
|
14323
|
+
show: authed.meta(
|
|
14324
|
+
openapi7({
|
|
14325
|
+
method: "POST",
|
|
14326
|
+
path: "/rest/agent-trees/show",
|
|
14327
|
+
summary: "Show one session's agent tree, task list and workflow runs",
|
|
14328
|
+
tags: [SESSION_HISTORY_TAG],
|
|
14329
|
+
spec: (current) => ({ ...current, [READ_ONLY_OPERATION_EXTENSION]: true })
|
|
14330
|
+
})
|
|
14331
|
+
).input(AgentTreesShowInputSchema).output(AgentTreesShowOutputSchema).handler(({ input }) => {
|
|
14332
|
+
try {
|
|
14333
|
+
const view = deps.sessionShow(input.session, input.identity);
|
|
14334
|
+
return { identities: [...view.identities], ...view.tree };
|
|
14335
|
+
} catch (error) {
|
|
14336
|
+
return asBadRequest(error);
|
|
14337
|
+
}
|
|
14338
|
+
})
|
|
14339
|
+
}
|
|
14340
|
+
};
|
|
14341
|
+
}
|
|
14342
|
+
|
|
14172
14343
|
// src/frontdoor/controlApi.ts
|
|
14173
14344
|
var USAGE_API_TAG = "usage";
|
|
14174
14345
|
var FRONTDOOR_API_TAG2 = "frontdoor";
|
|
@@ -14179,12 +14350,12 @@ function createControlApiRouter(deps) {
|
|
|
14179
14350
|
const authed = doorApiAuth(deps.expectedToken);
|
|
14180
14351
|
return {
|
|
14181
14352
|
usage: {
|
|
14182
|
-
list: authed.meta(
|
|
14183
|
-
resets: authed.meta(
|
|
14184
|
-
effectiveWindow: authed.meta(
|
|
14353
|
+
list: authed.meta(openapi8({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
|
|
14354
|
+
resets: authed.meta(openapi8({ method: "GET", path: "/rest/usage/resets", summary: "List every recorded quota window with when it resets", tags: [USAGE_API_TAG] })).output(ResetScheduleSchema).handler(() => collectResets(deps.usageSnapshots(), deps.now())),
|
|
14355
|
+
effectiveWindow: authed.meta(openapi8({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
|
|
14185
14356
|
const snapshot = deps.usageSnapshotOf(input.identity);
|
|
14186
14357
|
if (snapshot === void 0) {
|
|
14187
|
-
throw new
|
|
14358
|
+
throw new ORPCError7("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
|
|
14188
14359
|
}
|
|
14189
14360
|
const provider = input.provider ?? ANTHROPIC_PROVIDER;
|
|
14190
14361
|
const rateLimit = snapshot.providers[provider]?.rateLimit;
|
|
@@ -14198,34 +14369,34 @@ function createControlApiRouter(deps) {
|
|
|
14198
14369
|
...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
|
|
14199
14370
|
};
|
|
14200
14371
|
}),
|
|
14201
|
-
live: authed.meta(
|
|
14372
|
+
live: authed.meta(openapi8({ 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 }) => {
|
|
14202
14373
|
const sessions = deps.liveRateLimits(input.session);
|
|
14203
14374
|
if (input.session !== void 0 && sessions.length === 0) {
|
|
14204
14375
|
if (deps.list().some((session) => session.id === input.session)) {
|
|
14205
|
-
throw new
|
|
14376
|
+
throw new ORPCError7("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` });
|
|
14206
14377
|
}
|
|
14207
|
-
throw new
|
|
14378
|
+
throw new ORPCError7("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
|
|
14208
14379
|
}
|
|
14209
14380
|
return { latest: deps.latestRateLimit(), sessions };
|
|
14210
14381
|
})
|
|
14211
14382
|
},
|
|
14212
14383
|
frontdoor: {
|
|
14213
|
-
status: authed.meta(
|
|
14214
|
-
sessions: authed.meta(
|
|
14384
|
+
status: authed.meta(openapi8({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
|
|
14385
|
+
sessions: authed.meta(openapi8({ 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 }))
|
|
14215
14386
|
},
|
|
14216
14387
|
check: {
|
|
14217
14388
|
// 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.
|
|
14218
|
-
run: authed.meta(
|
|
14389
|
+
run: authed.meta(openapi8({ 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)))
|
|
14219
14390
|
},
|
|
14220
14391
|
doctor: {
|
|
14221
|
-
run: authed.meta(
|
|
14392
|
+
run: authed.meta(openapi8({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
|
|
14222
14393
|
},
|
|
14223
14394
|
pool: {
|
|
14224
|
-
pick: authed.meta(
|
|
14395
|
+
pick: authed.meta(openapi8({ 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 }) => {
|
|
14225
14396
|
const report = deps.poolPick(input.pool, input.path);
|
|
14226
14397
|
if (report === void 0) {
|
|
14227
14398
|
const live = deps.poolNames();
|
|
14228
|
-
throw new
|
|
14399
|
+
throw new ORPCError7("NOT_FOUND", {
|
|
14229
14400
|
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(", ")}`
|
|
14230
14401
|
});
|
|
14231
14402
|
}
|
|
@@ -14237,7 +14408,7 @@ function createControlApiRouter(deps) {
|
|
|
14237
14408
|
function createDoorApiRouter(deps) {
|
|
14238
14409
|
const control = createControlApiRouter(deps);
|
|
14239
14410
|
const lifecycle = createLifecycleApiRouter(deps);
|
|
14240
|
-
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
14411
|
+
return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createAgentTreesApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
|
|
14241
14412
|
}
|
|
14242
14413
|
function createDoorApiNodeHandler(deps) {
|
|
14243
14414
|
return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
|
|
@@ -16305,90 +16476,7 @@ init_poolPick();
|
|
|
16305
16476
|
|
|
16306
16477
|
// src/agents/read.ts
|
|
16307
16478
|
import path33 from "node:path";
|
|
16308
|
-
import { z as
|
|
16309
|
-
|
|
16310
|
-
// src/agents/schema.ts
|
|
16311
|
-
import { z as z25 } from "zod";
|
|
16312
|
-
var AgentMetaSchema = z25.looseObject({
|
|
16313
|
-
agentType: z25.string(),
|
|
16314
|
-
isFork: z25.boolean().optional(),
|
|
16315
|
-
description: z25.string().optional(),
|
|
16316
|
-
name: z25.string().optional(),
|
|
16317
|
-
toolUseId: z25.string().optional(),
|
|
16318
|
-
spawnDepth: z25.number().int().nonnegative().optional(),
|
|
16319
|
-
parentAgentId: z25.string().optional(),
|
|
16320
|
-
model: z25.string().optional(),
|
|
16321
|
-
requestShape: z25.string().optional(),
|
|
16322
|
-
requestNonInteractive: z25.boolean().optional(),
|
|
16323
|
-
workflowPhase: z25.string().optional(),
|
|
16324
|
-
taskKind: z25.string().optional(),
|
|
16325
|
-
teamName: z25.string().optional(),
|
|
16326
|
-
worktreePath: z25.string().optional(),
|
|
16327
|
-
worktreeBranch: z25.string().optional(),
|
|
16328
|
-
stoppedByUser: z25.boolean().optional()
|
|
16329
|
-
});
|
|
16330
|
-
var AgentKindSchema = z25.enum(["subagent", "fork", "workflow-agent", "teammate"]);
|
|
16331
|
-
var AgentNodeSchema = z25.lazy(
|
|
16332
|
-
() => z25.strictObject({
|
|
16333
|
-
id: z25.string(),
|
|
16334
|
-
kind: AgentKindSchema,
|
|
16335
|
-
agentType: z25.string(),
|
|
16336
|
-
description: z25.string().optional(),
|
|
16337
|
-
name: z25.string().optional(),
|
|
16338
|
-
toolUseId: z25.string().optional(),
|
|
16339
|
-
spawnDepth: z25.number().int().nonnegative().optional(),
|
|
16340
|
-
model: z25.string().optional(),
|
|
16341
|
-
background: z25.boolean().optional(),
|
|
16342
|
-
workflowRunId: z25.string().optional(),
|
|
16343
|
-
workflowPhase: z25.string().optional(),
|
|
16344
|
-
teamName: z25.string().optional(),
|
|
16345
|
-
stoppedByUser: z25.boolean().optional(),
|
|
16346
|
-
transcript: z25.string(),
|
|
16347
|
-
children: z25.array(AgentNodeSchema)
|
|
16348
|
-
})
|
|
16349
|
-
);
|
|
16350
|
-
var TaskItemSchema = z25.strictObject({
|
|
16351
|
-
id: z25.string(),
|
|
16352
|
-
subject: z25.string(),
|
|
16353
|
-
description: z25.string().optional(),
|
|
16354
|
-
status: z25.string(),
|
|
16355
|
-
/** What a spinner shows while the task runs. */
|
|
16356
|
-
activeForm: z25.string().optional(),
|
|
16357
|
-
/** The teammate or agent name the task is assigned to, as Agent Teams writes it. */
|
|
16358
|
-
owner: z25.string().optional(),
|
|
16359
|
-
/** Free-form data the harness attaches to a task, kept as written. */
|
|
16360
|
-
metadata: z25.record(z25.string(), z25.unknown()).optional(),
|
|
16361
|
-
blocks: z25.array(z25.string()),
|
|
16362
|
-
blockedBy: z25.array(z25.string()),
|
|
16363
|
-
/** The id of the shared task list this task belongs to (a team's name, or a custom list id), absent for the session's own list. */
|
|
16364
|
-
taskList: z25.string().optional()
|
|
16365
|
-
});
|
|
16366
|
-
var WorkflowRunSchema = z25.strictObject({
|
|
16367
|
-
runId: z25.string(),
|
|
16368
|
-
workflowName: z25.string().optional(),
|
|
16369
|
-
status: z25.string().optional(),
|
|
16370
|
-
startTime: z25.number().optional(),
|
|
16371
|
-
phases: z25.array(z25.string()),
|
|
16372
|
-
summary: z25.string().optional()
|
|
16373
|
-
});
|
|
16374
|
-
var AgentTreeProblemSchema = z25.strictObject({
|
|
16375
|
-
/** Relative to the identity's configuration directory. */
|
|
16376
|
-
path: z25.string(),
|
|
16377
|
-
reason: z25.string()
|
|
16378
|
-
});
|
|
16379
|
-
var SessionAgentTreeSchema = z25.strictObject({
|
|
16380
|
-
project: z25.string(),
|
|
16381
|
-
sessionId: z25.string(),
|
|
16382
|
-
/** True for a session directory a resume superseded (`<session-id>.superseded-<epoch-ms>`). */
|
|
16383
|
-
superseded: z25.boolean(),
|
|
16384
|
-
/** The agents the session itself spawned, each with its descendants. */
|
|
16385
|
-
agents: z25.array(AgentNodeSchema),
|
|
16386
|
-
tasks: z25.array(TaskItemSchema),
|
|
16387
|
-
workflowRuns: z25.array(WorkflowRunSchema),
|
|
16388
|
-
problems: z25.array(AgentTreeProblemSchema)
|
|
16389
|
-
});
|
|
16390
|
-
|
|
16391
|
-
// src/agents/read.ts
|
|
16479
|
+
import { z as z27 } from "zod";
|
|
16392
16480
|
var PROJECTS_DIR = "projects";
|
|
16393
16481
|
var TASKS_DIR = "tasks";
|
|
16394
16482
|
var SUBAGENTS_DIR = "subagents";
|
|
@@ -16507,15 +16595,30 @@ function parseJson2(text) {
|
|
|
16507
16595
|
return void 0;
|
|
16508
16596
|
}
|
|
16509
16597
|
}
|
|
16510
|
-
var TaskFileSchema =
|
|
16511
|
-
var WorkflowRunFileSchema =
|
|
16512
|
-
runId:
|
|
16513
|
-
workflowName:
|
|
16514
|
-
status:
|
|
16515
|
-
startTime:
|
|
16516
|
-
phases:
|
|
16517
|
-
summary:
|
|
16598
|
+
var TaskFileSchema = z27.object({ ...TaskItemSchema.omit({ taskList: true }).shape, blocks: z27.array(z27.string()).default([]), blockedBy: z27.array(z27.string()).default([]) });
|
|
16599
|
+
var WorkflowRunFileSchema = z27.object({
|
|
16600
|
+
runId: z27.string(),
|
|
16601
|
+
workflowName: z27.string().optional(),
|
|
16602
|
+
status: z27.string().optional(),
|
|
16603
|
+
startTime: z27.number().optional(),
|
|
16604
|
+
phases: z27.array(z27.object({ title: z27.string() })).default([]),
|
|
16605
|
+
summary: z27.string().optional()
|
|
16518
16606
|
});
|
|
16607
|
+
function summariseSession(fs12, configDir, ref) {
|
|
16608
|
+
const sessionRelative = path33.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
16609
|
+
const subagentsRelative = path33.join(sessionRelative, SUBAGENTS_DIR);
|
|
16610
|
+
const workflowsUnderSubagents = path33.join(subagentsRelative, WORKFLOWS_DIR);
|
|
16611
|
+
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
16612
|
+
let agentCount = fs12.readdir(path33.join(configDir, subagentsRelative)).filter(isMeta).length;
|
|
16613
|
+
for (const runDir of fs12.readdir(path33.join(configDir, workflowsUnderSubagents))) {
|
|
16614
|
+
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
16615
|
+
agentCount += fs12.readdir(path33.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
16616
|
+
}
|
|
16617
|
+
}
|
|
16618
|
+
const workflowRunCount = fs12.readdir(path33.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
|
|
16619
|
+
const transcript = fs12.lstat(path33.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
|
|
16620
|
+
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
16621
|
+
}
|
|
16519
16622
|
function readSessionAgentTree(fs12, configDir, ref, options = {}) {
|
|
16520
16623
|
const problems = [];
|
|
16521
16624
|
const report = (problem) => {
|
|
@@ -16671,6 +16774,94 @@ function readWorkflowRuns(fs12, configDir, relativeDir, report) {
|
|
|
16671
16774
|
return runs;
|
|
16672
16775
|
}
|
|
16673
16776
|
|
|
16777
|
+
// src/agents/sessions.ts
|
|
16778
|
+
init_cliError();
|
|
16779
|
+
import path34 from "node:path";
|
|
16780
|
+
var SessionLookupError = class extends CliError {
|
|
16781
|
+
constructor(message) {
|
|
16782
|
+
super(message);
|
|
16783
|
+
this.name = "SessionLookupError";
|
|
16784
|
+
}
|
|
16785
|
+
};
|
|
16786
|
+
function identityConfigDir(identitiesDir, identity) {
|
|
16787
|
+
return path34.join(identitiesDir, identity);
|
|
16788
|
+
}
|
|
16789
|
+
function historyStores(fs12, identitiesDir, identities) {
|
|
16790
|
+
const byRealPath = /* @__PURE__ */ new Map();
|
|
16791
|
+
for (const identity of identities) {
|
|
16792
|
+
const configDir = identityConfigDir(identitiesDir, identity);
|
|
16793
|
+
const real = fs12.realpath(path34.join(configDir, "projects"));
|
|
16794
|
+
if (real === void 0) {
|
|
16795
|
+
continue;
|
|
16796
|
+
}
|
|
16797
|
+
const store = byRealPath.get(real);
|
|
16798
|
+
if (store === void 0) {
|
|
16799
|
+
byRealPath.set(real, { configDir, identities: [identity] });
|
|
16800
|
+
} else {
|
|
16801
|
+
store.identities.push(identity);
|
|
16802
|
+
}
|
|
16803
|
+
}
|
|
16804
|
+
return [...byRealPath.values()];
|
|
16805
|
+
}
|
|
16806
|
+
function collectSessionList(fs12, identitiesDir, identities, filters) {
|
|
16807
|
+
const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
|
|
16808
|
+
if (filters.identity !== void 0 && names.length === 0) {
|
|
16809
|
+
throw new SessionLookupError(`no identity named "${filters.identity}"`);
|
|
16810
|
+
}
|
|
16811
|
+
const sessions = [];
|
|
16812
|
+
for (const store of historyStores(fs12, identitiesDir, names)) {
|
|
16813
|
+
for (const ref of listSessions2(fs12, store.configDir)) {
|
|
16814
|
+
const summary = summariseSession(fs12, store.configDir, ref);
|
|
16815
|
+
if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
|
|
16816
|
+
sessions.push({ ...summary, identities: store.identities });
|
|
16817
|
+
}
|
|
16818
|
+
}
|
|
16819
|
+
}
|
|
16820
|
+
return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
|
|
16821
|
+
}
|
|
16822
|
+
function locateSession(fs12, identitiesDir, identities, query, onlyIdentity) {
|
|
16823
|
+
const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
|
|
16824
|
+
if (onlyIdentity !== void 0 && names.length === 0) {
|
|
16825
|
+
throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
|
|
16826
|
+
}
|
|
16827
|
+
const matches = [];
|
|
16828
|
+
for (const store of historyStores(fs12, identitiesDir, names)) {
|
|
16829
|
+
for (const ref of listSessions2(fs12, store.configDir)) {
|
|
16830
|
+
if (ref.sessionId.startsWith(query)) {
|
|
16831
|
+
matches.push({ identities: store.identities, configDir: store.configDir, ref });
|
|
16832
|
+
}
|
|
16833
|
+
}
|
|
16834
|
+
}
|
|
16835
|
+
const exact = matches.filter((match) => match.ref.sessionId === query);
|
|
16836
|
+
const candidates = exact.length > 0 ? exact : matches;
|
|
16837
|
+
const only = candidates[0];
|
|
16838
|
+
if (candidates.length === 1 && only !== void 0) {
|
|
16839
|
+
return only;
|
|
16840
|
+
}
|
|
16841
|
+
if (candidates.length === 0) {
|
|
16842
|
+
throw new SessionLookupError(`no session matches "${query}"`);
|
|
16843
|
+
}
|
|
16844
|
+
throw new SessionLookupError(`"${query}" matches ${String(candidates.length)} sessions: ${candidates.map((match) => `${match.ref.sessionId} (${match.identities.join(", ")})`).join("; ")}; give more of the id or pass --identity`);
|
|
16845
|
+
}
|
|
16846
|
+
function showSession(fs12, identitiesDir, identities, query, onlyIdentity) {
|
|
16847
|
+
const located = locateSession(fs12, identitiesDir, identities, query, onlyIdentity);
|
|
16848
|
+
return { identities: located.identities, tree: readSessionAgentTree(fs12, located.configDir, located.ref) };
|
|
16849
|
+
}
|
|
16850
|
+
|
|
16851
|
+
// src/agents/realFs.ts
|
|
16852
|
+
init_realPorts();
|
|
16853
|
+
import nodeFs from "node:fs";
|
|
16854
|
+
var realSessionFs = {
|
|
16855
|
+
...realFarmFs,
|
|
16856
|
+
realpath: (candidate) => {
|
|
16857
|
+
try {
|
|
16858
|
+
return nodeFs.realpathSync(candidate);
|
|
16859
|
+
} catch {
|
|
16860
|
+
return void 0;
|
|
16861
|
+
}
|
|
16862
|
+
}
|
|
16863
|
+
};
|
|
16864
|
+
|
|
16674
16865
|
// src/index.ts
|
|
16675
16866
|
init_conditions();
|
|
16676
16867
|
init_ensure();
|
|
@@ -16782,6 +16973,10 @@ export {
|
|
|
16782
16973
|
AgentKindSchema,
|
|
16783
16974
|
AgentMetaSchema,
|
|
16784
16975
|
AgentNodeSchema,
|
|
16976
|
+
AgentTreesListInputSchema,
|
|
16977
|
+
AgentTreesListOutputSchema,
|
|
16978
|
+
AgentTreesShowInputSchema,
|
|
16979
|
+
AgentTreesShowOutputSchema,
|
|
16785
16980
|
CHECK_CREDENTIAL_APPLIES,
|
|
16786
16981
|
CODEX_APP_SERVER_GENERATED_AGAINST,
|
|
16787
16982
|
CODEX_APP_SERVER_TIMEOUT_MS,
|
|
@@ -16929,6 +17124,8 @@ export {
|
|
|
16929
17124
|
ResetRowSchema,
|
|
16930
17125
|
ResetScheduleSchema,
|
|
16931
17126
|
SessionAgentTreeSchema,
|
|
17127
|
+
SessionLookupError,
|
|
17128
|
+
SessionSummarySchema,
|
|
16932
17129
|
TaskItemSchema,
|
|
16933
17130
|
USAGE_EVENT_SOURCE,
|
|
16934
17131
|
UpdateCheckOutputSchema,
|
|
@@ -16976,6 +17173,8 @@ export {
|
|
|
16976
17173
|
collectFrontDoorStatus,
|
|
16977
17174
|
collectPoolPick,
|
|
16978
17175
|
collectResets,
|
|
17176
|
+
collectSessionList,
|
|
17177
|
+
createAgentTreesApiRouter,
|
|
16979
17178
|
createCodexApiRouter,
|
|
16980
17179
|
createConfigApiRouter,
|
|
16981
17180
|
createControlApiRouter,
|
|
@@ -17044,6 +17243,7 @@ export {
|
|
|
17044
17243
|
listProviders,
|
|
17045
17244
|
listSessions2 as listSessions,
|
|
17046
17245
|
listUsageSnapshots,
|
|
17246
|
+
locateSession,
|
|
17047
17247
|
matchBranch,
|
|
17048
17248
|
mintLeaf,
|
|
17049
17249
|
mintRcSelfHostCredential,
|
|
@@ -17086,6 +17286,7 @@ export {
|
|
|
17086
17286
|
realRcEventDial,
|
|
17087
17287
|
realRcStreamDial,
|
|
17088
17288
|
realRcWebFetch,
|
|
17289
|
+
realSessionFs,
|
|
17089
17290
|
reconnectRcSessionMcpServer,
|
|
17090
17291
|
recoverFarm,
|
|
17091
17292
|
recoveryDiagnostics,
|
|
@@ -17127,11 +17328,13 @@ export {
|
|
|
17127
17328
|
setProfileMetadata,
|
|
17128
17329
|
setRcSessionModel,
|
|
17129
17330
|
setRcSessionPermissionMode,
|
|
17331
|
+
showSession,
|
|
17130
17332
|
snapshotPath,
|
|
17131
17333
|
spawnClaude,
|
|
17132
17334
|
startConnectServer,
|
|
17133
17335
|
submitRcSessionMcpOAuthCallbackUrl,
|
|
17134
17336
|
suggestRcSessionFiles,
|
|
17337
|
+
summariseSession,
|
|
17135
17338
|
teleportRcSession,
|
|
17136
17339
|
topLevelNames,
|
|
17137
17340
|
updateDirectoryRule,
|