claude-use 11.22.0 → 11.23.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/dist/cli.cjs +613 -596
- package/dist/index.cjs +129 -103
- package/dist/index.mjs +117 -91
- package/dist/types/index.d.ts +2 -0
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -624,7 +624,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
|
|
|
624
624
|
return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
|
|
625
625
|
}
|
|
626
626
|
function describeIgnoredKeys(filePath, ignored) {
|
|
627
|
-
const places = ignored.map(({ path:
|
|
627
|
+
const places = ignored.map(({ path: path42, keys }) => `${path42.length === 0 ? "" : `${path42.map(String).join(".")}.`}${keys.join(", ")}`);
|
|
628
628
|
return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
|
|
629
629
|
}
|
|
630
630
|
function noteIgnoredKeys(filePath, ignored) {
|
|
@@ -646,9 +646,9 @@ function restoreIgnoredKeys(filePath, value) {
|
|
|
646
646
|
return value;
|
|
647
647
|
}
|
|
648
648
|
const restored = structuredClone(value);
|
|
649
|
-
for (const { path:
|
|
649
|
+
for (const { path: path42, values } of ignored) {
|
|
650
650
|
let holder = restored;
|
|
651
|
-
for (const step of
|
|
651
|
+
for (const step of path42) {
|
|
652
652
|
holder = isRecord(holder) ? holder[step] : void 0;
|
|
653
653
|
}
|
|
654
654
|
if (isRecord(holder)) {
|
|
@@ -2928,7 +2928,7 @@ var init_package = __esm({
|
|
|
2928
2928
|
"package.json"() {
|
|
2929
2929
|
package_default = {
|
|
2930
2930
|
name: "claude-use",
|
|
2931
|
-
version: "11.
|
|
2931
|
+
version: "11.23.0",
|
|
2932
2932
|
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.",
|
|
2933
2933
|
license: "MIT",
|
|
2934
2934
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -6733,6 +6733,49 @@ var init_providersStore = __esm({
|
|
|
6733
6733
|
}
|
|
6734
6734
|
});
|
|
6735
6735
|
|
|
6736
|
+
// src/usage/signIn.ts
|
|
6737
|
+
function claudeCodeKeychainService(configDir) {
|
|
6738
|
+
return `${KEYCHAIN_SERVICE_PREFIX}-${(0, import_node_crypto9.createHash)("sha256").update(configDir).digest("hex").slice(0, KEYCHAIN_SERVICE_HASH_DIGITS)}`;
|
|
6739
|
+
}
|
|
6740
|
+
function keychainHasItem(run, configDir) {
|
|
6741
|
+
return run.run("security", ["find-generic-password", "-s", claudeCodeKeychainService(configDir)]).status === 0;
|
|
6742
|
+
}
|
|
6743
|
+
function decideSignIn(facts) {
|
|
6744
|
+
if (facts.hasCredentialBlock) {
|
|
6745
|
+
return { state: "token", detail: "supplies its own credential through a credential block, so a stored login is not what a launch uses" };
|
|
6746
|
+
}
|
|
6747
|
+
if (facts.keychainItem === true) {
|
|
6748
|
+
return { state: "signed-in", detail: "a login is stored in the macOS Keychain" };
|
|
6749
|
+
}
|
|
6750
|
+
if (facts.credentialsFile) {
|
|
6751
|
+
return { state: "signed-in", detail: `a login is stored in ${CREDENTIALS_FILE}` };
|
|
6752
|
+
}
|
|
6753
|
+
return { state: "signed-out", detail: facts.platform === "darwin" ? `no Keychain item and no ${CREDENTIALS_FILE}` : `no ${CREDENTIALS_FILE}` };
|
|
6754
|
+
}
|
|
6755
|
+
function credentialsFilePath(farmRoot) {
|
|
6756
|
+
return import_node_path26.default.join(farmRoot, CREDENTIALS_FILE);
|
|
6757
|
+
}
|
|
6758
|
+
function identitySignIn(fs13, probe, identity) {
|
|
6759
|
+
const probing = !identity.hasCredentialBlock;
|
|
6760
|
+
return decideSignIn({
|
|
6761
|
+
hasCredentialBlock: identity.hasCredentialBlock,
|
|
6762
|
+
keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
|
|
6763
|
+
credentialsFile: probing && fs13.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
|
|
6764
|
+
platform: probe.platform
|
|
6765
|
+
});
|
|
6766
|
+
}
|
|
6767
|
+
var import_node_crypto9, import_node_path26, CREDENTIALS_FILE, KEYCHAIN_SERVICE_PREFIX, KEYCHAIN_SERVICE_HASH_DIGITS;
|
|
6768
|
+
var init_signIn = __esm({
|
|
6769
|
+
"src/usage/signIn.ts"() {
|
|
6770
|
+
"use strict";
|
|
6771
|
+
import_node_crypto9 = require("node:crypto");
|
|
6772
|
+
import_node_path26 = __toESM(require("node:path"), 1);
|
|
6773
|
+
CREDENTIALS_FILE = ".credentials.json";
|
|
6774
|
+
KEYCHAIN_SERVICE_PREFIX = "Claude Code-credentials";
|
|
6775
|
+
KEYCHAIN_SERVICE_HASH_DIGITS = 8;
|
|
6776
|
+
}
|
|
6777
|
+
});
|
|
6778
|
+
|
|
6736
6779
|
// src/cli/bool.ts
|
|
6737
6780
|
function parseBoolWord(input) {
|
|
6738
6781
|
switch (input) {
|
|
@@ -6886,10 +6929,10 @@ function commandFilename(ownExecutablePath, commandName) {
|
|
|
6886
6929
|
}
|
|
6887
6930
|
function resolveOwnBinaryCheck(paths, contentSourcePath) {
|
|
6888
6931
|
const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
6889
|
-
const recordedTarget = state === void 0 ? void 0 :
|
|
6932
|
+
const recordedTarget = state === void 0 ? void 0 : import_node_path28.default.resolve(state.targetPath);
|
|
6890
6933
|
let ownStat;
|
|
6891
6934
|
return (candidate) => {
|
|
6892
|
-
if (recordedTarget !== void 0 &&
|
|
6935
|
+
if (recordedTarget !== void 0 && import_node_path28.default.resolve(candidate) === recordedTarget) {
|
|
6893
6936
|
return true;
|
|
6894
6937
|
}
|
|
6895
6938
|
ownStat ??= statOrUndefined(contentSourcePath);
|
|
@@ -6912,22 +6955,22 @@ function statOrUndefined(target) {
|
|
|
6912
6955
|
}
|
|
6913
6956
|
}
|
|
6914
6957
|
function findPathShadow(params) {
|
|
6915
|
-
const resolvedTargetDir =
|
|
6958
|
+
const resolvedTargetDir = import_node_path28.default.resolve(params.targetDir);
|
|
6916
6959
|
for (const dir of params.pathDirs) {
|
|
6917
6960
|
const found = params.findExecutableInDir(dir, params.targetFilename);
|
|
6918
6961
|
if (found === void 0) {
|
|
6919
6962
|
continue;
|
|
6920
6963
|
}
|
|
6921
|
-
return
|
|
6964
|
+
return import_node_path28.default.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
|
|
6922
6965
|
}
|
|
6923
|
-
return params.pathDirs.some((dir) =>
|
|
6966
|
+
return params.pathDirs.some((dir) => import_node_path28.default.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
|
|
6924
6967
|
}
|
|
6925
|
-
var import_node_fs7,
|
|
6968
|
+
var import_node_fs7, import_node_path28, import_zod19, ClaudeShimStateSchema, nodeLinkFs;
|
|
6926
6969
|
var init_claudeShim = __esm({
|
|
6927
6970
|
"src/claudeShim.ts"() {
|
|
6928
6971
|
"use strict";
|
|
6929
6972
|
import_node_fs7 = __toESM(require("node:fs"), 1);
|
|
6930
|
-
|
|
6973
|
+
import_node_path28 = __toESM(require("node:path"), 1);
|
|
6931
6974
|
import_zod19 = require("zod");
|
|
6932
6975
|
init_commandDeps();
|
|
6933
6976
|
init_store();
|
|
@@ -7128,7 +7171,7 @@ function ensureFrontDoor(params) {
|
|
|
7128
7171
|
if (supervisorPid !== void 0 && !distrusted.has(supervisorPid) && ports.isRunning(supervisorPid)) {
|
|
7129
7172
|
if (state?.port !== void 0 && state.connectPort !== void 0) {
|
|
7130
7173
|
if (supervisorPid === params.launcherPid && params.replace !== true && ports.isFrontDoorSupervisor(supervisorPid)) {
|
|
7131
|
-
const token = (0,
|
|
7174
|
+
const token = (0, import_node_crypto10.randomUUID)();
|
|
7132
7175
|
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
|
|
7133
7176
|
return { port: state.port, connectPort: state.connectPort, token };
|
|
7134
7177
|
}
|
|
@@ -7142,7 +7185,7 @@ function ensureFrontDoor(params) {
|
|
|
7142
7185
|
continue;
|
|
7143
7186
|
}
|
|
7144
7187
|
if (verdict.ok) {
|
|
7145
|
-
const token = (0,
|
|
7188
|
+
const token = (0, import_node_crypto10.randomUUID)();
|
|
7146
7189
|
writeFrontDoorSession(ports.fs, paths.frontdoorSessionsDir, { pid: params.launcherPid, startedAt: ports.now(), token, supervisorPid });
|
|
7147
7190
|
return { port: state.port, connectPort: state.connectPort, token };
|
|
7148
7191
|
}
|
|
@@ -7195,11 +7238,11 @@ function ensureFrontDoor(params) {
|
|
|
7195
7238
|
ports.sleep(FRONTDOOR_LAUNCHER_POLL_MS);
|
|
7196
7239
|
}
|
|
7197
7240
|
}
|
|
7198
|
-
var
|
|
7241
|
+
var import_node_crypto10, FRONTDOOR_START_TIMEOUT_MS, FRONTDOOR_LAUNCHER_POLL_MS, FRONTDOOR_PROBE_ATTEMPTS, FRONTDOOR_EXIT_GRACE_MS, FrontDoorStartError;
|
|
7199
7242
|
var init_ensure2 = __esm({
|
|
7200
7243
|
"src/frontdoor/ensure.ts"() {
|
|
7201
7244
|
"use strict";
|
|
7202
|
-
|
|
7245
|
+
import_node_crypto10 = require("node:crypto");
|
|
7203
7246
|
init_cliError();
|
|
7204
7247
|
init_state2();
|
|
7205
7248
|
init_state();
|
|
@@ -7580,7 +7623,7 @@ function buildEnv(params) {
|
|
|
7580
7623
|
}
|
|
7581
7624
|
}
|
|
7582
7625
|
if (params.provider !== void 0) {
|
|
7583
|
-
env.ANTHROPIC_AUTH_TOKEN = void 0;
|
|
7626
|
+
env.ANTHROPIC_AUTH_TOKEN = params.remoteControl ? void 0 : PROVIDER_SESSION_PLACEHOLDER;
|
|
7584
7627
|
env.ANTHROPIC_API_KEY = void 0;
|
|
7585
7628
|
env.CLAUDE_CODE_OAUTH_TOKEN = void 0;
|
|
7586
7629
|
} else if (params.identityCredential !== void 0) {
|
|
@@ -7612,7 +7655,7 @@ function buildEnv(params) {
|
|
|
7612
7655
|
}
|
|
7613
7656
|
return env;
|
|
7614
7657
|
}
|
|
7615
|
-
var import_node_path36, LOOPBACK_HOSTS;
|
|
7658
|
+
var import_node_path36, LOOPBACK_HOSTS, PROVIDER_SESSION_PLACEHOLDER;
|
|
7616
7659
|
var init_flags = __esm({
|
|
7617
7660
|
"src/launcher/flags.ts"() {
|
|
7618
7661
|
"use strict";
|
|
@@ -7623,6 +7666,7 @@ var init_flags = __esm({
|
|
|
7623
7666
|
init_capability();
|
|
7624
7667
|
init_route();
|
|
7625
7668
|
LOOPBACK_HOSTS = ["127.0.0.1", "localhost", "::1"];
|
|
7669
|
+
PROVIDER_SESSION_PLACEHOLDER = "agent-shim-provider-session";
|
|
7626
7670
|
}
|
|
7627
7671
|
});
|
|
7628
7672
|
|
|
@@ -8180,7 +8224,7 @@ function decideLaunch(params, readOnly) {
|
|
|
8180
8224
|
}
|
|
8181
8225
|
const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
|
|
8182
8226
|
const discovered = params.resolveClaudeBinary(pinnedVersion === void 0 ? void 0 : { version: pinnedVersion.version });
|
|
8183
|
-
const
|
|
8227
|
+
const requestedFlags = resolveLaunchFlags({
|
|
8184
8228
|
env,
|
|
8185
8229
|
...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
|
|
8186
8230
|
flags: {
|
|
@@ -8190,6 +8234,11 @@ function decideLaunch(params, readOnly) {
|
|
|
8190
8234
|
...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
|
|
8191
8235
|
}
|
|
8192
8236
|
});
|
|
8237
|
+
const loginlessProvider = requestedFlags.remoteControl && selectedProvider !== void 0 && farmIdentity !== void 0 && params.hasStoredLogin?.(farmIdentity) === false ? { identity: farmIdentity, provider: selectedProvider.name } : void 0;
|
|
8238
|
+
if (loginlessProvider !== void 0 && !readOnly) {
|
|
8239
|
+
log.info(`agent-shim: identity ${loginlessProvider.identity} has no stored login, so Remote Control, which needs one, is off for this launch; provider ${loginlessProvider.provider} runs without it`);
|
|
8240
|
+
}
|
|
8241
|
+
const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
|
|
8193
8242
|
const args = buildArgv({
|
|
8194
8243
|
toolFlags: buildFlagArgs(flags),
|
|
8195
8244
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
@@ -8305,7 +8354,7 @@ function prepareLaunch(params) {
|
|
|
8305
8354
|
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})`}`);
|
|
8306
8355
|
}
|
|
8307
8356
|
const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
|
|
8308
|
-
const sessionId = params.supervised?.sessionId ?? (0,
|
|
8357
|
+
const sessionId = params.supervised?.sessionId ?? (0, import_node_crypto11.randomUUID)();
|
|
8309
8358
|
const finalEnv = buildEnv({
|
|
8310
8359
|
baseEnv: env,
|
|
8311
8360
|
configDirEscapeHatch: configDirEscapeHatchApplies,
|
|
@@ -8315,7 +8364,8 @@ function prepareLaunch(params) {
|
|
|
8315
8364
|
...identityCredential === void 0 ? {} : { identityCredential },
|
|
8316
8365
|
...frontDoor === void 0 ? {} : { frontdoor: frontDoor },
|
|
8317
8366
|
...headroom === void 0 ? {} : { headroom },
|
|
8318
|
-
sessionId
|
|
8367
|
+
sessionId,
|
|
8368
|
+
remoteControl: resolvedFlags.remoteControl
|
|
8319
8369
|
});
|
|
8320
8370
|
const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
|
|
8321
8371
|
const release = () => {
|
|
@@ -8337,7 +8387,8 @@ function resolveLaunch(params) {
|
|
|
8337
8387
|
...decided.provider === void 0 ? {} : { provider: decided.provider },
|
|
8338
8388
|
...frontDoor ? { frontdoor: { port: 0, connectPort: 0, trustBundlePath: "", sessionToken: "" } } : {},
|
|
8339
8389
|
...decided.flags.headroom ? { headroom: { socketPath: "", projectId: "" } } : {},
|
|
8340
|
-
sessionId: ""
|
|
8390
|
+
sessionId: "",
|
|
8391
|
+
remoteControl: decided.flags.remoteControl
|
|
8341
8392
|
});
|
|
8342
8393
|
const credentialNames = decided.identityCredentialBlock === void 0 ? [] : Object.keys(credentialVariables(decided.identityCredentialBlock.target ?? "bearer", ""));
|
|
8343
8394
|
const environment = [.../* @__PURE__ */ new Set([...Object.keys(built).filter((name) => built[name] !== env[name]), ...credentialNames])].sort();
|
|
@@ -8368,11 +8419,11 @@ function runLaunchPlan(plan, spawn3) {
|
|
|
8368
8419
|
function runLauncher(params) {
|
|
8369
8420
|
params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
|
|
8370
8421
|
}
|
|
8371
|
-
var
|
|
8422
|
+
var import_node_crypto11, import_node_path38;
|
|
8372
8423
|
var init_launcher = __esm({
|
|
8373
8424
|
"src/launcher.ts"() {
|
|
8374
8425
|
"use strict";
|
|
8375
|
-
|
|
8426
|
+
import_node_crypto11 = require("node:crypto");
|
|
8376
8427
|
import_node_path38 = __toESM(require("node:path"), 1);
|
|
8377
8428
|
init_package();
|
|
8378
8429
|
init_envBool();
|
|
@@ -8456,18 +8507,18 @@ function resolveTrustBundle(params) {
|
|
|
8456
8507
|
}
|
|
8457
8508
|
const combined = `${inheritedPem.trimEnd()}
|
|
8458
8509
|
${caPem}`;
|
|
8459
|
-
const bundle = import_node_path40.default.join(bundlesDir, `${(0,
|
|
8510
|
+
const bundle = import_node_path40.default.join(bundlesDir, `${(0, import_node_crypto12.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
8460
8511
|
if (!fs13.exists(bundle)) {
|
|
8461
8512
|
fs13.mkdirp(bundlesDir);
|
|
8462
8513
|
fs13.writeFileAtomic(bundle, combined);
|
|
8463
8514
|
}
|
|
8464
8515
|
return { path: bundle };
|
|
8465
8516
|
}
|
|
8466
|
-
var
|
|
8517
|
+
var import_node_crypto12, import_node_path40, BUNDLE_NAME_HEX_DIGITS;
|
|
8467
8518
|
var init_trust = __esm({
|
|
8468
8519
|
"src/frontdoor/trust.ts"() {
|
|
8469
8520
|
"use strict";
|
|
8470
|
-
|
|
8521
|
+
import_node_crypto12 = require("node:crypto");
|
|
8471
8522
|
import_node_path40 = __toESM(require("node:path"), 1);
|
|
8472
8523
|
BUNDLE_NAME_HEX_DIGITS = 16;
|
|
8473
8524
|
}
|
|
@@ -8561,7 +8612,7 @@ function buildFarmRuntime(paths, cwd) {
|
|
|
8561
8612
|
...cliOverride === void 0 ? {} : { cliOverride }
|
|
8562
8613
|
}).input,
|
|
8563
8614
|
now: () => Date.now(),
|
|
8564
|
-
uniqueSuffix: `${String(process.pid)}.${(0,
|
|
8615
|
+
uniqueSuffix: `${String(process.pid)}.${(0, import_node_crypto13.randomUUID)()}`,
|
|
8565
8616
|
// Zombie-aware on purpose: a previous launcher that crashed out of a resync without releasing the lock may sit unreaped, still answering signal 0 as alive, and must read as a dead holder so this launch takes the lock over instead of timing out.
|
|
8566
8617
|
lock: { pid: process.pid, isRunning: realIsProcessRunning, sleep: realSleepSync }
|
|
8567
8618
|
},
|
|
@@ -8587,6 +8638,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
8587
8638
|
headroom: realHeadroomPort(paths, { spawnDaemon: options.spawnDaemon, cwd: farm.runtime.cwd }),
|
|
8588
8639
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|
|
8589
8640
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
8641
|
+
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: realRunPort }, { farmRoot: import_node_path41.default.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
|
|
8590
8642
|
...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
|
|
8591
8643
|
...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
|
|
8592
8644
|
...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
|
|
@@ -8643,12 +8695,13 @@ function resolveClaudeLaunch(options) {
|
|
|
8643
8695
|
};
|
|
8644
8696
|
return { resolution: resolveLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, farm: buildFarmRuntime(paths, options.cwd) })), warnings };
|
|
8645
8697
|
}
|
|
8646
|
-
var import_node_os7,
|
|
8698
|
+
var import_node_os7, import_node_path41, import_node_crypto13, LaunchRefusedError;
|
|
8647
8699
|
var init_launchWiring = __esm({
|
|
8648
8700
|
"src/launchWiring.ts"() {
|
|
8649
8701
|
"use strict";
|
|
8650
8702
|
import_node_os7 = __toESM(require("node:os"), 1);
|
|
8651
|
-
|
|
8703
|
+
import_node_path41 = __toESM(require("node:path"), 1);
|
|
8704
|
+
import_node_crypto13 = require("node:crypto");
|
|
8652
8705
|
init_cliError();
|
|
8653
8706
|
init_claudeShim();
|
|
8654
8707
|
init_classify();
|
|
@@ -8660,6 +8713,7 @@ var init_launchWiring = __esm({
|
|
|
8660
8713
|
init_launchHook();
|
|
8661
8714
|
init_cascade();
|
|
8662
8715
|
init_paths();
|
|
8716
|
+
init_signIn();
|
|
8663
8717
|
init_realPorts();
|
|
8664
8718
|
LaunchRefusedError = class extends CliError {
|
|
8665
8719
|
exitCode;
|
|
@@ -9951,8 +10005,8 @@ function parseConnectTarget(authority) {
|
|
|
9951
10005
|
function isInterceptedHost(host, interceptHosts) {
|
|
9952
10006
|
return interceptHosts.includes(host);
|
|
9953
10007
|
}
|
|
9954
|
-
function servedByPipeline(
|
|
9955
|
-
return
|
|
10008
|
+
function servedByPipeline(path42) {
|
|
10009
|
+
return path42?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
9956
10010
|
}
|
|
9957
10011
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
9958
10012
|
"connection",
|
|
@@ -10746,11 +10800,11 @@ function createRcSessionTracker(deps) {
|
|
|
10746
10800
|
};
|
|
10747
10801
|
const observeExchange = (request4) => {
|
|
10748
10802
|
const method = (request4.method ?? "").toUpperCase();
|
|
10749
|
-
const
|
|
10750
|
-
if (!
|
|
10803
|
+
const path42 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
10804
|
+
if (!path42.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
10751
10805
|
return void 0;
|
|
10752
10806
|
}
|
|
10753
|
-
const tail =
|
|
10807
|
+
const tail = path42.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
10754
10808
|
const facts = {
|
|
10755
10809
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
10756
10810
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -11140,8 +11194,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
11140
11194
|
function isRcReadFileEncoding(value) {
|
|
11141
11195
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
11142
11196
|
}
|
|
11143
|
-
function buildRcReadFilePayload(requestId,
|
|
11144
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
11197
|
+
function buildRcReadFilePayload(requestId, path42, options) {
|
|
11198
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path42, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
11145
11199
|
}
|
|
11146
11200
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
11147
11201
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -11243,15 +11297,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
11243
11297
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
11244
11298
|
return result.ok ? { ...result, requestId } : result;
|
|
11245
11299
|
}
|
|
11246
|
-
async function readRcSessionFile(deps, sessionId,
|
|
11247
|
-
if (
|
|
11300
|
+
async function readRcSessionFile(deps, sessionId, path42, options) {
|
|
11301
|
+
if (path42 === "") {
|
|
11248
11302
|
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" };
|
|
11249
11303
|
}
|
|
11250
11304
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
11251
11305
|
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" };
|
|
11252
11306
|
}
|
|
11253
11307
|
const requestId = deps.newUuid();
|
|
11254
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
11308
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path42, options), `read ${path42} from session ${sessionId}`);
|
|
11255
11309
|
return result.ok ? { ...result, requestId } : result;
|
|
11256
11310
|
}
|
|
11257
11311
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -11420,11 +11474,11 @@ function createRcControlHandler(deps) {
|
|
|
11420
11474
|
path: "read-file",
|
|
11421
11475
|
read: (body) => {
|
|
11422
11476
|
const session = bodyString(body, "session");
|
|
11423
|
-
const
|
|
11477
|
+
const path42 = bodyString(body, "path");
|
|
11424
11478
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
11425
11479
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
11426
|
-
const refused2 = session === void 0 ||
|
|
11427
|
-
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,
|
|
11480
|
+
const refused2 = session === void 0 || path42 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
11481
|
+
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, path42, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
|
|
11428
11482
|
}
|
|
11429
11483
|
},
|
|
11430
11484
|
{
|
|
@@ -11734,9 +11788,9 @@ function requestIdOfBody(body) {
|
|
|
11734
11788
|
}
|
|
11735
11789
|
function frontDoorRcControl(transport, token) {
|
|
11736
11790
|
const headers = { authorization: `Bearer ${token}` };
|
|
11737
|
-
const listAnswerOf = async (
|
|
11791
|
+
const listAnswerOf = async (path42, what) => {
|
|
11738
11792
|
try {
|
|
11739
|
-
return await transport.request({ method: "GET", path:
|
|
11793
|
+
return await transport.request({ method: "GET", path: path42, headers });
|
|
11740
11794
|
} catch (error) {
|
|
11741
11795
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
11742
11796
|
}
|
|
@@ -11808,10 +11862,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
11808
11862
|
}
|
|
11809
11863
|
return pending;
|
|
11810
11864
|
};
|
|
11811
|
-
const writeOf = async (
|
|
11865
|
+
const writeOf = async (path42, body, describeFailure2) => {
|
|
11812
11866
|
let answer;
|
|
11813
11867
|
try {
|
|
11814
|
-
answer = await transport.request({ method: "POST", path:
|
|
11868
|
+
answer = await transport.request({ method: "POST", path: path42, headers: { ...headers, "content-type": "application/json" }, body });
|
|
11815
11869
|
} catch (error) {
|
|
11816
11870
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
11817
11871
|
}
|
|
@@ -11842,10 +11896,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
11842
11896
|
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}`),
|
|
11843
11897
|
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}`),
|
|
11844
11898
|
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}`),
|
|
11845
|
-
readFile: async (sessionId,
|
|
11899
|
+
readFile: async (sessionId, path42, options) => await writeOf(
|
|
11846
11900
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
11847
|
-
JSON.stringify({ session: sessionId, path:
|
|
11848
|
-
(status, message) => `reading ${
|
|
11901
|
+
JSON.stringify({ session: sessionId, path: path42, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
11902
|
+
(status, message) => `reading ${path42} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
11849
11903
|
),
|
|
11850
11904
|
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}`),
|
|
11851
11905
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -12004,12 +12058,12 @@ function tlsFacts(options) {
|
|
|
12004
12058
|
}
|
|
12005
12059
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
12006
12060
|
const agent = new ExemptTlsAgent();
|
|
12007
|
-
const post = async (
|
|
12061
|
+
const post = async (path42, headers, body) => await new Promise((resolve, reject) => {
|
|
12008
12062
|
const options = {
|
|
12009
12063
|
host: target.host,
|
|
12010
12064
|
port: target.port,
|
|
12011
12065
|
method: "POST",
|
|
12012
|
-
path:
|
|
12066
|
+
path: path42,
|
|
12013
12067
|
// 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.
|
|
12014
12068
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
12015
12069
|
agent
|
|
@@ -12074,12 +12128,12 @@ function lateRcStreamDial(resolve) {
|
|
|
12074
12128
|
}
|
|
12075
12129
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
12076
12130
|
const agent = new ExemptTlsAgent();
|
|
12077
|
-
const request4 = async (method,
|
|
12131
|
+
const request4 = async (method, path42, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
12078
12132
|
const options = {
|
|
12079
12133
|
host: target.host,
|
|
12080
12134
|
port: target.port,
|
|
12081
12135
|
method,
|
|
12082
|
-
path:
|
|
12136
|
+
path: path42,
|
|
12083
12137
|
// 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.
|
|
12084
12138
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
12085
12139
|
agent,
|
|
@@ -12121,9 +12175,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
12121
12175
|
return { status, body: await readAll(response) };
|
|
12122
12176
|
},
|
|
12123
12177
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
12124
|
-
const
|
|
12178
|
+
const path42 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
|
|
12125
12179
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
12126
|
-
const { status, response } = await request4("GET",
|
|
12180
|
+
const { status, response } = await request4("GET", path42, streamHeaders, void 0, signal);
|
|
12127
12181
|
if (!isSuccessful2(status)) {
|
|
12128
12182
|
await readAll(response);
|
|
12129
12183
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -13275,19 +13329,19 @@ function writePools(paths, pools) {
|
|
|
13275
13329
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
13276
13330
|
}
|
|
13277
13331
|
function poolCycleOf(pools, name) {
|
|
13278
|
-
const walk = (current,
|
|
13332
|
+
const walk = (current, path42) => {
|
|
13279
13333
|
for (const entry of pools[current]?.identities ?? []) {
|
|
13280
13334
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
13281
13335
|
if (nested === void 0) {
|
|
13282
13336
|
continue;
|
|
13283
13337
|
}
|
|
13284
13338
|
if (nested === name) {
|
|
13285
|
-
return [...
|
|
13339
|
+
return [...path42, nested];
|
|
13286
13340
|
}
|
|
13287
|
-
if (
|
|
13341
|
+
if (path42.includes(nested)) {
|
|
13288
13342
|
continue;
|
|
13289
13343
|
}
|
|
13290
|
-
const found = walk(nested, [...
|
|
13344
|
+
const found = walk(nested, [...path42, nested]);
|
|
13291
13345
|
if (found !== void 0) {
|
|
13292
13346
|
return found;
|
|
13293
13347
|
}
|
|
@@ -13409,8 +13463,9 @@ init_cascade();
|
|
|
13409
13463
|
init_paths();
|
|
13410
13464
|
init_realCredentialCache();
|
|
13411
13465
|
init_providersStore();
|
|
13466
|
+
init_signIn();
|
|
13412
13467
|
init_realPorts();
|
|
13413
|
-
var
|
|
13468
|
+
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
13414
13469
|
var import_zod15 = require("zod");
|
|
13415
13470
|
init_envBool();
|
|
13416
13471
|
init_load();
|
|
@@ -13478,26 +13533,18 @@ function formatDecision(decision) {
|
|
|
13478
13533
|
const eliminatedNote = decision.eliminated !== void 0 && decision.eliminated.length > 0 ? ` [${String(decision.eliminated.length)} more specific rule(s) eliminated by a failing when-condition]` : "";
|
|
13479
13534
|
return `${decision.relPath}: ${status} \u2014 ${reason}${eliminatedNote}`;
|
|
13480
13535
|
}
|
|
13481
|
-
function parseKeychainServiceName(stderr) {
|
|
13482
|
-
const match = /"svce"<blob>="([^"]*)"/.exec(stderr);
|
|
13483
|
-
return match?.[1];
|
|
13484
|
-
}
|
|
13485
13536
|
function lookupKeychainService(run, farmRoot) {
|
|
13486
|
-
const
|
|
13537
|
+
const serviceName = claudeCodeKeychainService(farmRoot);
|
|
13538
|
+
const result = run.run("security", ["find-generic-password", "-s", serviceName]);
|
|
13487
13539
|
if (result.status !== 0) {
|
|
13488
13540
|
return {
|
|
13489
13541
|
checked: true,
|
|
13490
13542
|
found: false,
|
|
13491
|
-
|
|
13543
|
+
serviceName,
|
|
13544
|
+
note: `No Keychain entry found for service "${serviceName}" (security exited ${result.status === null ? "with no status" : String(result.status)}).`
|
|
13492
13545
|
};
|
|
13493
13546
|
}
|
|
13494
|
-
|
|
13495
|
-
return {
|
|
13496
|
-
checked: true,
|
|
13497
|
-
found: true,
|
|
13498
|
-
...serviceName === void 0 ? {} : { serviceName },
|
|
13499
|
-
note: serviceName === void 0 ? `A Keychain entry was found for account "${farmRoot}" but its service name could not be parsed from security's output.` : `Keychain service name for this identity: "${serviceName}".`
|
|
13500
|
-
};
|
|
13547
|
+
return { checked: true, found: true, serviceName, note: `Keychain service name for this identity: "${serviceName}".` };
|
|
13501
13548
|
}
|
|
13502
13549
|
var SettingsSecretsShapeSchema = import_zod15.z.looseObject({
|
|
13503
13550
|
env: import_zod15.z.record(import_zod15.z.string(), import_zod15.z.unknown()).optional(),
|
|
@@ -13759,10 +13806,10 @@ function collectCheckReport(params) {
|
|
|
13759
13806
|
}).input;
|
|
13760
13807
|
const providerName = cascadeProviderName(cascade);
|
|
13761
13808
|
const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
|
|
13762
|
-
const farmRoot = identityDecision.name === void 0 ? void 0 :
|
|
13809
|
+
const farmRoot = identityDecision.name === void 0 ? void 0 : import_node_path27.default.join(paths.identitiesDir, identityDecision.name);
|
|
13763
13810
|
const settingsFiles = {
|
|
13764
|
-
"settings.json": realFsPort.readFileUtf8(
|
|
13765
|
-
"settings.local.json": realFsPort.readFileUtf8(
|
|
13811
|
+
"settings.json": realFsPort.readFileUtf8(import_node_path27.default.join(claudeHome, "settings.json")),
|
|
13812
|
+
"settings.local.json": realFsPort.readFileUtf8(import_node_path27.default.join(claudeHome, "settings.local.json"))
|
|
13766
13813
|
};
|
|
13767
13814
|
const report = runCheck({
|
|
13768
13815
|
cwd,
|
|
@@ -14063,7 +14110,7 @@ init_store();
|
|
|
14063
14110
|
|
|
14064
14111
|
// src/identityStore.ts
|
|
14065
14112
|
var import_node_fs8 = __toESM(require("node:fs"), 1);
|
|
14066
|
-
var
|
|
14113
|
+
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
14067
14114
|
init_load();
|
|
14068
14115
|
init_store();
|
|
14069
14116
|
init_schema();
|
|
@@ -14097,7 +14144,7 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
14097
14144
|
attemptedName;
|
|
14098
14145
|
};
|
|
14099
14146
|
function identityJsonPath(paths, name) {
|
|
14100
|
-
return
|
|
14147
|
+
return import_node_path29.default.join(paths.identitiesDir, name, "identity.json");
|
|
14101
14148
|
}
|
|
14102
14149
|
function requireIdentityNames(paths, names) {
|
|
14103
14150
|
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
@@ -14212,7 +14259,7 @@ function setIdentityCredential(paths, identityName, change) {
|
|
|
14212
14259
|
});
|
|
14213
14260
|
}
|
|
14214
14261
|
function belongsToIdentity(entry, name) {
|
|
14215
|
-
return entry === name || entry ===
|
|
14262
|
+
return entry === name || entry === import_node_path29.default.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
|
|
14216
14263
|
}
|
|
14217
14264
|
function removeIdentity(paths, name) {
|
|
14218
14265
|
if (!identityExists(paths, name)) {
|
|
@@ -14220,7 +14267,7 @@ function removeIdentity(paths, name) {
|
|
|
14220
14267
|
}
|
|
14221
14268
|
for (const entry of import_node_fs8.default.readdirSync(paths.identitiesDir)) {
|
|
14222
14269
|
if (belongsToIdentity(entry, name)) {
|
|
14223
|
-
import_node_fs8.default.rmSync(
|
|
14270
|
+
import_node_fs8.default.rmSync(import_node_path29.default.join(paths.identitiesDir, entry), { recursive: true, force: true });
|
|
14224
14271
|
}
|
|
14225
14272
|
}
|
|
14226
14273
|
if (readActiveIdentity2(paths) === name) {
|
|
@@ -14232,28 +14279,7 @@ function removeIdentity(paths, name) {
|
|
|
14232
14279
|
init_realPorts();
|
|
14233
14280
|
var import_node_fs10 = __toESM(require("node:fs"), 1);
|
|
14234
14281
|
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
14235
|
-
|
|
14236
|
-
// src/usage/signIn.ts
|
|
14237
|
-
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
14238
|
-
var CREDENTIALS_FILE = ".credentials.json";
|
|
14239
|
-
function keychainHasItem(run, account) {
|
|
14240
|
-
return run.run("security", ["find-generic-password", "-a", account]).status === 0;
|
|
14241
|
-
}
|
|
14242
|
-
function decideSignIn(facts) {
|
|
14243
|
-
if (facts.hasCredentialBlock) {
|
|
14244
|
-
return { state: "token", detail: "supplies its own credential through a credential block, so a stored login is not what a launch uses" };
|
|
14245
|
-
}
|
|
14246
|
-
if (facts.keychainItem === true) {
|
|
14247
|
-
return { state: "signed-in", detail: "a login is stored in the macOS Keychain" };
|
|
14248
|
-
}
|
|
14249
|
-
if (facts.credentialsFile) {
|
|
14250
|
-
return { state: "signed-in", detail: `a login is stored in ${CREDENTIALS_FILE}` };
|
|
14251
|
-
}
|
|
14252
|
-
return { state: "signed-out", detail: facts.platform === "darwin" ? `no Keychain item and no ${CREDENTIALS_FILE}` : `no ${CREDENTIALS_FILE}` };
|
|
14253
|
-
}
|
|
14254
|
-
function credentialsFilePath(farmRoot) {
|
|
14255
|
-
return import_node_path29.default.join(farmRoot, CREDENTIALS_FILE);
|
|
14256
|
-
}
|
|
14282
|
+
init_signIn();
|
|
14257
14283
|
|
|
14258
14284
|
// src/codex/siwcStore.ts
|
|
14259
14285
|
var import_zod22 = require("zod");
|
|
@@ -15594,7 +15620,7 @@ function profileValue(name, paths) {
|
|
|
15594
15620
|
function createConfigApiRouter(deps) {
|
|
15595
15621
|
const authed = doorApiAuth(deps.expectedToken);
|
|
15596
15622
|
const { paths } = deps;
|
|
15597
|
-
const route = (
|
|
15623
|
+
const route = (path42, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path42, summary, tags: [CONFIG_API_TAG] }));
|
|
15598
15624
|
return {
|
|
15599
15625
|
config: {
|
|
15600
15626
|
identity: {
|