claude-use 9.7.2 → 9.8.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 +418 -367
- package/dist/index.cjs +111 -74
- package/dist/index.mjs +107 -70
- package/dist/types/index.d.ts +7 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2663,7 +2663,7 @@ var init_package = __esm({
|
|
|
2663
2663
|
"package.json"() {
|
|
2664
2664
|
package_default = {
|
|
2665
2665
|
name: "claude-use",
|
|
2666
|
-
version: "9.
|
|
2666
|
+
version: "9.8.0",
|
|
2667
2667
|
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.",
|
|
2668
2668
|
license: "MIT",
|
|
2669
2669
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -6567,7 +6567,7 @@ function buildEnv(params) {
|
|
|
6567
6567
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
6568
6568
|
let providerCustomHeaders;
|
|
6569
6569
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
6570
|
-
env.CLAUDE_CONFIG_DIR =
|
|
6570
|
+
env.CLAUDE_CONFIG_DIR = import_node_path33.default.join(params.identitiesDir, params.resolvedIdentityName);
|
|
6571
6571
|
}
|
|
6572
6572
|
if (params.provider !== void 0) {
|
|
6573
6573
|
const providerEnv = params.provider.definition.env ?? {};
|
|
@@ -6611,11 +6611,11 @@ function buildEnv(params) {
|
|
|
6611
6611
|
}
|
|
6612
6612
|
return env;
|
|
6613
6613
|
}
|
|
6614
|
-
var
|
|
6614
|
+
var import_node_path33, LOOPBACK_HOSTS;
|
|
6615
6615
|
var init_flags = __esm({
|
|
6616
6616
|
"src/launcher/flags.ts"() {
|
|
6617
6617
|
"use strict";
|
|
6618
|
-
|
|
6618
|
+
import_node_path33 = __toESM(require("node:path"), 1);
|
|
6619
6619
|
init_envBool();
|
|
6620
6620
|
init_credential();
|
|
6621
6621
|
init_headers();
|
|
@@ -6938,7 +6938,7 @@ function decideLaunch(params, readOnly) {
|
|
|
6938
6938
|
identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
|
|
6939
6939
|
globalDefaultConfigProfile: params.globalDefaultConfigProfile
|
|
6940
6940
|
});
|
|
6941
|
-
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(
|
|
6941
|
+
if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(import_node_path34.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
|
|
6942
6942
|
log.error(
|
|
6943
6943
|
`agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
|
|
6944
6944
|
);
|
|
@@ -7050,7 +7050,7 @@ function decideLaunch(params, readOnly) {
|
|
|
7050
7050
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
7051
7051
|
passthrough: parsedArgv.rest
|
|
7052
7052
|
});
|
|
7053
|
-
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR :
|
|
7053
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path34.default.join(paths.identitiesDir, identityDecision.name);
|
|
7054
7054
|
const decision = {
|
|
7055
7055
|
identitySource: identityDecision.source,
|
|
7056
7056
|
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
@@ -7091,7 +7091,7 @@ function prepareLaunch(params) {
|
|
|
7091
7091
|
);
|
|
7092
7092
|
const updateCheck = runLaunchUpdateCheck({
|
|
7093
7093
|
mode: params.updateMode ?? "off",
|
|
7094
|
-
checkPath:
|
|
7094
|
+
checkPath: import_node_path34.default.join(paths.root, "update.check"),
|
|
7095
7095
|
currentVersion: package_default.version,
|
|
7096
7096
|
port: params.update
|
|
7097
7097
|
});
|
|
@@ -7222,12 +7222,12 @@ function runLaunchPlan(plan, spawn2) {
|
|
|
7222
7222
|
function runLauncher(params) {
|
|
7223
7223
|
params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
|
|
7224
7224
|
}
|
|
7225
|
-
var import_node_crypto10,
|
|
7225
|
+
var import_node_crypto10, import_node_path34;
|
|
7226
7226
|
var init_launcher = __esm({
|
|
7227
7227
|
"src/launcher.ts"() {
|
|
7228
7228
|
"use strict";
|
|
7229
7229
|
import_node_crypto10 = require("node:crypto");
|
|
7230
|
-
|
|
7230
|
+
import_node_path34 = __toESM(require("node:path"), 1);
|
|
7231
7231
|
init_package();
|
|
7232
7232
|
init_envBool();
|
|
7233
7233
|
init_argv();
|
|
@@ -7258,13 +7258,13 @@ function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string"
|
|
|
7258
7258
|
if (distDir === void 0) {
|
|
7259
7259
|
throw new OwnCliPathUnknownError();
|
|
7260
7260
|
}
|
|
7261
|
-
return
|
|
7261
|
+
return import_node_path35.default.join(distDir, OWN_CLI_FILE_NAME);
|
|
7262
7262
|
}
|
|
7263
|
-
var
|
|
7263
|
+
var import_node_path35, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
7264
7264
|
var init_ownCli = __esm({
|
|
7265
7265
|
"src/ownCli.ts"() {
|
|
7266
7266
|
"use strict";
|
|
7267
|
-
|
|
7267
|
+
import_node_path35 = __toESM(require("node:path"), 1);
|
|
7268
7268
|
init_cliError();
|
|
7269
7269
|
OWN_CLI_FILE_NAME = "cli.cjs";
|
|
7270
7270
|
OwnCliPathUnknownError = class extends CliError {
|
|
@@ -7349,7 +7349,7 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
|
|
|
7349
7349
|
// src/frontdoor/trust.ts
|
|
7350
7350
|
function resolveTrustBundle(params) {
|
|
7351
7351
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
|
|
7352
|
-
if (inherited === void 0 || inherited === "" ||
|
|
7352
|
+
if (inherited === void 0 || inherited === "" || import_node_path36.default.resolve(inherited) === import_node_path36.default.resolve(caCertFile)) {
|
|
7353
7353
|
return { path: caCertFile };
|
|
7354
7354
|
}
|
|
7355
7355
|
const caPem = fs12.readFileUtf8(caCertFile);
|
|
@@ -7367,19 +7367,19 @@ function resolveTrustBundle(params) {
|
|
|
7367
7367
|
}
|
|
7368
7368
|
const combined = `${inheritedPem.trimEnd()}
|
|
7369
7369
|
${caPem}`;
|
|
7370
|
-
const bundle =
|
|
7370
|
+
const bundle = import_node_path36.default.join(bundlesDir, `${(0, import_node_crypto11.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
7371
7371
|
if (!fs12.exists(bundle)) {
|
|
7372
7372
|
fs12.mkdirp(bundlesDir);
|
|
7373
7373
|
fs12.writeFileAtomic(bundle, combined);
|
|
7374
7374
|
}
|
|
7375
7375
|
return { path: bundle };
|
|
7376
7376
|
}
|
|
7377
|
-
var import_node_crypto11,
|
|
7377
|
+
var import_node_crypto11, import_node_path36, BUNDLE_NAME_HEX_DIGITS;
|
|
7378
7378
|
var init_trust = __esm({
|
|
7379
7379
|
"src/frontdoor/trust.ts"() {
|
|
7380
7380
|
"use strict";
|
|
7381
7381
|
import_node_crypto11 = require("node:crypto");
|
|
7382
|
-
|
|
7382
|
+
import_node_path36 = __toESM(require("node:path"), 1);
|
|
7383
7383
|
BUNDLE_NAME_HEX_DIGITS = 16;
|
|
7384
7384
|
}
|
|
7385
7385
|
});
|
|
@@ -8723,8 +8723,8 @@ function parseConnectTarget(authority) {
|
|
|
8723
8723
|
function isInterceptedHost(host, interceptHosts) {
|
|
8724
8724
|
return interceptHosts.includes(host);
|
|
8725
8725
|
}
|
|
8726
|
-
function servedByPipeline(
|
|
8727
|
-
return
|
|
8726
|
+
function servedByPipeline(path37) {
|
|
8727
|
+
return path37?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
8728
8728
|
}
|
|
8729
8729
|
var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
|
|
8730
8730
|
"connection",
|
|
@@ -9259,11 +9259,11 @@ function createRcSessionTracker(deps) {
|
|
|
9259
9259
|
};
|
|
9260
9260
|
const observeExchange = (request4) => {
|
|
9261
9261
|
const method = (request4.method ?? "").toUpperCase();
|
|
9262
|
-
const
|
|
9263
|
-
if (!
|
|
9262
|
+
const path37 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
9263
|
+
if (!path37.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
9264
9264
|
return void 0;
|
|
9265
9265
|
}
|
|
9266
|
-
const tail =
|
|
9266
|
+
const tail = path37.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
9267
9267
|
const facts = {
|
|
9268
9268
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
9269
9269
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -9645,8 +9645,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
9645
9645
|
function isRcReadFileEncoding(value) {
|
|
9646
9646
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
9647
9647
|
}
|
|
9648
|
-
function buildRcReadFilePayload(requestId,
|
|
9649
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
9648
|
+
function buildRcReadFilePayload(requestId, path37, options) {
|
|
9649
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path37, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
9650
9650
|
}
|
|
9651
9651
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
9652
9652
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -9748,15 +9748,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
9748
9748
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
9749
9749
|
return result.ok ? { ...result, requestId } : result;
|
|
9750
9750
|
}
|
|
9751
|
-
async function readRcSessionFile(deps, sessionId,
|
|
9752
|
-
if (
|
|
9751
|
+
async function readRcSessionFile(deps, sessionId, path37, options) {
|
|
9752
|
+
if (path37 === "") {
|
|
9753
9753
|
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" };
|
|
9754
9754
|
}
|
|
9755
9755
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
9756
9756
|
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" };
|
|
9757
9757
|
}
|
|
9758
9758
|
const requestId = deps.newUuid();
|
|
9759
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
9759
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path37, options), `read ${path37} from session ${sessionId}`);
|
|
9760
9760
|
return result.ok ? { ...result, requestId } : result;
|
|
9761
9761
|
}
|
|
9762
9762
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -9925,11 +9925,11 @@ function createRcControlHandler(deps) {
|
|
|
9925
9925
|
path: "read-file",
|
|
9926
9926
|
read: (body) => {
|
|
9927
9927
|
const session = bodyString(body, "session");
|
|
9928
|
-
const
|
|
9928
|
+
const path37 = bodyString(body, "path");
|
|
9929
9929
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
9930
9930
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
9931
|
-
const refused2 = session === void 0 ||
|
|
9932
|
-
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,
|
|
9931
|
+
const refused2 = session === void 0 || path37 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
9932
|
+
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, path37, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
|
|
9933
9933
|
}
|
|
9934
9934
|
},
|
|
9935
9935
|
{
|
|
@@ -10239,9 +10239,9 @@ function requestIdOfBody(body) {
|
|
|
10239
10239
|
}
|
|
10240
10240
|
function frontDoorRcControl(transport, token) {
|
|
10241
10241
|
const headers = { authorization: `Bearer ${token}` };
|
|
10242
|
-
const listAnswerOf = async (
|
|
10242
|
+
const listAnswerOf = async (path37, what) => {
|
|
10243
10243
|
try {
|
|
10244
|
-
return await transport.request({ method: "GET", path:
|
|
10244
|
+
return await transport.request({ method: "GET", path: path37, headers });
|
|
10245
10245
|
} catch (error) {
|
|
10246
10246
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
10247
10247
|
}
|
|
@@ -10313,10 +10313,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
10313
10313
|
}
|
|
10314
10314
|
return pending;
|
|
10315
10315
|
};
|
|
10316
|
-
const writeOf = async (
|
|
10316
|
+
const writeOf = async (path37, body, describeFailure) => {
|
|
10317
10317
|
let answer;
|
|
10318
10318
|
try {
|
|
10319
|
-
answer = await transport.request({ method: "POST", path:
|
|
10319
|
+
answer = await transport.request({ method: "POST", path: path37, headers: { ...headers, "content-type": "application/json" }, body });
|
|
10320
10320
|
} catch (error) {
|
|
10321
10321
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
10322
10322
|
}
|
|
@@ -10347,10 +10347,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
10347
10347
|
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}`),
|
|
10348
10348
|
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}`),
|
|
10349
10349
|
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}`),
|
|
10350
|
-
readFile: async (sessionId,
|
|
10350
|
+
readFile: async (sessionId, path37, options) => await writeOf(
|
|
10351
10351
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
10352
|
-
JSON.stringify({ session: sessionId, path:
|
|
10353
|
-
(status, message) => `reading ${
|
|
10352
|
+
JSON.stringify({ session: sessionId, path: path37, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
10353
|
+
(status, message) => `reading ${path37} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
10354
10354
|
),
|
|
10355
10355
|
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}`),
|
|
10356
10356
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -10509,12 +10509,12 @@ function tlsFacts(options) {
|
|
|
10509
10509
|
}
|
|
10510
10510
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10511
10511
|
const agent = new ExemptTlsAgent();
|
|
10512
|
-
const post = async (
|
|
10512
|
+
const post = async (path37, headers, body) => await new Promise((resolve, reject) => {
|
|
10513
10513
|
const options = {
|
|
10514
10514
|
host: target.host,
|
|
10515
10515
|
port: target.port,
|
|
10516
10516
|
method: "POST",
|
|
10517
|
-
path:
|
|
10517
|
+
path: path37,
|
|
10518
10518
|
// 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.
|
|
10519
10519
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
10520
10520
|
agent
|
|
@@ -10579,12 +10579,12 @@ function lateRcStreamDial(resolve) {
|
|
|
10579
10579
|
}
|
|
10580
10580
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
10581
10581
|
const agent = new ExemptTlsAgent();
|
|
10582
|
-
const request4 = async (method,
|
|
10582
|
+
const request4 = async (method, path37, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
10583
10583
|
const options = {
|
|
10584
10584
|
host: target.host,
|
|
10585
10585
|
port: target.port,
|
|
10586
10586
|
method,
|
|
10587
|
-
path:
|
|
10587
|
+
path: path37,
|
|
10588
10588
|
// 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.
|
|
10589
10589
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
10590
10590
|
agent,
|
|
@@ -10626,9 +10626,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
10626
10626
|
return { status, body: await readAll(response) };
|
|
10627
10627
|
},
|
|
10628
10628
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
10629
|
-
const
|
|
10629
|
+
const path37 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
|
|
10630
10630
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
10631
|
-
const { status, response } = await request4("GET",
|
|
10631
|
+
const { status, response } = await request4("GET", path37, streamHeaders, void 0, signal);
|
|
10632
10632
|
if (!isSuccessful2(status)) {
|
|
10633
10633
|
await readAll(response);
|
|
10634
10634
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -11543,19 +11543,19 @@ function writePools(paths, pools) {
|
|
|
11543
11543
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
11544
11544
|
}
|
|
11545
11545
|
function poolCycleOf(pools, name) {
|
|
11546
|
-
const walk = (current,
|
|
11546
|
+
const walk = (current, path37) => {
|
|
11547
11547
|
for (const entry of pools[current]?.identities ?? []) {
|
|
11548
11548
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
11549
11549
|
if (nested === void 0) {
|
|
11550
11550
|
continue;
|
|
11551
11551
|
}
|
|
11552
11552
|
if (nested === name) {
|
|
11553
|
-
return [...
|
|
11553
|
+
return [...path37, nested];
|
|
11554
11554
|
}
|
|
11555
|
-
if (
|
|
11555
|
+
if (path37.includes(nested)) {
|
|
11556
11556
|
continue;
|
|
11557
11557
|
}
|
|
11558
|
-
const found = walk(nested, [...
|
|
11558
|
+
const found = walk(nested, [...path37, nested]);
|
|
11559
11559
|
if (found !== void 0) {
|
|
11560
11560
|
return found;
|
|
11561
11561
|
}
|
|
@@ -12228,7 +12228,7 @@ init_middleware();
|
|
|
12228
12228
|
init_preflight();
|
|
12229
12229
|
|
|
12230
12230
|
// src/frontdoor/controlSchemas.ts
|
|
12231
|
-
var
|
|
12231
|
+
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
12232
12232
|
var import_zod19 = require("zod");
|
|
12233
12233
|
|
|
12234
12234
|
// src/doctorReport.ts
|
|
@@ -12399,7 +12399,29 @@ function removeIdentity(paths, name) {
|
|
|
12399
12399
|
// src/doctorReport.ts
|
|
12400
12400
|
init_realPorts();
|
|
12401
12401
|
var import_node_fs9 = __toESM(require("node:fs"), 1);
|
|
12402
|
+
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
12403
|
+
|
|
12404
|
+
// src/usage/signIn.ts
|
|
12402
12405
|
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
12406
|
+
var CREDENTIALS_FILE = ".credentials.json";
|
|
12407
|
+
function keychainHasItem(run, account) {
|
|
12408
|
+
return run.run("security", ["find-generic-password", "-a", account]).status === 0;
|
|
12409
|
+
}
|
|
12410
|
+
function decideSignIn(facts) {
|
|
12411
|
+
if (facts.hasCredentialBlock) {
|
|
12412
|
+
return { state: "token", detail: "supplies its own credential through a credential block, so a stored login is not what a launch uses" };
|
|
12413
|
+
}
|
|
12414
|
+
if (facts.keychainItem === true) {
|
|
12415
|
+
return { state: "signed-in", detail: "a login is stored in the macOS Keychain" };
|
|
12416
|
+
}
|
|
12417
|
+
if (facts.credentialsFile) {
|
|
12418
|
+
return { state: "signed-in", detail: `a login is stored in ${CREDENTIALS_FILE}` };
|
|
12419
|
+
}
|
|
12420
|
+
return { state: "signed-out", detail: facts.platform === "darwin" ? `no Keychain item and no ${CREDENTIALS_FILE}` : `no ${CREDENTIALS_FILE}` };
|
|
12421
|
+
}
|
|
12422
|
+
function credentialsFilePath(farmRoot) {
|
|
12423
|
+
return import_node_path28.default.join(farmRoot, CREDENTIALS_FILE);
|
|
12424
|
+
}
|
|
12403
12425
|
|
|
12404
12426
|
// src/codex/siwcStore.ts
|
|
12405
12427
|
var import_zod18 = require("zod");
|
|
@@ -12500,6 +12522,7 @@ var DOCTOR_SECTIONS = [
|
|
|
12500
12522
|
"legacy-name",
|
|
12501
12523
|
"config-profile",
|
|
12502
12524
|
"identity",
|
|
12525
|
+
"sign-in",
|
|
12503
12526
|
"pool",
|
|
12504
12527
|
"provider",
|
|
12505
12528
|
"keychain",
|
|
@@ -12542,7 +12565,7 @@ function tcpPortEraRecord(raw) {
|
|
|
12542
12565
|
return (has("port") || has("lastPort")) && !has("socketPath");
|
|
12543
12566
|
}
|
|
12544
12567
|
function pushPathResolution(push, resolution) {
|
|
12545
|
-
const ownDir =
|
|
12568
|
+
const ownDir = import_node_path29.default.dirname(resolution.ownExecutablePath);
|
|
12546
12569
|
switch (resolution.agentShim.status) {
|
|
12547
12570
|
case "ok":
|
|
12548
12571
|
push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
|
|
@@ -12641,14 +12664,14 @@ function pushProvider(push, entry, cacheEnv, signIn) {
|
|
|
12641
12664
|
}
|
|
12642
12665
|
function pushLegacyName(push, params) {
|
|
12643
12666
|
const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
|
|
12644
|
-
if (legacyVariables.length === 0 &&
|
|
12667
|
+
if (legacyVariables.length === 0 && import_node_path29.default.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
|
|
12645
12668
|
push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
|
|
12646
12669
|
return;
|
|
12647
12670
|
}
|
|
12648
12671
|
for (const name of legacyVariables) {
|
|
12649
12672
|
push("legacy-name", "warn", `${name} is the former name of ${name.replace(LEGACY_ENV_PREFIX, ENV_PREFIX)}. Rename it; the old name still works but is only a fallback.`, name);
|
|
12650
12673
|
}
|
|
12651
|
-
if (
|
|
12674
|
+
if (import_node_path29.default.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
|
|
12652
12675
|
push(
|
|
12653
12676
|
"legacy-name",
|
|
12654
12677
|
"warn",
|
|
@@ -12745,6 +12768,18 @@ function runDoctor(params) {
|
|
|
12745
12768
|
`${entry.name} is valid and authenticates with ${credential === void 0 ? "its stored login" : `credential ${describeCredential(credential)}`}${cache.text}.`,
|
|
12746
12769
|
entry.name
|
|
12747
12770
|
);
|
|
12771
|
+
const signIn = decideSignIn({
|
|
12772
|
+
hasCredentialBlock: credential !== void 0,
|
|
12773
|
+
keychainItem: params.platform === "darwin" && params.run !== void 0 ? keychainHasItem(params.run, entry.farmRoot) : void 0,
|
|
12774
|
+
credentialsFile: entry.credentialsFilePresent,
|
|
12775
|
+
platform: params.platform
|
|
12776
|
+
});
|
|
12777
|
+
push(
|
|
12778
|
+
"sign-in",
|
|
12779
|
+
signIn.state === "signed-out" ? "warn" : "pass",
|
|
12780
|
+
signIn.state === "signed-out" ? `${entry.name} is signed out (${signIn.detail}). Run \`agent-shim run @${entry.name}\` and sign in.` : `${entry.name} ${signIn.state === "token" ? "uses a credential block" : "is signed in"} (${signIn.detail}).`,
|
|
12781
|
+
entry.name
|
|
12782
|
+
);
|
|
12748
12783
|
}
|
|
12749
12784
|
}
|
|
12750
12785
|
const validatedGlobalConfig = params.globalConfig.raw === void 0 ? void 0 : validateJson(GlobalConfigSchema, params.globalConfig);
|
|
@@ -12790,7 +12825,7 @@ function runDoctor(params) {
|
|
|
12790
12825
|
} else {
|
|
12791
12826
|
for (const entry of params.identities) {
|
|
12792
12827
|
const result = lookupKeychainService(params.run, entry.farmRoot);
|
|
12793
|
-
push("keychain", result.found ?
|
|
12828
|
+
push("keychain", "pass", result.found ? result.note : `${result.note} The sign-in section reports whether a login is stored elsewhere.`, entry.name);
|
|
12794
12829
|
}
|
|
12795
12830
|
}
|
|
12796
12831
|
if (params.directoryRules.raw === void 0) {
|
|
@@ -12925,6 +12960,7 @@ var SECTION_TITLES = {
|
|
|
12925
12960
|
"legacy-name": "Former `claude-use` name",
|
|
12926
12961
|
"config-profile": "Configuration profiles",
|
|
12927
12962
|
identity: "Identities",
|
|
12963
|
+
"sign-in": "Sign-in",
|
|
12928
12964
|
pool: "Pools",
|
|
12929
12965
|
provider: "Providers",
|
|
12930
12966
|
keychain: "macOS Keychain",
|
|
@@ -12941,6 +12977,7 @@ var SECTION_ORDER = [
|
|
|
12941
12977
|
"path-resolution",
|
|
12942
12978
|
"config-profile",
|
|
12943
12979
|
"identity",
|
|
12980
|
+
"sign-in",
|
|
12944
12981
|
"pool",
|
|
12945
12982
|
"provider",
|
|
12946
12983
|
"keychain",
|
|
@@ -12990,18 +13027,18 @@ function collectDoctorReport(params) {
|
|
|
12990
13027
|
const { paths } = params;
|
|
12991
13028
|
const identityNames = import_node_fs9.default.existsSync(paths.identitiesDir) ? import_node_fs9.default.readdirSync(paths.identitiesDir, { withFileTypes: true }).filter((entry) => entry.isDirectory() && isIdentityDirectoryName(entry.name)).map((entry) => entry.name).sort() : [];
|
|
12992
13029
|
const identities = identityNames.map((name) => {
|
|
12993
|
-
const farmRoot =
|
|
12994
|
-
const identityPath =
|
|
12995
|
-
return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot };
|
|
13030
|
+
const farmRoot = import_node_path29.default.join(paths.identitiesDir, name);
|
|
13031
|
+
const identityPath = import_node_path29.default.join(farmRoot, "identity.json");
|
|
13032
|
+
return { name, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: import_node_fs9.default.existsSync(credentialsFilePath(farmRoot)) };
|
|
12996
13033
|
});
|
|
12997
13034
|
const profileNames = import_node_fs9.default.existsSync(paths.configProfilesDir) ? import_node_fs9.default.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
12998
13035
|
const configProfiles = profileNames.map((name) => {
|
|
12999
|
-
const profilePath =
|
|
13036
|
+
const profilePath = import_node_path29.default.join(paths.configProfilesDir, `${name}.json`);
|
|
13000
13037
|
return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
|
|
13001
13038
|
});
|
|
13002
13039
|
const providerNames = import_node_fs9.default.existsSync(paths.providersDir) ? import_node_fs9.default.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
13003
13040
|
const providers = providerNames.map((name) => {
|
|
13004
|
-
const providerPath =
|
|
13041
|
+
const providerPath = import_node_path29.default.join(paths.providersDir, `${name}.json`);
|
|
13005
13042
|
return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
|
|
13006
13043
|
});
|
|
13007
13044
|
const ownExecutablePath = realOwnExecutablePath();
|
|
@@ -13013,12 +13050,12 @@ function collectDoctorReport(params) {
|
|
|
13013
13050
|
binaryDiscovery = { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
13014
13051
|
}
|
|
13015
13052
|
const shimState = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
13016
|
-
const pathDirs = (params.env.PATH ?? "").split(
|
|
13053
|
+
const pathDirs = (params.env.PATH ?? "").split(import_node_path29.default.delimiter).filter((dir) => dir !== "");
|
|
13017
13054
|
const claudeShimShadow = shimState === void 0 ? void 0 : refinePathShadow(
|
|
13018
13055
|
findPathShadow({
|
|
13019
13056
|
pathDirs,
|
|
13020
|
-
targetDir:
|
|
13021
|
-
targetFilename:
|
|
13057
|
+
targetDir: import_node_path29.default.dirname(shimState.targetPath),
|
|
13058
|
+
targetFilename: import_node_path29.default.basename(shimState.targetPath),
|
|
13022
13059
|
findExecutableInDir
|
|
13023
13060
|
}),
|
|
13024
13061
|
shimState.targetPath,
|
|
@@ -13044,7 +13081,7 @@ function collectDoctorReport(params) {
|
|
|
13044
13081
|
agentShim: refinePathShadow(
|
|
13045
13082
|
findPathShadow({
|
|
13046
13083
|
pathDirs,
|
|
13047
|
-
targetDir:
|
|
13084
|
+
targetDir: import_node_path29.default.dirname(ownExecutablePath),
|
|
13048
13085
|
targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
|
|
13049
13086
|
findExecutableInDir
|
|
13050
13087
|
}),
|
|
@@ -13118,11 +13155,11 @@ var FrontDoorSessionsOutputSchema = import_zod19.z.strictObject({ sessions: impo
|
|
|
13118
13155
|
var CheckRunInputSchema = import_zod19.z.strictObject({
|
|
13119
13156
|
path: import_zod19.z.string().min(1),
|
|
13120
13157
|
identity: import_zod19.z.string().min(1).optional()
|
|
13121
|
-
}).refine((input) =>
|
|
13158
|
+
}).refine((input) => import_node_path30.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
13122
13159
|
var PoolPickInputSchema = import_zod19.z.strictObject({
|
|
13123
13160
|
pool: import_zod19.z.string().min(1),
|
|
13124
13161
|
path: import_zod19.z.string().min(1)
|
|
13125
|
-
}).refine((input) =>
|
|
13162
|
+
}).refine((input) => import_node_path30.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
13126
13163
|
var DoctorFindingSchema = import_zod19.z.strictObject({
|
|
13127
13164
|
section: import_zod19.z.enum(DOCTOR_SECTIONS),
|
|
13128
13165
|
subject: import_zod19.z.string().optional(),
|
|
@@ -13498,7 +13535,7 @@ function profileValue(name, paths) {
|
|
|
13498
13535
|
function createConfigApiRouter(deps) {
|
|
13499
13536
|
const authed = doorApiAuth(deps.expectedToken);
|
|
13500
13537
|
const { paths } = deps;
|
|
13501
|
-
const route = (
|
|
13538
|
+
const route = (path37, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path37, summary, tags: [CONFIG_API_TAG] }));
|
|
13502
13539
|
return {
|
|
13503
13540
|
config: {
|
|
13504
13541
|
identity: {
|
|
@@ -13857,7 +13894,7 @@ var import_openapi6 = require("@orpc/openapi");
|
|
|
13857
13894
|
init_cliError();
|
|
13858
13895
|
|
|
13859
13896
|
// src/frontdoor/launchSchemas.ts
|
|
13860
|
-
var
|
|
13897
|
+
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
13861
13898
|
var import_zod22 = require("zod");
|
|
13862
13899
|
init_claudeVersion();
|
|
13863
13900
|
init_identity();
|
|
@@ -13867,7 +13904,7 @@ var LaunchResolveInputSchema = import_zod22.z.strictObject({
|
|
|
13867
13904
|
argv: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())).optional(),
|
|
13868
13905
|
/** The launch's inherited environment. Absent means an empty one: the door's own environment is never a substitute for the caller's, so a caller that wants `AGENT_SHIM_*` switches or a `CLAUDE_CONFIG_DIR` considered names them here. Values are read, never reported. */
|
|
13869
13906
|
env: import_zod22.z.record(import_zod22.z.string(), import_zod22.z.string()).optional()
|
|
13870
|
-
}).refine((input) =>
|
|
13907
|
+
}).refine((input) => import_node_path31.default.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
13871
13908
|
var LaunchPoolDecisionSchema = import_zod22.z.strictObject({
|
|
13872
13909
|
name: import_zod22.z.string(),
|
|
13873
13910
|
reasons: import_zod22.z.readonly(import_zod22.z.array(import_zod22.z.string())),
|
|
@@ -15962,9 +15999,9 @@ data: ${JSON.stringify(envelope)}
|
|
|
15962
15999
|
}
|
|
15963
16000
|
|
|
15964
16001
|
// src/frontdoor/rcSelfHostMint.ts
|
|
15965
|
-
var
|
|
16002
|
+
var import_node_path32 = __toESM(require("node:path"), 1);
|
|
15966
16003
|
init_account();
|
|
15967
|
-
var
|
|
16004
|
+
var CREDENTIALS_FILE2 = ".credentials.json";
|
|
15968
16005
|
var CLAUDE_JSON2 = ".claude.json";
|
|
15969
16006
|
var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
|
|
15970
16007
|
var RC_SELF_HOST_RECORD_FILE = "credential.json";
|
|
@@ -15987,7 +16024,7 @@ function readJsonObject(fs12, file) {
|
|
|
15987
16024
|
return isRecord11(parsed) ? parsed : void 0;
|
|
15988
16025
|
}
|
|
15989
16026
|
function readRcSelfHostRecord(fs12, frontdoorDir) {
|
|
15990
|
-
const parsed = readJsonObject(fs12,
|
|
16027
|
+
const parsed = readJsonObject(fs12, import_node_path32.default.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
15991
16028
|
if (parsed === void 0) {
|
|
15992
16029
|
return void 0;
|
|
15993
16030
|
}
|
|
@@ -16001,11 +16038,11 @@ function mintRcSelfHostCredential(deps) {
|
|
|
16001
16038
|
if (!isIdentityName(deps.identity)) {
|
|
16002
16039
|
throw new Error(`"${deps.identity}" is not a valid identity name.`);
|
|
16003
16040
|
}
|
|
16004
|
-
const identityDir =
|
|
16005
|
-
const credentialsFile =
|
|
16006
|
-
const claudeJsonFile =
|
|
16007
|
-
const recordDir =
|
|
16008
|
-
const recordFile =
|
|
16041
|
+
const identityDir = import_node_path32.default.join(deps.identitiesDir, deps.identity);
|
|
16042
|
+
const credentialsFile = import_node_path32.default.join(identityDir, CREDENTIALS_FILE2);
|
|
16043
|
+
const claudeJsonFile = import_node_path32.default.join(identityDir, CLAUDE_JSON2);
|
|
16044
|
+
const recordDir = import_node_path32.default.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
|
|
16045
|
+
const recordFile = import_node_path32.default.join(recordDir, RC_SELF_HOST_RECORD_FILE);
|
|
16009
16046
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
16010
16047
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
16011
16048
|
const existingOauth = isRecord11(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
@@ -16021,7 +16058,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
16021
16058
|
const organizationUuid = deps.newUuid();
|
|
16022
16059
|
const accountUuid = deps.newUuid();
|
|
16023
16060
|
const mintedAt = new Date(deps.now()).toISOString();
|
|
16024
|
-
deps.fs.mkdirPrivate(
|
|
16061
|
+
deps.fs.mkdirPrivate(import_node_path32.default.dirname(credentialsFile));
|
|
16025
16062
|
deps.fs.writeFilePrivate(credentialsFile, `${JSON.stringify({ ...existingCredentials, claudeAiOauth: { accessToken, refreshToken, expiresAt: null, scopes: [...RC_SELF_HOST_SCOPE_LIST], subscriptionType: SELF_HOST_SUBSCRIPTION_TYPE, rateLimitTier: null } }, null, 2)}
|
|
16026
16063
|
`);
|
|
16027
16064
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|