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.mjs
CHANGED
|
@@ -602,7 +602,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
|
|
|
602
602
|
return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
|
|
603
603
|
}
|
|
604
604
|
function describeIgnoredKeys(filePath, ignored) {
|
|
605
|
-
const places = ignored.map(({ path:
|
|
605
|
+
const places = ignored.map(({ path: path42, keys }) => `${path42.length === 0 ? "" : `${path42.map(String).join(".")}.`}${keys.join(", ")}`);
|
|
606
606
|
return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
|
|
607
607
|
}
|
|
608
608
|
function noteIgnoredKeys(filePath, ignored) {
|
|
@@ -624,9 +624,9 @@ function restoreIgnoredKeys(filePath, value) {
|
|
|
624
624
|
return value;
|
|
625
625
|
}
|
|
626
626
|
const restored = structuredClone(value);
|
|
627
|
-
for (const { path:
|
|
627
|
+
for (const { path: path42, values } of ignored) {
|
|
628
628
|
let holder = restored;
|
|
629
|
-
for (const step of
|
|
629
|
+
for (const step of path42) {
|
|
630
630
|
holder = isRecord(holder) ? holder[step] : void 0;
|
|
631
631
|
}
|
|
632
632
|
if (isRecord(holder)) {
|
|
@@ -2904,7 +2904,7 @@ var init_package = __esm({
|
|
|
2904
2904
|
"package.json"() {
|
|
2905
2905
|
package_default = {
|
|
2906
2906
|
name: "claude-use",
|
|
2907
|
-
version: "11.
|
|
2907
|
+
version: "11.23.0",
|
|
2908
2908
|
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.",
|
|
2909
2909
|
license: "MIT",
|
|
2910
2910
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -6706,6 +6706,49 @@ var init_providersStore = __esm({
|
|
|
6706
6706
|
}
|
|
6707
6707
|
});
|
|
6708
6708
|
|
|
6709
|
+
// src/usage/signIn.ts
|
|
6710
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
6711
|
+
import path26 from "node:path";
|
|
6712
|
+
function claudeCodeKeychainService(configDir) {
|
|
6713
|
+
return `${KEYCHAIN_SERVICE_PREFIX}-${createHash6("sha256").update(configDir).digest("hex").slice(0, KEYCHAIN_SERVICE_HASH_DIGITS)}`;
|
|
6714
|
+
}
|
|
6715
|
+
function keychainHasItem(run, configDir) {
|
|
6716
|
+
return run.run("security", ["find-generic-password", "-s", claudeCodeKeychainService(configDir)]).status === 0;
|
|
6717
|
+
}
|
|
6718
|
+
function decideSignIn(facts) {
|
|
6719
|
+
if (facts.hasCredentialBlock) {
|
|
6720
|
+
return { state: "token", detail: "supplies its own credential through a credential block, so a stored login is not what a launch uses" };
|
|
6721
|
+
}
|
|
6722
|
+
if (facts.keychainItem === true) {
|
|
6723
|
+
return { state: "signed-in", detail: "a login is stored in the macOS Keychain" };
|
|
6724
|
+
}
|
|
6725
|
+
if (facts.credentialsFile) {
|
|
6726
|
+
return { state: "signed-in", detail: `a login is stored in ${CREDENTIALS_FILE}` };
|
|
6727
|
+
}
|
|
6728
|
+
return { state: "signed-out", detail: facts.platform === "darwin" ? `no Keychain item and no ${CREDENTIALS_FILE}` : `no ${CREDENTIALS_FILE}` };
|
|
6729
|
+
}
|
|
6730
|
+
function credentialsFilePath(farmRoot) {
|
|
6731
|
+
return path26.join(farmRoot, CREDENTIALS_FILE);
|
|
6732
|
+
}
|
|
6733
|
+
function identitySignIn(fs13, probe, identity) {
|
|
6734
|
+
const probing = !identity.hasCredentialBlock;
|
|
6735
|
+
return decideSignIn({
|
|
6736
|
+
hasCredentialBlock: identity.hasCredentialBlock,
|
|
6737
|
+
keychainItem: probing && probe.platform === "darwin" && probe.run !== void 0 ? keychainHasItem(probe.run, identity.farmRoot) : void 0,
|
|
6738
|
+
credentialsFile: probing && fs13.lstat(credentialsFilePath(identity.farmRoot)) !== void 0,
|
|
6739
|
+
platform: probe.platform
|
|
6740
|
+
});
|
|
6741
|
+
}
|
|
6742
|
+
var CREDENTIALS_FILE, KEYCHAIN_SERVICE_PREFIX, KEYCHAIN_SERVICE_HASH_DIGITS;
|
|
6743
|
+
var init_signIn = __esm({
|
|
6744
|
+
"src/usage/signIn.ts"() {
|
|
6745
|
+
"use strict";
|
|
6746
|
+
CREDENTIALS_FILE = ".credentials.json";
|
|
6747
|
+
KEYCHAIN_SERVICE_PREFIX = "Claude Code-credentials";
|
|
6748
|
+
KEYCHAIN_SERVICE_HASH_DIGITS = 8;
|
|
6749
|
+
}
|
|
6750
|
+
});
|
|
6751
|
+
|
|
6709
6752
|
// src/cli/bool.ts
|
|
6710
6753
|
function parseBoolWord(input) {
|
|
6711
6754
|
switch (input) {
|
|
@@ -6855,17 +6898,17 @@ var init_commandDeps = __esm({
|
|
|
6855
6898
|
|
|
6856
6899
|
// src/claudeShim.ts
|
|
6857
6900
|
import fs8 from "node:fs";
|
|
6858
|
-
import
|
|
6901
|
+
import path28 from "node:path";
|
|
6859
6902
|
import { z as z19 } from "zod";
|
|
6860
6903
|
function commandFilename(ownExecutablePath, commandName) {
|
|
6861
6904
|
return ownExecutablePath.toLowerCase().endsWith(".exe") ? `${commandName}.exe` : commandName;
|
|
6862
6905
|
}
|
|
6863
6906
|
function resolveOwnBinaryCheck(paths, contentSourcePath) {
|
|
6864
6907
|
const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
6865
|
-
const recordedTarget = state === void 0 ? void 0 :
|
|
6908
|
+
const recordedTarget = state === void 0 ? void 0 : path28.resolve(state.targetPath);
|
|
6866
6909
|
let ownStat;
|
|
6867
6910
|
return (candidate) => {
|
|
6868
|
-
if (recordedTarget !== void 0 &&
|
|
6911
|
+
if (recordedTarget !== void 0 && path28.resolve(candidate) === recordedTarget) {
|
|
6869
6912
|
return true;
|
|
6870
6913
|
}
|
|
6871
6914
|
ownStat ??= statOrUndefined(contentSourcePath);
|
|
@@ -6888,15 +6931,15 @@ function statOrUndefined(target) {
|
|
|
6888
6931
|
}
|
|
6889
6932
|
}
|
|
6890
6933
|
function findPathShadow(params) {
|
|
6891
|
-
const resolvedTargetDir =
|
|
6934
|
+
const resolvedTargetDir = path28.resolve(params.targetDir);
|
|
6892
6935
|
for (const dir of params.pathDirs) {
|
|
6893
6936
|
const found = params.findExecutableInDir(dir, params.targetFilename);
|
|
6894
6937
|
if (found === void 0) {
|
|
6895
6938
|
continue;
|
|
6896
6939
|
}
|
|
6897
|
-
return
|
|
6940
|
+
return path28.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
|
|
6898
6941
|
}
|
|
6899
|
-
return params.pathDirs.some((dir) =>
|
|
6942
|
+
return params.pathDirs.some((dir) => path28.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
|
|
6900
6943
|
}
|
|
6901
6944
|
var ClaudeShimStateSchema, nodeLinkFs;
|
|
6902
6945
|
var init_claudeShim = __esm({
|
|
@@ -7554,7 +7597,7 @@ function buildEnv(params) {
|
|
|
7554
7597
|
}
|
|
7555
7598
|
}
|
|
7556
7599
|
if (params.provider !== void 0) {
|
|
7557
|
-
env.ANTHROPIC_AUTH_TOKEN = void 0;
|
|
7600
|
+
env.ANTHROPIC_AUTH_TOKEN = params.remoteControl ? void 0 : PROVIDER_SESSION_PLACEHOLDER;
|
|
7558
7601
|
env.ANTHROPIC_API_KEY = void 0;
|
|
7559
7602
|
env.CLAUDE_CODE_OAUTH_TOKEN = void 0;
|
|
7560
7603
|
} else if (params.identityCredential !== void 0) {
|
|
@@ -7586,7 +7629,7 @@ function buildEnv(params) {
|
|
|
7586
7629
|
}
|
|
7587
7630
|
return env;
|
|
7588
7631
|
}
|
|
7589
|
-
var LOOPBACK_HOSTS;
|
|
7632
|
+
var LOOPBACK_HOSTS, PROVIDER_SESSION_PLACEHOLDER;
|
|
7590
7633
|
var init_flags = __esm({
|
|
7591
7634
|
"src/launcher/flags.ts"() {
|
|
7592
7635
|
"use strict";
|
|
@@ -7596,6 +7639,7 @@ var init_flags = __esm({
|
|
|
7596
7639
|
init_capability();
|
|
7597
7640
|
init_route();
|
|
7598
7641
|
LOOPBACK_HOSTS = ["127.0.0.1", "localhost", "::1"];
|
|
7642
|
+
PROVIDER_SESSION_PLACEHOLDER = "agent-shim-provider-session";
|
|
7599
7643
|
}
|
|
7600
7644
|
});
|
|
7601
7645
|
|
|
@@ -8154,7 +8198,7 @@ function decideLaunch(params, readOnly) {
|
|
|
8154
8198
|
}
|
|
8155
8199
|
const pinnedVersion = resolveClaudeVersion({ env, ...parsedArgv.claudeVersion === void 0 ? {} : { flag: parsedArgv.claudeVersion }, ...cascadeLaunch?.claudeVersion === void 0 ? {} : { cascade: cascadeLaunch.claudeVersion } });
|
|
8156
8200
|
const discovered = params.resolveClaudeBinary(pinnedVersion === void 0 ? void 0 : { version: pinnedVersion.version });
|
|
8157
|
-
const
|
|
8201
|
+
const requestedFlags = resolveLaunchFlags({
|
|
8158
8202
|
env,
|
|
8159
8203
|
...cascadeLaunch === void 0 ? {} : { cascade: cascadeLaunch },
|
|
8160
8204
|
flags: {
|
|
@@ -8164,6 +8208,11 @@ function decideLaunch(params, readOnly) {
|
|
|
8164
8208
|
...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage }
|
|
8165
8209
|
}
|
|
8166
8210
|
});
|
|
8211
|
+
const loginlessProvider = requestedFlags.remoteControl && selectedProvider !== void 0 && farmIdentity !== void 0 && params.hasStoredLogin?.(farmIdentity) === false ? { identity: farmIdentity, provider: selectedProvider.name } : void 0;
|
|
8212
|
+
if (loginlessProvider !== void 0 && !readOnly) {
|
|
8213
|
+
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`);
|
|
8214
|
+
}
|
|
8215
|
+
const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
|
|
8167
8216
|
const args = buildArgv({
|
|
8168
8217
|
toolFlags: buildFlagArgs(flags),
|
|
8169
8218
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
@@ -8289,7 +8338,8 @@ function prepareLaunch(params) {
|
|
|
8289
8338
|
...identityCredential === void 0 ? {} : { identityCredential },
|
|
8290
8339
|
...frontDoor === void 0 ? {} : { frontdoor: frontDoor },
|
|
8291
8340
|
...headroom === void 0 ? {} : { headroom },
|
|
8292
|
-
sessionId
|
|
8341
|
+
sessionId,
|
|
8342
|
+
remoteControl: resolvedFlags.remoteControl
|
|
8293
8343
|
});
|
|
8294
8344
|
const releases = [...headroom === void 0 || headroomPort === void 0 ? [] : [headroomPort.release], ...frontDoorRelease === void 0 ? [] : [frontDoorRelease]];
|
|
8295
8345
|
const release = () => {
|
|
@@ -8311,7 +8361,8 @@ function resolveLaunch(params) {
|
|
|
8311
8361
|
...decided.provider === void 0 ? {} : { provider: decided.provider },
|
|
8312
8362
|
...frontDoor ? { frontdoor: { port: 0, connectPort: 0, trustBundlePath: "", sessionToken: "" } } : {},
|
|
8313
8363
|
...decided.flags.headroom ? { headroom: { socketPath: "", projectId: "" } } : {},
|
|
8314
|
-
sessionId: ""
|
|
8364
|
+
sessionId: "",
|
|
8365
|
+
remoteControl: decided.flags.remoteControl
|
|
8315
8366
|
});
|
|
8316
8367
|
const credentialNames = decided.identityCredentialBlock === void 0 ? [] : Object.keys(credentialVariables(decided.identityCredentialBlock.target ?? "bearer", ""));
|
|
8317
8368
|
const environment = [.../* @__PURE__ */ new Set([...Object.keys(built).filter((name) => built[name] !== env[name]), ...credentialNames])].sort();
|
|
@@ -8407,7 +8458,7 @@ var init_selfIdentity = __esm({
|
|
|
8407
8458
|
});
|
|
8408
8459
|
|
|
8409
8460
|
// src/frontdoor/trust.ts
|
|
8410
|
-
import { createHash as
|
|
8461
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
8411
8462
|
import path40 from "node:path";
|
|
8412
8463
|
function resolveTrustBundle(params) {
|
|
8413
8464
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs13 } = params;
|
|
@@ -8429,7 +8480,7 @@ function resolveTrustBundle(params) {
|
|
|
8429
8480
|
}
|
|
8430
8481
|
const combined = `${inheritedPem.trimEnd()}
|
|
8431
8482
|
${caPem}`;
|
|
8432
|
-
const bundle = path40.join(bundlesDir, `${
|
|
8483
|
+
const bundle = path40.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
8433
8484
|
if (!fs13.exists(bundle)) {
|
|
8434
8485
|
fs13.mkdirp(bundlesDir);
|
|
8435
8486
|
fs13.writeFileAtomic(bundle, combined);
|
|
@@ -8507,6 +8558,7 @@ var init_realFrontDoorPort = __esm({
|
|
|
8507
8558
|
|
|
8508
8559
|
// src/launchWiring.ts
|
|
8509
8560
|
import os8 from "node:os";
|
|
8561
|
+
import path41 from "node:path";
|
|
8510
8562
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
8511
8563
|
function buildFarmRuntime(paths, cwd) {
|
|
8512
8564
|
const home = os8.homedir();
|
|
@@ -8560,6 +8612,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
8560
8612
|
headroom: realHeadroomPort(paths, { spawnDaemon: options.spawnDaemon, cwd: farm.runtime.cwd }),
|
|
8561
8613
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|
|
8562
8614
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
8615
|
+
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: realRunPort }, { farmRoot: path41.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
|
|
8563
8616
|
...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
|
|
8564
8617
|
...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
|
|
8565
8618
|
...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
|
|
@@ -8631,6 +8684,7 @@ var init_launchWiring = __esm({
|
|
|
8631
8684
|
init_launchHook();
|
|
8632
8685
|
init_cascade();
|
|
8633
8686
|
init_paths();
|
|
8687
|
+
init_signIn();
|
|
8634
8688
|
init_realPorts();
|
|
8635
8689
|
LaunchRefusedError = class extends CliError {
|
|
8636
8690
|
exitCode;
|
|
@@ -9538,8 +9592,8 @@ function parseConnectTarget(authority) {
|
|
|
9538
9592
|
function isInterceptedHost(host, interceptHosts) {
|
|
9539
9593
|
return interceptHosts.includes(host);
|
|
9540
9594
|
}
|
|
9541
|
-
function servedByPipeline(
|
|
9542
|
-
return
|
|
9595
|
+
function servedByPipeline(path42) {
|
|
9596
|
+
return path42?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
9543
9597
|
}
|
|
9544
9598
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
9545
9599
|
"connection",
|
|
@@ -10333,11 +10387,11 @@ function createRcSessionTracker(deps) {
|
|
|
10333
10387
|
};
|
|
10334
10388
|
const observeExchange = (request4) => {
|
|
10335
10389
|
const method = (request4.method ?? "").toUpperCase();
|
|
10336
|
-
const
|
|
10337
|
-
if (!
|
|
10390
|
+
const path42 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
10391
|
+
if (!path42.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
10338
10392
|
return void 0;
|
|
10339
10393
|
}
|
|
10340
|
-
const tail =
|
|
10394
|
+
const tail = path42.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
10341
10395
|
const facts = {
|
|
10342
10396
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
10343
10397
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -10727,8 +10781,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
10727
10781
|
function isRcReadFileEncoding(value) {
|
|
10728
10782
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
10729
10783
|
}
|
|
10730
|
-
function buildRcReadFilePayload(requestId,
|
|
10731
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
10784
|
+
function buildRcReadFilePayload(requestId, path42, options) {
|
|
10785
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path42, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
10732
10786
|
}
|
|
10733
10787
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
10734
10788
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -10830,15 +10884,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
10830
10884
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
10831
10885
|
return result.ok ? { ...result, requestId } : result;
|
|
10832
10886
|
}
|
|
10833
|
-
async function readRcSessionFile(deps, sessionId,
|
|
10834
|
-
if (
|
|
10887
|
+
async function readRcSessionFile(deps, sessionId, path42, options) {
|
|
10888
|
+
if (path42 === "") {
|
|
10835
10889
|
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" };
|
|
10836
10890
|
}
|
|
10837
10891
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
10838
10892
|
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" };
|
|
10839
10893
|
}
|
|
10840
10894
|
const requestId = deps.newUuid();
|
|
10841
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
10895
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path42, options), `read ${path42} from session ${sessionId}`);
|
|
10842
10896
|
return result.ok ? { ...result, requestId } : result;
|
|
10843
10897
|
}
|
|
10844
10898
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -11007,11 +11061,11 @@ function createRcControlHandler(deps) {
|
|
|
11007
11061
|
path: "read-file",
|
|
11008
11062
|
read: (body) => {
|
|
11009
11063
|
const session = bodyString(body, "session");
|
|
11010
|
-
const
|
|
11064
|
+
const path42 = bodyString(body, "path");
|
|
11011
11065
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
11012
11066
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
11013
|
-
const refused2 = session === void 0 ||
|
|
11014
|
-
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,
|
|
11067
|
+
const refused2 = session === void 0 || path42 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
11068
|
+
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 } }) };
|
|
11015
11069
|
}
|
|
11016
11070
|
},
|
|
11017
11071
|
{
|
|
@@ -11321,9 +11375,9 @@ function requestIdOfBody(body) {
|
|
|
11321
11375
|
}
|
|
11322
11376
|
function frontDoorRcControl(transport, token) {
|
|
11323
11377
|
const headers = { authorization: `Bearer ${token}` };
|
|
11324
|
-
const listAnswerOf = async (
|
|
11378
|
+
const listAnswerOf = async (path42, what) => {
|
|
11325
11379
|
try {
|
|
11326
|
-
return await transport.request({ method: "GET", path:
|
|
11380
|
+
return await transport.request({ method: "GET", path: path42, headers });
|
|
11327
11381
|
} catch (error) {
|
|
11328
11382
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
11329
11383
|
}
|
|
@@ -11395,10 +11449,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
11395
11449
|
}
|
|
11396
11450
|
return pending;
|
|
11397
11451
|
};
|
|
11398
|
-
const writeOf = async (
|
|
11452
|
+
const writeOf = async (path42, body, describeFailure2) => {
|
|
11399
11453
|
let answer;
|
|
11400
11454
|
try {
|
|
11401
|
-
answer = await transport.request({ method: "POST", path:
|
|
11455
|
+
answer = await transport.request({ method: "POST", path: path42, headers: { ...headers, "content-type": "application/json" }, body });
|
|
11402
11456
|
} catch (error) {
|
|
11403
11457
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
11404
11458
|
}
|
|
@@ -11429,10 +11483,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
11429
11483
|
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}`),
|
|
11430
11484
|
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}`),
|
|
11431
11485
|
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}`),
|
|
11432
|
-
readFile: async (sessionId,
|
|
11486
|
+
readFile: async (sessionId, path42, options) => await writeOf(
|
|
11433
11487
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
11434
|
-
JSON.stringify({ session: sessionId, path:
|
|
11435
|
-
(status, message) => `reading ${
|
|
11488
|
+
JSON.stringify({ session: sessionId, path: path42, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
11489
|
+
(status, message) => `reading ${path42} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
11436
11490
|
),
|
|
11437
11491
|
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}`),
|
|
11438
11492
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -11591,12 +11645,12 @@ function tlsFacts(options) {
|
|
|
11591
11645
|
}
|
|
11592
11646
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
11593
11647
|
const agent = new ExemptTlsAgent();
|
|
11594
|
-
const post = async (
|
|
11648
|
+
const post = async (path42, headers, body) => await new Promise((resolve, reject) => {
|
|
11595
11649
|
const options = {
|
|
11596
11650
|
host: target.host,
|
|
11597
11651
|
port: target.port,
|
|
11598
11652
|
method: "POST",
|
|
11599
|
-
path:
|
|
11653
|
+
path: path42,
|
|
11600
11654
|
// 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.
|
|
11601
11655
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
11602
11656
|
agent
|
|
@@ -11661,12 +11715,12 @@ function lateRcStreamDial(resolve) {
|
|
|
11661
11715
|
}
|
|
11662
11716
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
11663
11717
|
const agent = new ExemptTlsAgent();
|
|
11664
|
-
const request4 = async (method,
|
|
11718
|
+
const request4 = async (method, path42, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
11665
11719
|
const options = {
|
|
11666
11720
|
host: target.host,
|
|
11667
11721
|
port: target.port,
|
|
11668
11722
|
method,
|
|
11669
|
-
path:
|
|
11723
|
+
path: path42,
|
|
11670
11724
|
// 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.
|
|
11671
11725
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
11672
11726
|
agent,
|
|
@@ -11708,9 +11762,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
11708
11762
|
return { status, body: await readAll(response) };
|
|
11709
11763
|
},
|
|
11710
11764
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
11711
|
-
const
|
|
11765
|
+
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)}`;
|
|
11712
11766
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
11713
|
-
const { status, response } = await request4("GET",
|
|
11767
|
+
const { status, response } = await request4("GET", path42, streamHeaders, void 0, signal);
|
|
11714
11768
|
if (!isSuccessful2(status)) {
|
|
11715
11769
|
await readAll(response);
|
|
11716
11770
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -12862,19 +12916,19 @@ function writePools(paths, pools) {
|
|
|
12862
12916
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
12863
12917
|
}
|
|
12864
12918
|
function poolCycleOf(pools, name) {
|
|
12865
|
-
const walk = (current,
|
|
12919
|
+
const walk = (current, path42) => {
|
|
12866
12920
|
for (const entry of pools[current]?.identities ?? []) {
|
|
12867
12921
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
12868
12922
|
if (nested === void 0) {
|
|
12869
12923
|
continue;
|
|
12870
12924
|
}
|
|
12871
12925
|
if (nested === name) {
|
|
12872
|
-
return [...
|
|
12926
|
+
return [...path42, nested];
|
|
12873
12927
|
}
|
|
12874
|
-
if (
|
|
12928
|
+
if (path42.includes(nested)) {
|
|
12875
12929
|
continue;
|
|
12876
12930
|
}
|
|
12877
|
-
const found = walk(nested, [...
|
|
12931
|
+
const found = walk(nested, [...path42, nested]);
|
|
12878
12932
|
if (found !== void 0) {
|
|
12879
12933
|
return found;
|
|
12880
12934
|
}
|
|
@@ -12996,6 +13050,7 @@ init_cascade();
|
|
|
12996
13050
|
init_paths();
|
|
12997
13051
|
init_realCredentialCache();
|
|
12998
13052
|
init_providersStore();
|
|
13053
|
+
init_signIn();
|
|
12999
13054
|
init_realPorts();
|
|
13000
13055
|
init_envBool();
|
|
13001
13056
|
init_load();
|
|
@@ -13008,7 +13063,7 @@ init_guard();
|
|
|
13008
13063
|
init_providersStore();
|
|
13009
13064
|
init_projects();
|
|
13010
13065
|
init_pipeline();
|
|
13011
|
-
import
|
|
13066
|
+
import path27 from "node:path";
|
|
13012
13067
|
import { z as z15 } from "zod";
|
|
13013
13068
|
var HISTORY_PROJECTS_KEY_PREFIX = "history/projects/";
|
|
13014
13069
|
function projectFragmentOf(rawKey) {
|
|
@@ -13065,26 +13120,18 @@ function formatDecision(decision) {
|
|
|
13065
13120
|
const eliminatedNote = decision.eliminated !== void 0 && decision.eliminated.length > 0 ? ` [${String(decision.eliminated.length)} more specific rule(s) eliminated by a failing when-condition]` : "";
|
|
13066
13121
|
return `${decision.relPath}: ${status} \u2014 ${reason}${eliminatedNote}`;
|
|
13067
13122
|
}
|
|
13068
|
-
function parseKeychainServiceName(stderr) {
|
|
13069
|
-
const match = /"svce"<blob>="([^"]*)"/.exec(stderr);
|
|
13070
|
-
return match?.[1];
|
|
13071
|
-
}
|
|
13072
13123
|
function lookupKeychainService(run, farmRoot) {
|
|
13073
|
-
const
|
|
13124
|
+
const serviceName = claudeCodeKeychainService(farmRoot);
|
|
13125
|
+
const result = run.run("security", ["find-generic-password", "-s", serviceName]);
|
|
13074
13126
|
if (result.status !== 0) {
|
|
13075
13127
|
return {
|
|
13076
13128
|
checked: true,
|
|
13077
13129
|
found: false,
|
|
13078
|
-
|
|
13130
|
+
serviceName,
|
|
13131
|
+
note: `No Keychain entry found for service "${serviceName}" (security exited ${result.status === null ? "with no status" : String(result.status)}).`
|
|
13079
13132
|
};
|
|
13080
13133
|
}
|
|
13081
|
-
|
|
13082
|
-
return {
|
|
13083
|
-
checked: true,
|
|
13084
|
-
found: true,
|
|
13085
|
-
...serviceName === void 0 ? {} : { serviceName },
|
|
13086
|
-
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}".`
|
|
13087
|
-
};
|
|
13134
|
+
return { checked: true, found: true, serviceName, note: `Keychain service name for this identity: "${serviceName}".` };
|
|
13088
13135
|
}
|
|
13089
13136
|
var SettingsSecretsShapeSchema = z15.looseObject({
|
|
13090
13137
|
env: z15.record(z15.string(), z15.unknown()).optional(),
|
|
@@ -13346,10 +13393,10 @@ function collectCheckReport(params) {
|
|
|
13346
13393
|
}).input;
|
|
13347
13394
|
const providerName = cascadeProviderName(cascade);
|
|
13348
13395
|
const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
|
|
13349
|
-
const farmRoot = identityDecision.name === void 0 ? void 0 :
|
|
13396
|
+
const farmRoot = identityDecision.name === void 0 ? void 0 : path27.join(paths.identitiesDir, identityDecision.name);
|
|
13350
13397
|
const settingsFiles = {
|
|
13351
|
-
"settings.json": realFsPort.readFileUtf8(
|
|
13352
|
-
"settings.local.json": realFsPort.readFileUtf8(
|
|
13398
|
+
"settings.json": realFsPort.readFileUtf8(path27.join(claudeHome, "settings.json")),
|
|
13399
|
+
"settings.local.json": realFsPort.readFileUtf8(path27.join(claudeHome, "settings.local.json"))
|
|
13353
13400
|
};
|
|
13354
13401
|
const report = runCheck({
|
|
13355
13402
|
cwd,
|
|
@@ -13655,7 +13702,7 @@ init_schema();
|
|
|
13655
13702
|
init_cliError();
|
|
13656
13703
|
init_identity();
|
|
13657
13704
|
import fs9 from "node:fs";
|
|
13658
|
-
import
|
|
13705
|
+
import path29 from "node:path";
|
|
13659
13706
|
init_lock();
|
|
13660
13707
|
var IdentityNotFoundError = class extends CliError {
|
|
13661
13708
|
constructor(name) {
|
|
@@ -13684,7 +13731,7 @@ var InvalidIdentityNameError = class extends CliError {
|
|
|
13684
13731
|
attemptedName;
|
|
13685
13732
|
};
|
|
13686
13733
|
function identityJsonPath(paths, name) {
|
|
13687
|
-
return
|
|
13734
|
+
return path29.join(paths.identitiesDir, name, "identity.json");
|
|
13688
13735
|
}
|
|
13689
13736
|
function requireIdentityNames(paths, names) {
|
|
13690
13737
|
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
@@ -13799,7 +13846,7 @@ function setIdentityCredential(paths, identityName, change) {
|
|
|
13799
13846
|
});
|
|
13800
13847
|
}
|
|
13801
13848
|
function belongsToIdentity(entry, name) {
|
|
13802
|
-
return entry === name || entry ===
|
|
13849
|
+
return entry === name || entry === path29.basename(identityLockPath("", name)) || entry.startsWith(`.${name}.scratch.`) || entry.startsWith(`.${name}.previous.`);
|
|
13803
13850
|
}
|
|
13804
13851
|
function removeIdentity(paths, name) {
|
|
13805
13852
|
if (!identityExists(paths, name)) {
|
|
@@ -13807,7 +13854,7 @@ function removeIdentity(paths, name) {
|
|
|
13807
13854
|
}
|
|
13808
13855
|
for (const entry of fs9.readdirSync(paths.identitiesDir)) {
|
|
13809
13856
|
if (belongsToIdentity(entry, name)) {
|
|
13810
|
-
fs9.rmSync(
|
|
13857
|
+
fs9.rmSync(path29.join(paths.identitiesDir, entry), { recursive: true, force: true });
|
|
13811
13858
|
}
|
|
13812
13859
|
}
|
|
13813
13860
|
if (readActiveIdentity2(paths) === name) {
|
|
@@ -13819,28 +13866,7 @@ function removeIdentity(paths, name) {
|
|
|
13819
13866
|
init_realPorts();
|
|
13820
13867
|
import fs11 from "node:fs";
|
|
13821
13868
|
import path30 from "node:path";
|
|
13822
|
-
|
|
13823
|
-
// src/usage/signIn.ts
|
|
13824
|
-
import path29 from "node:path";
|
|
13825
|
-
var CREDENTIALS_FILE = ".credentials.json";
|
|
13826
|
-
function keychainHasItem(run, account) {
|
|
13827
|
-
return run.run("security", ["find-generic-password", "-a", account]).status === 0;
|
|
13828
|
-
}
|
|
13829
|
-
function decideSignIn(facts) {
|
|
13830
|
-
if (facts.hasCredentialBlock) {
|
|
13831
|
-
return { state: "token", detail: "supplies its own credential through a credential block, so a stored login is not what a launch uses" };
|
|
13832
|
-
}
|
|
13833
|
-
if (facts.keychainItem === true) {
|
|
13834
|
-
return { state: "signed-in", detail: "a login is stored in the macOS Keychain" };
|
|
13835
|
-
}
|
|
13836
|
-
if (facts.credentialsFile) {
|
|
13837
|
-
return { state: "signed-in", detail: `a login is stored in ${CREDENTIALS_FILE}` };
|
|
13838
|
-
}
|
|
13839
|
-
return { state: "signed-out", detail: facts.platform === "darwin" ? `no Keychain item and no ${CREDENTIALS_FILE}` : `no ${CREDENTIALS_FILE}` };
|
|
13840
|
-
}
|
|
13841
|
-
function credentialsFilePath(farmRoot) {
|
|
13842
|
-
return path29.join(farmRoot, CREDENTIALS_FILE);
|
|
13843
|
-
}
|
|
13869
|
+
init_signIn();
|
|
13844
13870
|
|
|
13845
13871
|
// src/codex/siwcStore.ts
|
|
13846
13872
|
import { z as z22 } from "zod";
|
|
@@ -15181,7 +15207,7 @@ function profileValue(name, paths) {
|
|
|
15181
15207
|
function createConfigApiRouter(deps) {
|
|
15182
15208
|
const authed = doorApiAuth(deps.expectedToken);
|
|
15183
15209
|
const { paths } = deps;
|
|
15184
|
-
const route = (
|
|
15210
|
+
const route = (path42, summary) => authed.meta(openapi3({ method: "POST", path: path42, summary, tags: [CONFIG_API_TAG] }));
|
|
15185
15211
|
return {
|
|
15186
15212
|
config: {
|
|
15187
15213
|
identity: {
|
package/dist/types/index.d.ts
CHANGED
|
@@ -7218,6 +7218,8 @@ interface PrepareLaunchParams {
|
|
|
7218
7218
|
readonly supervised?: SupervisedLaunch;
|
|
7219
7219
|
/** Wires the launch-time update check behind `update.mode`. Omitted by a caller that cannot resolve releases, re-invoke this binary, or write to the terminal; a mode of `notify` or `auto` with no port wired simply checks nothing. */
|
|
7220
7220
|
readonly update?: UpdateLaunchPort;
|
|
7221
|
+
/** Whether an identity has a stored login Claude Code can use (a Keychain item or a credentials file). Absent when the caller cannot ask, in which case a launch assumes it does. */
|
|
7222
|
+
readonly hasStoredLogin?: (identity: string) => boolean;
|
|
7221
7223
|
}
|
|
7222
7224
|
/** Inputs to `runLauncher`: a launch's inputs plus the port that spawns the child. */
|
|
7223
7225
|
interface RunLauncherParams extends PrepareLaunchParams {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-use",
|
|
3
|
-
"version": "11.
|
|
3
|
+
"version": "11.23.0",
|
|
4
4
|
"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.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Joseph Mearman <joseph@mearman.co.uk>",
|