claude-use 11.64.1 → 11.65.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +888 -553
- package/dist/index.cjs +264 -129
- package/dist/index.mjs +257 -124
- package/dist/types/index.d.ts +1605 -886
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -229,18 +229,24 @@ var init_names = __esm({
|
|
|
229
229
|
function drawsNothing(text) {
|
|
230
230
|
return (0, import_string_width.default)(text.replace(BLANK_CELLS, "")) === 0;
|
|
231
231
|
}
|
|
232
|
-
var import_string_width, BLANK_CELLS;
|
|
232
|
+
var import_string_width, BLANK_CELLS, BLANK_CELLS_BUT_SPACE;
|
|
233
233
|
var init_blank = __esm({
|
|
234
234
|
"src/statusline/blank.ts"() {
|
|
235
235
|
"use strict";
|
|
236
236
|
import_string_width = __toESM(require("string-width"), 1);
|
|
237
237
|
BLANK_CELLS = /[\p{Zs}\u2800\u3164\uFFA0]/gu;
|
|
238
|
+
BLANK_CELLS_BUT_SPACE = new RegExp(`[${BLANK_CELLS.source}--[ ]]`, "gv");
|
|
238
239
|
}
|
|
239
240
|
});
|
|
240
241
|
|
|
241
242
|
// src/statusline/graphemes.ts
|
|
243
|
+
function* graphemeStream(text) {
|
|
244
|
+
for (const part of SEGMENTER.segment(text)) {
|
|
245
|
+
yield part.segment;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
242
248
|
function graphemesOf(text) {
|
|
243
|
-
return Array.from(
|
|
249
|
+
return Array.from(graphemeStream(text));
|
|
244
250
|
}
|
|
245
251
|
var SEGMENTER;
|
|
246
252
|
var init_graphemes = __esm({
|
|
@@ -318,7 +324,7 @@ function resolveStatusline(settings) {
|
|
|
318
324
|
}
|
|
319
325
|
return resolved;
|
|
320
326
|
}
|
|
321
|
-
var import_string_width2, import_zod2, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PRESETS, GIT_WITH_DIRTY_MARKER, JJ_OFF, PRESET_BUNDLES, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MIN_STATUSLINE_COLUMNS, MAX_STATUSLINE_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, LABEL_RE2, OPTIONAL_LABEL_RE, mergeGroups, colourValue, barCharacter, STATUSLINE_CONTEXT_VALUES, STATUSLINE_CONTEXT_ESTIMATES, AUTOCOMPACT_RESERVE_FRACTION, AUTOCOMPACT_RESERVE_RAMP_START, AUTOCOMPACT_RESERVE_RAMP_END, labelWithinColumns, labelWithinColumnsMessage, labelShowsSomething, labelShowsSomethingMessage, labelIsPlainText, labelIsPlainTextMessage, windowLabel, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, LANGUAGE_DESCRIPTION, LANGUAGE_TAGS, LANGUAGE_ALIASES, TOP_LEVEL, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
327
|
+
var import_string_width2, import_zod2, STATUSLINE_HEADER_SEGMENTS, STATUSLINE_ROWS, STATUSLINE_SESSION_TIME_PARTS, PROMPT_CACHE_TTL_SECONDS, ORANGE_PALETTE_INDEX, STATUSLINE_COLOUR_NAMES, DEFAULT_HEADER_SEGMENTS, DEFAULT_ROWS, STATUSLINE_PRESETS, GIT_WITH_DIRTY_MARKER, JJ_OFF, PRESET_BUNDLES, STATUSLINE_PATH_LEVELS, STATUSLINE_USAGE_VALUES, STATUSLINE_TIME_FORMATS, STATUSLINE_HOUR_CYCLES, MAX_PERCENT, MAX_STATUSLINE_PALETTE_INDEX, MAX_STATUSLINE_LABEL_COLUMNS, MIN_STATUSLINE_COLUMNS, MAX_STATUSLINE_COLUMNS, MAX_BAR_CELLS, MAX_ACCOUNT_USER_CHARS, MAX_DISPLAY_TEXT_CHARS, MAX_EXTRA_COMMAND_ARGUMENTS, MAX_EXTRA_COMMAND_ARGUMENT_CHARS, STATUSLINE_EXTRA_GROUP, commandArgument, LABEL_RE2, OPTIONAL_LABEL_RE, mergeGroups, colourValue, barCharacter, STATUSLINE_CONTEXT_VALUES, STATUSLINE_CONTEXT_ESTIMATES, AUTOCOMPACT_RESERVE_FRACTION, AUTOCOMPACT_RESERVE_RAMP_START, AUTOCOMPACT_RESERVE_RAMP_END, labelWithinColumns, labelWithinColumnsMessage, labelShowsSomething, labelShowsSomethingMessage, labelIsPlainText, labelIsPlainTextMessage, windowLabel, overrideText, wholePercent, thresholdPercent, SHAPES, UNSET_NOTE, LANGUAGE_DESCRIPTION, LANGUAGE_TAGS, LANGUAGE_ALIASES, TOP_LEVEL, StatuslineSchema, ResolvedStatuslineSchema, STATUSLINE_DEFAULTS, STATUSLINE_ENV;
|
|
322
328
|
var init_statusline = __esm({
|
|
323
329
|
"src/config/statusline.ts"() {
|
|
324
330
|
"use strict";
|
|
@@ -327,10 +333,11 @@ var init_statusline = __esm({
|
|
|
327
333
|
init_blank();
|
|
328
334
|
init_graphemes();
|
|
329
335
|
init_languages();
|
|
330
|
-
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "dailyCost", "sessionName", "duration", "speed"];
|
|
336
|
+
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "dailyCost", "sessionName", "duration", "speed", "extra"];
|
|
331
337
|
STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles", "memory", "environment", "sessionTime", "promptCache", "compactions", "tokens", "tools", "skills", "mcp", "agents", "todos"];
|
|
332
338
|
STATUSLINE_SESSION_TIME_PARTS = ["started", "lastReply"];
|
|
333
339
|
PROMPT_CACHE_TTL_SECONDS = { fiveMinutes: 300, oneHour: 3600 };
|
|
340
|
+
ORANGE_PALETTE_INDEX = 208;
|
|
334
341
|
STATUSLINE_COLOUR_NAMES = [
|
|
335
342
|
"default",
|
|
336
343
|
"dim",
|
|
@@ -359,14 +366,14 @@ var init_statusline = __esm({
|
|
|
359
366
|
PRESET_BUNDLES = {
|
|
360
367
|
standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: false }, context: { breakdown: "never" } },
|
|
361
368
|
full: {
|
|
362
|
-
layout: { header: ["model", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "sessionName", "duration"], rows: ["context", "quota", "addedDirs", "memory", "environment", "tools", "skills", "mcp", "agents", "todos", "promptCache", "compactions", "tokens"] },
|
|
369
|
+
layout: { header: ["model", "project", "vcs", "effort", "advisor", "version", "extra", "outputStyle", "cost", "sessionName", "duration"], rows: ["context", "quota", "addedDirs", "memory", "environment", "tools", "skills", "mcp", "agents", "todos", "promptCache", "compactions", "tokens"] },
|
|
363
370
|
git: GIT_WITH_DIRTY_MARKER,
|
|
364
371
|
jj: { enabled: true, showDirty: true, showConflicts: true },
|
|
365
372
|
usage: { resetLabel: true },
|
|
366
373
|
context: { breakdown: "critical" }
|
|
367
374
|
},
|
|
368
|
-
essential: { layout: { header: ["model", "project", "vcs", "duration"], rows: ["context", "addedDirs", "tools", "agents", "todos"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } },
|
|
369
|
-
minimal: { layout: { header: ["model", "project", "vcs"], rows: ["context", "addedDirs"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } }
|
|
375
|
+
essential: { layout: { header: ["model", "project", "vcs", "extra", "duration"], rows: ["context", "addedDirs", "tools", "agents", "todos"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } },
|
|
376
|
+
minimal: { layout: { header: ["model", "project", "vcs", "extra"], rows: ["context", "addedDirs"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } }
|
|
370
377
|
};
|
|
371
378
|
STATUSLINE_PATH_LEVELS = ["1", "2", "3", "full"];
|
|
372
379
|
STATUSLINE_USAGE_VALUES = ["used", "remaining"];
|
|
@@ -380,6 +387,10 @@ var init_statusline = __esm({
|
|
|
380
387
|
MAX_BAR_CELLS = 40;
|
|
381
388
|
MAX_ACCOUNT_USER_CHARS = 254;
|
|
382
389
|
MAX_DISPLAY_TEXT_CHARS = 80;
|
|
390
|
+
MAX_EXTRA_COMMAND_ARGUMENTS = 16;
|
|
391
|
+
MAX_EXTRA_COMMAND_ARGUMENT_CHARS = 1024;
|
|
392
|
+
STATUSLINE_EXTRA_GROUP = "extra";
|
|
393
|
+
commandArgument = import_zod2.z.string().max(MAX_EXTRA_COMMAND_ARGUMENT_CHARS).refine((argument) => !argument.includes("\0"), "must not contain a NUL character");
|
|
383
394
|
LABEL_RE2 = /^[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*$/u;
|
|
384
395
|
OPTIONAL_LABEL_RE = /^(?:[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*)?$/u;
|
|
385
396
|
mergeGroups = import_zod2.z.array(distinctList(import_zod2.z.enum(STATUSLINE_ROWS)).min(2)).refine((groups) => {
|
|
@@ -442,6 +453,15 @@ var init_statusline = __esm({
|
|
|
442
453
|
estimate: import_zod2.z.enum(STATUSLINE_CONTEXT_ESTIMATES).describe(`What to draw when the client reports no percentage of the window in use, or reports 0 while tokens are already held (which is how a client says it has not worked it out yet): never (nothing is estimated: a percentage reported, 0 included, is drawn as it is, and none reported draws nothing), raw (the tokens held over the window), or buffered (that, plus the ${String(AUTOCOMPACT_RESERVE_FRACTION * MAX_PERCENT)}% of the window Claude Code reserves for compaction, rising from nothing at ${String(AUTOCOMPACT_RESERVE_RAMP_START * MAX_PERCENT)}% of the window held to the whole reserve at ${String(AUTOCOMPACT_RESERVE_RAMP_END * MAX_PERCENT)}%).`),
|
|
443
454
|
breakdown: import_zod2.z.enum(["never", "critical"]).describe("Whether to add the input and cache tokens of the last request to the context row once its use reaches context.criticalAt.")
|
|
444
455
|
},
|
|
456
|
+
customLine: {
|
|
457
|
+
text: overrideText.describe(`A line of your own text to draw, in colours.custom; empty draws nothing. It is refused when longer than ${String(MAX_DISPLAY_TEXT_CHARS)} characters or when it holds control, format or separator characters, and words are separated by single spaces. A character that passes but draws nothing, such as a braille blank, is removed, and the line is cut to the usable width.`),
|
|
458
|
+
position: import_zod2.z.enum(["first", "last"]).describe("Where the custom line sits: first draws it above the header, and last below the last row, as a line of its own in either layout mode.")
|
|
459
|
+
},
|
|
460
|
+
extra: {
|
|
461
|
+
command: import_zod2.z.array(commandArgument).max(MAX_EXTRA_COMMAND_ARGUMENTS).refine((command) => command[0]?.startsWith("-") !== true, "the program, the first item, must not start with a dash, which the system would read as an option: name it by an absolute path").describe(
|
|
462
|
+
`The program and arguments the extra segment runs, as a list and not a shell string (for example ["git", "describe", "--tags"]). The first line of its standard output that shows something, or the label of a JSON object it prints, is the segment; a line with nothing a person could see in it, such as spaces, zero-width characters or an escape sequence alone, is skipped. Escape sequences are removed from the whole output first, so an operating system command with no terminator removes everything up to the next escape character or the end of the output, line breaks included. A command that fails or prints nothing draws nothing. It is refused when it has more than ${String(MAX_EXTRA_COMMAND_ARGUMENTS)} arguments (the program included), when an argument is longer than ${String(MAX_EXTRA_COMMAND_ARGUMENT_CHARS)} characters or holds a NUL, and when the program starts with a dash. It runs on every refresh with your privileges and the statusline's whole environment. Its output is written to a file the system limits in size. That limit applies to every file it writes and every process it starts, so a program that writes a large cache is stopped and draws nothing, and so does one whose output reaches the limit. A process it starts is left running when it is killed for outrunning its time limit or when a newer update cancels the refresh. Because it runs a program with your privileges, only your own configuration may set it. That means the global config, a profile in your config-profiles directory, a directory rule or a command-line assignment. A project file such as .agent-shim.json is refused, though it may select one of your profiles by name, and a config write through the door's API (an MCP agent or the web client with the writes grant) is refused the extra settings for the same reason.`
|
|
463
|
+
)
|
|
464
|
+
},
|
|
445
465
|
bands: {
|
|
446
466
|
warnAt: wholePercent.describe("The whole percentage of use at which a bar turns yellow; it must be below criticalAt."),
|
|
447
467
|
criticalAt: wholePercent.describe("The whole percentage of use at which a bar turns red.")
|
|
@@ -498,7 +518,8 @@ var init_statusline = __esm({
|
|
|
498
518
|
git: colourValue.describe("The colour of the version control segment's wrapper text (`git:(` and `)`)."),
|
|
499
519
|
gitBranch: colourValue.describe("The colour of the branch or bookmark and its ahead, behind and dirty markers."),
|
|
500
520
|
activity: colourValue.describe("The colour of the names of the tools, skills and MCP servers the tools, skills and mcp rows draw. Their running markers take colours.warning and their finished markers colours.context."),
|
|
501
|
-
agent: colourValue.describe("The colour of an agent's type in the agents row.")
|
|
521
|
+
agent: colourValue.describe("The colour of an agent's type in the agents row."),
|
|
522
|
+
custom: colourValue.describe("The colour of the custom line.")
|
|
502
523
|
},
|
|
503
524
|
project: {
|
|
504
525
|
pathLevels: import_zod2.z.enum(STATUSLINE_PATH_LEVELS).describe("How many trailing directories of the working directory the project segment shows: 1, 2 or 3, or full for the whole absolute path."),
|
|
@@ -525,7 +546,7 @@ var init_statusline = __esm({
|
|
|
525
546
|
LANGUAGE_ALIASES = { zh: "zh-Hans", "zh-TW": "zh-Hant" };
|
|
526
547
|
TOP_LEVEL = {
|
|
527
548
|
language: import_zod2.z.enum(STATUSLINE_LANGUAGES).describe(LANGUAGE_DESCRIPTION),
|
|
528
|
-
preset: import_zod2.z.enum(STATUSLINE_PRESETS).describe("A named bundle of settings (layout.header, layout.rows, git.enabled, git.showDirty, git.showAheadBehind, git.showLineDiff, jj.enabled, jj.showDirty, jj.showConflicts, usage.resetLabel and context.breakdown) that this layer sets beneath the keys it names itself and above everything the shallower layers set: standard is the statusline's own; full, essential and minimal are claude-hud's presets. Each draws the model, project and version control segments and the context row; full adds the effort, advisor, version, output style, cost, session name and duration segments and the quota, added directories, memory, environment, tools, skills, mcp, agents, todos, prompt cache, compactions and session tokens rows, with the token breakdown at high use, essential adds the duration, the added directories row and the tools, agents and todos rows, and minimal adds the added directories row alone.")
|
|
549
|
+
preset: import_zod2.z.enum(STATUSLINE_PRESETS).describe("A named bundle of settings (layout.header, layout.rows, git.enabled, git.showDirty, git.showAheadBehind, git.showLineDiff, jj.enabled, jj.showDirty, jj.showConflicts, usage.resetLabel and context.breakdown) that this layer sets beneath the keys it names itself and above everything the shallower layers set: standard is the statusline's own; full, essential and minimal are claude-hud's presets. Each draws the model, project and version control segments, the extra segment once extra.command is set, and the context row; full adds the effort, advisor, version, output style, cost, session name and duration segments and the quota, added directories, memory, environment, tools, skills, mcp, agents, todos, prompt cache, compactions and session tokens rows, with the token breakdown at high use, essential adds the duration, the added directories row and the tools, agents and todos rows, and minimal adds the added directories row alone.")
|
|
529
550
|
};
|
|
530
551
|
StatuslineSchema = import_zod2.z.strictObject({
|
|
531
552
|
language: import_zod2.z.enum(LANGUAGE_TAGS).transform(canonicalLanguage).describe(LANGUAGE_DESCRIPTION).optional(),
|
|
@@ -537,6 +558,8 @@ var init_statusline = __esm({
|
|
|
537
558
|
effort: import_zod2.z.strictObject(SHAPES.effort).partial().optional(),
|
|
538
559
|
advisor: import_zod2.z.strictObject(SHAPES.advisor).partial().optional(),
|
|
539
560
|
context: import_zod2.z.strictObject({ ...SHAPES.context, warnAt: unsettable(SHAPES.context.warnAt), criticalAt: unsettable(SHAPES.context.criticalAt), autoCompactWindow: unsettable(SHAPES.context.autoCompactWindow) }).partial().optional(),
|
|
561
|
+
customLine: import_zod2.z.strictObject(SHAPES.customLine).partial().optional(),
|
|
562
|
+
extra: import_zod2.z.strictObject(SHAPES.extra).partial().optional(),
|
|
540
563
|
bands: import_zod2.z.strictObject(SHAPES.bands).partial().optional(),
|
|
541
564
|
labels: import_zod2.z.strictObject(SHAPES.labels).partial().optional(),
|
|
542
565
|
bar: import_zod2.z.strictObject(SHAPES.bar).partial().optional(),
|
|
@@ -562,6 +585,8 @@ var init_statusline = __esm({
|
|
|
562
585
|
effort: import_zod2.z.strictObject(SHAPES.effort),
|
|
563
586
|
advisor: import_zod2.z.strictObject(SHAPES.advisor),
|
|
564
587
|
context: import_zod2.z.strictObject(SHAPES.context),
|
|
588
|
+
customLine: import_zod2.z.strictObject(SHAPES.customLine),
|
|
589
|
+
extra: import_zod2.z.strictObject(SHAPES.extra),
|
|
565
590
|
bands: import_zod2.z.strictObject(SHAPES.bands),
|
|
566
591
|
labels: import_zod2.z.strictObject(SHAPES.labels),
|
|
567
592
|
bar: import_zod2.z.strictObject(SHAPES.bar),
|
|
@@ -587,6 +612,8 @@ var init_statusline = __esm({
|
|
|
587
612
|
effort: { format: "full" },
|
|
588
613
|
advisor: { override: "" },
|
|
589
614
|
context: { bar: "shown", value: "both", estimate: "never", breakdown: "never" },
|
|
615
|
+
customLine: { text: "", position: "last" },
|
|
616
|
+
extra: { command: [] },
|
|
590
617
|
bands: { warnAt: 70, criticalAt: 90 },
|
|
591
618
|
labels: { fiveHour: "", sevenDay: "" },
|
|
592
619
|
bar: { width: 10, filled: "\u2588", empty: "\u2591" },
|
|
@@ -610,7 +637,8 @@ var init_statusline = __esm({
|
|
|
610
637
|
git: "magenta",
|
|
611
638
|
gitBranch: "cyan",
|
|
612
639
|
activity: "cyan",
|
|
613
|
-
agent: "magenta"
|
|
640
|
+
agent: "magenta",
|
|
641
|
+
custom: ORANGE_PALETTE_INDEX
|
|
614
642
|
},
|
|
615
643
|
project: { pathLevels: "1", addedDirsLayout: "inline" },
|
|
616
644
|
git: { enabled: true, showDirty: true, showAheadBehind: false, showLineDiff: false, branchOverflow: "truncate", pushWarnAt: 0, pushCriticalAt: 0 },
|
|
@@ -1121,6 +1149,10 @@ var init_schema = __esm({
|
|
|
1121
1149
|
configProfile: FileNameSchema.optional(),
|
|
1122
1150
|
identity: IdentitySelectorSchema.optional(),
|
|
1123
1151
|
when: WhenSchema.optional()
|
|
1152
|
+
}).superRefine((config, context) => {
|
|
1153
|
+
if (config.launch?.statusline?.[STATUSLINE_EXTRA_GROUP] !== void 0) {
|
|
1154
|
+
context.addIssue({ code: "custom", path: ["launch", "statusline", STATUSLINE_EXTRA_GROUP], message: "a project file cannot set the statusline's extra command: it runs a program, so only your own configuration (the global config, a profile, a directory rule) may set it" });
|
|
1155
|
+
}
|
|
1124
1156
|
});
|
|
1125
1157
|
HEADROOM_MODES = ["cache", "token"];
|
|
1126
1158
|
HEADROOM_CCR_MODES = ["default", "lossless", "none"];
|
|
@@ -1246,7 +1278,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
|
|
|
1246
1278
|
return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
|
|
1247
1279
|
}
|
|
1248
1280
|
function describeIgnoredKeys(filePath, ignored) {
|
|
1249
|
-
const places = ignored.map(({ path:
|
|
1281
|
+
const places = ignored.map(({ path: path42, keys }) => `${path42.length === 0 ? "" : `${path42.map(String).join(".")}.`}${keys.join(", ")}`);
|
|
1250
1282
|
return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
|
|
1251
1283
|
}
|
|
1252
1284
|
function noteIgnoredKeys(filePath, ignored) {
|
|
@@ -1268,9 +1300,9 @@ function restoreIgnoredKeys(filePath, value) {
|
|
|
1268
1300
|
return value;
|
|
1269
1301
|
}
|
|
1270
1302
|
const restored = structuredClone(value);
|
|
1271
|
-
for (const { path:
|
|
1303
|
+
for (const { path: path42, values } of ignored) {
|
|
1272
1304
|
let holder = restored;
|
|
1273
|
-
for (const step of
|
|
1305
|
+
for (const step of path42) {
|
|
1274
1306
|
holder = isRecord(holder) ? holder[step] : void 0;
|
|
1275
1307
|
}
|
|
1276
1308
|
if (isRecord(holder)) {
|
|
@@ -3901,28 +3933,38 @@ function recordOf(details) {
|
|
|
3901
3933
|
}
|
|
3902
3934
|
function writeFrontDoorSession(fs14, sessionsDir, session) {
|
|
3903
3935
|
fs14.mkdirPrivate(sessionsDir);
|
|
3904
|
-
fs14.writeFilePrivate(import_node_path9.default.join(sessionsDir,
|
|
3936
|
+
fs14.writeFilePrivate(import_node_path9.default.join(sessionsDir, sessionRecordName(session.pid)), `${JSON.stringify(session, null, 2)}
|
|
3905
3937
|
`);
|
|
3906
3938
|
}
|
|
3939
|
+
function sessionRecordName(pid) {
|
|
3940
|
+
return `${String(pid)}.json`;
|
|
3941
|
+
}
|
|
3942
|
+
function isSessionRecordName(name) {
|
|
3943
|
+
return name.endsWith(".json");
|
|
3944
|
+
}
|
|
3945
|
+
function summaryOf(session) {
|
|
3946
|
+
return { pid: session.pid, startedAt: session.startedAt, ...session.supervisorPid === void 0 ? {} : { supervisorPid: session.supervisorPid } };
|
|
3947
|
+
}
|
|
3948
|
+
function readFrontDoorSessionRecord(fs14, sessionsDir, name) {
|
|
3949
|
+
try {
|
|
3950
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs14.readFileUtf8(import_node_path9.default.join(sessionsDir, name)) ?? ""));
|
|
3951
|
+
return parsed.success ? parsed.data : void 0;
|
|
3952
|
+
} catch {
|
|
3953
|
+
return void 0;
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3907
3956
|
function listFrontDoorSessions(fs14, sessionsDir) {
|
|
3908
3957
|
const sessions = [];
|
|
3909
3958
|
for (const name of fs14.readdir(sessionsDir)) {
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
|
|
3913
|
-
try {
|
|
3914
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs14.readFileUtf8(import_node_path9.default.join(sessionsDir, name)) ?? ""));
|
|
3915
|
-
if (parsed.success) {
|
|
3916
|
-
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
|
|
3917
|
-
}
|
|
3918
|
-
} catch {
|
|
3919
|
-
continue;
|
|
3959
|
+
const record = isSessionRecordName(name) ? readFrontDoorSessionRecord(fs14, sessionsDir, name) : void 0;
|
|
3960
|
+
if (record !== void 0) {
|
|
3961
|
+
sessions.push(summaryOf(record));
|
|
3920
3962
|
}
|
|
3921
3963
|
}
|
|
3922
3964
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
3923
3965
|
}
|
|
3924
3966
|
function removeFrontDoorSession(fs14, sessionsDir, pid) {
|
|
3925
|
-
fs14.removeRecursive(import_node_path9.default.join(sessionsDir,
|
|
3967
|
+
fs14.removeRecursive(import_node_path9.default.join(sessionsDir, sessionRecordName(pid)));
|
|
3926
3968
|
}
|
|
3927
3969
|
function pruneDeadFrontDoorSessions(fs14, sessionsDir, listed, isRunning) {
|
|
3928
3970
|
const removed = [];
|
|
@@ -4182,9 +4224,10 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4182
4224
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
4183
4225
|
}
|
|
4184
4226
|
ticks += 1;
|
|
4185
|
-
const listed =
|
|
4227
|
+
const listed = ports.registry.rescan();
|
|
4186
4228
|
const running = await ports.runningAmong(listed.map((session) => session.pid));
|
|
4187
4229
|
const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, listed, (pid) => running.has(pid));
|
|
4230
|
+
ports.registry.forget(pruned);
|
|
4188
4231
|
ports.observeLaunchRegistry(listed, pruned);
|
|
4189
4232
|
ports.checkQuotaExpiry();
|
|
4190
4233
|
const prunedPids = new Set(pruned);
|
|
@@ -4257,8 +4300,8 @@ function parseConnectTarget(authority) {
|
|
|
4257
4300
|
function isInterceptedHost(host, interceptHosts) {
|
|
4258
4301
|
return interceptHosts.includes(host);
|
|
4259
4302
|
}
|
|
4260
|
-
function servedByPipeline(
|
|
4261
|
-
return
|
|
4303
|
+
function servedByPipeline(path42) {
|
|
4304
|
+
return path42?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
4262
4305
|
}
|
|
4263
4306
|
function forwardableHeaders(headers) {
|
|
4264
4307
|
const connectionTokens = new Set(
|
|
@@ -4704,7 +4747,7 @@ var init_package = __esm({
|
|
|
4704
4747
|
"package.json"() {
|
|
4705
4748
|
package_default = {
|
|
4706
4749
|
name: "claude-use",
|
|
4707
|
-
version: "11.
|
|
4750
|
+
version: "11.65.1",
|
|
4708
4751
|
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.",
|
|
4709
4752
|
license: "MIT",
|
|
4710
4753
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -7910,9 +7953,9 @@ var init_poolPick = __esm({
|
|
|
7910
7953
|
});
|
|
7911
7954
|
|
|
7912
7955
|
// src/statusline/keys.ts
|
|
7913
|
-
function valueAt(source,
|
|
7956
|
+
function valueAt(source, path42) {
|
|
7914
7957
|
let current = source;
|
|
7915
|
-
for (const part of
|
|
7958
|
+
for (const part of path42) {
|
|
7916
7959
|
if (!isPlainObject(current)) {
|
|
7917
7960
|
return void 0;
|
|
7918
7961
|
}
|
|
@@ -7920,10 +7963,10 @@ function valueAt(source, path41) {
|
|
|
7920
7963
|
}
|
|
7921
7964
|
return current;
|
|
7922
7965
|
}
|
|
7923
|
-
function keyOf(
|
|
7966
|
+
function keyOf(path42, declared) {
|
|
7924
7967
|
const optional = declared instanceof import_zod16.z.ZodOptional;
|
|
7925
7968
|
const leaf = optional ? declared.unwrap() : declared;
|
|
7926
|
-
const common = { path:
|
|
7969
|
+
const common = { path: path42.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path42), optional };
|
|
7927
7970
|
if (leaf instanceof import_zod16.z.ZodNumber) {
|
|
7928
7971
|
return { ...common, kind: "integer", choices: [] };
|
|
7929
7972
|
}
|
|
@@ -7945,7 +7988,10 @@ function keyOf(path41, declared) {
|
|
|
7945
7988
|
if (leaf instanceof import_zod16.z.ZodArray && leaf.element instanceof import_zod16.z.ZodArray && leaf.element.element instanceof import_zod16.z.ZodEnum) {
|
|
7946
7989
|
return { ...common, kind: "groups", choices: Object.values(leaf.element.element.enum).map(String) };
|
|
7947
7990
|
}
|
|
7948
|
-
|
|
7991
|
+
if (leaf instanceof import_zod16.z.ZodArray && leaf.element instanceof import_zod16.z.ZodString) {
|
|
7992
|
+
return { ...common, kind: "textList", choices: [] };
|
|
7993
|
+
}
|
|
7994
|
+
throw new TypeError(`statusline setting ${path42.join(".")} has a kind the key listing does not describe`);
|
|
7949
7995
|
}
|
|
7950
7996
|
function walk(shape, prefix) {
|
|
7951
7997
|
return Object.entries(shape).flatMap(([name, schema]) => schema instanceof import_zod16.z.ZodObject ? walk(schema.shape, [...prefix, name]) : [keyOf([...prefix, name], schema)]);
|
|
@@ -7963,15 +8009,15 @@ var init_keys = __esm({
|
|
|
7963
8009
|
});
|
|
7964
8010
|
|
|
7965
8011
|
// src/statusline/change.ts
|
|
7966
|
-
function keyNamed(
|
|
7967
|
-
const found = statuslineKeys().find((key) => key.path ===
|
|
8012
|
+
function keyNamed(path42) {
|
|
8013
|
+
const found = statuslineKeys().find((key) => key.path === path42);
|
|
7968
8014
|
if (found === void 0) {
|
|
7969
|
-
throw new UsageError(`"${
|
|
8015
|
+
throw new UsageError(`"${path42}" is not a statusline setting; \`agent-shim statusline keys\` lists them.`);
|
|
7970
8016
|
}
|
|
7971
8017
|
return found;
|
|
7972
8018
|
}
|
|
7973
|
-
function setAt(target,
|
|
7974
|
-
const [head, ...rest] =
|
|
8019
|
+
function setAt(target, path42, value) {
|
|
8020
|
+
const [head, ...rest] = path42;
|
|
7975
8021
|
if (head === void 0) {
|
|
7976
8022
|
return;
|
|
7977
8023
|
}
|
|
@@ -7984,8 +8030,8 @@ function setAt(target, path41, value) {
|
|
|
7984
8030
|
target[head] = next;
|
|
7985
8031
|
setAt(next, rest, value);
|
|
7986
8032
|
}
|
|
7987
|
-
function removeAt(target,
|
|
7988
|
-
const [head, ...rest] =
|
|
8033
|
+
function removeAt(target, path42) {
|
|
8034
|
+
const [head, ...rest] = path42;
|
|
7989
8035
|
if (head === void 0) {
|
|
7990
8036
|
return;
|
|
7991
8037
|
}
|
|
@@ -8003,13 +8049,13 @@ function removeAt(target, path41) {
|
|
|
8003
8049
|
}
|
|
8004
8050
|
function applyStatuslineChange(existing, change) {
|
|
8005
8051
|
const draft = structuredClone(existing ?? {});
|
|
8006
|
-
for (const [
|
|
8007
|
-
keyNamed(
|
|
8008
|
-
setAt(draft,
|
|
8052
|
+
for (const [path42, value] of Object.entries(change.set ?? {})) {
|
|
8053
|
+
keyNamed(path42);
|
|
8054
|
+
setAt(draft, path42.split("."), value);
|
|
8009
8055
|
}
|
|
8010
|
-
for (const
|
|
8011
|
-
keyNamed(
|
|
8012
|
-
removeAt(draft,
|
|
8056
|
+
for (const path42 of change.unset ?? []) {
|
|
8057
|
+
keyNamed(path42);
|
|
8058
|
+
removeAt(draft, path42.split("."));
|
|
8013
8059
|
}
|
|
8014
8060
|
const result = StatuslineSchema.safeParse(draft);
|
|
8015
8061
|
if (!result.success) {
|
|
@@ -10802,7 +10848,7 @@ function buildEnv(params) {
|
|
|
10802
10848
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
10803
10849
|
let providerCustomHeaders;
|
|
10804
10850
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
10805
|
-
env.CLAUDE_CONFIG_DIR =
|
|
10851
|
+
env.CLAUDE_CONFIG_DIR = import_node_path36.default.join(params.identitiesDir, params.resolvedIdentityName);
|
|
10806
10852
|
}
|
|
10807
10853
|
if (params.provider !== void 0) {
|
|
10808
10854
|
const providerEnv = params.provider.definition.kind !== void 0 && params.provider.definition.kind !== "http" ? {} : params.provider.definition.env ?? {};
|
|
@@ -10856,11 +10902,11 @@ function buildEnv(params) {
|
|
|
10856
10902
|
}
|
|
10857
10903
|
return env;
|
|
10858
10904
|
}
|
|
10859
|
-
var
|
|
10905
|
+
var import_node_path36, LOOPBACK_HOSTS, PROVIDER_SESSION_PLACEHOLDER;
|
|
10860
10906
|
var init_flags = __esm({
|
|
10861
10907
|
"src/launcher/flags.ts"() {
|
|
10862
10908
|
"use strict";
|
|
10863
|
-
|
|
10909
|
+
import_node_path36 = __toESM(require("node:path"), 1);
|
|
10864
10910
|
init_envBool();
|
|
10865
10911
|
init_cliError();
|
|
10866
10912
|
init_conditions();
|
|
@@ -10952,7 +10998,7 @@ function newestTranscript(fs14, projectDir) {
|
|
|
10952
10998
|
if (!name.endsWith(".jsonl")) {
|
|
10953
10999
|
continue;
|
|
10954
11000
|
}
|
|
10955
|
-
const candidate =
|
|
11001
|
+
const candidate = import_node_path37.default.join(projectDir, name);
|
|
10956
11002
|
const stat = fs14.lstat(candidate);
|
|
10957
11003
|
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
10958
11004
|
newestMs = stat.mtimeMs;
|
|
@@ -10966,16 +11012,16 @@ function resumedContextTokens(fs14, params) {
|
|
|
10966
11012
|
if (target === void 0) {
|
|
10967
11013
|
return void 0;
|
|
10968
11014
|
}
|
|
10969
|
-
const projectDir =
|
|
10970
|
-
const file = target.kind === "id" ?
|
|
11015
|
+
const projectDir = import_node_path37.default.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
11016
|
+
const file = target.kind === "id" ? import_node_path37.default.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs14, projectDir);
|
|
10971
11017
|
const text = file === void 0 ? void 0 : fs14.readFileUtf8(file);
|
|
10972
11018
|
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
10973
11019
|
}
|
|
10974
|
-
var
|
|
11020
|
+
var import_node_path37;
|
|
10975
11021
|
var init_resumeContext = __esm({
|
|
10976
11022
|
"src/usage/resumeContext.ts"() {
|
|
10977
11023
|
"use strict";
|
|
10978
|
-
|
|
11024
|
+
import_node_path37 = __toESM(require("node:path"), 1);
|
|
10979
11025
|
}
|
|
10980
11026
|
});
|
|
10981
11027
|
|
|
@@ -11654,7 +11700,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11654
11700
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
11655
11701
|
passthrough: withLauncherSettings(params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised), launcherSettings)
|
|
11656
11702
|
});
|
|
11657
|
-
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR :
|
|
11703
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path38.default.join(paths.identitiesDir, identityDecision.name);
|
|
11658
11704
|
const decision = {
|
|
11659
11705
|
identitySource: identityDecision.source,
|
|
11660
11706
|
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
@@ -11707,7 +11753,7 @@ function prepareLaunch(params) {
|
|
|
11707
11753
|
let warnings = [];
|
|
11708
11754
|
const updateCheck = runLaunchUpdateCheck({
|
|
11709
11755
|
mode: params.updateMode ?? "off",
|
|
11710
|
-
checkPath:
|
|
11756
|
+
checkPath: import_node_path38.default.join(paths.root, "update.check"),
|
|
11711
11757
|
currentVersion: package_default.version,
|
|
11712
11758
|
port: params.update
|
|
11713
11759
|
});
|
|
@@ -11854,13 +11900,13 @@ function runLaunchPlan(plan, spawn3) {
|
|
|
11854
11900
|
function runLauncher(params) {
|
|
11855
11901
|
params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
|
|
11856
11902
|
}
|
|
11857
|
-
var import_node_crypto11, import_node_util2,
|
|
11903
|
+
var import_node_crypto11, import_node_util2, import_node_path38;
|
|
11858
11904
|
var init_launcher = __esm({
|
|
11859
11905
|
"src/launcher.ts"() {
|
|
11860
11906
|
"use strict";
|
|
11861
11907
|
import_node_crypto11 = require("node:crypto");
|
|
11862
11908
|
import_node_util2 = require("node:util");
|
|
11863
|
-
|
|
11909
|
+
import_node_path38 = __toESM(require("node:path"), 1);
|
|
11864
11910
|
init_package();
|
|
11865
11911
|
init_envBool();
|
|
11866
11912
|
init_argv();
|
|
@@ -11903,13 +11949,13 @@ function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string"
|
|
|
11903
11949
|
if (distDir === void 0) {
|
|
11904
11950
|
throw new OwnCliPathUnknownError();
|
|
11905
11951
|
}
|
|
11906
|
-
return
|
|
11952
|
+
return import_node_path39.default.join(distDir, OWN_CLI_FILE_NAME);
|
|
11907
11953
|
}
|
|
11908
|
-
var
|
|
11954
|
+
var import_node_path39, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
11909
11955
|
var init_ownCli = __esm({
|
|
11910
11956
|
"src/ownCli.ts"() {
|
|
11911
11957
|
"use strict";
|
|
11912
|
-
|
|
11958
|
+
import_node_path39 = __toESM(require("node:path"), 1);
|
|
11913
11959
|
init_cliError();
|
|
11914
11960
|
OWN_CLI_FILE_NAME = "cli.cjs";
|
|
11915
11961
|
OwnCliPathUnknownError = class extends CliError {
|
|
@@ -11952,7 +11998,7 @@ var init_selfIdentity = __esm({
|
|
|
11952
11998
|
// src/frontdoor/trust.ts
|
|
11953
11999
|
function resolveTrustBundle(params) {
|
|
11954
12000
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs14 } = params;
|
|
11955
|
-
if (inherited === void 0 || inherited === "" ||
|
|
12001
|
+
if (inherited === void 0 || inherited === "" || import_node_path40.default.resolve(inherited) === import_node_path40.default.resolve(caCertFile)) {
|
|
11956
12002
|
return { path: caCertFile };
|
|
11957
12003
|
}
|
|
11958
12004
|
const caPem = fs14.readFileUtf8(caCertFile);
|
|
@@ -11970,19 +12016,19 @@ function resolveTrustBundle(params) {
|
|
|
11970
12016
|
}
|
|
11971
12017
|
const combined = `${inheritedPem.trimEnd()}
|
|
11972
12018
|
${caPem}`;
|
|
11973
|
-
const bundle =
|
|
12019
|
+
const bundle = import_node_path40.default.join(bundlesDir, `${(0, import_node_crypto12.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
11974
12020
|
if (!fs14.exists(bundle)) {
|
|
11975
12021
|
fs14.mkdirp(bundlesDir);
|
|
11976
12022
|
fs14.writeFileAtomic(bundle, combined);
|
|
11977
12023
|
}
|
|
11978
12024
|
return { path: bundle };
|
|
11979
12025
|
}
|
|
11980
|
-
var import_node_crypto12,
|
|
12026
|
+
var import_node_crypto12, import_node_path40, BUNDLE_NAME_HEX_DIGITS;
|
|
11981
12027
|
var init_trust = __esm({
|
|
11982
12028
|
"src/frontdoor/trust.ts"() {
|
|
11983
12029
|
"use strict";
|
|
11984
12030
|
import_node_crypto12 = require("node:crypto");
|
|
11985
|
-
|
|
12031
|
+
import_node_path40 = __toESM(require("node:path"), 1);
|
|
11986
12032
|
BUNDLE_NAME_HEX_DIGITS = 16;
|
|
11987
12033
|
}
|
|
11988
12034
|
});
|
|
@@ -12157,7 +12203,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
12157
12203
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|
|
12158
12204
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
12159
12205
|
hold: realHoldPort,
|
|
12160
|
-
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot:
|
|
12206
|
+
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot: import_node_path41.default.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
|
|
12161
12207
|
...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
|
|
12162
12208
|
...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
|
|
12163
12209
|
...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
|
|
@@ -12216,12 +12262,12 @@ function resolveClaudeLaunch(options, run = realRunPort) {
|
|
|
12216
12262
|
};
|
|
12217
12263
|
return { resolution: resolveLaunch(realPrepareLaunchParams(paths, { proc, log, spawnDaemon, run, farm: buildFarmRuntime(paths, options.cwd, run) })), warnings };
|
|
12218
12264
|
}
|
|
12219
|
-
var import_node_os7,
|
|
12265
|
+
var import_node_os7, import_node_path41, import_node_crypto13, LaunchRefusedError;
|
|
12220
12266
|
var init_launchWiring = __esm({
|
|
12221
12267
|
"src/launchWiring.ts"() {
|
|
12222
12268
|
"use strict";
|
|
12223
12269
|
import_node_os7 = __toESM(require("node:os"), 1);
|
|
12224
|
-
|
|
12270
|
+
import_node_path41 = __toESM(require("node:path"), 1);
|
|
12225
12271
|
import_node_crypto13 = require("node:crypto");
|
|
12226
12272
|
init_cliError();
|
|
12227
12273
|
init_claudeShim();
|
|
@@ -12824,6 +12870,7 @@ __export(index_exports, {
|
|
|
12824
12870
|
createLaunchEventPublisher: () => createLaunchEventPublisher,
|
|
12825
12871
|
createLeafCache: () => createLeafCache,
|
|
12826
12872
|
createLifecycleApiRouter: () => createLifecycleApiRouter,
|
|
12873
|
+
createLiveSessionRegistry: () => createLiveSessionRegistry,
|
|
12827
12874
|
createProfile: () => createProfile,
|
|
12828
12875
|
createQuotaExpiringPublisher: () => createQuotaExpiringPublisher,
|
|
12829
12876
|
createRcApiNodeHandler: () => createRcApiNodeHandler,
|
|
@@ -13437,11 +13484,11 @@ function createRcSessionTracker(deps) {
|
|
|
13437
13484
|
};
|
|
13438
13485
|
const observeExchange = (request4) => {
|
|
13439
13486
|
const method = (request4.method ?? "").toUpperCase();
|
|
13440
|
-
const
|
|
13441
|
-
if (!
|
|
13487
|
+
const path42 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
13488
|
+
if (!path42.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
13442
13489
|
return void 0;
|
|
13443
13490
|
}
|
|
13444
|
-
const tail =
|
|
13491
|
+
const tail = path42.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
13445
13492
|
const facts = {
|
|
13446
13493
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
13447
13494
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -13558,7 +13605,7 @@ function createRcSessionTracker(deps) {
|
|
|
13558
13605
|
}
|
|
13559
13606
|
};
|
|
13560
13607
|
};
|
|
13561
|
-
const
|
|
13608
|
+
const summaryOf2 = ({ id, createdAt, lastSeenAt }) => ({ id, createdAt, lastSeenAt });
|
|
13562
13609
|
const pendingSummaryOf = ({ sessionId, requestId, type, summary, observedAt: observedAt2 }) => ({ sessionId, requestId, type, summary, observedAt: observedAt2 });
|
|
13563
13610
|
const sortedEntries = () => [...entries.values()].sort((left, right) => left.createdAt - right.createdAt || (left.id < right.id ? -1 : 1));
|
|
13564
13611
|
const pendingSorted = (entry) => [...entry.pending.values()].sort((left, right) => left.observedAt - right.observedAt || (left.requestId < right.requestId ? -1 : 1)).map(pendingSummaryOf);
|
|
@@ -13566,11 +13613,11 @@ function createRcSessionTracker(deps) {
|
|
|
13566
13613
|
observeExchange,
|
|
13567
13614
|
list: () => {
|
|
13568
13615
|
sweep();
|
|
13569
|
-
return sortedEntries().map(
|
|
13616
|
+
return sortedEntries().map(summaryOf2);
|
|
13570
13617
|
},
|
|
13571
13618
|
statusOf: (sessionId) => {
|
|
13572
13619
|
sweep();
|
|
13573
|
-
return sortedEntries().filter((entry) => sessionId === void 0 || entry.id === sessionId).map((entry) => ({ ...
|
|
13620
|
+
return sortedEntries().filter((entry) => sessionId === void 0 || entry.id === sessionId).map((entry) => ({ ...summaryOf2(entry), workerState: entry.workerState, workerIdleSeconds: entry.workerIdleSeconds, pending: pendingSorted(entry) }));
|
|
13574
13621
|
},
|
|
13575
13622
|
pendingOf: (sessionId) => {
|
|
13576
13623
|
sweep();
|
|
@@ -13831,8 +13878,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
13831
13878
|
function isRcReadFileEncoding(value) {
|
|
13832
13879
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
13833
13880
|
}
|
|
13834
|
-
function buildRcReadFilePayload(requestId,
|
|
13835
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
13881
|
+
function buildRcReadFilePayload(requestId, path42, options) {
|
|
13882
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path42, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
13836
13883
|
}
|
|
13837
13884
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
13838
13885
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -13934,15 +13981,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
13934
13981
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
13935
13982
|
return result.ok ? { ...result, requestId } : result;
|
|
13936
13983
|
}
|
|
13937
|
-
async function readRcSessionFile(deps, sessionId,
|
|
13938
|
-
if (
|
|
13984
|
+
async function readRcSessionFile(deps, sessionId, path42, options) {
|
|
13985
|
+
if (path42 === "") {
|
|
13939
13986
|
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" };
|
|
13940
13987
|
}
|
|
13941
13988
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
13942
13989
|
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" };
|
|
13943
13990
|
}
|
|
13944
13991
|
const requestId = deps.newUuid();
|
|
13945
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
13992
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path42, options), `read ${path42} from session ${sessionId}`);
|
|
13946
13993
|
return result.ok ? { ...result, requestId } : result;
|
|
13947
13994
|
}
|
|
13948
13995
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -14111,11 +14158,11 @@ function createRcControlHandler(deps) {
|
|
|
14111
14158
|
path: "read-file",
|
|
14112
14159
|
read: (body) => {
|
|
14113
14160
|
const session = bodyString(body, "session");
|
|
14114
|
-
const
|
|
14161
|
+
const path42 = bodyString(body, "path");
|
|
14115
14162
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
14116
14163
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
14117
|
-
const refused2 = session === void 0 ||
|
|
14118
|
-
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,
|
|
14164
|
+
const refused2 = session === void 0 || path42 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
14165
|
+
return refused2 ? { error: `the read-file body must be JSON naming a non-empty session id and path, maxBytes only as a positive whole number or absent, and an encoding the SDK's own type permits (${RC_READ_FILE_ENCODINGS.join(", ")}) or none` } : { session, run: async () => await deps.readFile(session, path42, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
|
|
14119
14166
|
}
|
|
14120
14167
|
},
|
|
14121
14168
|
{
|
|
@@ -14425,9 +14472,9 @@ function requestIdOfBody(body) {
|
|
|
14425
14472
|
}
|
|
14426
14473
|
function frontDoorRcControl(transport, token) {
|
|
14427
14474
|
const headers = { authorization: `Bearer ${token}` };
|
|
14428
|
-
const listAnswerOf = async (
|
|
14475
|
+
const listAnswerOf = async (path42, what) => {
|
|
14429
14476
|
try {
|
|
14430
|
-
return await transport.request({ method: "GET", path:
|
|
14477
|
+
return await transport.request({ method: "GET", path: path42, headers });
|
|
14431
14478
|
} catch (error) {
|
|
14432
14479
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
14433
14480
|
}
|
|
@@ -14499,10 +14546,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
14499
14546
|
}
|
|
14500
14547
|
return pending;
|
|
14501
14548
|
};
|
|
14502
|
-
const writeOf = async (
|
|
14549
|
+
const writeOf = async (path42, body, describeFailure2) => {
|
|
14503
14550
|
let answer;
|
|
14504
14551
|
try {
|
|
14505
|
-
answer = await transport.request({ method: "POST", path:
|
|
14552
|
+
answer = await transport.request({ method: "POST", path: path42, headers: { ...headers, "content-type": "application/json" }, body });
|
|
14506
14553
|
} catch (error) {
|
|
14507
14554
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
14508
14555
|
}
|
|
@@ -14533,10 +14580,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
14533
14580
|
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}`),
|
|
14534
14581
|
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}`),
|
|
14535
14582
|
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}`),
|
|
14536
|
-
readFile: async (sessionId,
|
|
14583
|
+
readFile: async (sessionId, path42, options) => await writeOf(
|
|
14537
14584
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
14538
|
-
JSON.stringify({ session: sessionId, path:
|
|
14539
|
-
(status, message) => `reading ${
|
|
14585
|
+
JSON.stringify({ session: sessionId, path: path42, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
14586
|
+
(status, message) => `reading ${path42} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
14540
14587
|
),
|
|
14541
14588
|
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}`),
|
|
14542
14589
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -14695,12 +14742,12 @@ function tlsFacts(options) {
|
|
|
14695
14742
|
}
|
|
14696
14743
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
14697
14744
|
const agent = new ExemptTlsAgent();
|
|
14698
|
-
const post = async (
|
|
14745
|
+
const post = async (path42, headers, body) => await new Promise((resolve, reject) => {
|
|
14699
14746
|
const options = {
|
|
14700
14747
|
host: target.host,
|
|
14701
14748
|
port: target.port,
|
|
14702
14749
|
method: "POST",
|
|
14703
|
-
path:
|
|
14750
|
+
path: path42,
|
|
14704
14751
|
// 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.
|
|
14705
14752
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
14706
14753
|
agent
|
|
@@ -14765,12 +14812,12 @@ function lateRcStreamDial(resolve) {
|
|
|
14765
14812
|
}
|
|
14766
14813
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
14767
14814
|
const agent = new ExemptTlsAgent();
|
|
14768
|
-
const request4 = async (method,
|
|
14815
|
+
const request4 = async (method, path42, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
14769
14816
|
const options = {
|
|
14770
14817
|
host: target.host,
|
|
14771
14818
|
port: target.port,
|
|
14772
14819
|
method,
|
|
14773
|
-
path:
|
|
14820
|
+
path: path42,
|
|
14774
14821
|
// 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.
|
|
14775
14822
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
14776
14823
|
agent,
|
|
@@ -14812,9 +14859,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
14812
14859
|
return { status, body: await readAll(response) };
|
|
14813
14860
|
},
|
|
14814
14861
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
14815
|
-
const
|
|
14862
|
+
const path42 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
|
|
14816
14863
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
14817
|
-
const { status, response } = await request4("GET",
|
|
14864
|
+
const { status, response } = await request4("GET", path42, streamHeaders, void 0, signal);
|
|
14818
14865
|
if (!isSuccessful2(status)) {
|
|
14819
14866
|
await readAll(response);
|
|
14820
14867
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -15807,19 +15854,19 @@ function writePools(paths, pools) {
|
|
|
15807
15854
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
15808
15855
|
}
|
|
15809
15856
|
function poolCycleOf(pools, name) {
|
|
15810
|
-
const walk2 = (current,
|
|
15857
|
+
const walk2 = (current, path42) => {
|
|
15811
15858
|
for (const entry of pools[current]?.identities ?? []) {
|
|
15812
15859
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
15813
15860
|
if (nested === void 0) {
|
|
15814
15861
|
continue;
|
|
15815
15862
|
}
|
|
15816
15863
|
if (nested === name) {
|
|
15817
|
-
return [...
|
|
15864
|
+
return [...path42, nested];
|
|
15818
15865
|
}
|
|
15819
|
-
if (
|
|
15866
|
+
if (path42.includes(nested)) {
|
|
15820
15867
|
continue;
|
|
15821
15868
|
}
|
|
15822
|
-
const found = walk2(nested, [...
|
|
15869
|
+
const found = walk2(nested, [...path42, nested]);
|
|
15823
15870
|
if (found !== void 0) {
|
|
15824
15871
|
return found;
|
|
15825
15872
|
}
|
|
@@ -18054,6 +18101,7 @@ init_providersStore();
|
|
|
18054
18101
|
// src/frontdoor/configSchemas.ts
|
|
18055
18102
|
var import_zod30 = require("zod");
|
|
18056
18103
|
init_schema();
|
|
18104
|
+
init_statusline();
|
|
18057
18105
|
var RemovalConfirmationSchema = import_zod30.z.boolean();
|
|
18058
18106
|
var CredentialWriteSchema = (targets) => import_zod30.z.strictObject({
|
|
18059
18107
|
sources: import_zod30.z.array(RemoteCredentialSourceSchema).min(1).optional(),
|
|
@@ -18106,6 +18154,13 @@ var ConfigIdentitySetInputSchema = import_zod30.z.strictObject({
|
|
|
18106
18154
|
var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
|
|
18107
18155
|
var ConfigIdentityRemoveInputSchema = import_zod30.z.strictObject({ name: import_zod30.z.string().min(1), confirm: RemovalConfirmationSchema });
|
|
18108
18156
|
var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
|
|
18157
|
+
var ConfigStatuslineSetSchema = import_zod30.z.record(import_zod30.z.string(), import_zod30.z.unknown()).superRefine((settings, context) => {
|
|
18158
|
+
for (const key of Object.keys(settings)) {
|
|
18159
|
+
if (key === STATUSLINE_EXTRA_GROUP || key.startsWith(`${STATUSLINE_EXTRA_GROUP}.`)) {
|
|
18160
|
+
context.addIssue({ code: "custom", path: [key], message: `a config write through the API cannot set "${key}": the extra segment's command runs a program, so only your own configuration (the global config, a profile you edit yourself, a directory rule or a command-line assignment) may set it` });
|
|
18161
|
+
}
|
|
18162
|
+
}
|
|
18163
|
+
});
|
|
18109
18164
|
var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
|
|
18110
18165
|
var ConfigProfileAddInputSchema = import_zod30.z.strictObject({
|
|
18111
18166
|
name: import_zod30.z.string().min(1),
|
|
@@ -18131,7 +18186,7 @@ var ConfigProfileSetInputSchema = import_zod30.z.strictObject({
|
|
|
18131
18186
|
explain: import_zod30.z.boolean().optional(),
|
|
18132
18187
|
proxyBypass: import_zod30.z.union([import_zod30.z.array(import_zod30.z.string().min(1)), import_zod30.z.literal(false)]).optional(),
|
|
18133
18188
|
statusline: import_zod30.z.strictObject({
|
|
18134
|
-
set:
|
|
18189
|
+
set: ConfigStatuslineSetSchema.optional(),
|
|
18135
18190
|
unset: import_zod30.z.array(import_zod30.z.string()).optional()
|
|
18136
18191
|
}).optional()
|
|
18137
18192
|
}).optional()
|
|
@@ -18257,7 +18312,7 @@ function profileValue(name, paths) {
|
|
|
18257
18312
|
function createConfigApiRouter(deps) {
|
|
18258
18313
|
const authed = doorApiAuth(deps.expectedToken);
|
|
18259
18314
|
const { paths } = deps;
|
|
18260
|
-
const route = (
|
|
18315
|
+
const route = (path42, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path42, summary, tags: [CONFIG_API_TAG] }));
|
|
18261
18316
|
return {
|
|
18262
18317
|
config: {
|
|
18263
18318
|
identity: {
|
|
@@ -20908,6 +20963,85 @@ function mintRcSelfHostCredential(deps) {
|
|
|
20908
20963
|
|
|
20909
20964
|
// src/index.ts
|
|
20910
20965
|
init_ensure2();
|
|
20966
|
+
|
|
20967
|
+
// src/frontdoor/liveSessionRegistry.ts
|
|
20968
|
+
var import_node_path33 = __toESM(require("node:path"), 1);
|
|
20969
|
+
init_capability();
|
|
20970
|
+
init_state();
|
|
20971
|
+
function sameStat(recorded, current) {
|
|
20972
|
+
return recorded?.mtimeMs === current.mtimeMs && recorded.sizeBytes === current.sizeBytes;
|
|
20973
|
+
}
|
|
20974
|
+
function createLiveSessionRegistry(ports) {
|
|
20975
|
+
const { fs: fs14, sessionsDir } = ports;
|
|
20976
|
+
const known = /* @__PURE__ */ new Map();
|
|
20977
|
+
let tokens = /* @__PURE__ */ new Set();
|
|
20978
|
+
let bySessionId = /* @__PURE__ */ new Map();
|
|
20979
|
+
const recordNames = () => fs14.readdir(sessionsDir).filter(isSessionRecordName);
|
|
20980
|
+
const rebuildIndexes = () => {
|
|
20981
|
+
const records = [...known.values()].flatMap(({ record }) => record === void 0 ? [] : [record]);
|
|
20982
|
+
tokens = new Set(records.map((record) => record.token));
|
|
20983
|
+
bySessionId = new Map(records.flatMap((record) => record.sessionId === void 0 ? [] : [[record.sessionId, record]]));
|
|
20984
|
+
};
|
|
20985
|
+
const load = (name, stat) => {
|
|
20986
|
+
known.set(name, { stat: { mtimeMs: stat.mtimeMs, sizeBytes: stat.sizeBytes }, record: readFrontDoorSessionRecord(fs14, sessionsDir, name) });
|
|
20987
|
+
};
|
|
20988
|
+
const statOf = (name) => fs14.lstat(import_node_path33.default.join(sessionsDir, name));
|
|
20989
|
+
const reconcile = () => {
|
|
20990
|
+
const names = new Set(recordNames());
|
|
20991
|
+
let changed = false;
|
|
20992
|
+
for (const name of known.keys()) {
|
|
20993
|
+
if (!names.has(name)) {
|
|
20994
|
+
known.delete(name);
|
|
20995
|
+
changed = true;
|
|
20996
|
+
}
|
|
20997
|
+
}
|
|
20998
|
+
for (const name of names) {
|
|
20999
|
+
const held = known.get(name);
|
|
21000
|
+
const stat = statOf(name);
|
|
21001
|
+
if (stat === void 0) {
|
|
21002
|
+
changed = known.delete(name) || changed;
|
|
21003
|
+
} else if (!sameStat(held?.stat, stat)) {
|
|
21004
|
+
load(name, stat);
|
|
21005
|
+
changed = true;
|
|
21006
|
+
}
|
|
21007
|
+
}
|
|
21008
|
+
if (changed) {
|
|
21009
|
+
rebuildIndexes();
|
|
21010
|
+
}
|
|
21011
|
+
return changed;
|
|
21012
|
+
};
|
|
21013
|
+
return {
|
|
21014
|
+
admits: (token) => {
|
|
21015
|
+
if (isLiveCapability(token, tokens)) {
|
|
21016
|
+
return true;
|
|
21017
|
+
}
|
|
21018
|
+
return reconcile() && isLiveCapability(token, tokens);
|
|
21019
|
+
},
|
|
21020
|
+
modelsOf: (sessionId) => {
|
|
21021
|
+
const held = bySessionId.get(sessionId) ?? (reconcile() ? bySessionId.get(sessionId) : void 0);
|
|
21022
|
+
return held?.models;
|
|
21023
|
+
},
|
|
21024
|
+
rescan: () => {
|
|
21025
|
+
known.clear();
|
|
21026
|
+
for (const name of recordNames()) {
|
|
21027
|
+
const stat = statOf(name);
|
|
21028
|
+
if (stat !== void 0) {
|
|
21029
|
+
load(name, stat);
|
|
21030
|
+
}
|
|
21031
|
+
}
|
|
21032
|
+
rebuildIndexes();
|
|
21033
|
+
return [...known.values()].flatMap(({ record }) => record === void 0 ? [] : [summaryOf(record)]).sort((a, b) => a.pid - b.pid);
|
|
21034
|
+
},
|
|
21035
|
+
forget: (pids) => {
|
|
21036
|
+
for (const pid of pids) {
|
|
21037
|
+
known.delete(sessionRecordName(pid));
|
|
21038
|
+
}
|
|
21039
|
+
rebuildIndexes();
|
|
21040
|
+
}
|
|
21041
|
+
};
|
|
21042
|
+
}
|
|
21043
|
+
|
|
21044
|
+
// src/index.ts
|
|
20911
21045
|
init_supervisor();
|
|
20912
21046
|
init_read();
|
|
20913
21047
|
init_schema2();
|
|
@@ -20917,7 +21051,7 @@ init_plan2();
|
|
|
20917
21051
|
init_poolPick();
|
|
20918
21052
|
|
|
20919
21053
|
// src/agents/read.ts
|
|
20920
|
-
var
|
|
21054
|
+
var import_node_path34 = __toESM(require("node:path"), 1);
|
|
20921
21055
|
var import_zod34 = require("zod");
|
|
20922
21056
|
var PROJECTS_DIR = "projects";
|
|
20923
21057
|
var TASKS_DIR = "tasks";
|
|
@@ -20943,15 +21077,15 @@ function parseEntry2(project, entry) {
|
|
|
20943
21077
|
}
|
|
20944
21078
|
function listSessions2(fs14, configDir) {
|
|
20945
21079
|
const found = [];
|
|
20946
|
-
for (const project of fs14.readdir(
|
|
20947
|
-
const projectDir =
|
|
21080
|
+
for (const project of fs14.readdir(import_node_path34.default.join(configDir, PROJECTS_DIR))) {
|
|
21081
|
+
const projectDir = import_node_path34.default.join(configDir, PROJECTS_DIR, project);
|
|
20948
21082
|
const entries = /* @__PURE__ */ new Set();
|
|
20949
21083
|
for (const name of fs14.readdir(projectDir)) {
|
|
20950
21084
|
if (name.endsWith(TRANSCRIPT_SUFFIX)) {
|
|
20951
21085
|
entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
|
|
20952
21086
|
continue;
|
|
20953
21087
|
}
|
|
20954
|
-
const children = fs14.readdir(
|
|
21088
|
+
const children = fs14.readdir(import_node_path34.default.join(projectDir, name));
|
|
20955
21089
|
if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
|
|
20956
21090
|
entries.add(name);
|
|
20957
21091
|
}
|
|
@@ -20971,8 +21105,8 @@ function locateAgents(fs14, configDir, relativeDir, workflowRunId, report) {
|
|
|
20971
21105
|
const id = name.slice(AGENT_FILE_PREFIX.length, -META_SUFFIX.length);
|
|
20972
21106
|
located.push({
|
|
20973
21107
|
id,
|
|
20974
|
-
metaPath:
|
|
20975
|
-
transcriptPath:
|
|
21108
|
+
metaPath: import_node_path34.default.join(relativeDir, name),
|
|
21109
|
+
transcriptPath: import_node_path34.default.join(relativeDir, `${AGENT_FILE_PREFIX}${id}${TRANSCRIPT_SUFFIX}`),
|
|
20976
21110
|
workflowRunId
|
|
20977
21111
|
});
|
|
20978
21112
|
}
|
|
@@ -21015,7 +21149,7 @@ function describeFailure(error) {
|
|
|
21015
21149
|
}
|
|
21016
21150
|
function readFileOrReport(fs14, configDir, relative, report) {
|
|
21017
21151
|
try {
|
|
21018
|
-
return fs14.readFileUtf8(
|
|
21152
|
+
return fs14.readFileUtf8(import_node_path34.default.join(configDir, relative));
|
|
21019
21153
|
} catch (error) {
|
|
21020
21154
|
report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
|
|
21021
21155
|
return void 0;
|
|
@@ -21023,7 +21157,7 @@ function readFileOrReport(fs14, configDir, relative, report) {
|
|
|
21023
21157
|
}
|
|
21024
21158
|
function listDirOrReport(fs14, configDir, relative, report) {
|
|
21025
21159
|
try {
|
|
21026
|
-
return fs14.readdir(
|
|
21160
|
+
return fs14.readdir(import_node_path34.default.join(configDir, relative));
|
|
21027
21161
|
} catch (error) {
|
|
21028
21162
|
report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
|
|
21029
21163
|
return [];
|
|
@@ -21047,18 +21181,18 @@ var WorkflowRunFileSchema = import_zod34.z.object({
|
|
|
21047
21181
|
summary: import_zod34.z.string().optional()
|
|
21048
21182
|
});
|
|
21049
21183
|
function summariseSession(fs14, configDir, ref) {
|
|
21050
|
-
const sessionRelative =
|
|
21051
|
-
const subagentsRelative =
|
|
21052
|
-
const workflowsUnderSubagents =
|
|
21184
|
+
const sessionRelative = import_node_path34.default.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
21185
|
+
const subagentsRelative = import_node_path34.default.join(sessionRelative, SUBAGENTS_DIR);
|
|
21186
|
+
const workflowsUnderSubagents = import_node_path34.default.join(subagentsRelative, WORKFLOWS_DIR);
|
|
21053
21187
|
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
21054
|
-
let agentCount = fs14.readdir(
|
|
21055
|
-
for (const runDir of fs14.readdir(
|
|
21188
|
+
let agentCount = fs14.readdir(import_node_path34.default.join(configDir, subagentsRelative)).filter(isMeta).length;
|
|
21189
|
+
for (const runDir of fs14.readdir(import_node_path34.default.join(configDir, workflowsUnderSubagents))) {
|
|
21056
21190
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
21057
|
-
agentCount += fs14.readdir(
|
|
21191
|
+
agentCount += fs14.readdir(import_node_path34.default.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
21058
21192
|
}
|
|
21059
21193
|
}
|
|
21060
|
-
const workflowRunCount = fs14.readdir(
|
|
21061
|
-
const transcript = fs14.lstat(
|
|
21194
|
+
const workflowRunCount = fs14.readdir(import_node_path34.default.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
|
|
21195
|
+
const transcript = fs14.lstat(import_node_path34.default.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
|
|
21062
21196
|
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
21063
21197
|
}
|
|
21064
21198
|
function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
@@ -21066,13 +21200,13 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
|
21066
21200
|
const report = (problem) => {
|
|
21067
21201
|
problems.push(problem);
|
|
21068
21202
|
};
|
|
21069
|
-
const sessionRelative =
|
|
21070
|
-
const subagentsRelative =
|
|
21071
|
-
const workflowsUnderSubagents =
|
|
21203
|
+
const sessionRelative = import_node_path34.default.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
21204
|
+
const subagentsRelative = import_node_path34.default.join(sessionRelative, SUBAGENTS_DIR);
|
|
21205
|
+
const workflowsUnderSubagents = import_node_path34.default.join(subagentsRelative, WORKFLOWS_DIR);
|
|
21072
21206
|
const located = locateAgents(fs14, configDir, subagentsRelative, void 0, report);
|
|
21073
21207
|
for (const runDir of listDirOrReport(fs14, configDir, workflowsUnderSubagents, report)) {
|
|
21074
21208
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
21075
|
-
located.push(...locateAgents(fs14, configDir,
|
|
21209
|
+
located.push(...locateAgents(fs14, configDir, import_node_path34.default.join(workflowsUnderSubagents, runDir), runDir, report));
|
|
21076
21210
|
}
|
|
21077
21211
|
}
|
|
21078
21212
|
const agents = /* @__PURE__ */ new Map();
|
|
@@ -21113,7 +21247,7 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
|
21113
21247
|
superseded: ref.superseded,
|
|
21114
21248
|
agents: roots.sort().map(build),
|
|
21115
21249
|
tasks: readTasks(fs14, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
|
|
21116
|
-
workflowRuns: readWorkflowRuns(fs14, configDir,
|
|
21250
|
+
workflowRuns: readWorkflowRuns(fs14, configDir, import_node_path34.default.join(sessionRelative, WORKFLOWS_DIR), report),
|
|
21117
21251
|
problems
|
|
21118
21252
|
};
|
|
21119
21253
|
}
|
|
@@ -21178,12 +21312,12 @@ function ownTaskLists(sessionId) {
|
|
|
21178
21312
|
function readTasks(fs14, configDir, ownLists, sharedLists, report) {
|
|
21179
21313
|
const tasks = [];
|
|
21180
21314
|
[...ownLists, ...sharedLists].forEach((scope, index) => {
|
|
21181
|
-
const relativeDir =
|
|
21315
|
+
const relativeDir = import_node_path34.default.join(TASKS_DIR, scope);
|
|
21182
21316
|
for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
|
|
21183
21317
|
if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
|
|
21184
21318
|
continue;
|
|
21185
21319
|
}
|
|
21186
|
-
const relative =
|
|
21320
|
+
const relative = import_node_path34.default.join(relativeDir, name);
|
|
21187
21321
|
const text = readFileOrReport(fs14, configDir, relative, report);
|
|
21188
21322
|
const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
21189
21323
|
if (parsed.success) {
|
|
@@ -21201,7 +21335,7 @@ function readWorkflowRuns(fs14, configDir, relativeDir, report) {
|
|
|
21201
21335
|
if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
|
|
21202
21336
|
continue;
|
|
21203
21337
|
}
|
|
21204
|
-
const relative =
|
|
21338
|
+
const relative = import_node_path34.default.join(relativeDir, name);
|
|
21205
21339
|
const text = readFileOrReport(fs14, configDir, relative, report);
|
|
21206
21340
|
const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
21207
21341
|
if (!parsed.success) {
|
|
@@ -21217,7 +21351,7 @@ function readWorkflowRuns(fs14, configDir, relativeDir, report) {
|
|
|
21217
21351
|
}
|
|
21218
21352
|
|
|
21219
21353
|
// src/agents/sessions.ts
|
|
21220
|
-
var
|
|
21354
|
+
var import_node_path35 = __toESM(require("node:path"), 1);
|
|
21221
21355
|
init_cliError();
|
|
21222
21356
|
var SessionLookupError = class extends CliError {
|
|
21223
21357
|
constructor(message) {
|
|
@@ -21226,13 +21360,13 @@ var SessionLookupError = class extends CliError {
|
|
|
21226
21360
|
}
|
|
21227
21361
|
};
|
|
21228
21362
|
function identityConfigDir(identitiesDir, identity) {
|
|
21229
|
-
return
|
|
21363
|
+
return import_node_path35.default.join(identitiesDir, identity);
|
|
21230
21364
|
}
|
|
21231
21365
|
function historyStores(fs14, identitiesDir, identities) {
|
|
21232
21366
|
const byRealPath = /* @__PURE__ */ new Map();
|
|
21233
21367
|
for (const identity of identities) {
|
|
21234
21368
|
const configDir = identityConfigDir(identitiesDir, identity);
|
|
21235
|
-
const real = fs14.realpath(
|
|
21369
|
+
const real = fs14.realpath(import_node_path35.default.join(configDir, "projects"));
|
|
21236
21370
|
if (real === void 0) {
|
|
21237
21371
|
continue;
|
|
21238
21372
|
}
|
|
@@ -21638,6 +21772,7 @@ init_ownCli();
|
|
|
21638
21772
|
createLaunchEventPublisher,
|
|
21639
21773
|
createLeafCache,
|
|
21640
21774
|
createLifecycleApiRouter,
|
|
21775
|
+
createLiveSessionRegistry,
|
|
21641
21776
|
createProfile,
|
|
21642
21777
|
createQuotaExpiringPublisher,
|
|
21643
21778
|
createRcApiNodeHandler,
|