claude-use 11.2.0 → 11.4.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 +976 -711
- package/dist/index.cjs +169 -46
- package/dist/index.mjs +165 -43
- package/dist/types/index.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2758,7 +2758,7 @@ var init_package = __esm({
|
|
|
2758
2758
|
"package.json"() {
|
|
2759
2759
|
package_default = {
|
|
2760
2760
|
name: "claude-use",
|
|
2761
|
-
version: "11.
|
|
2761
|
+
version: "11.4.0",
|
|
2762
2762
|
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.",
|
|
2763
2763
|
license: "MIT",
|
|
2764
2764
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -4029,7 +4029,7 @@ function realHeadroomPort(paths, options) {
|
|
|
4029
4029
|
ensure: ({ routesProvider }) => {
|
|
4030
4030
|
const up = ensureHeadroom({
|
|
4031
4031
|
paths,
|
|
4032
|
-
launcherPid: process.pid,
|
|
4032
|
+
launcherPid: options.registerAs ?? process.pid,
|
|
4033
4033
|
...routesProvider ? { requiredUpstreams: () => launchRequiredUpstreams(realFarmFs, paths) } : {},
|
|
4034
4034
|
ports: {
|
|
4035
4035
|
fs: realFarmFs,
|
|
@@ -4047,7 +4047,7 @@ function realHeadroomPort(paths, options) {
|
|
|
4047
4047
|
};
|
|
4048
4048
|
},
|
|
4049
4049
|
release: () => {
|
|
4050
|
-
removeSession(realFarmFs, paths.headroomSessionsDir, process.pid);
|
|
4050
|
+
removeSession(realFarmFs, paths.headroomSessionsDir, options.registerAs ?? process.pid);
|
|
4051
4051
|
}
|
|
4052
4052
|
};
|
|
4053
4053
|
}
|
|
@@ -5132,6 +5132,28 @@ function windowBurn(records, which) {
|
|
|
5132
5132
|
}
|
|
5133
5133
|
return (last.utilization - first.utilization) / (last.atMs - first.atMs);
|
|
5134
5134
|
}
|
|
5135
|
+
function billedTokensOf(record) {
|
|
5136
|
+
const usage = record.usage;
|
|
5137
|
+
return (usage?.inputTokens ?? 0) + (usage?.cacheCreationInputTokens ?? 0) + (usage?.outputTokens ?? 0);
|
|
5138
|
+
}
|
|
5139
|
+
function utilisationPerBilledToken(records) {
|
|
5140
|
+
const points = [];
|
|
5141
|
+
for (const record of records) {
|
|
5142
|
+
const window = record.rateLimitHeaders === void 0 ? void 0 : parseUnifiedRateLimit(record.rateLimitHeaders)?.fiveHour;
|
|
5143
|
+
if (window?.utilization !== void 0 && window.resetsAt !== void 0) {
|
|
5144
|
+
points.push({ resetsAt: window.resetsAt, utilization: window.utilization, billed: billedTokensOf(record) });
|
|
5145
|
+
}
|
|
5146
|
+
}
|
|
5147
|
+
const latest = points.at(-1)?.resetsAt;
|
|
5148
|
+
const current = points.filter((point) => point.resetsAt === latest);
|
|
5149
|
+
const first = current.at(0);
|
|
5150
|
+
const last = current.at(-1);
|
|
5151
|
+
if (first === void 0 || last === void 0 || last.utilization <= first.utilization) {
|
|
5152
|
+
return void 0;
|
|
5153
|
+
}
|
|
5154
|
+
const billed = current.slice(1).reduce((sum, point) => sum + point.billed, 0);
|
|
5155
|
+
return billed > 0 ? (last.utilization - first.utilization) / billed : void 0;
|
|
5156
|
+
}
|
|
5135
5157
|
function windowRatio(records) {
|
|
5136
5158
|
const points = [];
|
|
5137
5159
|
for (const record of records) {
|
|
@@ -5308,6 +5330,16 @@ function rankPool(input) {
|
|
|
5308
5330
|
drySpots.push(`7d window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(sevenDay.untilResetMs)}`);
|
|
5309
5331
|
}
|
|
5310
5332
|
}
|
|
5333
|
+
const { sticky: sticky2 } = input;
|
|
5334
|
+
const warmHere = sticky2?.identity === candidate.identity && nowMs - Date.parse(sticky2.at) <= PROMPT_CACHE_TTL_MS;
|
|
5335
|
+
if (input.resuming && input.resumeContextTokens !== void 0 && fiveHour !== void 0 && !warmHere) {
|
|
5336
|
+
const perToken = utilisationPerBilledToken(assessment.member.records);
|
|
5337
|
+
const cost = perToken === void 0 ? void 0 : input.resumeContextTokens * perToken;
|
|
5338
|
+
if (cost !== void 0 && cost > fiveHour.remaining) {
|
|
5339
|
+
dryAfterMs.push(0);
|
|
5340
|
+
drySpots.push(`resuming a ${String(input.resumeContextTokens)}-token conversation here would cost about ${percent(cost)} of the 5h window, which has ${percent(fiveHour.remaining)} left`);
|
|
5341
|
+
}
|
|
5342
|
+
}
|
|
5311
5343
|
if (drySpots.length === 0) {
|
|
5312
5344
|
return { ...candidate, feasible: true };
|
|
5313
5345
|
}
|
|
@@ -5655,6 +5687,7 @@ function rankNamedPool(input, poolName, stack, sticky) {
|
|
|
5655
5687
|
members,
|
|
5656
5688
|
nowMs: input.nowMs,
|
|
5657
5689
|
resuming: input.resuming,
|
|
5690
|
+
...input.resumeContextTokens === void 0 ? {} : { resumeContextTokens: input.resumeContextTokens },
|
|
5658
5691
|
...sticky === void 0 ? {} : { sticky },
|
|
5659
5692
|
...pool.preference === void 0 ? {} : { preference: pool.preference }
|
|
5660
5693
|
});
|
|
@@ -5796,6 +5829,7 @@ function buildLayoutPaths(root) {
|
|
|
5796
5829
|
claudeShimFile: import_node_path23.default.join(root, "claude-shim.json"),
|
|
5797
5830
|
headroomDir: import_node_path23.default.join(root, "headroom"),
|
|
5798
5831
|
headroomStateFile: import_node_path23.default.join(root, "headroom", "state.json"),
|
|
5832
|
+
headroomRoutingFile: import_node_path23.default.join(root, "headroom", "routing.json"),
|
|
5799
5833
|
headroomLegacyStateFile: import_node_path23.default.join(root, "headroom", "state.v2.json"),
|
|
5800
5834
|
headroomAllowlistFile: import_node_path23.default.join(root, "headroom", "run", "allowlist.txt"),
|
|
5801
5835
|
headroomSocketDir: import_node_path23.default.join(root, "headroom", "run"),
|
|
@@ -7273,6 +7307,7 @@ function resolvePoolLaunch(params) {
|
|
|
7273
7307
|
poolName,
|
|
7274
7308
|
nowMs,
|
|
7275
7309
|
resuming,
|
|
7310
|
+
...params.resumeContextTokens === void 0 ? {} : { resumeContextTokens: params.resumeContextTokens },
|
|
7276
7311
|
identityExists: (name) => loadIdentity(params.paths.identitiesDir, name, params.fs) !== void 0,
|
|
7277
7312
|
...stickyRead.sticky === void 0 ? {} : { sticky: stickyRead.sticky }
|
|
7278
7313
|
});
|
|
@@ -7343,6 +7378,91 @@ var init_pool = __esm({
|
|
|
7343
7378
|
}
|
|
7344
7379
|
});
|
|
7345
7380
|
|
|
7381
|
+
// src/usage/resumeContext.ts
|
|
7382
|
+
function projectDirNameOf(cwd) {
|
|
7383
|
+
return cwd.replace(/[^A-Za-z0-9]/g, "-");
|
|
7384
|
+
}
|
|
7385
|
+
function resumeTargetOf(passthrough) {
|
|
7386
|
+
const end = passthrough.indexOf("--");
|
|
7387
|
+
const tokens = end === -1 ? passthrough : passthrough.slice(0, end);
|
|
7388
|
+
for (const [index, token] of tokens.entries()) {
|
|
7389
|
+
if (token === "--continue" || token === "-c") {
|
|
7390
|
+
return { kind: "latest" };
|
|
7391
|
+
}
|
|
7392
|
+
if (token === "--resume" || token === "-r") {
|
|
7393
|
+
const next = tokens[index + 1];
|
|
7394
|
+
return next === void 0 || next.startsWith("-") ? void 0 : { kind: "id", id: next };
|
|
7395
|
+
}
|
|
7396
|
+
if (token.startsWith("--resume=")) {
|
|
7397
|
+
const id = token.slice("--resume=".length);
|
|
7398
|
+
return id === "" ? void 0 : { kind: "id", id };
|
|
7399
|
+
}
|
|
7400
|
+
}
|
|
7401
|
+
return void 0;
|
|
7402
|
+
}
|
|
7403
|
+
function countOf(usage, key) {
|
|
7404
|
+
const value = key in usage ? Reflect.get(usage, key) : void 0;
|
|
7405
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : 0;
|
|
7406
|
+
}
|
|
7407
|
+
function contextTokensOfTranscript(text) {
|
|
7408
|
+
const lines = text.split("\n");
|
|
7409
|
+
for (let index = lines.length - 1; index >= 0; index -= 1) {
|
|
7410
|
+
const line = lines[index];
|
|
7411
|
+
if (line === void 0 || line === "") {
|
|
7412
|
+
continue;
|
|
7413
|
+
}
|
|
7414
|
+
let parsed;
|
|
7415
|
+
try {
|
|
7416
|
+
parsed = JSON.parse(line);
|
|
7417
|
+
} catch {
|
|
7418
|
+
continue;
|
|
7419
|
+
}
|
|
7420
|
+
if (typeof parsed !== "object" || parsed === null || !("type" in parsed) || parsed.type !== "assistant" || !("message" in parsed)) {
|
|
7421
|
+
continue;
|
|
7422
|
+
}
|
|
7423
|
+
const { message } = parsed;
|
|
7424
|
+
if (typeof message !== "object" || message === null || !("usage" in message) || typeof message.usage !== "object" || message.usage === null) {
|
|
7425
|
+
continue;
|
|
7426
|
+
}
|
|
7427
|
+
const { usage } = message;
|
|
7428
|
+
return countOf(usage, "input_tokens") + countOf(usage, "cache_read_input_tokens") + countOf(usage, "cache_creation_input_tokens");
|
|
7429
|
+
}
|
|
7430
|
+
return void 0;
|
|
7431
|
+
}
|
|
7432
|
+
function resumedContextTokens(fs12, params) {
|
|
7433
|
+
const target = resumeTargetOf(params.passthrough);
|
|
7434
|
+
if (target === void 0) {
|
|
7435
|
+
return void 0;
|
|
7436
|
+
}
|
|
7437
|
+
const projectDir = import_node_path37.default.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
7438
|
+
let file;
|
|
7439
|
+
if (target.kind === "id") {
|
|
7440
|
+
file = import_node_path37.default.join(projectDir, `${target.id}.jsonl`);
|
|
7441
|
+
} else {
|
|
7442
|
+
let newestMs = -Infinity;
|
|
7443
|
+
for (const name of fs12.readdir(projectDir)) {
|
|
7444
|
+
if (!name.endsWith(".jsonl")) {
|
|
7445
|
+
continue;
|
|
7446
|
+
}
|
|
7447
|
+
const candidate = import_node_path37.default.join(projectDir, name);
|
|
7448
|
+
const stat = fs12.lstat(candidate);
|
|
7449
|
+
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
7450
|
+
newestMs = stat.mtimeMs;
|
|
7451
|
+
file = candidate;
|
|
7452
|
+
}
|
|
7453
|
+
}
|
|
7454
|
+
}
|
|
7455
|
+
const text = file === void 0 ? void 0 : fs12.readFileUtf8(file);
|
|
7456
|
+
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
7457
|
+
}
|
|
7458
|
+
var import_node_path37;
|
|
7459
|
+
var init_resumeContext = __esm({
|
|
7460
|
+
"src/usage/resumeContext.ts"() {
|
|
7461
|
+
"use strict";
|
|
7462
|
+
import_node_path37 = __toESM(require("node:path"), 1);
|
|
7463
|
+
}
|
|
7464
|
+
});
|
|
7465
|
+
|
|
7346
7466
|
// src/launcher/spawn.ts
|
|
7347
7467
|
function childExitCode(result) {
|
|
7348
7468
|
if (result.status !== null) {
|
|
@@ -7459,6 +7579,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
7459
7579
|
log.error(`agent-shim: pool "${decided.pool}" was selected, but this launcher has no farm wired to read usage and pick a member with.`);
|
|
7460
7580
|
return proc.exit(1);
|
|
7461
7581
|
}
|
|
7582
|
+
const resumeContextTokens = resumedContextTokens(farmRuntime.fs, { claudeHome: farmRuntime.claudeHome, cwd: farmRuntime.cwd, passthrough: parsedArgv.rest });
|
|
7462
7583
|
const resolution = resolvePoolLaunch({
|
|
7463
7584
|
poolName: decided.pool,
|
|
7464
7585
|
selectedVia: decided.source,
|
|
@@ -7470,6 +7591,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
|
|
|
7470
7591
|
now: farmRuntime.now,
|
|
7471
7592
|
sleep: farmRuntime.lock.sleep,
|
|
7472
7593
|
passthrough: parsedArgv.rest,
|
|
7594
|
+
...resumeContextTokens === void 0 ? {} : { resumeContextTokens },
|
|
7473
7595
|
// 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.
|
|
7474
7596
|
wait: !readOnly && parsedArgv.wait === true,
|
|
7475
7597
|
recordPick: !readOnly,
|
|
@@ -7551,7 +7673,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7551
7673
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
7552
7674
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
7553
7675
|
});
|
|
7554
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(
|
|
7676
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(import_node_path38.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
7555
7677
|
log.error(
|
|
7556
7678
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
7557
7679
|
);
|
|
@@ -7661,7 +7783,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7661
7783
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
7662
7784
|
passthrough: parsedArgv.rest
|
|
7663
7785
|
});
|
|
7664
|
-
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR :
|
|
7786
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path38.default.join(paths.identitiesDir, identityDecision.name);
|
|
7665
7787
|
const decision = {
|
|
7666
7788
|
identitySource: identityDecision.source,
|
|
7667
7789
|
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
@@ -7702,7 +7824,7 @@ function prepareLaunch(params) {
|
|
|
7702
7824
|
);
|
|
7703
7825
|
const updateCheck = runLaunchUpdateCheck({
|
|
7704
7826
|
mode: params.updateMode ?? "off",
|
|
7705
|
-
checkPath:
|
|
7827
|
+
checkPath: import_node_path38.default.join(paths.root, "update.check"),
|
|
7706
7828
|
currentVersion: package_default.version,
|
|
7707
7829
|
port: params.update
|
|
7708
7830
|
});
|
|
@@ -7833,12 +7955,12 @@ function runLaunchPlan(plan, spawn3) {
|
|
|
7833
7955
|
function runLauncher(params) {
|
|
7834
7956
|
params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
|
|
7835
7957
|
}
|
|
7836
|
-
var import_node_crypto10,
|
|
7958
|
+
var import_node_crypto10, import_node_path38;
|
|
7837
7959
|
var init_launcher = __esm({
|
|
7838
7960
|
"src/launcher.ts"() {
|
|
7839
7961
|
"use strict";
|
|
7840
7962
|
import_node_crypto10 = require("node:crypto");
|
|
7841
|
-
|
|
7963
|
+
import_node_path38 = __toESM(require("node:path"), 1);
|
|
7842
7964
|
init_package();
|
|
7843
7965
|
init_envBool();
|
|
7844
7966
|
init_argv();
|
|
@@ -7849,6 +7971,7 @@ var init_launcher = __esm({
|
|
|
7849
7971
|
init_flags();
|
|
7850
7972
|
init_extraFlags();
|
|
7851
7973
|
init_pool();
|
|
7974
|
+
init_resumeContext();
|
|
7852
7975
|
init_lock();
|
|
7853
7976
|
init_spawn();
|
|
7854
7977
|
init_providersStore();
|
|
@@ -7869,13 +7992,13 @@ function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string"
|
|
|
7869
7992
|
if (distDir === void 0) {
|
|
7870
7993
|
throw new OwnCliPathUnknownError();
|
|
7871
7994
|
}
|
|
7872
|
-
return
|
|
7995
|
+
return import_node_path39.default.join(distDir, OWN_CLI_FILE_NAME);
|
|
7873
7996
|
}
|
|
7874
|
-
var
|
|
7997
|
+
var import_node_path39, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
7875
7998
|
var init_ownCli = __esm({
|
|
7876
7999
|
"src/ownCli.ts"() {
|
|
7877
8000
|
"use strict";
|
|
7878
|
-
|
|
8001
|
+
import_node_path39 = __toESM(require("node:path"), 1);
|
|
7879
8002
|
init_cliError();
|
|
7880
8003
|
OWN_CLI_FILE_NAME = "cli.cjs";
|
|
7881
8004
|
OwnCliPathUnknownError = class extends CliError {
|
|
@@ -7960,7 +8083,7 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
|
|
|
7960
8083
|
// src/frontdoor/trust.ts
|
|
7961
8084
|
function resolveTrustBundle(params) {
|
|
7962
8085
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
|
|
7963
|
-
if (inherited === void 0 || inherited === "" ||
|
|
8086
|
+
if (inherited === void 0 || inherited === "" || import_node_path40.default.resolve(inherited) === import_node_path40.default.resolve(caCertFile)) {
|
|
7964
8087
|
return { path: caCertFile };
|
|
7965
8088
|
}
|
|
7966
8089
|
const caPem = fs12.readFileUtf8(caCertFile);
|
|
@@ -7978,19 +8101,19 @@ function resolveTrustBundle(params) {
|
|
|
7978
8101
|
}
|
|
7979
8102
|
const combined = `${inheritedPem.trimEnd()}
|
|
7980
8103
|
${caPem}`;
|
|
7981
|
-
const bundle =
|
|
8104
|
+
const bundle = import_node_path40.default.join(bundlesDir, `${(0, import_node_crypto11.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
7982
8105
|
if (!fs12.exists(bundle)) {
|
|
7983
8106
|
fs12.mkdirp(bundlesDir);
|
|
7984
8107
|
fs12.writeFileAtomic(bundle, combined);
|
|
7985
8108
|
}
|
|
7986
8109
|
return { path: bundle };
|
|
7987
8110
|
}
|
|
7988
|
-
var import_node_crypto11,
|
|
8111
|
+
var import_node_crypto11, import_node_path40, BUNDLE_NAME_HEX_DIGITS;
|
|
7989
8112
|
var init_trust = __esm({
|
|
7990
8113
|
"src/frontdoor/trust.ts"() {
|
|
7991
8114
|
"use strict";
|
|
7992
8115
|
import_node_crypto11 = require("node:crypto");
|
|
7993
|
-
|
|
8116
|
+
import_node_path40 = __toESM(require("node:path"), 1);
|
|
7994
8117
|
BUNDLE_NAME_HEX_DIGITS = 16;
|
|
7995
8118
|
}
|
|
7996
8119
|
});
|
|
@@ -9425,8 +9548,8 @@ function parseConnectTarget(authority) {
|
|
|
9425
9548
|
function isInterceptedHost(host, interceptHosts) {
|
|
9426
9549
|
return interceptHosts.includes(host);
|
|
9427
9550
|
}
|
|
9428
|
-
function servedByPipeline(
|
|
9429
|
-
return
|
|
9551
|
+
function servedByPipeline(path41) {
|
|
9552
|
+
return path41?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
9430
9553
|
}
|
|
9431
9554
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
9432
9555
|
"connection",
|
|
@@ -10220,11 +10343,11 @@ function createRcSessionTracker(deps) {
|
|
|
10220
10343
|
};
|
|
10221
10344
|
const observeExchange = (request4) => {
|
|
10222
10345
|
const method = (request4.method ?? "").toUpperCase();
|
|
10223
|
-
const
|
|
10224
|
-
if (!
|
|
10346
|
+
const path41 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
10347
|
+
if (!path41.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
10225
10348
|
return void 0;
|
|
10226
10349
|
}
|
|
10227
|
-
const tail =
|
|
10350
|
+
const tail = path41.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
10228
10351
|
const facts = {
|
|
10229
10352
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
10230
10353
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -10614,8 +10737,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
10614
10737
|
function isRcReadFileEncoding(value) {
|
|
10615
10738
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
10616
10739
|
}
|
|
10617
|
-
function buildRcReadFilePayload(requestId,
|
|
10618
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
10740
|
+
function buildRcReadFilePayload(requestId, path41, options) {
|
|
10741
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path41, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
10619
10742
|
}
|
|
10620
10743
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
10621
10744
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -10717,15 +10840,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
10717
10840
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
10718
10841
|
return result.ok ? { ...result, requestId } : result;
|
|
10719
10842
|
}
|
|
10720
|
-
async function readRcSessionFile(deps, sessionId,
|
|
10721
|
-
if (
|
|
10843
|
+
async function readRcSessionFile(deps, sessionId, path41, options) {
|
|
10844
|
+
if (path41 === "") {
|
|
10722
10845
|
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" };
|
|
10723
10846
|
}
|
|
10724
10847
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
10725
10848
|
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" };
|
|
10726
10849
|
}
|
|
10727
10850
|
const requestId = deps.newUuid();
|
|
10728
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
10851
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path41, options), `read ${path41} from session ${sessionId}`);
|
|
10729
10852
|
return result.ok ? { ...result, requestId } : result;
|
|
10730
10853
|
}
|
|
10731
10854
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -10894,11 +11017,11 @@ function createRcControlHandler(deps) {
|
|
|
10894
11017
|
path: "read-file",
|
|
10895
11018
|
read: (body) => {
|
|
10896
11019
|
const session = bodyString(body, "session");
|
|
10897
|
-
const
|
|
11020
|
+
const path41 = bodyString(body, "path");
|
|
10898
11021
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
10899
11022
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
10900
|
-
const refused2 = session === void 0 ||
|
|
10901
|
-
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,
|
|
11023
|
+
const refused2 = session === void 0 || path41 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
11024
|
+
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, path41, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
|
|
10902
11025
|
}
|
|
10903
11026
|
},
|
|
10904
11027
|
{
|
|
@@ -11208,9 +11331,9 @@ function requestIdOfBody(body) {
|
|
|
11208
11331
|
}
|
|
11209
11332
|
function frontDoorRcControl(transport, token) {
|
|
11210
11333
|
const headers = { authorization: `Bearer ${token}` };
|
|
11211
|
-
const listAnswerOf = async (
|
|
11334
|
+
const listAnswerOf = async (path41, what) => {
|
|
11212
11335
|
try {
|
|
11213
|
-
return await transport.request({ method: "GET", path:
|
|
11336
|
+
return await transport.request({ method: "GET", path: path41, headers });
|
|
11214
11337
|
} catch (error) {
|
|
11215
11338
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
11216
11339
|
}
|
|
@@ -11282,10 +11405,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
11282
11405
|
}
|
|
11283
11406
|
return pending;
|
|
11284
11407
|
};
|
|
11285
|
-
const writeOf = async (
|
|
11408
|
+
const writeOf = async (path41, body, describeFailure2) => {
|
|
11286
11409
|
let answer;
|
|
11287
11410
|
try {
|
|
11288
|
-
answer = await transport.request({ method: "POST", path:
|
|
11411
|
+
answer = await transport.request({ method: "POST", path: path41, headers: { ...headers, "content-type": "application/json" }, body });
|
|
11289
11412
|
} catch (error) {
|
|
11290
11413
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
11291
11414
|
}
|
|
@@ -11316,10 +11439,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
11316
11439
|
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}`),
|
|
11317
11440
|
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}`),
|
|
11318
11441
|
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}`),
|
|
11319
|
-
readFile: async (sessionId,
|
|
11442
|
+
readFile: async (sessionId, path41, options) => await writeOf(
|
|
11320
11443
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
11321
|
-
JSON.stringify({ session: sessionId, path:
|
|
11322
|
-
(status, message) => `reading ${
|
|
11444
|
+
JSON.stringify({ session: sessionId, path: path41, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
11445
|
+
(status, message) => `reading ${path41} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
11323
11446
|
),
|
|
11324
11447
|
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}`),
|
|
11325
11448
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -11478,12 +11601,12 @@ function tlsFacts(options) {
|
|
|
11478
11601
|
}
|
|
11479
11602
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
11480
11603
|
const agent = new ExemptTlsAgent();
|
|
11481
|
-
const post = async (
|
|
11604
|
+
const post = async (path41, headers, body) => await new Promise((resolve, reject) => {
|
|
11482
11605
|
const options = {
|
|
11483
11606
|
host: target.host,
|
|
11484
11607
|
port: target.port,
|
|
11485
11608
|
method: "POST",
|
|
11486
|
-
path:
|
|
11609
|
+
path: path41,
|
|
11487
11610
|
// 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.
|
|
11488
11611
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
11489
11612
|
agent
|
|
@@ -11548,12 +11671,12 @@ function lateRcStreamDial(resolve) {
|
|
|
11548
11671
|
}
|
|
11549
11672
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
11550
11673
|
const agent = new ExemptTlsAgent();
|
|
11551
|
-
const request4 = async (method,
|
|
11674
|
+
const request4 = async (method, path41, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
11552
11675
|
const options = {
|
|
11553
11676
|
host: target.host,
|
|
11554
11677
|
port: target.port,
|
|
11555
11678
|
method,
|
|
11556
|
-
path:
|
|
11679
|
+
path: path41,
|
|
11557
11680
|
// 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.
|
|
11558
11681
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
11559
11682
|
agent,
|
|
@@ -11595,9 +11718,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
11595
11718
|
return { status, body: await readAll(response) };
|
|
11596
11719
|
},
|
|
11597
11720
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
11598
|
-
const
|
|
11721
|
+
const path41 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
|
|
11599
11722
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
11600
|
-
const { status, response } = await request4("GET",
|
|
11723
|
+
const { status, response } = await request4("GET", path41, streamHeaders, void 0, signal);
|
|
11601
11724
|
if (!isSuccessful2(status)) {
|
|
11602
11725
|
await readAll(response);
|
|
11603
11726
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -12749,19 +12872,19 @@ function writePools(paths, pools) {
|
|
|
12749
12872
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
12750
12873
|
}
|
|
12751
12874
|
function poolCycleOf(pools, name) {
|
|
12752
|
-
const walk = (current,
|
|
12875
|
+
const walk = (current, path41) => {
|
|
12753
12876
|
for (const entry of pools[current]?.identities ?? []) {
|
|
12754
12877
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
12755
12878
|
if (nested === void 0) {
|
|
12756
12879
|
continue;
|
|
12757
12880
|
}
|
|
12758
12881
|
if (nested === name) {
|
|
12759
|
-
return [...
|
|
12882
|
+
return [...path41, nested];
|
|
12760
12883
|
}
|
|
12761
|
-
if (
|
|
12884
|
+
if (path41.includes(nested)) {
|
|
12762
12885
|
continue;
|
|
12763
12886
|
}
|
|
12764
|
-
const found = walk(nested, [...
|
|
12887
|
+
const found = walk(nested, [...path41, nested]);
|
|
12765
12888
|
if (found !== void 0) {
|
|
12766
12889
|
return found;
|
|
12767
12890
|
}
|
|
@@ -14972,7 +15095,7 @@ function profileValue(name, paths) {
|
|
|
14972
15095
|
function createConfigApiRouter(deps) {
|
|
14973
15096
|
const authed = doorApiAuth(deps.expectedToken);
|
|
14974
15097
|
const { paths } = deps;
|
|
14975
|
-
const route = (
|
|
15098
|
+
const route = (path41, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path41, summary, tags: [CONFIG_API_TAG] }));
|
|
14976
15099
|
return {
|
|
14977
15100
|
config: {
|
|
14978
15101
|
identity: {
|