agent-shim 11.86.4 → 11.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -0
- package/dist/cli.cjs +1687 -1433
- package/dist/index.cjs +390 -341
- package/dist/index.mjs +368 -319
- package/dist/types/index.d.ts +25 -10
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1212,6 +1212,8 @@ var init_schema = __esm({
|
|
|
1212
1212
|
jobs: z3.record(PoolNameSchema, JobSchema).optional()
|
|
1213
1213
|
});
|
|
1214
1214
|
IdentitySchema = z3.strictObject({
|
|
1215
|
+
/** The CLI this login belongs to; absent means Claude Code for backwards compatibility. */
|
|
1216
|
+
agent: z3.enum(["claude", "codex"]).optional(),
|
|
1215
1217
|
$schema: z3.string().optional(),
|
|
1216
1218
|
name: FileNameSchema,
|
|
1217
1219
|
/** What the identity is for, in the person's words, drawn beside its name in `identity list` and `show`, the launch banner and the statusline. Display only: the name stays the key for lookup and for the references to the identity (pools, rules, jobs, model refs), and the id for paths and Keychain service names. */
|
|
@@ -1283,7 +1285,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
|
|
|
1283
1285
|
return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
|
|
1284
1286
|
}
|
|
1285
1287
|
function describeIgnoredKeys(filePath, ignored) {
|
|
1286
|
-
const places = ignored.map(({ path:
|
|
1288
|
+
const places = ignored.map(({ path: path54, keys }) => `${path54.length === 0 ? "" : `${path54.map(String).join(".")}.`}${keys.join(", ")}`);
|
|
1287
1289
|
return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
|
|
1288
1290
|
}
|
|
1289
1291
|
function noteIgnoredKeys(filePath, ignored) {
|
|
@@ -1305,9 +1307,9 @@ function restoreIgnoredKeys(filePath, value) {
|
|
|
1305
1307
|
return value;
|
|
1306
1308
|
}
|
|
1307
1309
|
const restored = structuredClone(value);
|
|
1308
|
-
for (const { path:
|
|
1310
|
+
for (const { path: path54, values } of ignored) {
|
|
1309
1311
|
let holder = restored;
|
|
1310
|
-
for (const step of
|
|
1312
|
+
for (const step of path54) {
|
|
1311
1313
|
holder = isRecord(holder) ? holder[step] : void 0;
|
|
1312
1314
|
}
|
|
1313
1315
|
if (isRecord(holder)) {
|
|
@@ -4701,8 +4703,8 @@ function parseConnectTarget(authority) {
|
|
|
4701
4703
|
function isInterceptedHost(host, interceptHosts) {
|
|
4702
4704
|
return interceptHosts.includes(host);
|
|
4703
4705
|
}
|
|
4704
|
-
function servedByPipeline(
|
|
4705
|
-
return
|
|
4706
|
+
function servedByPipeline(path54) {
|
|
4707
|
+
return path54?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
4706
4708
|
}
|
|
4707
4709
|
function forwardableHeaders(headers) {
|
|
4708
4710
|
const connectionTokens = new Set(
|
|
@@ -5146,7 +5148,7 @@ var init_package = __esm({
|
|
|
5146
5148
|
"package.json"() {
|
|
5147
5149
|
package_default = {
|
|
5148
5150
|
name: "agent-shim",
|
|
5149
|
-
version: "11.
|
|
5151
|
+
version: "11.87.0",
|
|
5150
5152
|
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.",
|
|
5151
5153
|
license: "MIT",
|
|
5152
5154
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -6972,19 +6974,68 @@ var init_realPorts = __esm({
|
|
|
6972
6974
|
}
|
|
6973
6975
|
});
|
|
6974
6976
|
|
|
6977
|
+
// src/cli/bool.ts
|
|
6978
|
+
function parseBoolWord(input) {
|
|
6979
|
+
switch (input) {
|
|
6980
|
+
case "true":
|
|
6981
|
+
case "1":
|
|
6982
|
+
return true;
|
|
6983
|
+
case "false":
|
|
6984
|
+
case "0":
|
|
6985
|
+
return false;
|
|
6986
|
+
default:
|
|
6987
|
+
return void 0;
|
|
6988
|
+
}
|
|
6989
|
+
}
|
|
6990
|
+
var init_bool = __esm({
|
|
6991
|
+
"src/cli/bool.ts"() {
|
|
6992
|
+
"use strict";
|
|
6993
|
+
}
|
|
6994
|
+
});
|
|
6995
|
+
|
|
6996
|
+
// src/cli/envBool.ts
|
|
6997
|
+
function parseEnvBool(variable, value) {
|
|
6998
|
+
if (value === void 0 || value === "") {
|
|
6999
|
+
return void 0;
|
|
7000
|
+
}
|
|
7001
|
+
const parsed = parseBoolWord(value);
|
|
7002
|
+
if (parsed === void 0) {
|
|
7003
|
+
throw new InvalidEnvBoolError(variable, value);
|
|
7004
|
+
}
|
|
7005
|
+
return parsed;
|
|
7006
|
+
}
|
|
7007
|
+
var InvalidEnvBoolError;
|
|
7008
|
+
var init_envBool = __esm({
|
|
7009
|
+
"src/cli/envBool.ts"() {
|
|
7010
|
+
"use strict";
|
|
7011
|
+
init_cliError();
|
|
7012
|
+
init_bool();
|
|
7013
|
+
InvalidEnvBoolError = class extends UsageError {
|
|
7014
|
+
constructor(variable, value) {
|
|
7015
|
+
super(`${variable} must be one of true, false, 1 or 0, got "${value}".`);
|
|
7016
|
+
this.variable = variable;
|
|
7017
|
+
this.value = value;
|
|
7018
|
+
this.name = "InvalidEnvBoolError";
|
|
7019
|
+
}
|
|
7020
|
+
variable;
|
|
7021
|
+
value;
|
|
7022
|
+
};
|
|
7023
|
+
}
|
|
7024
|
+
});
|
|
7025
|
+
|
|
6975
7026
|
// src/pathNorm.ts
|
|
6976
|
-
import
|
|
7027
|
+
import path21 from "node:path";
|
|
6977
7028
|
function expandTilde(value, home) {
|
|
6978
7029
|
if (value === "~") {
|
|
6979
7030
|
return home;
|
|
6980
7031
|
}
|
|
6981
7032
|
if (value.startsWith("~/")) {
|
|
6982
|
-
return
|
|
7033
|
+
return path21.join(home, value.slice(2));
|
|
6983
7034
|
}
|
|
6984
7035
|
return value;
|
|
6985
7036
|
}
|
|
6986
7037
|
function normaliseRulePath(rulePath, home) {
|
|
6987
|
-
return
|
|
7038
|
+
return path21.resolve(expandTilde(rulePath, home));
|
|
6988
7039
|
}
|
|
6989
7040
|
var init_pathNorm = __esm({
|
|
6990
7041
|
"src/pathNorm.ts"() {
|
|
@@ -6993,7 +7044,7 @@ var init_pathNorm = __esm({
|
|
|
6993
7044
|
});
|
|
6994
7045
|
|
|
6995
7046
|
// src/launcher/cascade.ts
|
|
6996
|
-
import
|
|
7047
|
+
import path22 from "node:path";
|
|
6997
7048
|
function loadCascadeInput(params) {
|
|
6998
7049
|
const globalConfig = loadConfigFile(params.paths.globalConfigFile, GlobalConfigSchema, params.read);
|
|
6999
7050
|
const directoryRules = loadConfigFile(params.paths.directoryRulesFile, DirectoryRulesSchema, params.read);
|
|
@@ -7013,8 +7064,8 @@ function loadCascadeInput(params) {
|
|
|
7013
7064
|
});
|
|
7014
7065
|
const levels = [];
|
|
7015
7066
|
for (const dir of dirs) {
|
|
7016
|
-
const portable = loadConfigFile(
|
|
7017
|
-
const portableLocal = loadConfigFile(
|
|
7067
|
+
const portable = loadConfigFile(path22.join(dir, PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(path22.join(dir, LEGACY_PORTABLE_CONFIG_FILENAME), PortableConfigSchema, params.read);
|
|
7068
|
+
const portableLocal = loadConfigFile(path22.join(dir, PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read) ?? loadConfigFile(path22.join(dir, LEGACY_PORTABLE_LOCAL_CONFIG_FILENAME), PortableConfigSchema, params.read);
|
|
7018
7069
|
const rules = (directoryRules?.config.rules ?? []).map((rule, index) => ({ rule, index })).filter(({ rule }) => normaliseRulePath(rule.path, params.home) === dir).map(({ rule, index }) => {
|
|
7019
7070
|
const entryOrder = directoryRules?.ruleEntryOrders[index];
|
|
7020
7071
|
return {
|
|
@@ -7077,7 +7128,7 @@ var init_cascade = __esm({
|
|
|
7077
7128
|
});
|
|
7078
7129
|
|
|
7079
7130
|
// src/launcher/identity.ts
|
|
7080
|
-
import
|
|
7131
|
+
import path23 from "node:path";
|
|
7081
7132
|
function poolNameOf(selector) {
|
|
7082
7133
|
return selector.startsWith(POOL_SELECTOR_PREFIX) ? selector.slice(POOL_SELECTOR_PREFIX.length) : void 0;
|
|
7083
7134
|
}
|
|
@@ -7166,7 +7217,7 @@ function loadIdentity(identitiesDir, name, fs17) {
|
|
|
7166
7217
|
throw new UnsafeNameError(name, "identity", FILE_NAME_RULE);
|
|
7167
7218
|
}
|
|
7168
7219
|
const id = resolveIdentityId(identitiesDir, name, fs17);
|
|
7169
|
-
return id === void 0 ? void 0 : loadConfigFile(
|
|
7220
|
+
return id === void 0 ? void 0 : loadConfigFile(path23.join(identitiesDir, id, "identity.json"), IdentitySchema, fs17.readConfigFile);
|
|
7170
7221
|
}
|
|
7171
7222
|
var IDENTITY_DECISION_SOURCES, IDENTITY_SOURCE_LABELS, CONFIG_PROFILE_DECISION_SOURCES;
|
|
7172
7223
|
var init_identity = __esm({
|
|
@@ -7412,7 +7463,7 @@ var init_schema2 = __esm({
|
|
|
7412
7463
|
});
|
|
7413
7464
|
|
|
7414
7465
|
// src/usage/account.ts
|
|
7415
|
-
import
|
|
7466
|
+
import path24 from "node:path";
|
|
7416
7467
|
function isObject(value) {
|
|
7417
7468
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7418
7469
|
}
|
|
@@ -7431,7 +7482,7 @@ function requireIdentityDirectoryId(id) {
|
|
|
7431
7482
|
}
|
|
7432
7483
|
}
|
|
7433
7484
|
function claudeJsonPath(identitiesDir, identity) {
|
|
7434
|
-
return
|
|
7485
|
+
return path24.join(identitiesDir, identity, CLAUDE_JSON);
|
|
7435
7486
|
}
|
|
7436
7487
|
function readAccountMetadata(fs17, identitiesDir, identity) {
|
|
7437
7488
|
requireIdentityDirectoryId(identity);
|
|
@@ -8157,7 +8208,7 @@ var init_pick = __esm({
|
|
|
8157
8208
|
});
|
|
8158
8209
|
|
|
8159
8210
|
// src/usage/read.ts
|
|
8160
|
-
import
|
|
8211
|
+
import path25 from "node:path";
|
|
8161
8212
|
function segmentDay(epochMs) {
|
|
8162
8213
|
return new Date(epochMs).toISOString().slice(0, "YYYY-MM-DD".length);
|
|
8163
8214
|
}
|
|
@@ -8197,7 +8248,7 @@ function readUsageLog(fs17, logDir, options = {}) {
|
|
|
8197
8248
|
return { records, invalidLines };
|
|
8198
8249
|
}
|
|
8199
8250
|
function readSegment(fs17, logDir, segment) {
|
|
8200
|
-
const contents = fs17.readFileUtf8(
|
|
8251
|
+
const contents = fs17.readFileUtf8(path25.join(logDir, segment.name));
|
|
8201
8252
|
if (contents === void 0) {
|
|
8202
8253
|
return void 0;
|
|
8203
8254
|
}
|
|
@@ -8227,7 +8278,7 @@ function readSegment(fs17, logDir, segment) {
|
|
|
8227
8278
|
}
|
|
8228
8279
|
function snapshotPath(snapshotsDir, identity) {
|
|
8229
8280
|
requireIdentityDirectoryId(identity);
|
|
8230
|
-
return
|
|
8281
|
+
return path25.join(snapshotsDir, `${identity}.json`);
|
|
8231
8282
|
}
|
|
8232
8283
|
function readUsageSnapshot(fs17, snapshotsDir, identity) {
|
|
8233
8284
|
const file = snapshotPath(snapshotsDir, identity);
|
|
@@ -8280,12 +8331,12 @@ var init_read = __esm({
|
|
|
8280
8331
|
});
|
|
8281
8332
|
|
|
8282
8333
|
// src/usage/store.ts
|
|
8283
|
-
import
|
|
8334
|
+
import path26 from "node:path";
|
|
8284
8335
|
function pruneUsageLog(fs17, logDir, nowMs) {
|
|
8285
8336
|
const cutoff = nowMs - USAGE_RETENTION_MS;
|
|
8286
8337
|
for (const segment of listLogSegments(fs17, logDir)) {
|
|
8287
8338
|
if (segment.endsAt <= cutoff) {
|
|
8288
|
-
fs17.removeRecursive(
|
|
8339
|
+
fs17.removeRecursive(path26.join(logDir, segment.name));
|
|
8289
8340
|
}
|
|
8290
8341
|
}
|
|
8291
8342
|
}
|
|
@@ -8367,7 +8418,7 @@ function createUsageStore(deps) {
|
|
|
8367
8418
|
pruneUsageLog(fs17, paths.usageLogDir, nowMs);
|
|
8368
8419
|
prunedDay = day;
|
|
8369
8420
|
}
|
|
8370
|
-
fs17.appendFilePrivate(
|
|
8421
|
+
fs17.appendFilePrivate(path26.join(paths.usageLogDir, segmentName(day, deps.pid)), `${JSON.stringify(record)}
|
|
8371
8422
|
`);
|
|
8372
8423
|
deps.onRecord?.(record);
|
|
8373
8424
|
if (record.identity !== void 0) {
|
|
@@ -8406,7 +8457,7 @@ var init_store2 = __esm({
|
|
|
8406
8457
|
});
|
|
8407
8458
|
|
|
8408
8459
|
// src/usage/poolPick.ts
|
|
8409
|
-
import
|
|
8460
|
+
import path27 from "node:path";
|
|
8410
8461
|
import { z as z17 } from "zod";
|
|
8411
8462
|
function errorMessage(error) {
|
|
8412
8463
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -8585,7 +8636,7 @@ function recordStickyPick(fs17, picksFile, directory, identity, nowMs) {
|
|
|
8585
8636
|
const current = readPicksFile(fs17, picksFile).file.picks;
|
|
8586
8637
|
const kept = Object.entries(current).filter(([, entry]) => nowMs - Date.parse(entry.at) <= USAGE_RETENTION_MS);
|
|
8587
8638
|
const next = { schemaVersion: SCHEMA_VERSION, picks: { ...Object.fromEntries(kept), [directory]: { identity, at: new Date(nowMs).toISOString() } } };
|
|
8588
|
-
fs17.mkdirPrivate(
|
|
8639
|
+
fs17.mkdirPrivate(path27.dirname(picksFile));
|
|
8589
8640
|
fs17.writeFilePrivate(picksFile, `${JSON.stringify(next, null, 2)}
|
|
8590
8641
|
`);
|
|
8591
8642
|
}
|
|
@@ -8619,9 +8670,9 @@ var init_poolPick = __esm({
|
|
|
8619
8670
|
|
|
8620
8671
|
// src/statusline/keys.ts
|
|
8621
8672
|
import { z as z18 } from "zod";
|
|
8622
|
-
function valueAt(source,
|
|
8673
|
+
function valueAt(source, path54) {
|
|
8623
8674
|
let current = source;
|
|
8624
|
-
for (const part of
|
|
8675
|
+
for (const part of path54) {
|
|
8625
8676
|
if (!isPlainObject(current)) {
|
|
8626
8677
|
return void 0;
|
|
8627
8678
|
}
|
|
@@ -8629,14 +8680,14 @@ function valueAt(source, path53) {
|
|
|
8629
8680
|
}
|
|
8630
8681
|
return current;
|
|
8631
8682
|
}
|
|
8632
|
-
function acceptsNull(
|
|
8633
|
-
const layer =
|
|
8683
|
+
function acceptsNull(path54) {
|
|
8684
|
+
const layer = path54.reduceRight((inner, part) => ({ [part]: inner }), null);
|
|
8634
8685
|
return StatuslineSchema.safeParse(layer).success;
|
|
8635
8686
|
}
|
|
8636
|
-
function keyOf(
|
|
8687
|
+
function keyOf(path54, declared) {
|
|
8637
8688
|
const optional = declared instanceof z18.ZodOptional;
|
|
8638
8689
|
const leaf = optional ? declared.unwrap() : declared;
|
|
8639
|
-
const common = { path:
|
|
8690
|
+
const common = { path: path54.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path54), optional, unsettable: acceptsNull(path54) };
|
|
8640
8691
|
if (leaf instanceof z18.ZodNumber) {
|
|
8641
8692
|
return { ...common, kind: "integer", choices: [] };
|
|
8642
8693
|
}
|
|
@@ -8661,7 +8712,7 @@ function keyOf(path53, declared) {
|
|
|
8661
8712
|
if (leaf instanceof z18.ZodArray && leaf.element instanceof z18.ZodString) {
|
|
8662
8713
|
return { ...common, kind: "textList", choices: [] };
|
|
8663
8714
|
}
|
|
8664
|
-
throw new TypeError(`statusline setting ${
|
|
8715
|
+
throw new TypeError(`statusline setting ${path54.join(".")} has a kind the key listing does not describe`);
|
|
8665
8716
|
}
|
|
8666
8717
|
function walk(shape, prefix) {
|
|
8667
8718
|
return Object.entries(shape).flatMap(([name, schema]) => schema instanceof z18.ZodObject ? walk(schema.shape, [...prefix, name]) : [keyOf([...prefix, name], schema)]);
|
|
@@ -8677,15 +8728,15 @@ var init_keys = __esm({
|
|
|
8677
8728
|
});
|
|
8678
8729
|
|
|
8679
8730
|
// src/statusline/change.ts
|
|
8680
|
-
function keyNamed(
|
|
8681
|
-
const found = statuslineKeys().find((key) => key.path ===
|
|
8731
|
+
function keyNamed(path54) {
|
|
8732
|
+
const found = statuslineKeys().find((key) => key.path === path54);
|
|
8682
8733
|
if (found === void 0) {
|
|
8683
|
-
throw new UsageError(`"${
|
|
8734
|
+
throw new UsageError(`"${path54}" is not a statusline setting; \`agent-shim statusline keys\` lists them.`);
|
|
8684
8735
|
}
|
|
8685
8736
|
return found;
|
|
8686
8737
|
}
|
|
8687
|
-
function setAt(target,
|
|
8688
|
-
const [head, ...rest] =
|
|
8738
|
+
function setAt(target, path54, value) {
|
|
8739
|
+
const [head, ...rest] = path54;
|
|
8689
8740
|
if (head === void 0) {
|
|
8690
8741
|
return;
|
|
8691
8742
|
}
|
|
@@ -8698,8 +8749,8 @@ function setAt(target, path53, value) {
|
|
|
8698
8749
|
target[head] = next;
|
|
8699
8750
|
setAt(next, rest, value);
|
|
8700
8751
|
}
|
|
8701
|
-
function removeAt(target,
|
|
8702
|
-
const [head, ...rest] =
|
|
8752
|
+
function removeAt(target, path54) {
|
|
8753
|
+
const [head, ...rest] = path54;
|
|
8703
8754
|
if (head === void 0) {
|
|
8704
8755
|
return;
|
|
8705
8756
|
}
|
|
@@ -8717,13 +8768,13 @@ function removeAt(target, path53) {
|
|
|
8717
8768
|
}
|
|
8718
8769
|
function applyStatuslineChange(existing, change) {
|
|
8719
8770
|
const draft = structuredClone(existing ?? {});
|
|
8720
|
-
for (const [
|
|
8721
|
-
keyNamed(
|
|
8722
|
-
setAt(draft,
|
|
8771
|
+
for (const [path54, value] of Object.entries(change.set ?? {})) {
|
|
8772
|
+
keyNamed(path54);
|
|
8773
|
+
setAt(draft, path54.split("."), value);
|
|
8723
8774
|
}
|
|
8724
|
-
for (const
|
|
8725
|
-
keyNamed(
|
|
8726
|
-
removeAt(draft,
|
|
8775
|
+
for (const path54 of change.unset ?? []) {
|
|
8776
|
+
keyNamed(path54);
|
|
8777
|
+
removeAt(draft, path54.split("."));
|
|
8727
8778
|
}
|
|
8728
8779
|
const result = StatuslineSchema.safeParse(draft);
|
|
8729
8780
|
if (!result.success) {
|
|
@@ -8959,19 +9010,19 @@ function writePools(paths, pools) {
|
|
|
8959
9010
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
8960
9011
|
}
|
|
8961
9012
|
function poolCycleOf(pools, name) {
|
|
8962
|
-
const walk2 = (current,
|
|
9013
|
+
const walk2 = (current, path54) => {
|
|
8963
9014
|
for (const entry of pools[current]?.identities ?? []) {
|
|
8964
9015
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
8965
9016
|
if (nested === void 0) {
|
|
8966
9017
|
continue;
|
|
8967
9018
|
}
|
|
8968
9019
|
if (nested === name) {
|
|
8969
|
-
return [...
|
|
9020
|
+
return [...path54, nested];
|
|
8970
9021
|
}
|
|
8971
|
-
if (
|
|
9022
|
+
if (path54.includes(nested)) {
|
|
8972
9023
|
continue;
|
|
8973
9024
|
}
|
|
8974
|
-
const found = walk2(nested, [...
|
|
9025
|
+
const found = walk2(nested, [...path54, nested]);
|
|
8975
9026
|
if (found !== void 0) {
|
|
8976
9027
|
return found;
|
|
8977
9028
|
}
|
|
@@ -9081,14 +9132,14 @@ var init_poolStore = __esm({
|
|
|
9081
9132
|
// src/paths.ts
|
|
9082
9133
|
import fs6 from "node:fs";
|
|
9083
9134
|
import os5 from "node:os";
|
|
9084
|
-
import
|
|
9135
|
+
import path28 from "node:path";
|
|
9085
9136
|
function resolveAgentShimHome(env = process.env, home = os5.homedir(), isDirectory = isExistingDirectory) {
|
|
9086
9137
|
const fromEnv = env.AGENT_SHIM_HOME;
|
|
9087
9138
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
9088
9139
|
return fromEnv;
|
|
9089
9140
|
}
|
|
9090
|
-
const current =
|
|
9091
|
-
const legacy =
|
|
9141
|
+
const current = path28.join(home, HOME_DIRNAME);
|
|
9142
|
+
const legacy = path28.join(home, LEGACY_HOME_DIRNAME);
|
|
9092
9143
|
return !isDirectory(current) && isDirectory(legacy) ? legacy : current;
|
|
9093
9144
|
}
|
|
9094
9145
|
function isExistingDirectory(candidate) {
|
|
@@ -9099,59 +9150,59 @@ function resolveClaudeHome() {
|
|
|
9099
9150
|
if (fromEnv !== void 0 && fromEnv !== "") {
|
|
9100
9151
|
return fromEnv;
|
|
9101
9152
|
}
|
|
9102
|
-
return
|
|
9153
|
+
return path28.join(os5.homedir(), ".claude");
|
|
9103
9154
|
}
|
|
9104
9155
|
function buildLayoutPaths(root) {
|
|
9105
9156
|
return {
|
|
9106
9157
|
root,
|
|
9107
|
-
identitiesDir:
|
|
9108
|
-
configProfilesDir:
|
|
9109
|
-
providersDir:
|
|
9110
|
-
providerAliasesFile:
|
|
9111
|
-
directoryRulesFile:
|
|
9112
|
-
activeIdentityFile:
|
|
9113
|
-
globalConfigFile:
|
|
9114
|
-
categoriesLocalFile:
|
|
9115
|
-
claudeShimFile:
|
|
9116
|
-
headroomDir:
|
|
9117
|
-
headroomStateFile:
|
|
9118
|
-
headroomRoutingFile:
|
|
9119
|
-
headroomLegacyStateFile:
|
|
9120
|
-
headroomAllowlistFile:
|
|
9121
|
-
headroomSocketDir:
|
|
9122
|
-
headroomLockFile:
|
|
9123
|
-
headroomSessionsDir:
|
|
9124
|
-
logsDir:
|
|
9125
|
-
headroomLogPath:
|
|
9126
|
-
frontdoorDir:
|
|
9127
|
-
frontdoorCaDir:
|
|
9128
|
-
frontdoorCaCertFile:
|
|
9129
|
-
frontdoorCaKeyFile:
|
|
9130
|
-
frontdoorCaBundlesDir:
|
|
9131
|
-
chatgptSignInFile:
|
|
9132
|
-
frontdoorStateFile:
|
|
9133
|
-
frontdoorLockFile:
|
|
9134
|
-
frontdoorControlTokenFile:
|
|
9135
|
-
frontdoorSessionsDir:
|
|
9136
|
-
frontdoorDirectRecordsDir:
|
|
9137
|
-
frontdoorDrainingDir:
|
|
9138
|
-
frontdoorRcCredentialsDir:
|
|
9139
|
-
frontdoorLogPath:
|
|
9140
|
-
usageDir:
|
|
9141
|
-
usageLogDir:
|
|
9142
|
-
usageSnapshotsDir:
|
|
9143
|
-
statuslineDir:
|
|
9144
|
-
catalogueDir:
|
|
9145
|
-
usagePicksFile:
|
|
9146
|
-
usageAnchorsFile:
|
|
9147
|
-
usageJobsFile:
|
|
9148
|
-
jobLogsDir:
|
|
9149
|
-
identityRenamesDir:
|
|
9150
|
-
identityNameRenamesDir:
|
|
9151
|
-
launchesDir:
|
|
9152
|
-
superviseDir:
|
|
9153
|
-
modelMovesDir:
|
|
9154
|
-
mcpPermissionsFile:
|
|
9158
|
+
identitiesDir: path28.join(root, "identities"),
|
|
9159
|
+
configProfilesDir: path28.join(root, "config-profiles"),
|
|
9160
|
+
providersDir: path28.join(root, "providers"),
|
|
9161
|
+
providerAliasesFile: path28.join(root, "provider-aliases.json"),
|
|
9162
|
+
directoryRulesFile: path28.join(root, "directory-rules.json"),
|
|
9163
|
+
activeIdentityFile: path28.join(root, "active-identity"),
|
|
9164
|
+
globalConfigFile: path28.join(root, "config.json"),
|
|
9165
|
+
categoriesLocalFile: path28.join(root, "categories.local.json"),
|
|
9166
|
+
claudeShimFile: path28.join(root, "claude-shim.json"),
|
|
9167
|
+
headroomDir: path28.join(root, "headroom"),
|
|
9168
|
+
headroomStateFile: path28.join(root, "headroom", "state.json"),
|
|
9169
|
+
headroomRoutingFile: path28.join(root, "headroom", "routing.json"),
|
|
9170
|
+
headroomLegacyStateFile: path28.join(root, "headroom", "state.v2.json"),
|
|
9171
|
+
headroomAllowlistFile: path28.join(root, "headroom", "run", "allowlist.txt"),
|
|
9172
|
+
headroomSocketDir: path28.join(root, "headroom", "run"),
|
|
9173
|
+
headroomLockFile: path28.join(root, "headroom", "start.lock"),
|
|
9174
|
+
headroomSessionsDir: path28.join(root, "headroom", "sessions"),
|
|
9175
|
+
logsDir: path28.join(root, "logs"),
|
|
9176
|
+
headroomLogPath: path28.join(root, "logs", "headroom.log"),
|
|
9177
|
+
frontdoorDir: path28.join(root, "frontdoor"),
|
|
9178
|
+
frontdoorCaDir: path28.join(root, "frontdoor", "ca"),
|
|
9179
|
+
frontdoorCaCertFile: path28.join(root, "frontdoor", "ca", "ca.pem"),
|
|
9180
|
+
frontdoorCaKeyFile: path28.join(root, "frontdoor", "ca", "ca.key"),
|
|
9181
|
+
frontdoorCaBundlesDir: path28.join(root, "frontdoor", "ca", "bundles"),
|
|
9182
|
+
chatgptSignInFile: path28.join(root, "codex", "chatgpt-sign-in.json"),
|
|
9183
|
+
frontdoorStateFile: path28.join(root, "frontdoor", "state.json"),
|
|
9184
|
+
frontdoorLockFile: path28.join(root, "frontdoor", "start.lock"),
|
|
9185
|
+
frontdoorControlTokenFile: path28.join(root, "frontdoor", "control-token"),
|
|
9186
|
+
frontdoorSessionsDir: path28.join(root, "frontdoor", "sessions"),
|
|
9187
|
+
frontdoorDirectRecordsDir: path28.join(root, "frontdoor", "direct"),
|
|
9188
|
+
frontdoorDrainingDir: path28.join(root, "frontdoor", "draining"),
|
|
9189
|
+
frontdoorRcCredentialsDir: path28.join(root, "frontdoor", "rc-credentials"),
|
|
9190
|
+
frontdoorLogPath: path28.join(root, "logs", "frontdoor.log"),
|
|
9191
|
+
usageDir: path28.join(root, "usage"),
|
|
9192
|
+
usageLogDir: path28.join(root, "usage", "log"),
|
|
9193
|
+
usageSnapshotsDir: path28.join(root, "usage", "snapshots"),
|
|
9194
|
+
statuslineDir: path28.join(root, "statusline"),
|
|
9195
|
+
catalogueDir: path28.join(root, "catalogues"),
|
|
9196
|
+
usagePicksFile: path28.join(root, "usage", "picks.json"),
|
|
9197
|
+
usageAnchorsFile: path28.join(root, "usage", "anchors.json"),
|
|
9198
|
+
usageJobsFile: path28.join(root, "usage", "jobs.json"),
|
|
9199
|
+
jobLogsDir: path28.join(root, "logs", "jobs"),
|
|
9200
|
+
identityRenamesDir: path28.join(root, "identity-renames"),
|
|
9201
|
+
identityNameRenamesDir: path28.join(root, "identity-name-renames"),
|
|
9202
|
+
launchesDir: path28.join(root, "launches"),
|
|
9203
|
+
superviseDir: path28.join(root, "supervise"),
|
|
9204
|
+
modelMovesDir: path28.join(root, "model-moves"),
|
|
9205
|
+
mcpPermissionsFile: path28.join(root, "mcp", "permissions.json")
|
|
9155
9206
|
};
|
|
9156
9207
|
}
|
|
9157
9208
|
function resolveLayoutPaths() {
|
|
@@ -9166,7 +9217,7 @@ var init_paths = __esm({
|
|
|
9166
9217
|
|
|
9167
9218
|
// src/usage/signIn.ts
|
|
9168
9219
|
import { createHash as createHash6 } from "node:crypto";
|
|
9169
|
-
import
|
|
9220
|
+
import path29 from "node:path";
|
|
9170
9221
|
function claudeCodeKeychainService(configDir) {
|
|
9171
9222
|
return `${KEYCHAIN_SERVICE_PREFIX}-${createHash6("sha256").update(configDir).digest("hex").slice(0, KEYCHAIN_SERVICE_HASH_DIGITS)}`;
|
|
9172
9223
|
}
|
|
@@ -9189,7 +9240,7 @@ function decideSignIn(facts) {
|
|
|
9189
9240
|
return { state: "signed-out", detail: facts.platform === "darwin" ? `no Keychain item and no ${CREDENTIALS_FILE}` : `no ${CREDENTIALS_FILE}` };
|
|
9190
9241
|
}
|
|
9191
9242
|
function credentialsFilePath(farmRoot) {
|
|
9192
|
-
return
|
|
9243
|
+
return path29.join(farmRoot, CREDENTIALS_FILE);
|
|
9193
9244
|
}
|
|
9194
9245
|
function identitySignIn(fs17, probe, identity) {
|
|
9195
9246
|
const probing = !identity.hasCredentialBlock && identity.provider === void 0;
|
|
@@ -9405,7 +9456,7 @@ var init_keychainLogin = __esm({
|
|
|
9405
9456
|
// src/realCredentialCache.ts
|
|
9406
9457
|
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
9407
9458
|
import fs7 from "node:fs";
|
|
9408
|
-
import
|
|
9459
|
+
import path30 from "node:path";
|
|
9409
9460
|
function keychainCacheDeleteArgs(owner) {
|
|
9410
9461
|
return ["delete-generic-password", "-s", KEYCHAIN_CACHE_SERVICE, "-a", owner];
|
|
9411
9462
|
}
|
|
@@ -9420,7 +9471,7 @@ function serialisedFor(entry, owner) {
|
|
|
9420
9471
|
return JSON.stringify({ owner, ...withoutOwner(entry) });
|
|
9421
9472
|
}
|
|
9422
9473
|
function tempPathFor(target) {
|
|
9423
|
-
return
|
|
9474
|
+
return path30.join(path30.dirname(target), `${TEMP_PREFIX}${String(process.pid)}-${randomUUID3()}`);
|
|
9424
9475
|
}
|
|
9425
9476
|
function processRuns(pid) {
|
|
9426
9477
|
try {
|
|
@@ -9438,7 +9489,7 @@ function abandonedTempFiles(entries) {
|
|
|
9438
9489
|
}
|
|
9439
9490
|
function sweepAbandonedTempFiles(dir) {
|
|
9440
9491
|
for (const entry of abandonedTempFiles(fs7.existsSync(dir) ? fs7.readdirSync(dir) : [])) {
|
|
9441
|
-
fs7.rmSync(
|
|
9492
|
+
fs7.rmSync(path30.join(dir, entry), { force: true });
|
|
9442
9493
|
}
|
|
9443
9494
|
}
|
|
9444
9495
|
function storedEntry(store, entry, owner) {
|
|
@@ -9477,8 +9528,8 @@ function security(args, stdin) {
|
|
|
9477
9528
|
return { status: result.status, stdout: result.stdout };
|
|
9478
9529
|
}
|
|
9479
9530
|
function createRealCredentialCache(root, keychain = { run: security, platform: process.platform }) {
|
|
9480
|
-
const dir =
|
|
9481
|
-
const filePath = (owner) =>
|
|
9531
|
+
const dir = path30.join(root, "credential-cache");
|
|
9532
|
+
const filePath = (owner) => path30.join(dir, cacheFileNameFor(owner));
|
|
9482
9533
|
return {
|
|
9483
9534
|
read(store, owner) {
|
|
9484
9535
|
if (store === "file") {
|
|
@@ -10449,62 +10500,13 @@ var init_providersStore = __esm({
|
|
|
10449
10500
|
}
|
|
10450
10501
|
});
|
|
10451
10502
|
|
|
10452
|
-
// src/cli/bool.ts
|
|
10453
|
-
function parseBoolWord(input) {
|
|
10454
|
-
switch (input) {
|
|
10455
|
-
case "true":
|
|
10456
|
-
case "1":
|
|
10457
|
-
return true;
|
|
10458
|
-
case "false":
|
|
10459
|
-
case "0":
|
|
10460
|
-
return false;
|
|
10461
|
-
default:
|
|
10462
|
-
return void 0;
|
|
10463
|
-
}
|
|
10464
|
-
}
|
|
10465
|
-
var init_bool = __esm({
|
|
10466
|
-
"src/cli/bool.ts"() {
|
|
10467
|
-
"use strict";
|
|
10468
|
-
}
|
|
10469
|
-
});
|
|
10470
|
-
|
|
10471
|
-
// src/cli/envBool.ts
|
|
10472
|
-
function parseEnvBool(variable, value) {
|
|
10473
|
-
if (value === void 0 || value === "") {
|
|
10474
|
-
return void 0;
|
|
10475
|
-
}
|
|
10476
|
-
const parsed = parseBoolWord(value);
|
|
10477
|
-
if (parsed === void 0) {
|
|
10478
|
-
throw new InvalidEnvBoolError(variable, value);
|
|
10479
|
-
}
|
|
10480
|
-
return parsed;
|
|
10481
|
-
}
|
|
10482
|
-
var InvalidEnvBoolError;
|
|
10483
|
-
var init_envBool = __esm({
|
|
10484
|
-
"src/cli/envBool.ts"() {
|
|
10485
|
-
"use strict";
|
|
10486
|
-
init_cliError();
|
|
10487
|
-
init_bool();
|
|
10488
|
-
InvalidEnvBoolError = class extends UsageError {
|
|
10489
|
-
constructor(variable, value) {
|
|
10490
|
-
super(`${variable} must be one of true, false, 1 or 0, got "${value}".`);
|
|
10491
|
-
this.variable = variable;
|
|
10492
|
-
this.value = value;
|
|
10493
|
-
this.name = "InvalidEnvBoolError";
|
|
10494
|
-
}
|
|
10495
|
-
variable;
|
|
10496
|
-
value;
|
|
10497
|
-
};
|
|
10498
|
-
}
|
|
10499
|
-
});
|
|
10500
|
-
|
|
10501
10503
|
// src/identityToken.ts
|
|
10502
|
-
import
|
|
10504
|
+
import path31 from "node:path";
|
|
10503
10505
|
function identityTokenDir(paths) {
|
|
10504
|
-
return
|
|
10506
|
+
return path31.join(paths.root, "credentials");
|
|
10505
10507
|
}
|
|
10506
10508
|
function identityTokenPath(paths, identityId) {
|
|
10507
|
-
return
|
|
10509
|
+
return path31.join(identityTokenDir(paths), `${identityId}.token`);
|
|
10508
10510
|
}
|
|
10509
10511
|
var init_identityToken = __esm({
|
|
10510
10512
|
"src/identityToken.ts"() {
|
|
@@ -10728,7 +10730,7 @@ var init_readableConfig = __esm({
|
|
|
10728
10730
|
|
|
10729
10731
|
// src/identityRenameJournal.ts
|
|
10730
10732
|
import { createHash as createHash7 } from "node:crypto";
|
|
10731
|
-
import
|
|
10733
|
+
import path32 from "node:path";
|
|
10732
10734
|
import { z as z21 } from "zod";
|
|
10733
10735
|
function renamePairFileName(from, to, suffix) {
|
|
10734
10736
|
return `${createHash7("sha256").update(`${from}\0${to}`).digest("hex").slice(0, FILE_NAME_HASH_DIGITS)}${suffix}`;
|
|
@@ -10757,7 +10759,7 @@ function listRenameJournals(fs17, directory) {
|
|
|
10757
10759
|
if (!name.endsWith(JOURNAL_SUFFIX)) {
|
|
10758
10760
|
continue;
|
|
10759
10761
|
}
|
|
10760
|
-
const file =
|
|
10762
|
+
const file = path32.join(directory, name);
|
|
10761
10763
|
try {
|
|
10762
10764
|
const journal = readRenameJournal(fs17, file);
|
|
10763
10765
|
if (journal !== void 0) {
|
|
@@ -10845,7 +10847,7 @@ var init_identityRenameJournal = __esm({
|
|
|
10845
10847
|
|
|
10846
10848
|
// src/identityNameRenameRecord.ts
|
|
10847
10849
|
import fs9 from "node:fs";
|
|
10848
|
-
import
|
|
10850
|
+
import path33 from "node:path";
|
|
10849
10851
|
import { z as z22 } from "zod";
|
|
10850
10852
|
function readRecordFiles(paths) {
|
|
10851
10853
|
if (!fs9.existsSync(paths.identityNameRenamesDir)) {
|
|
@@ -10855,7 +10857,7 @@ function readRecordFiles(paths) {
|
|
|
10855
10857
|
if (!entry.endsWith(RECORD_SUFFIX)) {
|
|
10856
10858
|
return [];
|
|
10857
10859
|
}
|
|
10858
|
-
const file =
|
|
10860
|
+
const file = path33.join(paths.identityNameRenamesDir, entry);
|
|
10859
10861
|
let parsed;
|
|
10860
10862
|
try {
|
|
10861
10863
|
parsed = JSON.parse(fs9.readFileSync(file, "utf8"));
|
|
@@ -10867,7 +10869,7 @@ function readRecordFiles(paths) {
|
|
|
10867
10869
|
});
|
|
10868
10870
|
}
|
|
10869
10871
|
function isFiledForItsPair(entry) {
|
|
10870
|
-
return
|
|
10872
|
+
return path33.basename(entry.file) === renamePairFileName(entry.record.from, entry.record.to, RECORD_SUFFIX);
|
|
10871
10873
|
}
|
|
10872
10874
|
function readNameRenameRecords(paths) {
|
|
10873
10875
|
return readRecordFiles(paths).filter(isFiledForItsPair).map((entry) => entry.record);
|
|
@@ -10959,17 +10961,17 @@ var init_identityNameRenameRecord = __esm({
|
|
|
10959
10961
|
});
|
|
10960
10962
|
|
|
10961
10963
|
// src/launcher/launchRecords.ts
|
|
10962
|
-
import
|
|
10964
|
+
import path34 from "node:path";
|
|
10963
10965
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
10964
10966
|
import { z as z23 } from "zod";
|
|
10965
10967
|
function recordFile(directory, pid) {
|
|
10966
|
-
return
|
|
10968
|
+
return path34.join(directory, `${String(pid)}.${randomUUID4()}${RECORD_SUFFIX2}`);
|
|
10967
10969
|
}
|
|
10968
10970
|
function readRecord(fs17, directory, name) {
|
|
10969
10971
|
if (!name.endsWith(RECORD_SUFFIX2)) {
|
|
10970
10972
|
return void 0;
|
|
10971
10973
|
}
|
|
10972
|
-
const raw = fs17.readFileUtf8(
|
|
10974
|
+
const raw = fs17.readFileUtf8(path34.join(directory, name));
|
|
10973
10975
|
if (raw === void 0) {
|
|
10974
10976
|
return void 0;
|
|
10975
10977
|
}
|
|
@@ -10987,7 +10989,7 @@ function registerLaunch(fs17, directory, owner, isRunning) {
|
|
|
10987
10989
|
for (const name of fs17.readdir(directory)) {
|
|
10988
10990
|
const record2 = readRecord(fs17, directory, name);
|
|
10989
10991
|
if (record2 !== void 0 && !isRunning(record2.pid)) {
|
|
10990
|
-
fs17.removeRecursive(
|
|
10992
|
+
fs17.removeRecursive(path34.join(directory, name));
|
|
10991
10993
|
}
|
|
10992
10994
|
}
|
|
10993
10995
|
const file = recordFile(directory, owner.pid);
|
|
@@ -11020,7 +11022,7 @@ var init_launchRecords = __esm({
|
|
|
11020
11022
|
|
|
11021
11023
|
// src/identityStore.ts
|
|
11022
11024
|
import fs10 from "node:fs";
|
|
11023
|
-
import
|
|
11025
|
+
import path35 from "node:path";
|
|
11024
11026
|
function displacedIdentity(paths, verb, name, id) {
|
|
11025
11027
|
return new DisplacedIdentityError(verb, name, id, fs10.existsSync(identityDirectory(paths, id)));
|
|
11026
11028
|
}
|
|
@@ -11051,13 +11053,13 @@ function identityNameOf(paths, id) {
|
|
|
11051
11053
|
return identityNameIn(identityRecords(paths), id);
|
|
11052
11054
|
}
|
|
11053
11055
|
function identityDirectory(paths, id) {
|
|
11054
|
-
return
|
|
11056
|
+
return path35.join(paths.identitiesDir, id);
|
|
11055
11057
|
}
|
|
11056
11058
|
function identityJsonPath(paths, id) {
|
|
11057
11059
|
if (!isStoredName(id)) {
|
|
11058
11060
|
throw new UnsafeNameError(id, "identity");
|
|
11059
11061
|
}
|
|
11060
|
-
return
|
|
11062
|
+
return path35.join(identityDirectory(paths, id), IDENTITY_FILE);
|
|
11061
11063
|
}
|
|
11062
11064
|
function requireIdentityNames(paths, names) {
|
|
11063
11065
|
const existing = new Set(listIdentities(paths).map((entry) => entry.name));
|
|
@@ -11081,7 +11083,7 @@ function readIdentityById(paths, id) {
|
|
|
11081
11083
|
return readJson(identityJsonPath(paths, id), IdentitySchema);
|
|
11082
11084
|
}
|
|
11083
11085
|
function idKeyedFiles(paths, id) {
|
|
11084
|
-
return [identityTokenPath(paths, id),
|
|
11086
|
+
return [identityTokenPath(paths, id), path35.join(paths.root, "credential-cache", cacheFileNameFor(identityCacheKey(id))), snapshotPath(paths.usageSnapshotsDir, id)];
|
|
11085
11087
|
}
|
|
11086
11088
|
function loggedIdentityIds(paths) {
|
|
11087
11089
|
let logged;
|
|
@@ -11111,7 +11113,7 @@ function stateFiledUnder(paths, id, allocation, moving) {
|
|
|
11111
11113
|
const folded = id.toLowerCase();
|
|
11112
11114
|
const entry = (fs10.existsSync(paths.identitiesDir) ? fs10.readdirSync(paths.identitiesDir) : []).find((candidate) => candidate !== moving?.lockEntry && belongsToIdentity(candidate.toLowerCase(), folded));
|
|
11113
11115
|
if (entry !== void 0) {
|
|
11114
|
-
return `${
|
|
11116
|
+
return `${path35.join(paths.identitiesDir, entry)} exists${entry.toLowerCase() === folded && entry !== id ? `, and an id that differs from "${id}" only in case is the same directory on a filesystem that ignores case` : ""}`;
|
|
11115
11117
|
}
|
|
11116
11118
|
const sharing = allocation.recordIds().find((other) => other.toLowerCase() !== folded && other !== moving?.id && foldedCacheFile(other) === foldedCacheFile(id));
|
|
11117
11119
|
if (sharing !== void 0) {
|
|
@@ -11119,12 +11121,12 @@ function stateFiledUnder(paths, id, allocation, moving) {
|
|
|
11119
11121
|
const sharingFile = cacheFileNameFor(identityCacheKey(sharing));
|
|
11120
11122
|
return `the credential cache would file it in ${file}, ${file === sharingFile ? `the file of identities/${sharing}` : `which differs only in case from the file of identities/${sharing}, ${sharingFile}`}`;
|
|
11121
11123
|
}
|
|
11122
|
-
const cacheDir =
|
|
11124
|
+
const cacheDir = path35.join(paths.root, "credential-cache");
|
|
11123
11125
|
const ownCacheFile = moving !== void 0 && createRealCredentialCache(paths.root).read("file", identityCacheKey(moving.id)) !== void 0 ? cacheFileNameFor(identityCacheKey(moving.id)) : void 0;
|
|
11124
11126
|
for (const candidate of idKeyedFiles(paths, id)) {
|
|
11125
|
-
const onDisk = entriesOf(
|
|
11127
|
+
const onDisk = entriesOf(path35.dirname(candidate)).find((spelled) => spelled.toLowerCase() === path35.basename(candidate).toLowerCase() && !(path35.dirname(candidate) === cacheDir && spelled === ownCacheFile));
|
|
11126
11128
|
if (onDisk !== void 0) {
|
|
11127
|
-
return `${
|
|
11129
|
+
return `${path35.join(path35.dirname(candidate), onDisk)} exists${onDisk === path35.basename(candidate) ? "" : `, and a file name that differs from ${path35.basename(candidate)} only in case is the same file on a filesystem that ignores case`}`;
|
|
11128
11130
|
}
|
|
11129
11131
|
}
|
|
11130
11132
|
if (allocation.keychain !== void 0 && keychainCacheEntryExists(allocation.keychain, identityCacheKey(id))) {
|
|
@@ -11168,7 +11170,7 @@ function addIdentity(paths, name, options = {}) {
|
|
|
11168
11170
|
if (checkedId !== void 0 && idTaken(paths, checkedId, allocation)) {
|
|
11169
11171
|
throw new CheckedIdTakenError(name, checkedId);
|
|
11170
11172
|
}
|
|
11171
|
-
const identity = IdentitySchema.parse({ name, allowAmbientCredential: false });
|
|
11173
|
+
const identity = IdentitySchema.parse({ name, allowAmbientCredential: false, ...options.agent === void 0 ? {} : { agent: options.agent } });
|
|
11172
11174
|
writeJsonAtomic(identityJsonPath(paths, id()), identity);
|
|
11173
11175
|
return identity;
|
|
11174
11176
|
});
|
|
@@ -11229,7 +11231,7 @@ function listIdentityDirectories(paths) {
|
|
|
11229
11231
|
if (!isIdentityDirectoryName(entry.name)) {
|
|
11230
11232
|
continue;
|
|
11231
11233
|
}
|
|
11232
|
-
const entryPath =
|
|
11234
|
+
const entryPath = path35.join(paths.identitiesDir, entry.name);
|
|
11233
11235
|
const followed = entry.isDirectory() ? "directory" : entry.isSymbolicLink() ? followedLink(entryPath) : "other";
|
|
11234
11236
|
if (followed === "other") {
|
|
11235
11237
|
continue;
|
|
@@ -11339,7 +11341,7 @@ function isFarmEntry(entry, name) {
|
|
|
11339
11341
|
return entry === name || new RegExp(`^\\.${escapedForPattern(name)}${FARM_SUFFIX_PATTERN}$`, "u").test(entry);
|
|
11340
11342
|
}
|
|
11341
11343
|
function belongsToIdentity(entry, name) {
|
|
11342
|
-
return isFarmEntry(entry, name) || entry ===
|
|
11344
|
+
return isFarmEntry(entry, name) || entry === path35.basename(identityLockPath("", name));
|
|
11343
11345
|
}
|
|
11344
11346
|
function requireNewIdentityName(name) {
|
|
11345
11347
|
if (!FileNameSchema.safeParse(name).success) {
|
|
@@ -11347,7 +11349,7 @@ function requireNewIdentityName(name) {
|
|
|
11347
11349
|
}
|
|
11348
11350
|
}
|
|
11349
11351
|
function sameIdentityName(paths, first, second) {
|
|
11350
|
-
return sameDirectory(
|
|
11352
|
+
return sameDirectory(path35.join(paths.identitiesDir, first), path35.join(paths.identitiesDir, second)) || first.toLowerCase() === second.toLowerCase() && ignoresCase(paths.identitiesDir);
|
|
11351
11353
|
}
|
|
11352
11354
|
function requireNoUnfinishedRenameNaming(paths, name, action) {
|
|
11353
11355
|
requireNameFreeOfUnfinishedRename({ readFileUtf8: nodeStoreFs.readFileUtf8, readdir: (directory) => fs10.existsSync(directory) ? fs10.readdirSync(directory) : [] }, paths.identityRenamesDir, name, action, (first, second) => sameIdentityName(paths, first, second), (identity) => identityIdExists(paths, identity));
|
|
@@ -11377,17 +11379,17 @@ function removeIdentityWithLockHeld(paths, name, namesLock) {
|
|
|
11377
11379
|
}
|
|
11378
11380
|
const resync = acquireRemovalLock(paths, name, id, namesLock);
|
|
11379
11381
|
try {
|
|
11380
|
-
const lockFile =
|
|
11382
|
+
const lockFile = path35.basename(resync.path);
|
|
11381
11383
|
for (const file of idKeyedFiles(paths, id).filter((candidate) => fs10.existsSync(candidate))) {
|
|
11382
|
-
fs10.accessSync(
|
|
11384
|
+
fs10.accessSync(path35.dirname(file), fs10.constants.W_OK | fs10.constants.X_OK);
|
|
11383
11385
|
}
|
|
11384
|
-
const links = fs10.readdirSync(paths.identitiesDir).filter((entry) => !entry.startsWith(".") && entry !== id && sameDirectory(
|
|
11386
|
+
const links = fs10.readdirSync(paths.identitiesDir).filter((entry) => !entry.startsWith(".") && entry !== id && sameDirectory(path35.join(paths.identitiesDir, entry), path35.join(paths.identitiesDir, id)));
|
|
11385
11387
|
for (const entry of fs10.readdirSync(paths.identitiesDir)) {
|
|
11386
11388
|
if (links.includes(entry) || entry !== lockFile && belongsToIdentity(entry, id)) {
|
|
11387
|
-
fs10.rmSync(
|
|
11389
|
+
fs10.rmSync(path35.join(paths.identitiesDir, entry), { recursive: true, force: true });
|
|
11388
11390
|
}
|
|
11389
11391
|
}
|
|
11390
|
-
const cacheFile =
|
|
11392
|
+
const cacheFile = path35.join(paths.root, "credential-cache", cacheFileNameFor(identityCacheKey(id)));
|
|
11391
11393
|
for (const file of idKeyedFiles(paths, id).filter((candidate) => candidate !== cacheFile)) {
|
|
11392
11394
|
fs10.rmSync(file, { force: true });
|
|
11393
11395
|
}
|
|
@@ -11633,17 +11635,17 @@ var init_commandDeps = __esm({
|
|
|
11633
11635
|
|
|
11634
11636
|
// src/claudeShim.ts
|
|
11635
11637
|
import fs11 from "node:fs";
|
|
11636
|
-
import
|
|
11638
|
+
import path37 from "node:path";
|
|
11637
11639
|
import { z as z28 } from "zod";
|
|
11638
11640
|
function commandFilename(ownExecutablePath, commandName) {
|
|
11639
11641
|
return ownExecutablePath.toLowerCase().endsWith(".exe") ? `${commandName}.exe` : commandName;
|
|
11640
11642
|
}
|
|
11641
11643
|
function resolveOwnBinaryCheck(paths, contentSourcePath) {
|
|
11642
11644
|
const state = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
11643
|
-
const recordedTarget = state === void 0 ? void 0 :
|
|
11645
|
+
const recordedTarget = state === void 0 ? void 0 : path37.resolve(state.targetPath);
|
|
11644
11646
|
let ownStat;
|
|
11645
11647
|
return (candidate) => {
|
|
11646
|
-
if (recordedTarget !== void 0 &&
|
|
11648
|
+
if (recordedTarget !== void 0 && path37.resolve(candidate) === recordedTarget) {
|
|
11647
11649
|
return true;
|
|
11648
11650
|
}
|
|
11649
11651
|
ownStat ??= statOrUndefined(contentSourcePath);
|
|
@@ -11666,15 +11668,15 @@ function statOrUndefined(target) {
|
|
|
11666
11668
|
}
|
|
11667
11669
|
}
|
|
11668
11670
|
function findPathShadow(params) {
|
|
11669
|
-
const resolvedTargetDir =
|
|
11671
|
+
const resolvedTargetDir = path37.resolve(params.targetDir);
|
|
11670
11672
|
for (const dir of params.pathDirs) {
|
|
11671
11673
|
const found = params.findExecutableInDir(dir, params.targetFilename);
|
|
11672
11674
|
if (found === void 0) {
|
|
11673
11675
|
continue;
|
|
11674
11676
|
}
|
|
11675
|
-
return
|
|
11677
|
+
return path37.resolve(dir) === resolvedTargetDir ? { status: "ok" } : { status: "shadowed", by: found };
|
|
11676
11678
|
}
|
|
11677
|
-
return params.pathDirs.some((dir) =>
|
|
11679
|
+
return params.pathDirs.some((dir) => path37.resolve(dir) === resolvedTargetDir) ? { status: "ok" } : { status: "not-on-path" };
|
|
11678
11680
|
}
|
|
11679
11681
|
var ClaudeShimStateSchema, nodeLinkFs;
|
|
11680
11682
|
var init_claudeShim = __esm({
|
|
@@ -11843,7 +11845,7 @@ var init_modelsStore = __esm({
|
|
|
11843
11845
|
|
|
11844
11846
|
// src/codex/catalogueCredential.ts
|
|
11845
11847
|
import { createHash as createHash8 } from "node:crypto";
|
|
11846
|
-
import
|
|
11848
|
+
import path40 from "node:path";
|
|
11847
11849
|
import { z as z32 } from "zod";
|
|
11848
11850
|
function parseCatalogueBinding(raw) {
|
|
11849
11851
|
if (raw === void 0) return void 0;
|
|
@@ -11877,8 +11879,8 @@ function signInCatalogueFingerprint(raw, filePath) {
|
|
|
11877
11879
|
function savedCatalogueFingerprint(provider, paths, env, home, read) {
|
|
11878
11880
|
if (provider.codex?.login === "chatgpt-sign-in") return signInCatalogueFingerprint(read(paths.chatgptSignInFile), paths.chatgptSignInFile);
|
|
11879
11881
|
const configuredHome = env.CODEX_HOME;
|
|
11880
|
-
const codexHome = configuredHome === void 0 || configuredHome === "" ?
|
|
11881
|
-
return cliCatalogueFingerprint(read(
|
|
11882
|
+
const codexHome = configuredHome === void 0 || configuredHome === "" ? path40.join(home, ".codex") : configuredHome;
|
|
11883
|
+
return cliCatalogueFingerprint(read(path40.join(codexHome, "auth.json")));
|
|
11882
11884
|
}
|
|
11883
11885
|
var CatalogueBindingSchema;
|
|
11884
11886
|
var init_catalogueCredential = __esm({
|
|
@@ -13055,7 +13057,7 @@ var init_settings2 = __esm({
|
|
|
13055
13057
|
});
|
|
13056
13058
|
|
|
13057
13059
|
// src/launcher/flags.ts
|
|
13058
|
-
import
|
|
13060
|
+
import path48 from "node:path";
|
|
13059
13061
|
function resolveLaunchFlags(params) {
|
|
13060
13062
|
const statusline = resolveStatuslineSettings(params);
|
|
13061
13063
|
return {
|
|
@@ -13111,7 +13113,7 @@ function buildEnv(params) {
|
|
|
13111
13113
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
13112
13114
|
let providerCustomHeaders;
|
|
13113
13115
|
if (!params.configDirEscapeHatch && params.identityId !== void 0) {
|
|
13114
|
-
env.CLAUDE_CONFIG_DIR =
|
|
13116
|
+
env.CLAUDE_CONFIG_DIR = path48.join(params.identitiesDir, params.identityId);
|
|
13115
13117
|
}
|
|
13116
13118
|
if (params.provider !== void 0) {
|
|
13117
13119
|
const providerEnv = params.provider.definition.kind !== void 0 && params.provider.definition.kind !== "http" ? {} : params.provider.definition.env ?? {};
|
|
@@ -13203,7 +13205,7 @@ var init_extraFlags = __esm({
|
|
|
13203
13205
|
});
|
|
13204
13206
|
|
|
13205
13207
|
// src/usage/resumeContext.ts
|
|
13206
|
-
import
|
|
13208
|
+
import path49 from "node:path";
|
|
13207
13209
|
function projectDirNameOf(cwd) {
|
|
13208
13210
|
return cwd.replace(/[^A-Za-z0-9]/g, "-");
|
|
13209
13211
|
}
|
|
@@ -13261,7 +13263,7 @@ function newestTranscript(fs17, projectDir) {
|
|
|
13261
13263
|
if (!name.endsWith(".jsonl")) {
|
|
13262
13264
|
continue;
|
|
13263
13265
|
}
|
|
13264
|
-
const candidate =
|
|
13266
|
+
const candidate = path49.join(projectDir, name);
|
|
13265
13267
|
const stat = fs17.lstat(candidate);
|
|
13266
13268
|
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
13267
13269
|
newestMs = stat.mtimeMs;
|
|
@@ -13275,8 +13277,8 @@ function resumedContextTokens(fs17, params) {
|
|
|
13275
13277
|
if (target === void 0) {
|
|
13276
13278
|
return void 0;
|
|
13277
13279
|
}
|
|
13278
|
-
const projectDir =
|
|
13279
|
-
const file = target.kind === "id" ?
|
|
13280
|
+
const projectDir = path49.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
13281
|
+
const file = target.kind === "id" ? path49.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs17, projectDir);
|
|
13280
13282
|
const text = file === void 0 ? void 0 : fs17.readFileUtf8(file);
|
|
13281
13283
|
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
13282
13284
|
}
|
|
@@ -13874,7 +13876,7 @@ var init_launchHook = __esm({
|
|
|
13874
13876
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
13875
13877
|
import os9 from "node:os";
|
|
13876
13878
|
import { isDeepStrictEqual } from "node:util";
|
|
13877
|
-
import
|
|
13879
|
+
import path50 from "node:path";
|
|
13878
13880
|
function resolveIdentityCredential(identity, credential, env, port) {
|
|
13879
13881
|
if (port === void 0) {
|
|
13880
13882
|
return { ok: false, status: 1, message: `agent-shim: identity ${identity.name} needs its credential resolved, but this launcher has no credential port wired` };
|
|
@@ -13980,6 +13982,10 @@ function decideLaunch(params, readOnly, onRecorded) {
|
|
|
13980
13982
|
proc.exit(1);
|
|
13981
13983
|
}
|
|
13982
13984
|
}
|
|
13985
|
+
if (loadedIdentity?.config.agent === "codex") {
|
|
13986
|
+
log.error(`Identity "${identityDecision.name ?? ""}" belongs to Codex. Use agent-shim run --agent codex @${identityDecision.name ?? ""}.`);
|
|
13987
|
+
proc.exit(1);
|
|
13988
|
+
}
|
|
13983
13989
|
const configProfileDecision = decideConfigProfile({
|
|
13984
13990
|
env,
|
|
13985
13991
|
cliFlagConfigProfile: params.cliFlagConfigProfile ?? parsedArgv.configProfile,
|
|
@@ -14130,8 +14136,8 @@ function decideLaunch(params, readOnly, onRecorded) {
|
|
|
14130
14136
|
if (definition.kind === "codex" && readOnly && cache !== void 0) {
|
|
14131
14137
|
const binding = parseCatalogueBinding(params.fs.readFileUtf8(catalogueBindingPath(paths, name, catalogueOwner, generation)));
|
|
14132
14138
|
const configuredHome = catalogueEnv.CODEX_HOME;
|
|
14133
|
-
const home = configuredHome === void 0 || configuredHome === "" ?
|
|
14134
|
-
const source = definition.codex?.login === "chatgpt-sign-in" ? paths.chatgptSignInFile :
|
|
14139
|
+
const home = configuredHome === void 0 || configuredHome === "" ? path50.join(os9.homedir(), ".codex") : configuredHome;
|
|
14140
|
+
const source = definition.codex?.login === "chatgpt-sign-in" ? paths.chatgptSignInFile : path50.resolve(home, "auth.json");
|
|
14135
14141
|
const revision = params.fs.fileRevision?.(source);
|
|
14136
14142
|
if (binding === void 0 || binding.fingerprint !== cache.credentialFingerprint || binding.source !== source || revision === void 0 || revision !== binding.revision) return [];
|
|
14137
14143
|
}
|
|
@@ -14152,7 +14158,7 @@ function decideLaunch(params, readOnly, onRecorded) {
|
|
|
14152
14158
|
return { args: args2, pickerSuppressed: startsSession && pickerSettings !== void 0 && callerSettings };
|
|
14153
14159
|
};
|
|
14154
14160
|
const args = argsForSupervisor().args;
|
|
14155
|
-
const configDir = configDirEscapeHatchApplies || farmIdentity === void 0 ? env.CLAUDE_CONFIG_DIR :
|
|
14161
|
+
const configDir = configDirEscapeHatchApplies || farmIdentity === void 0 ? env.CLAUDE_CONFIG_DIR : path50.join(paths.identitiesDir, farmIdentity);
|
|
14156
14162
|
const decision = {
|
|
14157
14163
|
identitySource: identityDecision.source,
|
|
14158
14164
|
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
@@ -14239,7 +14245,7 @@ function prepareRegisteredLaunch(params, onRecorded) {
|
|
|
14239
14245
|
let warnings = [];
|
|
14240
14246
|
const updateCheck = runLaunchUpdateCheck({
|
|
14241
14247
|
mode: params.updateMode ?? "off",
|
|
14242
|
-
checkPath:
|
|
14248
|
+
checkPath: path50.join(paths.root, "update.check"),
|
|
14243
14249
|
currentVersion: package_default.version,
|
|
14244
14250
|
port: params.update
|
|
14245
14251
|
});
|
|
@@ -14262,7 +14268,7 @@ function prepareRegisteredLaunch(params, onRecorded) {
|
|
|
14262
14268
|
classification: resyncFarmRuntime.classification,
|
|
14263
14269
|
now: resyncFarmRuntime.now,
|
|
14264
14270
|
uniqueSuffix: resyncFarmRuntime.uniqueSuffix,
|
|
14265
|
-
identityExists: () => params.fs.readConfigFile(
|
|
14271
|
+
identityExists: () => params.fs.readConfigFile(path50.join(paths.identitiesDir, resyncIdentity, IDENTITY_FILE)) !== void 0,
|
|
14266
14272
|
lock: resyncFarmRuntime.lock
|
|
14267
14273
|
});
|
|
14268
14274
|
} catch (error) {
|
|
@@ -14451,12 +14457,12 @@ var init_launcher = __esm({
|
|
|
14451
14457
|
});
|
|
14452
14458
|
|
|
14453
14459
|
// src/ownCli.ts
|
|
14454
|
-
import
|
|
14460
|
+
import path51 from "node:path";
|
|
14455
14461
|
function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
|
|
14456
14462
|
if (distDir === void 0) {
|
|
14457
14463
|
throw new OwnCliPathUnknownError();
|
|
14458
14464
|
}
|
|
14459
|
-
return
|
|
14465
|
+
return path51.join(distDir, OWN_CLI_FILE_NAME);
|
|
14460
14466
|
}
|
|
14461
14467
|
var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
14462
14468
|
var init_ownCli = __esm({
|
|
@@ -14512,10 +14518,10 @@ var init_selfIdentity = __esm({
|
|
|
14512
14518
|
|
|
14513
14519
|
// src/frontdoor/trust.ts
|
|
14514
14520
|
import { createHash as createHash9 } from "node:crypto";
|
|
14515
|
-
import
|
|
14521
|
+
import path52 from "node:path";
|
|
14516
14522
|
function resolveTrustBundle(params) {
|
|
14517
14523
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs17 } = params;
|
|
14518
|
-
if (inherited === void 0 || inherited === "" ||
|
|
14524
|
+
if (inherited === void 0 || inherited === "" || path52.resolve(inherited) === path52.resolve(caCertFile)) {
|
|
14519
14525
|
return { path: caCertFile };
|
|
14520
14526
|
}
|
|
14521
14527
|
const caPem = fs17.readFileUtf8(caCertFile);
|
|
@@ -14533,7 +14539,7 @@ function resolveTrustBundle(params) {
|
|
|
14533
14539
|
}
|
|
14534
14540
|
const combined = `${inheritedPem.trimEnd()}
|
|
14535
14541
|
${caPem}`;
|
|
14536
|
-
const bundle =
|
|
14542
|
+
const bundle = path52.join(bundlesDir, `${createHash9("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
14537
14543
|
if (!fs17.exists(bundle)) {
|
|
14538
14544
|
fs17.mkdirp(bundlesDir);
|
|
14539
14545
|
fs17.writeFileAtomic(bundle, combined);
|
|
@@ -14677,7 +14683,7 @@ var init_realFrontDoorPort = __esm({
|
|
|
14677
14683
|
|
|
14678
14684
|
// src/launchWiring.ts
|
|
14679
14685
|
import os11 from "node:os";
|
|
14680
|
-
import
|
|
14686
|
+
import path53 from "node:path";
|
|
14681
14687
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
14682
14688
|
function buildFarmRuntime(paths, cwd, run = realRunPort) {
|
|
14683
14689
|
const home = os11.homedir();
|
|
@@ -14732,7 +14738,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
14732
14738
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|
|
14733
14739
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
14734
14740
|
hold: realHoldPort,
|
|
14735
|
-
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot:
|
|
14741
|
+
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot: path53.join(paths.identitiesDir, identity), hasCredentialBlock: false, provider: void 0 }).state !== "signed-out",
|
|
14736
14742
|
...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
|
|
14737
14743
|
...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
|
|
14738
14744
|
...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
|
|
@@ -15472,8 +15478,8 @@ function pathnameOf(url) {
|
|
|
15472
15478
|
return new URL(url ?? "/", "http://127.0.0.1").pathname;
|
|
15473
15479
|
}
|
|
15474
15480
|
function isRcSessionExchange(url) {
|
|
15475
|
-
const
|
|
15476
|
-
return
|
|
15481
|
+
const path54 = pathnameOf(url);
|
|
15482
|
+
return path54 === RC_SESSIONS_PATH_PREFIX || path54.startsWith(`${RC_SESSIONS_PATH_PREFIX}/`);
|
|
15477
15483
|
}
|
|
15478
15484
|
var RC_SESSION_ID_PREFIX = "cse_";
|
|
15479
15485
|
var RC_IDLE_EXPIRY_MS = 45e3;
|
|
@@ -16032,8 +16038,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
16032
16038
|
function isRcReadFileEncoding(value) {
|
|
16033
16039
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
16034
16040
|
}
|
|
16035
|
-
function buildRcReadFilePayload(requestId,
|
|
16036
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
16041
|
+
function buildRcReadFilePayload(requestId, path54, options) {
|
|
16042
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path54, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
16037
16043
|
}
|
|
16038
16044
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
16039
16045
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -16135,15 +16141,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
16135
16141
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
16136
16142
|
return result.ok ? { ...result, requestId } : result;
|
|
16137
16143
|
}
|
|
16138
|
-
async function readRcSessionFile(deps, sessionId,
|
|
16139
|
-
if (
|
|
16144
|
+
async function readRcSessionFile(deps, sessionId, path54, options) {
|
|
16145
|
+
if (path54 === "") {
|
|
16140
16146
|
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" };
|
|
16141
16147
|
}
|
|
16142
16148
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
16143
16149
|
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" };
|
|
16144
16150
|
}
|
|
16145
16151
|
const requestId = deps.newUuid();
|
|
16146
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
16152
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path54, options), `read ${path54} from session ${sessionId}`);
|
|
16147
16153
|
return result.ok ? { ...result, requestId } : result;
|
|
16148
16154
|
}
|
|
16149
16155
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -16312,11 +16318,11 @@ function createRcControlHandler(deps) {
|
|
|
16312
16318
|
path: "read-file",
|
|
16313
16319
|
read: (body) => {
|
|
16314
16320
|
const session = bodyString(body, "session");
|
|
16315
|
-
const
|
|
16321
|
+
const path54 = bodyString(body, "path");
|
|
16316
16322
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
16317
16323
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
16318
|
-
const refused2 = session === void 0 ||
|
|
16319
|
-
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,
|
|
16324
|
+
const refused2 = session === void 0 || path54 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
16325
|
+
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, path54, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
|
|
16320
16326
|
}
|
|
16321
16327
|
},
|
|
16322
16328
|
{
|
|
@@ -16626,9 +16632,9 @@ function requestIdOfBody(body) {
|
|
|
16626
16632
|
}
|
|
16627
16633
|
function frontDoorRcControl(transport, token) {
|
|
16628
16634
|
const headers = { authorization: `Bearer ${token}` };
|
|
16629
|
-
const listAnswerOf = async (
|
|
16635
|
+
const listAnswerOf = async (path54, what) => {
|
|
16630
16636
|
try {
|
|
16631
|
-
return await transport.request({ method: "GET", path:
|
|
16637
|
+
return await transport.request({ method: "GET", path: path54, headers });
|
|
16632
16638
|
} catch (error) {
|
|
16633
16639
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
16634
16640
|
}
|
|
@@ -16700,10 +16706,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
16700
16706
|
}
|
|
16701
16707
|
return pending;
|
|
16702
16708
|
};
|
|
16703
|
-
const writeOf = async (
|
|
16709
|
+
const writeOf = async (path54, body, describeFailure2) => {
|
|
16704
16710
|
let answer;
|
|
16705
16711
|
try {
|
|
16706
|
-
answer = await transport.request({ method: "POST", path:
|
|
16712
|
+
answer = await transport.request({ method: "POST", path: path54, headers: { ...headers, "content-type": "application/json" }, body });
|
|
16707
16713
|
} catch (error) {
|
|
16708
16714
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
16709
16715
|
}
|
|
@@ -16734,10 +16740,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
16734
16740
|
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}`),
|
|
16735
16741
|
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}`),
|
|
16736
16742
|
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}`),
|
|
16737
|
-
readFile: async (sessionId,
|
|
16743
|
+
readFile: async (sessionId, path54, options) => await writeOf(
|
|
16738
16744
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
16739
|
-
JSON.stringify({ session: sessionId, path:
|
|
16740
|
-
(status, message) => `reading ${
|
|
16745
|
+
JSON.stringify({ session: sessionId, path: path54, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
16746
|
+
(status, message) => `reading ${path54} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
16741
16747
|
),
|
|
16742
16748
|
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}`),
|
|
16743
16749
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -16896,12 +16902,12 @@ function tlsFacts(options) {
|
|
|
16896
16902
|
}
|
|
16897
16903
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
16898
16904
|
const agent = new ExemptTlsAgent();
|
|
16899
|
-
const post = async (
|
|
16905
|
+
const post = async (path54, headers, body) => await new Promise((resolve, reject) => {
|
|
16900
16906
|
const options = {
|
|
16901
16907
|
host: target.host,
|
|
16902
16908
|
port: target.port,
|
|
16903
16909
|
method: "POST",
|
|
16904
|
-
path:
|
|
16910
|
+
path: path54,
|
|
16905
16911
|
// 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.
|
|
16906
16912
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
16907
16913
|
agent
|
|
@@ -16966,12 +16972,12 @@ function lateRcStreamDial(resolve) {
|
|
|
16966
16972
|
}
|
|
16967
16973
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
16968
16974
|
const agent = new ExemptTlsAgent();
|
|
16969
|
-
const request4 = async (method,
|
|
16975
|
+
const request4 = async (method, path54, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
16970
16976
|
const options = {
|
|
16971
16977
|
host: target.host,
|
|
16972
16978
|
port: target.port,
|
|
16973
16979
|
method,
|
|
16974
|
-
path:
|
|
16980
|
+
path: path54,
|
|
16975
16981
|
// 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.
|
|
16976
16982
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
16977
16983
|
agent,
|
|
@@ -17013,9 +17019,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
17013
17019
|
return { status, body: await readAll(response) };
|
|
17014
17020
|
},
|
|
17015
17021
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
17016
|
-
const
|
|
17022
|
+
const path54 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
|
|
17017
17023
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
17018
|
-
const { status, response } = await request4("GET",
|
|
17024
|
+
const { status, response } = await request4("GET", path54, streamHeaders, void 0, signal);
|
|
17019
17025
|
if (!isSuccessful2(status)) {
|
|
17020
17026
|
await readAll(response);
|
|
17021
17027
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -17914,10 +17920,35 @@ init_realPorts();
|
|
|
17914
17920
|
import { createORPCClient as createORPCClient2, ORPCError as ORPCError7 } from "@orpc/client";
|
|
17915
17921
|
import { openapi as openapi8 } from "@orpc/openapi";
|
|
17916
17922
|
|
|
17923
|
+
// src/checkReport.ts
|
|
17924
|
+
init_cliError();
|
|
17925
|
+
import os6 from "node:os";
|
|
17926
|
+
|
|
17927
|
+
// src/codex/categories.ts
|
|
17928
|
+
var CODEX_CATEGORIES = {
|
|
17929
|
+
secret: ["auth.json", "auth.json.*", "*.sqlite*", "*.db*", "identity.json", "cap_sid", "credentials*", "secrets*"],
|
|
17930
|
+
runtime: [".git*", ".DS_Store", "log", "logs", "tmp", "cache", "shell_snapshots", "models_cache.json", "version.json", "packages", "bin", "state", "otel"],
|
|
17931
|
+
history: ["sessions", "archived_sessions", "history.jsonl", "session_index.jsonl", "memories"],
|
|
17932
|
+
knowledge: ["AGENTS.md", "AGENTS.override.md", "skills", "rules", "agents", "prompts"],
|
|
17933
|
+
settings: ["config.toml", "*.config.toml"]
|
|
17934
|
+
};
|
|
17935
|
+
|
|
17936
|
+
// src/codex/identity.ts
|
|
17937
|
+
init_envBool();
|
|
17938
|
+
import path20 from "node:path";
|
|
17939
|
+
var CODEX_AMBIENT_CREDENTIALS = ["OPENAI_API_KEY", "CODEX_API_KEY", "CODEX_ACCESS_TOKEN", "OPENAI_IDENTITY_TOKEN_FILE", "OPENAI_FEDERATION_RULE_ID"];
|
|
17940
|
+
function canonicalCodexHome(env, home) {
|
|
17941
|
+
return path20.resolve(env.AGENT_SHIM_CODEX_HOME === void 0 || env.AGENT_SHIM_CODEX_HOME === "" ? path20.join(home, ".codex") : env.AGENT_SHIM_CODEX_HOME);
|
|
17942
|
+
}
|
|
17943
|
+
function codexCredentialGuard(env, allowAmbientCredential) {
|
|
17944
|
+
const variable = CODEX_AMBIENT_CREDENTIALS.find((key) => (env[key] ?? "") !== "");
|
|
17945
|
+
if (variable === void 0 || allowAmbientCredential || parseEnvBool("AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL", env.AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL) === true) return { ok: true };
|
|
17946
|
+
return { ok: false, variable, message: `Ambient Codex credential variable ${variable} overrides the selected login. Unset it or explicitly allow ambient credentials with AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL=1 or identity set <name> --allow-ambient-credential.` };
|
|
17947
|
+
}
|
|
17948
|
+
|
|
17917
17949
|
// src/checkReport.ts
|
|
17918
17950
|
init_classify();
|
|
17919
17951
|
init_load();
|
|
17920
|
-
import os6 from "node:os";
|
|
17921
17952
|
|
|
17922
17953
|
// src/launchSelection.ts
|
|
17923
17954
|
init_load();
|
|
@@ -18029,7 +18060,7 @@ init_guard();
|
|
|
18029
18060
|
init_providersStore();
|
|
18030
18061
|
init_projects();
|
|
18031
18062
|
init_pipeline();
|
|
18032
|
-
import
|
|
18063
|
+
import path36 from "node:path";
|
|
18033
18064
|
import { z as z24 } from "zod";
|
|
18034
18065
|
var HISTORY_PROJECTS_KEY_PREFIX = "history/projects/";
|
|
18035
18066
|
function projectFragmentOf(rawKey) {
|
|
@@ -18187,6 +18218,7 @@ function buildClaudeVersionReport(params, cascadePin) {
|
|
|
18187
18218
|
};
|
|
18188
18219
|
}
|
|
18189
18220
|
function runCheck(params) {
|
|
18221
|
+
const isCodex = params.agent === "codex" || params.identity?.agent === "codex";
|
|
18190
18222
|
const facts = buildEntryFacts({
|
|
18191
18223
|
fs: params.farmFs,
|
|
18192
18224
|
claudeHome: params.claudeHome,
|
|
@@ -18201,7 +18233,7 @@ function runCheck(params) {
|
|
|
18201
18233
|
const resolved = resolveDecisions({ facts, cascade: params.cascade, classification: params.classification });
|
|
18202
18234
|
const decisionLines = [...resolved.decisions.values()].slice().sort((a, b) => a.relPath < b.relPath ? -1 : a.relPath > b.relPath ? 1 : 0).map(formatDecision);
|
|
18203
18235
|
const projectEncodingAmbiguities = flagAmbiguousEncodings(resolved.flattened, facts);
|
|
18204
|
-
const ambientCredential = evaluateAmbientCredentialGuard({
|
|
18236
|
+
const ambientCredential = isCodex ? codexCredentialGuard(params.env, params.identity?.allowAmbientCredential ?? false) : evaluateAmbientCredentialGuard({
|
|
18205
18237
|
env: params.env,
|
|
18206
18238
|
allowAmbientCredential: params.identity?.allowAmbientCredential ?? false,
|
|
18207
18239
|
allowAmbientCredentialOverride: parseEnvBool("AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL", params.env.AGENT_SHIM_ALLOW_AMBIENT_CREDENTIAL) === true,
|
|
@@ -18209,8 +18241,8 @@ function runCheck(params) {
|
|
|
18209
18241
|
});
|
|
18210
18242
|
const settingsShared = resolved.flattened.categories.get("settings") ?? SHIPPED_CATEGORY_DEFAULTS.settings;
|
|
18211
18243
|
const settingsExposure = inspectSettingsExposure({ settingsShared, files: params.settingsFiles });
|
|
18212
|
-
const keychain = params.platform === "darwin" && params.run !== void 0 && params.farmRoot !== void 0 ? lookupKeychainService(params.run, params.farmRoot) : void 0;
|
|
18213
|
-
const claudeVersion = buildClaudeVersionReport(params, resolved.flattened.launch.claudeVersion);
|
|
18244
|
+
const keychain = !isCodex && params.platform === "darwin" && params.run !== void 0 && params.farmRoot !== void 0 ? lookupKeychainService(params.run, params.farmRoot) : void 0;
|
|
18245
|
+
const claudeVersion = isCodex ? void 0 : buildClaudeVersionReport(params, resolved.flattened.launch.claudeVersion);
|
|
18214
18246
|
return {
|
|
18215
18247
|
...params.identityName === void 0 ? {} : { identityName: params.identityName },
|
|
18216
18248
|
identitySource: params.identitySource,
|
|
@@ -18241,7 +18273,7 @@ function formatCheckReport(report) {
|
|
|
18241
18273
|
}
|
|
18242
18274
|
lines.push("", "Resolved entries:");
|
|
18243
18275
|
if (report.decisionLines.length === 0) {
|
|
18244
|
-
lines.push(" (nothing
|
|
18276
|
+
lines.push(" (nothing in the canonical home to report)");
|
|
18245
18277
|
}
|
|
18246
18278
|
for (const line of report.decisionLines) {
|
|
18247
18279
|
lines.push(` ${line}`);
|
|
@@ -18344,13 +18376,15 @@ function loadCheckProvider(paths, name) {
|
|
|
18344
18376
|
function collectCheckReport(params) {
|
|
18345
18377
|
const { paths, cwd } = params;
|
|
18346
18378
|
const home = os6.homedir();
|
|
18347
|
-
const claudeHome = resolveClaudeHome();
|
|
18348
18379
|
const read = cosmiconfigReader();
|
|
18349
|
-
const classification = loadClassification(paths);
|
|
18350
18380
|
const loaded = loadCascadeInput({ paths, home, cwd, read });
|
|
18351
18381
|
const git = resolveGitBranch(realRunPort, cwd);
|
|
18352
|
-
const { selection, identityConfig } = selectLaunch({ paths, cwd, env: params.env, ...params.identity === void 0 ? {} : { identity: params.identity } }, loaded);
|
|
18382
|
+
const { selection, identityConfig } = selectLaunch({ paths, cwd, env: params.agent === "codex" ? { ...params.env, CLAUDE_CONFIG_DIR: void 0 } : params.env, ...params.identity === void 0 ? {} : { identity: params.identity } }, loaded);
|
|
18353
18383
|
const { identity: identityDecision, poolPick, configProfile: configProfileDecision } = selection;
|
|
18384
|
+
const isCodex = identityConfig?.agent === "codex" || params.agent === "codex";
|
|
18385
|
+
if (identityConfig !== void 0 && params.agent !== void 0 && (identityConfig.agent ?? "claude") !== params.agent) throw new UsageError("The selected identity belongs to a different agent.");
|
|
18386
|
+
const claudeHome = isCodex ? canonicalCodexHome(params.env, home) : resolveClaudeHome();
|
|
18387
|
+
const classification = isCodex ? { defaults: CODEX_CATEGORIES } : loadClassification(paths);
|
|
18354
18388
|
const cascade = loadCascadeInput({
|
|
18355
18389
|
paths,
|
|
18356
18390
|
home,
|
|
@@ -18361,12 +18395,13 @@ function collectCheckReport(params) {
|
|
|
18361
18395
|
const providerName = cascadeProviderName(cascade, identityConfig?.provider);
|
|
18362
18396
|
const provider = providerName === void 0 ? void 0 : loadCheckProvider(paths, providerName);
|
|
18363
18397
|
const identityId = identityDecision.name === void 0 ? void 0 : identityIdOf(paths, identityDecision.name);
|
|
18364
|
-
const farmRoot = identityId === void 0 ? void 0 :
|
|
18365
|
-
const settingsFiles = {
|
|
18366
|
-
"settings.json": realFsPort.readFileUtf8(
|
|
18367
|
-
"settings.local.json": realFsPort.readFileUtf8(
|
|
18398
|
+
const farmRoot = identityId === void 0 ? void 0 : path36.join(paths.identitiesDir, identityId);
|
|
18399
|
+
const settingsFiles = isCodex ? {} : {
|
|
18400
|
+
"settings.json": realFsPort.readFileUtf8(path36.join(claudeHome, "settings.json")),
|
|
18401
|
+
"settings.local.json": realFsPort.readFileUtf8(path36.join(claudeHome, "settings.local.json"))
|
|
18368
18402
|
};
|
|
18369
18403
|
const report = runCheck({
|
|
18404
|
+
...isCodex ? { agent: "codex" } : {},
|
|
18370
18405
|
cwd,
|
|
18371
18406
|
home,
|
|
18372
18407
|
claudeHome,
|
|
@@ -18387,7 +18422,7 @@ function collectCheckReport(params) {
|
|
|
18387
18422
|
settingsFiles,
|
|
18388
18423
|
run: realRunPort,
|
|
18389
18424
|
credentialCache: realCredentialCacheEnv(paths),
|
|
18390
|
-
installedClaudeVersions: realInstalledClaudeVersions(),
|
|
18425
|
+
...isCodex ? {} : { installedClaudeVersions: realInstalledClaudeVersions() },
|
|
18391
18426
|
...farmRoot === void 0 ? {} : { farmRoot },
|
|
18392
18427
|
platform: process.platform,
|
|
18393
18428
|
...provider === void 0 ? {} : { provider }
|
|
@@ -18608,9 +18643,18 @@ var ResetRowSchema = z27.strictObject({
|
|
|
18608
18643
|
var ResetScheduleSchema = z27.strictObject({ resets: z27.readonly(z27.array(ResetRowSchema)) });
|
|
18609
18644
|
|
|
18610
18645
|
// src/frontdoor/controlSchemas.ts
|
|
18611
|
-
import
|
|
18646
|
+
import path42 from "node:path";
|
|
18612
18647
|
import { z as z34 } from "zod";
|
|
18613
18648
|
|
|
18649
|
+
// src/codex/doctor.ts
|
|
18650
|
+
function codexIdentityFindings(entry, identity) {
|
|
18651
|
+
const incompatible = identity.provider !== void 0 || identity.credential !== void 0 || identity.anchors !== void 0;
|
|
18652
|
+
return [
|
|
18653
|
+
{ section: "identity", severity: incompatible ? "fail" : "pass", subject: entry.name, message: incompatible ? `${entry.name} is a Codex identity with Claude-only provider, credential or anchor settings.` : `${entry.name} is a valid Codex identity; its home is ${entry.farmRoot}.` },
|
|
18654
|
+
{ section: "sign-in", severity: "warn", subject: entry.name, message: `Codex login not queried. Run agent-shim run --agent codex @${entry.name} login status to validate its isolated login.` }
|
|
18655
|
+
];
|
|
18656
|
+
}
|
|
18657
|
+
|
|
18614
18658
|
// src/doctorReport.ts
|
|
18615
18659
|
init_claudeShim();
|
|
18616
18660
|
init_readableConfig();
|
|
@@ -18621,13 +18665,13 @@ init_identityRecords();
|
|
|
18621
18665
|
|
|
18622
18666
|
// src/doctorIdentityRecords.ts
|
|
18623
18667
|
init_identityRecords();
|
|
18624
|
-
import
|
|
18668
|
+
import path38 from "node:path";
|
|
18625
18669
|
function identityRecordFindings(records, displaced, nameRenames, strayNameRenameFiles) {
|
|
18626
18670
|
return [
|
|
18627
18671
|
...strayNameRenameFiles.map((file) => ({
|
|
18628
18672
|
severity: "warn",
|
|
18629
18673
|
message: `${file} holds the record of a rename of an identity's name, but not under the file name that rename keeps it in, so nothing reads it or removes it. Remove it.`,
|
|
18630
|
-
subject:
|
|
18674
|
+
subject: path38.basename(file)
|
|
18631
18675
|
})),
|
|
18632
18676
|
...nameRenames.map(({ from, description }) => ({ severity: "fail", message: description, subject: from })),
|
|
18633
18677
|
...duplicateIdentityNames(records).map(({ name, ids }) => ({
|
|
@@ -18652,7 +18696,7 @@ import fs14 from "node:fs";
|
|
|
18652
18696
|
init_blockingSpawn();
|
|
18653
18697
|
init_realPorts();
|
|
18654
18698
|
import fs12 from "node:fs";
|
|
18655
|
-
import
|
|
18699
|
+
import path39 from "node:path";
|
|
18656
18700
|
function realpathOrSelf(target) {
|
|
18657
18701
|
try {
|
|
18658
18702
|
return fs12.realpathSync(target);
|
|
@@ -18663,14 +18707,14 @@ function realpathOrSelf(target) {
|
|
|
18663
18707
|
var MAX_FORWARDING_SCRIPT_BYTES = 8192;
|
|
18664
18708
|
function resolveMiseDispatcher(target, pathDirs, env, trustedExecutable) {
|
|
18665
18709
|
const executable = realpathOrSelf(target);
|
|
18666
|
-
const trustedMise =
|
|
18667
|
-
if (
|
|
18668
|
-
const result = spawnSyncBlocking("a mise shim lookup", executable, ["which",
|
|
18710
|
+
const trustedMise = path39.join(path39.dirname(trustedExecutable), "mise");
|
|
18711
|
+
if (path39.basename(executable) !== "mise" || realpathOrSelf(trustedMise) !== executable) return void 0;
|
|
18712
|
+
const result = spawnSyncBlocking("a mise shim lookup", executable, ["which", path39.basename(target)], { encoding: "utf8", env });
|
|
18669
18713
|
if (result.error !== void 0) return void 0;
|
|
18670
18714
|
if (result.status === 0 && result.stdout.trim() !== "") return result.stdout.trim();
|
|
18671
18715
|
if (!result.stderr.includes("not currently active")) return void 0;
|
|
18672
18716
|
for (const dir of pathDirs) {
|
|
18673
|
-
const candidate = findExecutableInDir(dir,
|
|
18717
|
+
const candidate = findExecutableInDir(dir, path39.basename(target));
|
|
18674
18718
|
if (candidate !== void 0 && realpathOrSelf(candidate) !== executable) {
|
|
18675
18719
|
try {
|
|
18676
18720
|
const script = fs12.statSync(candidate).size <= MAX_FORWARDING_SCRIPT_BYTES ? realFsPort.readFileUtf8(candidate) : void 0;
|
|
@@ -18685,7 +18729,7 @@ function resolveMiseDispatcher(target, pathDirs, env, trustedExecutable) {
|
|
|
18685
18729
|
}
|
|
18686
18730
|
|
|
18687
18731
|
// src/doctorReport.ts
|
|
18688
|
-
import
|
|
18732
|
+
import path41 from "node:path";
|
|
18689
18733
|
init_signIn();
|
|
18690
18734
|
init_identityAccounts();
|
|
18691
18735
|
init_read();
|
|
@@ -19120,7 +19164,7 @@ function tcpPortEraRecord(raw) {
|
|
|
19120
19164
|
return (has("port") || has("lastPort")) && !has("socketPath");
|
|
19121
19165
|
}
|
|
19122
19166
|
function pushPathResolution(push, resolution) {
|
|
19123
|
-
const ownDir =
|
|
19167
|
+
const ownDir = path41.dirname(resolution.ownExecutablePath);
|
|
19124
19168
|
switch (resolution.agentShim.status) {
|
|
19125
19169
|
case "ok":
|
|
19126
19170
|
push("path-resolution", "pass", `\`agent-shim\` on PATH resolves to this running executable, ${resolution.ownExecutablePath}.`, "agent-shim");
|
|
@@ -19240,14 +19284,14 @@ function pushProvider(push, entry, cacheEnv, signIn) {
|
|
|
19240
19284
|
}
|
|
19241
19285
|
function pushLegacyName(push, params) {
|
|
19242
19286
|
const legacyVariables = Object.keys(params.env).filter((name) => name.startsWith(LEGACY_ENV_PREFIX) && params.env[name] !== void 0).sort();
|
|
19243
|
-
if (legacyVariables.length === 0 &&
|
|
19287
|
+
if (legacyVariables.length === 0 && path41.basename(params.rootPath) !== LEGACY_HOME_DIRNAME) {
|
|
19244
19288
|
push("legacy-name", "pass", "Nothing here still uses the former `claude-use` name.");
|
|
19245
19289
|
return;
|
|
19246
19290
|
}
|
|
19247
19291
|
for (const name of legacyVariables) {
|
|
19248
19292
|
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);
|
|
19249
19293
|
}
|
|
19250
|
-
if (
|
|
19294
|
+
if (path41.basename(params.rootPath) === LEGACY_HOME_DIRNAME) {
|
|
19251
19295
|
push(
|
|
19252
19296
|
"legacy-name",
|
|
19253
19297
|
"warn",
|
|
@@ -19341,9 +19385,9 @@ function runDoctor(params) {
|
|
|
19341
19385
|
push("identity", "warn", `identities/${name} cannot be reached (${code}), so it is not counted as an identity. Repair the permissions of the directory or of what a symlink points through, or remove the entry.`, name);
|
|
19342
19386
|
}
|
|
19343
19387
|
for (const { file, detail } of params.renameJournals?.unreadable ?? []) {
|
|
19344
|
-
push("identity", "fail", `${file} is not a rename journal this agent-shim can read (${detail}), so no identity can be renamed until it is fixed or removed, and it may be the trace of a rename that was left unfinished.`,
|
|
19388
|
+
push("identity", "fail", `${file} is not a rename journal this agent-shim can read (${detail}), so no identity can be renamed until it is fixed or removed, and it may be the trace of a rename that was left unfinished.`, path41.basename(file));
|
|
19345
19389
|
}
|
|
19346
|
-
const
|
|
19390
|
+
const validIdentityAgents = /* @__PURE__ */ new Map();
|
|
19347
19391
|
const signedInAccounts = [];
|
|
19348
19392
|
for (const entry of params.identities) {
|
|
19349
19393
|
const validated3 = validate(IdentitySchema, entry, "identity", entry.name);
|
|
@@ -19351,7 +19395,7 @@ function runDoctor(params) {
|
|
|
19351
19395
|
push("identity", "fail", validated3.message, entry.name);
|
|
19352
19396
|
continue;
|
|
19353
19397
|
}
|
|
19354
|
-
|
|
19398
|
+
validIdentityAgents.set(entry.name, validated3.data.agent ?? "claude");
|
|
19355
19399
|
const defaultProfile = validated3.data.defaultConfigProfile;
|
|
19356
19400
|
let consistent = true;
|
|
19357
19401
|
if (defaultProfile !== void 0 && !validProfileNames.has(defaultProfile)) {
|
|
@@ -19371,6 +19415,10 @@ function runDoctor(params) {
|
|
|
19371
19415
|
if (!consistent) {
|
|
19372
19416
|
continue;
|
|
19373
19417
|
}
|
|
19418
|
+
if (validated3.data.agent === "codex") {
|
|
19419
|
+
findings.push(...codexIdentityFindings(entry, validated3.data));
|
|
19420
|
+
continue;
|
|
19421
|
+
}
|
|
19374
19422
|
const credential = validated3.data.credential;
|
|
19375
19423
|
const cache = credential === void 0 ? { text: "", unreadable: false } : cacheClause(params.credentialCache, identityCacheKey(entry.id), credential);
|
|
19376
19424
|
const authenticatesWith = credential !== void 0 ? `credential ${describeCredential(credential)}` : identityProvider !== void 0 ? `the credential of provider "${identityProvider}"` : "its stored login";
|
|
@@ -19409,9 +19457,9 @@ function runDoctor(params) {
|
|
|
19409
19457
|
}
|
|
19410
19458
|
const validatedGlobalConfig = params.globalConfig.raw === void 0 ? void 0 : validateJson(GlobalConfigSchema, params.globalConfig);
|
|
19411
19459
|
const pools = validatedGlobalConfig?.ok === true ? validatedGlobalConfig.data.pools ?? {} : {};
|
|
19412
|
-
const accountByIdentity = new Map(params.identities.flatMap((entry) =>
|
|
19460
|
+
const accountByIdentity = new Map(params.identities.flatMap((entry) => validIdentityAgents.has(entry.name) && entry.account !== void 0 ? [[entry.name, entry.account]] : []));
|
|
19413
19461
|
for (const [poolName, pool] of Object.entries(pools)) {
|
|
19414
|
-
const missing = pool.identities.filter((member) => poolNameOf(poolMemberIdentity(member)) === void 0 && !
|
|
19462
|
+
const missing = pool.identities.filter((member) => poolNameOf(poolMemberIdentity(member)) === void 0 && !validIdentityAgents.has(poolMemberIdentity(member)));
|
|
19415
19463
|
const undefinedPools = pool.identities.flatMap((member) => {
|
|
19416
19464
|
const nested = poolNameOf(poolMemberIdentity(member));
|
|
19417
19465
|
return nested === void 0 || nested in pools ? [] : [nested];
|
|
@@ -19455,7 +19503,7 @@ function runDoctor(params) {
|
|
|
19455
19503
|
}
|
|
19456
19504
|
const selectionExists = (selector) => {
|
|
19457
19505
|
const poolName = poolNameOf(selector);
|
|
19458
|
-
return poolName === void 0 ?
|
|
19506
|
+
return poolName === void 0 ? validIdentityAgents.has(selector) : poolName in pools;
|
|
19459
19507
|
};
|
|
19460
19508
|
for (const entry of params.providers) {
|
|
19461
19509
|
if (!pushNameFinding(push, "provider", "provider", entry)) {
|
|
@@ -19471,6 +19519,7 @@ function runDoctor(params) {
|
|
|
19471
19519
|
push("keychain", "pass", "Skipped (not macOS).");
|
|
19472
19520
|
} else {
|
|
19473
19521
|
for (const entry of params.identities) {
|
|
19522
|
+
if (validIdentityAgents.get(entry.name) === "codex") continue;
|
|
19474
19523
|
const result = lookupKeychainService(params.run, entry.farmRoot);
|
|
19475
19524
|
push("keychain", "pass", result.found ? result.note : `${result.note} The sign-in section reports whether a login is stored elsewhere.`, entry.name);
|
|
19476
19525
|
}
|
|
@@ -19701,9 +19750,9 @@ function collectDoctorReport(params) {
|
|
|
19701
19750
|
const { names: identityNames, unreachable: unreachableIdentities } = listIdentityDirectories(paths);
|
|
19702
19751
|
const records = identityRecords(paths);
|
|
19703
19752
|
const displacedIdentities = records.filter((record) => !identityIdExists(paths, record.id) && !unreachableIdentities.some((entry) => entry.name === record.id));
|
|
19704
|
-
const identities = identityNames.filter((id) => (records.some((record) => record.id === id) || !fs14.existsSync(
|
|
19705
|
-
const farmRoot =
|
|
19706
|
-
const identityPath =
|
|
19753
|
+
const identities = identityNames.filter((id) => (records.some((record) => record.id === id) || !fs14.existsSync(path41.join(paths.identitiesDir, id, "identity.json"))) && !displacedIdentities.some((record) => record.id === id)).map((id) => {
|
|
19754
|
+
const farmRoot = path41.join(paths.identitiesDir, id);
|
|
19755
|
+
const identityPath = path41.join(farmRoot, "identity.json");
|
|
19707
19756
|
return { name: identityNameIn(records, id) ?? id, id, path: identityPath, raw: realFsPort.readFileUtf8(identityPath), farmRoot, credentialsFilePresent: fs14.existsSync(credentialsFilePath(farmRoot)), account: readIdentityAccount(realFsPort, paths.identitiesDir, id)?.account };
|
|
19708
19757
|
});
|
|
19709
19758
|
const usageSnapshots = {};
|
|
@@ -19721,12 +19770,12 @@ function collectDoctorReport(params) {
|
|
|
19721
19770
|
}
|
|
19722
19771
|
const profileNames = fs14.existsSync(paths.configProfilesDir) ? fs14.readdirSync(paths.configProfilesDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
19723
19772
|
const configProfiles = profileNames.map((name) => {
|
|
19724
|
-
const profilePath =
|
|
19773
|
+
const profilePath = path41.join(paths.configProfilesDir, `${name}.json`);
|
|
19725
19774
|
return { name, path: profilePath, raw: realFsPort.readFileUtf8(profilePath) };
|
|
19726
19775
|
});
|
|
19727
19776
|
const providerNames = fs14.existsSync(paths.providersDir) ? fs14.readdirSync(paths.providersDir, { withFileTypes: true }).filter((entry) => entry.isFile() && entry.name.endsWith(".json")).map((entry) => entry.name.slice(0, -".json".length)).sort() : [];
|
|
19728
19777
|
const providers = providerNames.map((name) => {
|
|
19729
|
-
const providerPath =
|
|
19778
|
+
const providerPath = path41.join(paths.providersDir, `${name}.json`);
|
|
19730
19779
|
return { name, path: providerPath, raw: realFsPort.readFileUtf8(providerPath) };
|
|
19731
19780
|
});
|
|
19732
19781
|
const ownExecutablePath = realOwnExecutablePath();
|
|
@@ -19738,12 +19787,12 @@ function collectDoctorReport(params) {
|
|
|
19738
19787
|
binaryDiscovery = { ok: false, message: error instanceof Error ? error.message : String(error) };
|
|
19739
19788
|
}
|
|
19740
19789
|
const shimState = readJson(paths.claudeShimFile, ClaudeShimStateSchema);
|
|
19741
|
-
const pathDirs = (params.env.PATH ?? "").split(
|
|
19790
|
+
const pathDirs = (params.env.PATH ?? "").split(path41.delimiter).filter((dir) => dir !== "");
|
|
19742
19791
|
const claudeShimShadow = shimState === void 0 ? void 0 : refinePathShadow(
|
|
19743
19792
|
findPathShadow({
|
|
19744
19793
|
pathDirs,
|
|
19745
|
-
targetDir:
|
|
19746
|
-
targetFilename:
|
|
19794
|
+
targetDir: path41.dirname(shimState.targetPath),
|
|
19795
|
+
targetFilename: path41.basename(shimState.targetPath),
|
|
19747
19796
|
findExecutableInDir
|
|
19748
19797
|
}),
|
|
19749
19798
|
shimState.targetPath,
|
|
@@ -19769,7 +19818,7 @@ function collectDoctorReport(params) {
|
|
|
19769
19818
|
providerAliases: readProviderAliases(paths),
|
|
19770
19819
|
renameJournals: listRenameJournals(realFarmFs, paths.identityRenamesDir),
|
|
19771
19820
|
unreachableIdentities,
|
|
19772
|
-
identityRecords: { all: records, displaced: displacedIdentities.map((record) => ({ ...record, directoryPresent: fs14.existsSync(
|
|
19821
|
+
identityRecords: { all: records, displaced: displacedIdentities.map((record) => ({ ...record, directoryPresent: fs14.existsSync(path41.join(paths.identitiesDir, record.id)) })), nameRenames: unfinishedNameRenames(paths).map((record) => ({ from: record.from, description: describeInterruptedNameRename(paths, record) })), strayNameRenameFiles: strayNameRenameRecordFiles(paths) },
|
|
19773
19822
|
directoryRules: { path: paths.directoryRulesFile, raw: realFsPort.readFileUtf8(paths.directoryRulesFile) },
|
|
19774
19823
|
globalConfig: { path: paths.globalConfigFile, raw: realFsPort.readFileUtf8(paths.globalConfigFile) },
|
|
19775
19824
|
models: readableOr(() => readGlobalConfig(paths)?.models, void 0),
|
|
@@ -19784,7 +19833,7 @@ function collectDoctorReport(params) {
|
|
|
19784
19833
|
agentShim: refinePathShadow(
|
|
19785
19834
|
findPathShadow({
|
|
19786
19835
|
pathDirs,
|
|
19787
|
-
targetDir:
|
|
19836
|
+
targetDir: path41.dirname(ownExecutablePath),
|
|
19788
19837
|
targetFilename: commandFilename(ownExecutablePath, "agent-shim"),
|
|
19789
19838
|
findExecutableInDir
|
|
19790
19839
|
}),
|
|
@@ -19875,11 +19924,11 @@ var FrontDoorSessionsOutputSchema = z34.strictObject({ sessions: z34.readonly(z3
|
|
|
19875
19924
|
var CheckRunInputSchema = z34.strictObject({
|
|
19876
19925
|
path: z34.string().min(1),
|
|
19877
19926
|
identity: z34.string().min(1).optional()
|
|
19878
|
-
}).refine((input) =>
|
|
19927
|
+
}).refine((input) => path42.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
19879
19928
|
var PoolPickInputSchema = z34.strictObject({
|
|
19880
19929
|
pool: z34.string().min(1),
|
|
19881
19930
|
path: z34.string().min(1)
|
|
19882
|
-
}).refine((input) =>
|
|
19931
|
+
}).refine((input) => path42.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
19883
19932
|
var DoctorFindingSchema = z34.strictObject({
|
|
19884
19933
|
section: z34.enum(DOCTOR_SECTIONS),
|
|
19885
19934
|
subject: z34.string().optional(),
|
|
@@ -20215,7 +20264,7 @@ function profileValue(name, paths) {
|
|
|
20215
20264
|
function createConfigApiRouter(deps) {
|
|
20216
20265
|
const authed = doorApiAuth(deps.expectedToken);
|
|
20217
20266
|
const { paths } = deps;
|
|
20218
|
-
const route = (
|
|
20267
|
+
const route = (path54, summary) => authed.meta(openapi3({ method: "POST", path: path54, summary, tags: [CONFIG_API_TAG] }));
|
|
20219
20268
|
return {
|
|
20220
20269
|
config: {
|
|
20221
20270
|
identity: {
|
|
@@ -20617,7 +20666,7 @@ import { ORPCError as ORPCError5 } from "@orpc/client";
|
|
|
20617
20666
|
import { openapi as openapi6 } from "@orpc/openapi";
|
|
20618
20667
|
|
|
20619
20668
|
// src/frontdoor/launchSchemas.ts
|
|
20620
|
-
import
|
|
20669
|
+
import path43 from "node:path";
|
|
20621
20670
|
import { z as z38 } from "zod";
|
|
20622
20671
|
init_statusline();
|
|
20623
20672
|
init_claudeVersion();
|
|
@@ -20628,7 +20677,7 @@ var LaunchResolveInputSchema = z38.strictObject({
|
|
|
20628
20677
|
argv: z38.readonly(z38.array(z38.string())).optional(),
|
|
20629
20678
|
/** 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. */
|
|
20630
20679
|
env: z38.record(z38.string(), z38.string()).optional()
|
|
20631
|
-
}).refine((input) =>
|
|
20680
|
+
}).refine((input) => path43.isAbsolute(input.path), { message: "path must be absolute: the door cannot resolve a relative path against the caller's working directory" });
|
|
20632
20681
|
var LaunchPoolDecisionSchema = z38.strictObject({
|
|
20633
20682
|
name: z38.string(),
|
|
20634
20683
|
reasons: z38.readonly(z38.array(z38.string())),
|
|
@@ -22811,7 +22860,7 @@ data: ${JSON.stringify(envelope)}
|
|
|
22811
22860
|
// src/frontdoor/rcSelfHostMint.ts
|
|
22812
22861
|
init_identityRecords();
|
|
22813
22862
|
init_account();
|
|
22814
|
-
import
|
|
22863
|
+
import path44 from "node:path";
|
|
22815
22864
|
var CREDENTIALS_FILE2 = ".credentials.json";
|
|
22816
22865
|
var CLAUDE_JSON2 = ".claude.json";
|
|
22817
22866
|
var RC_SELF_HOST_RECORD_DIR = "rc-selfhost";
|
|
@@ -22835,7 +22884,7 @@ function readJsonObject(fs17, file) {
|
|
|
22835
22884
|
return isRecord14(parsed) ? parsed : void 0;
|
|
22836
22885
|
}
|
|
22837
22886
|
function readRcSelfHostRecord(fs17, frontdoorDir) {
|
|
22838
|
-
const parsed = readJsonObject(fs17,
|
|
22887
|
+
const parsed = readJsonObject(fs17, path44.join(frontdoorDir, RC_SELF_HOST_RECORD_DIR, RC_SELF_HOST_RECORD_FILE));
|
|
22839
22888
|
if (parsed === void 0) {
|
|
22840
22889
|
return void 0;
|
|
22841
22890
|
}
|
|
@@ -22853,11 +22902,11 @@ function mintRcSelfHostCredential(deps) {
|
|
|
22853
22902
|
if (id === void 0) {
|
|
22854
22903
|
throw new Error(`No identity named "${deps.identity}".`);
|
|
22855
22904
|
}
|
|
22856
|
-
const identityDir =
|
|
22857
|
-
const credentialsFile =
|
|
22858
|
-
const claudeJsonFile =
|
|
22859
|
-
const recordDir =
|
|
22860
|
-
const recordFile2 =
|
|
22905
|
+
const identityDir = path44.join(deps.identitiesDir, id);
|
|
22906
|
+
const credentialsFile = path44.join(identityDir, CREDENTIALS_FILE2);
|
|
22907
|
+
const claudeJsonFile = path44.join(identityDir, CLAUDE_JSON2);
|
|
22908
|
+
const recordDir = path44.join(deps.frontdoorDir, RC_SELF_HOST_RECORD_DIR);
|
|
22909
|
+
const recordFile2 = path44.join(recordDir, RC_SELF_HOST_RECORD_FILE);
|
|
22861
22910
|
const previousRecord = readRcSelfHostRecord(deps.fs, deps.frontdoorDir);
|
|
22862
22911
|
const existingCredentials = readJsonObject(deps.fs, credentialsFile);
|
|
22863
22912
|
const existingOauth = isRecord14(existingCredentials?.claudeAiOauth) ? existingCredentials.claudeAiOauth : void 0;
|
|
@@ -22873,7 +22922,7 @@ function mintRcSelfHostCredential(deps) {
|
|
|
22873
22922
|
const organizationUuid = deps.newUuid();
|
|
22874
22923
|
const accountUuid = deps.newUuid();
|
|
22875
22924
|
const mintedAt = new Date(deps.now()).toISOString();
|
|
22876
|
-
deps.fs.mkdirPrivate(
|
|
22925
|
+
deps.fs.mkdirPrivate(path44.dirname(credentialsFile));
|
|
22877
22926
|
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)}
|
|
22878
22927
|
`);
|
|
22879
22928
|
const claudeJson = readJsonObject(deps.fs, claudeJsonFile) ?? {};
|
|
@@ -22911,7 +22960,7 @@ init_ensure2();
|
|
|
22911
22960
|
// src/frontdoor/liveSessionRegistry.ts
|
|
22912
22961
|
init_capability();
|
|
22913
22962
|
init_state();
|
|
22914
|
-
import
|
|
22963
|
+
import path45 from "node:path";
|
|
22915
22964
|
function sameStat(recorded, current) {
|
|
22916
22965
|
return recorded?.mtimeMs === current.mtimeMs && recorded.sizeBytes === current.sizeBytes;
|
|
22917
22966
|
}
|
|
@@ -22929,7 +22978,7 @@ function createLiveSessionRegistry(ports) {
|
|
|
22929
22978
|
const load = (name, stat) => {
|
|
22930
22979
|
known.set(name, { stat: { mtimeMs: stat.mtimeMs, sizeBytes: stat.sizeBytes }, record: readFrontDoorSessionRecord(fs17, sessionsDir, name) });
|
|
22931
22980
|
};
|
|
22932
|
-
const statOf = (name) => fs17.lstat(
|
|
22981
|
+
const statOf = (name) => fs17.lstat(path45.join(sessionsDir, name));
|
|
22933
22982
|
const reconcile = () => {
|
|
22934
22983
|
const names = new Set(recordNames());
|
|
22935
22984
|
let changed = false;
|
|
@@ -22996,7 +23045,7 @@ init_plan2();
|
|
|
22996
23045
|
init_poolPick();
|
|
22997
23046
|
|
|
22998
23047
|
// src/agents/read.ts
|
|
22999
|
-
import
|
|
23048
|
+
import path46 from "node:path";
|
|
23000
23049
|
import { z as z40 } from "zod";
|
|
23001
23050
|
var PROJECTS_DIR = "projects";
|
|
23002
23051
|
var TASKS_DIR = "tasks";
|
|
@@ -23022,15 +23071,15 @@ function parseEntry2(project, entry) {
|
|
|
23022
23071
|
}
|
|
23023
23072
|
function listSessions2(fs17, configDir) {
|
|
23024
23073
|
const found = [];
|
|
23025
|
-
for (const project of fs17.readdir(
|
|
23026
|
-
const projectDir =
|
|
23074
|
+
for (const project of fs17.readdir(path46.join(configDir, PROJECTS_DIR))) {
|
|
23075
|
+
const projectDir = path46.join(configDir, PROJECTS_DIR, project);
|
|
23027
23076
|
const entries = /* @__PURE__ */ new Set();
|
|
23028
23077
|
for (const name of fs17.readdir(projectDir)) {
|
|
23029
23078
|
if (name.endsWith(TRANSCRIPT_SUFFIX)) {
|
|
23030
23079
|
entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
|
|
23031
23080
|
continue;
|
|
23032
23081
|
}
|
|
23033
|
-
const children = fs17.readdir(
|
|
23082
|
+
const children = fs17.readdir(path46.join(projectDir, name));
|
|
23034
23083
|
if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
|
|
23035
23084
|
entries.add(name);
|
|
23036
23085
|
}
|
|
@@ -23050,8 +23099,8 @@ function locateAgents(fs17, configDir, relativeDir, workflowRunId, report) {
|
|
|
23050
23099
|
const id = name.slice(AGENT_FILE_PREFIX.length, -META_SUFFIX.length);
|
|
23051
23100
|
located.push({
|
|
23052
23101
|
id,
|
|
23053
|
-
metaPath:
|
|
23054
|
-
transcriptPath:
|
|
23102
|
+
metaPath: path46.join(relativeDir, name),
|
|
23103
|
+
transcriptPath: path46.join(relativeDir, `${AGENT_FILE_PREFIX}${id}${TRANSCRIPT_SUFFIX}`),
|
|
23055
23104
|
workflowRunId
|
|
23056
23105
|
});
|
|
23057
23106
|
}
|
|
@@ -23094,7 +23143,7 @@ function describeFailure(error) {
|
|
|
23094
23143
|
}
|
|
23095
23144
|
function readFileOrReport(fs17, configDir, relative, report) {
|
|
23096
23145
|
try {
|
|
23097
|
-
return fs17.readFileUtf8(
|
|
23146
|
+
return fs17.readFileUtf8(path46.join(configDir, relative));
|
|
23098
23147
|
} catch (error) {
|
|
23099
23148
|
report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
|
|
23100
23149
|
return void 0;
|
|
@@ -23102,7 +23151,7 @@ function readFileOrReport(fs17, configDir, relative, report) {
|
|
|
23102
23151
|
}
|
|
23103
23152
|
function listDirOrReport(fs17, configDir, relative, report) {
|
|
23104
23153
|
try {
|
|
23105
|
-
return fs17.readdir(
|
|
23154
|
+
return fs17.readdir(path46.join(configDir, relative));
|
|
23106
23155
|
} catch (error) {
|
|
23107
23156
|
report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
|
|
23108
23157
|
return [];
|
|
@@ -23126,18 +23175,18 @@ var WorkflowRunFileSchema = z40.object({
|
|
|
23126
23175
|
summary: z40.string().optional()
|
|
23127
23176
|
});
|
|
23128
23177
|
function summariseSession(fs17, configDir, ref) {
|
|
23129
|
-
const sessionRelative =
|
|
23130
|
-
const subagentsRelative =
|
|
23131
|
-
const workflowsUnderSubagents =
|
|
23178
|
+
const sessionRelative = path46.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
23179
|
+
const subagentsRelative = path46.join(sessionRelative, SUBAGENTS_DIR);
|
|
23180
|
+
const workflowsUnderSubagents = path46.join(subagentsRelative, WORKFLOWS_DIR);
|
|
23132
23181
|
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
23133
|
-
let agentCount = fs17.readdir(
|
|
23134
|
-
for (const runDir of fs17.readdir(
|
|
23182
|
+
let agentCount = fs17.readdir(path46.join(configDir, subagentsRelative)).filter(isMeta).length;
|
|
23183
|
+
for (const runDir of fs17.readdir(path46.join(configDir, workflowsUnderSubagents))) {
|
|
23135
23184
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
23136
|
-
agentCount += fs17.readdir(
|
|
23185
|
+
agentCount += fs17.readdir(path46.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
23137
23186
|
}
|
|
23138
23187
|
}
|
|
23139
|
-
const workflowRunCount = fs17.readdir(
|
|
23140
|
-
const transcript = fs17.lstat(
|
|
23188
|
+
const workflowRunCount = fs17.readdir(path46.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
|
|
23189
|
+
const transcript = fs17.lstat(path46.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
|
|
23141
23190
|
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
23142
23191
|
}
|
|
23143
23192
|
function readSessionAgentTree(fs17, configDir, ref, options = {}) {
|
|
@@ -23145,13 +23194,13 @@ function readSessionAgentTree(fs17, configDir, ref, options = {}) {
|
|
|
23145
23194
|
const report = (problem) => {
|
|
23146
23195
|
problems.push(problem);
|
|
23147
23196
|
};
|
|
23148
|
-
const sessionRelative =
|
|
23149
|
-
const subagentsRelative =
|
|
23150
|
-
const workflowsUnderSubagents =
|
|
23197
|
+
const sessionRelative = path46.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
23198
|
+
const subagentsRelative = path46.join(sessionRelative, SUBAGENTS_DIR);
|
|
23199
|
+
const workflowsUnderSubagents = path46.join(subagentsRelative, WORKFLOWS_DIR);
|
|
23151
23200
|
const located = locateAgents(fs17, configDir, subagentsRelative, void 0, report);
|
|
23152
23201
|
for (const runDir of listDirOrReport(fs17, configDir, workflowsUnderSubagents, report)) {
|
|
23153
23202
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
23154
|
-
located.push(...locateAgents(fs17, configDir,
|
|
23203
|
+
located.push(...locateAgents(fs17, configDir, path46.join(workflowsUnderSubagents, runDir), runDir, report));
|
|
23155
23204
|
}
|
|
23156
23205
|
}
|
|
23157
23206
|
const agents = /* @__PURE__ */ new Map();
|
|
@@ -23192,7 +23241,7 @@ function readSessionAgentTree(fs17, configDir, ref, options = {}) {
|
|
|
23192
23241
|
superseded: ref.superseded,
|
|
23193
23242
|
agents: roots.sort().map(build),
|
|
23194
23243
|
tasks: readTasks(fs17, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
|
|
23195
|
-
workflowRuns: readWorkflowRuns(fs17, configDir,
|
|
23244
|
+
workflowRuns: readWorkflowRuns(fs17, configDir, path46.join(sessionRelative, WORKFLOWS_DIR), report),
|
|
23196
23245
|
problems
|
|
23197
23246
|
};
|
|
23198
23247
|
}
|
|
@@ -23257,12 +23306,12 @@ function ownTaskLists(sessionId) {
|
|
|
23257
23306
|
function readTasks(fs17, configDir, ownLists, sharedLists, report) {
|
|
23258
23307
|
const tasks = [];
|
|
23259
23308
|
[...ownLists, ...sharedLists].forEach((scope, index) => {
|
|
23260
|
-
const relativeDir =
|
|
23309
|
+
const relativeDir = path46.join(TASKS_DIR, scope);
|
|
23261
23310
|
for (const name of [...listDirOrReport(fs17, configDir, relativeDir, report)].sort()) {
|
|
23262
23311
|
if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
|
|
23263
23312
|
continue;
|
|
23264
23313
|
}
|
|
23265
|
-
const relative =
|
|
23314
|
+
const relative = path46.join(relativeDir, name);
|
|
23266
23315
|
const text = readFileOrReport(fs17, configDir, relative, report);
|
|
23267
23316
|
const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
23268
23317
|
if (parsed.success) {
|
|
@@ -23280,7 +23329,7 @@ function readWorkflowRuns(fs17, configDir, relativeDir, report) {
|
|
|
23280
23329
|
if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
|
|
23281
23330
|
continue;
|
|
23282
23331
|
}
|
|
23283
|
-
const relative =
|
|
23332
|
+
const relative = path46.join(relativeDir, name);
|
|
23284
23333
|
const text = readFileOrReport(fs17, configDir, relative, report);
|
|
23285
23334
|
const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
23286
23335
|
if (!parsed.success) {
|
|
@@ -23297,7 +23346,7 @@ function readWorkflowRuns(fs17, configDir, relativeDir, report) {
|
|
|
23297
23346
|
|
|
23298
23347
|
// src/agents/sessions.ts
|
|
23299
23348
|
init_cliError();
|
|
23300
|
-
import
|
|
23349
|
+
import path47 from "node:path";
|
|
23301
23350
|
var SessionLookupError = class extends CliError {
|
|
23302
23351
|
constructor(message) {
|
|
23303
23352
|
super(message);
|
|
@@ -23308,7 +23357,7 @@ function historyStores(fs17, configDirOf, identities) {
|
|
|
23308
23357
|
const byRealPath = /* @__PURE__ */ new Map();
|
|
23309
23358
|
for (const identity of identities) {
|
|
23310
23359
|
const configDir = configDirOf(identity);
|
|
23311
|
-
const real = fs17.realpath(
|
|
23360
|
+
const real = fs17.realpath(path47.join(configDir, "projects"));
|
|
23312
23361
|
if (real === void 0) {
|
|
23313
23362
|
continue;
|
|
23314
23363
|
}
|