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.mjs
CHANGED
|
@@ -208,17 +208,23 @@ import stringWidth from "string-width";
|
|
|
208
208
|
function drawsNothing(text) {
|
|
209
209
|
return stringWidth(text.replace(BLANK_CELLS, "")) === 0;
|
|
210
210
|
}
|
|
211
|
-
var BLANK_CELLS;
|
|
211
|
+
var BLANK_CELLS, BLANK_CELLS_BUT_SPACE;
|
|
212
212
|
var init_blank = __esm({
|
|
213
213
|
"src/statusline/blank.ts"() {
|
|
214
214
|
"use strict";
|
|
215
215
|
BLANK_CELLS = /[\p{Zs}\u2800\u3164\uFFA0]/gu;
|
|
216
|
+
BLANK_CELLS_BUT_SPACE = new RegExp(`[${BLANK_CELLS.source}--[ ]]`, "gv");
|
|
216
217
|
}
|
|
217
218
|
});
|
|
218
219
|
|
|
219
220
|
// src/statusline/graphemes.ts
|
|
221
|
+
function* graphemeStream(text) {
|
|
222
|
+
for (const part of SEGMENTER.segment(text)) {
|
|
223
|
+
yield part.segment;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
220
226
|
function graphemesOf(text) {
|
|
221
|
-
return Array.from(
|
|
227
|
+
return Array.from(graphemeStream(text));
|
|
222
228
|
}
|
|
223
229
|
var SEGMENTER;
|
|
224
230
|
var init_graphemes = __esm({
|
|
@@ -298,17 +304,18 @@ function resolveStatusline(settings) {
|
|
|
298
304
|
}
|
|
299
305
|
return resolved;
|
|
300
306
|
}
|
|
301
|
-
var 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;
|
|
307
|
+
var 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;
|
|
302
308
|
var init_statusline = __esm({
|
|
303
309
|
"src/config/statusline.ts"() {
|
|
304
310
|
"use strict";
|
|
305
311
|
init_blank();
|
|
306
312
|
init_graphemes();
|
|
307
313
|
init_languages();
|
|
308
|
-
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "dailyCost", "sessionName", "duration", "speed"];
|
|
314
|
+
STATUSLINE_HEADER_SEGMENTS = ["model", "provider", "route", "account", "identity", "headroom", "project", "vcs", "effort", "advisor", "version", "outputStyle", "cost", "dailyCost", "sessionName", "duration", "speed", "extra"];
|
|
309
315
|
STATUSLINE_ROWS = ["context", "quota", "addedDirs", "gitFiles", "memory", "environment", "sessionTime", "promptCache", "compactions", "tokens", "tools", "skills", "mcp", "agents", "todos"];
|
|
310
316
|
STATUSLINE_SESSION_TIME_PARTS = ["started", "lastReply"];
|
|
311
317
|
PROMPT_CACHE_TTL_SECONDS = { fiveMinutes: 300, oneHour: 3600 };
|
|
318
|
+
ORANGE_PALETTE_INDEX = 208;
|
|
312
319
|
STATUSLINE_COLOUR_NAMES = [
|
|
313
320
|
"default",
|
|
314
321
|
"dim",
|
|
@@ -337,14 +344,14 @@ var init_statusline = __esm({
|
|
|
337
344
|
PRESET_BUNDLES = {
|
|
338
345
|
standard: { layout: { header: DEFAULT_HEADER_SEGMENTS, rows: DEFAULT_ROWS }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: false }, context: { breakdown: "never" } },
|
|
339
346
|
full: {
|
|
340
|
-
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"] },
|
|
347
|
+
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"] },
|
|
341
348
|
git: GIT_WITH_DIRTY_MARKER,
|
|
342
349
|
jj: { enabled: true, showDirty: true, showConflicts: true },
|
|
343
350
|
usage: { resetLabel: true },
|
|
344
351
|
context: { breakdown: "critical" }
|
|
345
352
|
},
|
|
346
|
-
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" } },
|
|
347
|
-
minimal: { layout: { header: ["model", "project", "vcs"], rows: ["context", "addedDirs"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } }
|
|
353
|
+
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" } },
|
|
354
|
+
minimal: { layout: { header: ["model", "project", "vcs", "extra"], rows: ["context", "addedDirs"] }, git: GIT_WITH_DIRTY_MARKER, jj: JJ_OFF, usage: { resetLabel: true }, context: { breakdown: "never" } }
|
|
348
355
|
};
|
|
349
356
|
STATUSLINE_PATH_LEVELS = ["1", "2", "3", "full"];
|
|
350
357
|
STATUSLINE_USAGE_VALUES = ["used", "remaining"];
|
|
@@ -358,6 +365,10 @@ var init_statusline = __esm({
|
|
|
358
365
|
MAX_BAR_CELLS = 40;
|
|
359
366
|
MAX_ACCOUNT_USER_CHARS = 254;
|
|
360
367
|
MAX_DISPLAY_TEXT_CHARS = 80;
|
|
368
|
+
MAX_EXTRA_COMMAND_ARGUMENTS = 16;
|
|
369
|
+
MAX_EXTRA_COMMAND_ARGUMENT_CHARS = 1024;
|
|
370
|
+
STATUSLINE_EXTRA_GROUP = "extra";
|
|
371
|
+
commandArgument = z2.string().max(MAX_EXTRA_COMMAND_ARGUMENT_CHARS).refine((argument) => !argument.includes("\0"), "must not contain a NUL character");
|
|
361
372
|
LABEL_RE2 = /^[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*$/u;
|
|
362
373
|
OPTIONAL_LABEL_RE = /^(?:[^\p{C}\p{Z}]+(?: [^\p{C}\p{Z}]+)*)?$/u;
|
|
363
374
|
mergeGroups = z2.array(distinctList(z2.enum(STATUSLINE_ROWS)).min(2)).refine((groups) => {
|
|
@@ -420,6 +431,15 @@ var init_statusline = __esm({
|
|
|
420
431
|
estimate: z2.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)}%).`),
|
|
421
432
|
breakdown: z2.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.")
|
|
422
433
|
},
|
|
434
|
+
customLine: {
|
|
435
|
+
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.`),
|
|
436
|
+
position: z2.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.")
|
|
437
|
+
},
|
|
438
|
+
extra: {
|
|
439
|
+
command: z2.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(
|
|
440
|
+
`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.`
|
|
441
|
+
)
|
|
442
|
+
},
|
|
423
443
|
bands: {
|
|
424
444
|
warnAt: wholePercent.describe("The whole percentage of use at which a bar turns yellow; it must be below criticalAt."),
|
|
425
445
|
criticalAt: wholePercent.describe("The whole percentage of use at which a bar turns red.")
|
|
@@ -476,7 +496,8 @@ var init_statusline = __esm({
|
|
|
476
496
|
git: colourValue.describe("The colour of the version control segment's wrapper text (`git:(` and `)`)."),
|
|
477
497
|
gitBranch: colourValue.describe("The colour of the branch or bookmark and its ahead, behind and dirty markers."),
|
|
478
498
|
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."),
|
|
479
|
-
agent: colourValue.describe("The colour of an agent's type in the agents row.")
|
|
499
|
+
agent: colourValue.describe("The colour of an agent's type in the agents row."),
|
|
500
|
+
custom: colourValue.describe("The colour of the custom line.")
|
|
480
501
|
},
|
|
481
502
|
project: {
|
|
482
503
|
pathLevels: z2.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."),
|
|
@@ -503,7 +524,7 @@ var init_statusline = __esm({
|
|
|
503
524
|
LANGUAGE_ALIASES = { zh: "zh-Hans", "zh-TW": "zh-Hant" };
|
|
504
525
|
TOP_LEVEL = {
|
|
505
526
|
language: z2.enum(STATUSLINE_LANGUAGES).describe(LANGUAGE_DESCRIPTION),
|
|
506
|
-
preset: z2.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.")
|
|
527
|
+
preset: z2.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.")
|
|
507
528
|
};
|
|
508
529
|
StatuslineSchema = z2.strictObject({
|
|
509
530
|
language: z2.enum(LANGUAGE_TAGS).transform(canonicalLanguage).describe(LANGUAGE_DESCRIPTION).optional(),
|
|
@@ -515,6 +536,8 @@ var init_statusline = __esm({
|
|
|
515
536
|
effort: z2.strictObject(SHAPES.effort).partial().optional(),
|
|
516
537
|
advisor: z2.strictObject(SHAPES.advisor).partial().optional(),
|
|
517
538
|
context: z2.strictObject({ ...SHAPES.context, warnAt: unsettable(SHAPES.context.warnAt), criticalAt: unsettable(SHAPES.context.criticalAt), autoCompactWindow: unsettable(SHAPES.context.autoCompactWindow) }).partial().optional(),
|
|
539
|
+
customLine: z2.strictObject(SHAPES.customLine).partial().optional(),
|
|
540
|
+
extra: z2.strictObject(SHAPES.extra).partial().optional(),
|
|
518
541
|
bands: z2.strictObject(SHAPES.bands).partial().optional(),
|
|
519
542
|
labels: z2.strictObject(SHAPES.labels).partial().optional(),
|
|
520
543
|
bar: z2.strictObject(SHAPES.bar).partial().optional(),
|
|
@@ -540,6 +563,8 @@ var init_statusline = __esm({
|
|
|
540
563
|
effort: z2.strictObject(SHAPES.effort),
|
|
541
564
|
advisor: z2.strictObject(SHAPES.advisor),
|
|
542
565
|
context: z2.strictObject(SHAPES.context),
|
|
566
|
+
customLine: z2.strictObject(SHAPES.customLine),
|
|
567
|
+
extra: z2.strictObject(SHAPES.extra),
|
|
543
568
|
bands: z2.strictObject(SHAPES.bands),
|
|
544
569
|
labels: z2.strictObject(SHAPES.labels),
|
|
545
570
|
bar: z2.strictObject(SHAPES.bar),
|
|
@@ -565,6 +590,8 @@ var init_statusline = __esm({
|
|
|
565
590
|
effort: { format: "full" },
|
|
566
591
|
advisor: { override: "" },
|
|
567
592
|
context: { bar: "shown", value: "both", estimate: "never", breakdown: "never" },
|
|
593
|
+
customLine: { text: "", position: "last" },
|
|
594
|
+
extra: { command: [] },
|
|
568
595
|
bands: { warnAt: 70, criticalAt: 90 },
|
|
569
596
|
labels: { fiveHour: "", sevenDay: "" },
|
|
570
597
|
bar: { width: 10, filled: "\u2588", empty: "\u2591" },
|
|
@@ -588,7 +615,8 @@ var init_statusline = __esm({
|
|
|
588
615
|
git: "magenta",
|
|
589
616
|
gitBranch: "cyan",
|
|
590
617
|
activity: "cyan",
|
|
591
|
-
agent: "magenta"
|
|
618
|
+
agent: "magenta",
|
|
619
|
+
custom: ORANGE_PALETTE_INDEX
|
|
592
620
|
},
|
|
593
621
|
project: { pathLevels: "1", addedDirsLayout: "inline" },
|
|
594
622
|
git: { enabled: true, showDirty: true, showAheadBehind: false, showLineDiff: false, branchOverflow: "truncate", pushWarnAt: 0, pushCriticalAt: 0 },
|
|
@@ -1099,6 +1127,10 @@ var init_schema = __esm({
|
|
|
1099
1127
|
configProfile: FileNameSchema.optional(),
|
|
1100
1128
|
identity: IdentitySelectorSchema.optional(),
|
|
1101
1129
|
when: WhenSchema.optional()
|
|
1130
|
+
}).superRefine((config, context) => {
|
|
1131
|
+
if (config.launch?.statusline?.[STATUSLINE_EXTRA_GROUP] !== void 0) {
|
|
1132
|
+
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" });
|
|
1133
|
+
}
|
|
1102
1134
|
});
|
|
1103
1135
|
HEADROOM_MODES = ["cache", "token"];
|
|
1104
1136
|
HEADROOM_CCR_MODES = ["default", "lossless", "none"];
|
|
@@ -1224,7 +1256,7 @@ function parseIgnoringUnrecognisedKeys(schema, raw) {
|
|
|
1224
1256
|
return second.success ? { success: true, data: second.data, ignored } : { success: false, issues: second.error.issues };
|
|
1225
1257
|
}
|
|
1226
1258
|
function describeIgnoredKeys(filePath, ignored) {
|
|
1227
|
-
const places = ignored.map(({ path:
|
|
1259
|
+
const places = ignored.map(({ path: path42, keys }) => `${path42.length === 0 ? "" : `${path42.map(String).join(".")}.`}${keys.join(", ")}`);
|
|
1228
1260
|
return `${filePath} has settings this version of agent-shim does not know and ignores: ${places.join("; ")}. A newer release may read them.`;
|
|
1229
1261
|
}
|
|
1230
1262
|
function noteIgnoredKeys(filePath, ignored) {
|
|
@@ -1246,9 +1278,9 @@ function restoreIgnoredKeys(filePath, value) {
|
|
|
1246
1278
|
return value;
|
|
1247
1279
|
}
|
|
1248
1280
|
const restored = structuredClone(value);
|
|
1249
|
-
for (const { path:
|
|
1281
|
+
for (const { path: path42, values } of ignored) {
|
|
1250
1282
|
let holder = restored;
|
|
1251
|
-
for (const step of
|
|
1283
|
+
for (const step of path42) {
|
|
1252
1284
|
holder = isRecord(holder) ? holder[step] : void 0;
|
|
1253
1285
|
}
|
|
1254
1286
|
if (isRecord(holder)) {
|
|
@@ -3879,28 +3911,38 @@ function recordOf(details) {
|
|
|
3879
3911
|
}
|
|
3880
3912
|
function writeFrontDoorSession(fs14, sessionsDir, session) {
|
|
3881
3913
|
fs14.mkdirPrivate(sessionsDir);
|
|
3882
|
-
fs14.writeFilePrivate(path9.join(sessionsDir,
|
|
3914
|
+
fs14.writeFilePrivate(path9.join(sessionsDir, sessionRecordName(session.pid)), `${JSON.stringify(session, null, 2)}
|
|
3883
3915
|
`);
|
|
3884
3916
|
}
|
|
3917
|
+
function sessionRecordName(pid) {
|
|
3918
|
+
return `${String(pid)}.json`;
|
|
3919
|
+
}
|
|
3920
|
+
function isSessionRecordName(name) {
|
|
3921
|
+
return name.endsWith(".json");
|
|
3922
|
+
}
|
|
3923
|
+
function summaryOf(session) {
|
|
3924
|
+
return { pid: session.pid, startedAt: session.startedAt, ...session.supervisorPid === void 0 ? {} : { supervisorPid: session.supervisorPid } };
|
|
3925
|
+
}
|
|
3926
|
+
function readFrontDoorSessionRecord(fs14, sessionsDir, name) {
|
|
3927
|
+
try {
|
|
3928
|
+
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs14.readFileUtf8(path9.join(sessionsDir, name)) ?? ""));
|
|
3929
|
+
return parsed.success ? parsed.data : void 0;
|
|
3930
|
+
} catch {
|
|
3931
|
+
return void 0;
|
|
3932
|
+
}
|
|
3933
|
+
}
|
|
3885
3934
|
function listFrontDoorSessions(fs14, sessionsDir) {
|
|
3886
3935
|
const sessions = [];
|
|
3887
3936
|
for (const name of fs14.readdir(sessionsDir)) {
|
|
3888
|
-
|
|
3889
|
-
|
|
3890
|
-
|
|
3891
|
-
try {
|
|
3892
|
-
const parsed = FrontDoorSessionSchema.safeParse(JSON.parse(fs14.readFileUtf8(path9.join(sessionsDir, name)) ?? ""));
|
|
3893
|
-
if (parsed.success) {
|
|
3894
|
-
sessions.push({ pid: parsed.data.pid, startedAt: parsed.data.startedAt, ...parsed.data.supervisorPid === void 0 ? {} : { supervisorPid: parsed.data.supervisorPid } });
|
|
3895
|
-
}
|
|
3896
|
-
} catch {
|
|
3897
|
-
continue;
|
|
3937
|
+
const record = isSessionRecordName(name) ? readFrontDoorSessionRecord(fs14, sessionsDir, name) : void 0;
|
|
3938
|
+
if (record !== void 0) {
|
|
3939
|
+
sessions.push(summaryOf(record));
|
|
3898
3940
|
}
|
|
3899
3941
|
}
|
|
3900
3942
|
return sessions.sort((a, b) => a.pid - b.pid);
|
|
3901
3943
|
}
|
|
3902
3944
|
function removeFrontDoorSession(fs14, sessionsDir, pid) {
|
|
3903
|
-
fs14.removeRecursive(path9.join(sessionsDir,
|
|
3945
|
+
fs14.removeRecursive(path9.join(sessionsDir, sessionRecordName(pid)));
|
|
3904
3946
|
}
|
|
3905
3947
|
function pruneDeadFrontDoorSessions(fs14, sessionsDir, listed, isRunning) {
|
|
3906
3948
|
const removed = [];
|
|
@@ -4159,9 +4201,10 @@ async function serveFrontDoor(idleShutdownMinutes, ports, options) {
|
|
|
4159
4201
|
return FRONTDOOR_SUPERVISOR_STILL_RUNNING;
|
|
4160
4202
|
}
|
|
4161
4203
|
ticks += 1;
|
|
4162
|
-
const listed =
|
|
4204
|
+
const listed = ports.registry.rescan();
|
|
4163
4205
|
const running = await ports.runningAmong(listed.map((session) => session.pid));
|
|
4164
4206
|
const pruned = pruneDeadFrontDoorSessions(fs14, paths.frontdoorSessionsDir, listed, (pid) => running.has(pid));
|
|
4207
|
+
ports.registry.forget(pruned);
|
|
4165
4208
|
ports.observeLaunchRegistry(listed, pruned);
|
|
4166
4209
|
ports.checkQuotaExpiry();
|
|
4167
4210
|
const prunedPids = new Set(pruned);
|
|
@@ -4235,8 +4278,8 @@ function parseConnectTarget(authority) {
|
|
|
4235
4278
|
function isInterceptedHost(host, interceptHosts) {
|
|
4236
4279
|
return interceptHosts.includes(host);
|
|
4237
4280
|
}
|
|
4238
|
-
function servedByPipeline(
|
|
4239
|
-
return
|
|
4281
|
+
function servedByPipeline(path42) {
|
|
4282
|
+
return path42?.startsWith(ROUTED_PATH_PREFIX) === true;
|
|
4240
4283
|
}
|
|
4241
4284
|
function forwardableHeaders(headers) {
|
|
4242
4285
|
const connectionTokens = new Set(
|
|
@@ -4680,7 +4723,7 @@ var init_package = __esm({
|
|
|
4680
4723
|
"package.json"() {
|
|
4681
4724
|
package_default = {
|
|
4682
4725
|
name: "claude-use",
|
|
4683
|
-
version: "11.
|
|
4726
|
+
version: "11.65.1",
|
|
4684
4727
|
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.",
|
|
4685
4728
|
license: "MIT",
|
|
4686
4729
|
author: "Joseph Mearman <joseph@mearman.co.uk>",
|
|
@@ -4786,7 +4829,6 @@ var init_package = __esm({
|
|
|
4786
4829
|
|
|
4787
4830
|
// src/blockingSpawn.ts
|
|
4788
4831
|
import {
|
|
4789
|
-
execFileSync,
|
|
4790
4832
|
spawnSync
|
|
4791
4833
|
} from "node:child_process";
|
|
4792
4834
|
function spawnSyncBlocking(operation, command, args, options) {
|
|
@@ -7887,9 +7929,9 @@ var init_poolPick = __esm({
|
|
|
7887
7929
|
|
|
7888
7930
|
// src/statusline/keys.ts
|
|
7889
7931
|
import { z as z16 } from "zod";
|
|
7890
|
-
function valueAt(source,
|
|
7932
|
+
function valueAt(source, path42) {
|
|
7891
7933
|
let current = source;
|
|
7892
|
-
for (const part of
|
|
7934
|
+
for (const part of path42) {
|
|
7893
7935
|
if (!isPlainObject(current)) {
|
|
7894
7936
|
return void 0;
|
|
7895
7937
|
}
|
|
@@ -7897,10 +7939,10 @@ function valueAt(source, path41) {
|
|
|
7897
7939
|
}
|
|
7898
7940
|
return current;
|
|
7899
7941
|
}
|
|
7900
|
-
function keyOf(
|
|
7942
|
+
function keyOf(path42, declared) {
|
|
7901
7943
|
const optional = declared instanceof z16.ZodOptional;
|
|
7902
7944
|
const leaf = optional ? declared.unwrap() : declared;
|
|
7903
|
-
const common = { path:
|
|
7945
|
+
const common = { path: path42.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path42), optional };
|
|
7904
7946
|
if (leaf instanceof z16.ZodNumber) {
|
|
7905
7947
|
return { ...common, kind: "integer", choices: [] };
|
|
7906
7948
|
}
|
|
@@ -7922,7 +7964,10 @@ function keyOf(path41, declared) {
|
|
|
7922
7964
|
if (leaf instanceof z16.ZodArray && leaf.element instanceof z16.ZodArray && leaf.element.element instanceof z16.ZodEnum) {
|
|
7923
7965
|
return { ...common, kind: "groups", choices: Object.values(leaf.element.element.enum).map(String) };
|
|
7924
7966
|
}
|
|
7925
|
-
|
|
7967
|
+
if (leaf instanceof z16.ZodArray && leaf.element instanceof z16.ZodString) {
|
|
7968
|
+
return { ...common, kind: "textList", choices: [] };
|
|
7969
|
+
}
|
|
7970
|
+
throw new TypeError(`statusline setting ${path42.join(".")} has a kind the key listing does not describe`);
|
|
7926
7971
|
}
|
|
7927
7972
|
function walk(shape, prefix) {
|
|
7928
7973
|
return Object.entries(shape).flatMap(([name, schema]) => schema instanceof z16.ZodObject ? walk(schema.shape, [...prefix, name]) : [keyOf([...prefix, name], schema)]);
|
|
@@ -7938,15 +7983,15 @@ var init_keys = __esm({
|
|
|
7938
7983
|
});
|
|
7939
7984
|
|
|
7940
7985
|
// src/statusline/change.ts
|
|
7941
|
-
function keyNamed(
|
|
7942
|
-
const found = statuslineKeys().find((key) => key.path ===
|
|
7986
|
+
function keyNamed(path42) {
|
|
7987
|
+
const found = statuslineKeys().find((key) => key.path === path42);
|
|
7943
7988
|
if (found === void 0) {
|
|
7944
|
-
throw new UsageError(`"${
|
|
7989
|
+
throw new UsageError(`"${path42}" is not a statusline setting; \`agent-shim statusline keys\` lists them.`);
|
|
7945
7990
|
}
|
|
7946
7991
|
return found;
|
|
7947
7992
|
}
|
|
7948
|
-
function setAt(target,
|
|
7949
|
-
const [head, ...rest] =
|
|
7993
|
+
function setAt(target, path42, value) {
|
|
7994
|
+
const [head, ...rest] = path42;
|
|
7950
7995
|
if (head === void 0) {
|
|
7951
7996
|
return;
|
|
7952
7997
|
}
|
|
@@ -7959,8 +8004,8 @@ function setAt(target, path41, value) {
|
|
|
7959
8004
|
target[head] = next;
|
|
7960
8005
|
setAt(next, rest, value);
|
|
7961
8006
|
}
|
|
7962
|
-
function removeAt(target,
|
|
7963
|
-
const [head, ...rest] =
|
|
8007
|
+
function removeAt(target, path42) {
|
|
8008
|
+
const [head, ...rest] = path42;
|
|
7964
8009
|
if (head === void 0) {
|
|
7965
8010
|
return;
|
|
7966
8011
|
}
|
|
@@ -7978,13 +8023,13 @@ function removeAt(target, path41) {
|
|
|
7978
8023
|
}
|
|
7979
8024
|
function applyStatuslineChange(existing, change) {
|
|
7980
8025
|
const draft = structuredClone(existing ?? {});
|
|
7981
|
-
for (const [
|
|
7982
|
-
keyNamed(
|
|
7983
|
-
setAt(draft,
|
|
8026
|
+
for (const [path42, value] of Object.entries(change.set ?? {})) {
|
|
8027
|
+
keyNamed(path42);
|
|
8028
|
+
setAt(draft, path42.split("."), value);
|
|
7984
8029
|
}
|
|
7985
|
-
for (const
|
|
7986
|
-
keyNamed(
|
|
7987
|
-
removeAt(draft,
|
|
8030
|
+
for (const path42 of change.unset ?? []) {
|
|
8031
|
+
keyNamed(path42);
|
|
8032
|
+
removeAt(draft, path42.split("."));
|
|
7988
8033
|
}
|
|
7989
8034
|
const result = StatuslineSchema.safeParse(draft);
|
|
7990
8035
|
if (!result.success) {
|
|
@@ -10721,7 +10766,7 @@ var init_settings2 = __esm({
|
|
|
10721
10766
|
});
|
|
10722
10767
|
|
|
10723
10768
|
// src/launcher/flags.ts
|
|
10724
|
-
import
|
|
10769
|
+
import path36 from "node:path";
|
|
10725
10770
|
function resolveLaunchFlags(params) {
|
|
10726
10771
|
const statusline = resolveStatuslineSettings(params);
|
|
10727
10772
|
return {
|
|
@@ -10777,7 +10822,7 @@ function buildEnv(params) {
|
|
|
10777
10822
|
const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
|
|
10778
10823
|
let providerCustomHeaders;
|
|
10779
10824
|
if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
|
|
10780
|
-
env.CLAUDE_CONFIG_DIR =
|
|
10825
|
+
env.CLAUDE_CONFIG_DIR = path36.join(params.identitiesDir, params.resolvedIdentityName);
|
|
10781
10826
|
}
|
|
10782
10827
|
if (params.provider !== void 0) {
|
|
10783
10828
|
const providerEnv = params.provider.definition.kind !== void 0 && params.provider.definition.kind !== "http" ? {} : params.provider.definition.env ?? {};
|
|
@@ -10869,7 +10914,7 @@ var init_extraFlags = __esm({
|
|
|
10869
10914
|
});
|
|
10870
10915
|
|
|
10871
10916
|
// src/usage/resumeContext.ts
|
|
10872
|
-
import
|
|
10917
|
+
import path37 from "node:path";
|
|
10873
10918
|
function projectDirNameOf(cwd) {
|
|
10874
10919
|
return cwd.replace(/[^A-Za-z0-9]/g, "-");
|
|
10875
10920
|
}
|
|
@@ -10927,7 +10972,7 @@ function newestTranscript(fs14, projectDir) {
|
|
|
10927
10972
|
if (!name.endsWith(".jsonl")) {
|
|
10928
10973
|
continue;
|
|
10929
10974
|
}
|
|
10930
|
-
const candidate =
|
|
10975
|
+
const candidate = path37.join(projectDir, name);
|
|
10931
10976
|
const stat = fs14.lstat(candidate);
|
|
10932
10977
|
if (stat?.kind === "file" && stat.mtimeMs > newestMs) {
|
|
10933
10978
|
newestMs = stat.mtimeMs;
|
|
@@ -10941,8 +10986,8 @@ function resumedContextTokens(fs14, params) {
|
|
|
10941
10986
|
if (target === void 0) {
|
|
10942
10987
|
return void 0;
|
|
10943
10988
|
}
|
|
10944
|
-
const projectDir =
|
|
10945
|
-
const file = target.kind === "id" ?
|
|
10989
|
+
const projectDir = path37.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
|
|
10990
|
+
const file = target.kind === "id" ? path37.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs14, projectDir);
|
|
10946
10991
|
const text = file === void 0 ? void 0 : fs14.readFileUtf8(file);
|
|
10947
10992
|
return text === void 0 ? void 0 : contextTokensOfTranscript(text);
|
|
10948
10993
|
}
|
|
@@ -11387,7 +11432,7 @@ var init_launchHook = __esm({
|
|
|
11387
11432
|
// src/launcher.ts
|
|
11388
11433
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
11389
11434
|
import { isDeepStrictEqual } from "node:util";
|
|
11390
|
-
import
|
|
11435
|
+
import path38 from "node:path";
|
|
11391
11436
|
function resolveIdentityCredential(identity, credential, env, port) {
|
|
11392
11437
|
if (port === void 0) {
|
|
11393
11438
|
return { ok: false, status: 1, message: `agent-shim: identity ${identity} needs its credential resolved, but this launcher has no credential port wired` };
|
|
@@ -11630,7 +11675,7 @@ function decideLaunch(params, readOnly) {
|
|
|
11630
11675
|
extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
|
|
11631
11676
|
passthrough: withLauncherSettings(params.supervised === void 0 ? parsedArgv.rest : withSupervision(parsedArgv.rest, params.supervised), launcherSettings)
|
|
11632
11677
|
});
|
|
11633
|
-
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR :
|
|
11678
|
+
const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : path38.join(paths.identitiesDir, identityDecision.name);
|
|
11634
11679
|
const decision = {
|
|
11635
11680
|
identitySource: identityDecision.source,
|
|
11636
11681
|
configDirEscapeHatch: identityDecision.configDirEscapeHatch,
|
|
@@ -11683,7 +11728,7 @@ function prepareLaunch(params) {
|
|
|
11683
11728
|
let warnings = [];
|
|
11684
11729
|
const updateCheck = runLaunchUpdateCheck({
|
|
11685
11730
|
mode: params.updateMode ?? "off",
|
|
11686
|
-
checkPath:
|
|
11731
|
+
checkPath: path38.join(paths.root, "update.check"),
|
|
11687
11732
|
currentVersion: package_default.version,
|
|
11688
11733
|
port: params.update
|
|
11689
11734
|
});
|
|
@@ -11871,12 +11916,12 @@ var init_launcher = __esm({
|
|
|
11871
11916
|
});
|
|
11872
11917
|
|
|
11873
11918
|
// src/ownCli.ts
|
|
11874
|
-
import
|
|
11919
|
+
import path39 from "node:path";
|
|
11875
11920
|
function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string" ? __AGENT_SHIM_DIST_DIR__ : void 0) {
|
|
11876
11921
|
if (distDir === void 0) {
|
|
11877
11922
|
throw new OwnCliPathUnknownError();
|
|
11878
11923
|
}
|
|
11879
|
-
return
|
|
11924
|
+
return path39.join(distDir, OWN_CLI_FILE_NAME);
|
|
11880
11925
|
}
|
|
11881
11926
|
var OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
|
|
11882
11927
|
var init_ownCli = __esm({
|
|
@@ -11922,10 +11967,10 @@ var init_selfIdentity = __esm({
|
|
|
11922
11967
|
|
|
11923
11968
|
// src/frontdoor/trust.ts
|
|
11924
11969
|
import { createHash as createHash7 } from "node:crypto";
|
|
11925
|
-
import
|
|
11970
|
+
import path40 from "node:path";
|
|
11926
11971
|
function resolveTrustBundle(params) {
|
|
11927
11972
|
const { caCertFile, bundlesDir, variable, inherited, fs: fs14 } = params;
|
|
11928
|
-
if (inherited === void 0 || inherited === "" ||
|
|
11973
|
+
if (inherited === void 0 || inherited === "" || path40.resolve(inherited) === path40.resolve(caCertFile)) {
|
|
11929
11974
|
return { path: caCertFile };
|
|
11930
11975
|
}
|
|
11931
11976
|
const caPem = fs14.readFileUtf8(caCertFile);
|
|
@@ -11943,7 +11988,7 @@ function resolveTrustBundle(params) {
|
|
|
11943
11988
|
}
|
|
11944
11989
|
const combined = `${inheritedPem.trimEnd()}
|
|
11945
11990
|
${caPem}`;
|
|
11946
|
-
const bundle =
|
|
11991
|
+
const bundle = path40.join(bundlesDir, `${createHash7("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
|
|
11947
11992
|
if (!fs14.exists(bundle)) {
|
|
11948
11993
|
fs14.mkdirp(bundlesDir);
|
|
11949
11994
|
fs14.writeFileAtomic(bundle, combined);
|
|
@@ -12076,7 +12121,7 @@ var init_replayRun = __esm({
|
|
|
12076
12121
|
|
|
12077
12122
|
// src/launchWiring.ts
|
|
12078
12123
|
import os8 from "node:os";
|
|
12079
|
-
import
|
|
12124
|
+
import path41 from "node:path";
|
|
12080
12125
|
import { randomUUID as randomUUID5 } from "node:crypto";
|
|
12081
12126
|
function buildFarmRuntime(paths, cwd, run = realRunPort) {
|
|
12082
12127
|
const home = os8.homedir();
|
|
@@ -12131,7 +12176,7 @@ function realPrepareLaunchParams(paths, options) {
|
|
|
12131
12176
|
frontdoor: realFrontDoorPort(paths, options.spawnDaemon),
|
|
12132
12177
|
credentials: { ...realCredentialPort, cache: realCredentialCacheEnv(paths) },
|
|
12133
12178
|
hold: realHoldPort,
|
|
12134
|
-
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot:
|
|
12179
|
+
hasStoredLogin: (identity) => identitySignIn(realFarmFs, { platform: process.platform, run: options.run ?? realRunPort }, { farmRoot: path41.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
|
|
12135
12180
|
...farm.directoryIdentity === void 0 ? {} : { directoryPinnedIdentity: farm.directoryIdentity },
|
|
12136
12181
|
...farm.directoryConfigProfile === void 0 ? {} : { directoryRuleConfigProfile: farm.directoryConfigProfile },
|
|
12137
12182
|
...farm.globalDefaultConfigProfile === void 0 ? {} : { globalDefaultConfigProfile: farm.globalDefaultConfigProfile },
|
|
@@ -13024,11 +13069,11 @@ function createRcSessionTracker(deps) {
|
|
|
13024
13069
|
};
|
|
13025
13070
|
const observeExchange = (request4) => {
|
|
13026
13071
|
const method = (request4.method ?? "").toUpperCase();
|
|
13027
|
-
const
|
|
13028
|
-
if (!
|
|
13072
|
+
const path42 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
|
|
13073
|
+
if (!path42.startsWith(RC_SESSIONS_PATH_PREFIX)) {
|
|
13029
13074
|
return void 0;
|
|
13030
13075
|
}
|
|
13031
|
-
const tail =
|
|
13076
|
+
const tail = path42.slice(RC_SESSIONS_PATH_PREFIX.length);
|
|
13032
13077
|
const facts = {
|
|
13033
13078
|
oauthAuthorization: oauthAuthorizationOf(request4.headers),
|
|
13034
13079
|
anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
|
|
@@ -13145,7 +13190,7 @@ function createRcSessionTracker(deps) {
|
|
|
13145
13190
|
}
|
|
13146
13191
|
};
|
|
13147
13192
|
};
|
|
13148
|
-
const
|
|
13193
|
+
const summaryOf2 = ({ id, createdAt, lastSeenAt }) => ({ id, createdAt, lastSeenAt });
|
|
13149
13194
|
const pendingSummaryOf = ({ sessionId, requestId, type, summary, observedAt: observedAt2 }) => ({ sessionId, requestId, type, summary, observedAt: observedAt2 });
|
|
13150
13195
|
const sortedEntries = () => [...entries.values()].sort((left, right) => left.createdAt - right.createdAt || (left.id < right.id ? -1 : 1));
|
|
13151
13196
|
const pendingSorted = (entry) => [...entry.pending.values()].sort((left, right) => left.observedAt - right.observedAt || (left.requestId < right.requestId ? -1 : 1)).map(pendingSummaryOf);
|
|
@@ -13153,11 +13198,11 @@ function createRcSessionTracker(deps) {
|
|
|
13153
13198
|
observeExchange,
|
|
13154
13199
|
list: () => {
|
|
13155
13200
|
sweep();
|
|
13156
|
-
return sortedEntries().map(
|
|
13201
|
+
return sortedEntries().map(summaryOf2);
|
|
13157
13202
|
},
|
|
13158
13203
|
statusOf: (sessionId) => {
|
|
13159
13204
|
sweep();
|
|
13160
|
-
return sortedEntries().filter((entry) => sessionId === void 0 || entry.id === sessionId).map((entry) => ({ ...
|
|
13205
|
+
return sortedEntries().filter((entry) => sessionId === void 0 || entry.id === sessionId).map((entry) => ({ ...summaryOf2(entry), workerState: entry.workerState, workerIdleSeconds: entry.workerIdleSeconds, pending: pendingSorted(entry) }));
|
|
13161
13206
|
},
|
|
13162
13207
|
pendingOf: (sessionId) => {
|
|
13163
13208
|
sweep();
|
|
@@ -13418,8 +13463,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
|
|
|
13418
13463
|
function isRcReadFileEncoding(value) {
|
|
13419
13464
|
return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
|
|
13420
13465
|
}
|
|
13421
|
-
function buildRcReadFilePayload(requestId,
|
|
13422
|
-
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path:
|
|
13466
|
+
function buildRcReadFilePayload(requestId, path42, options) {
|
|
13467
|
+
return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path42, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
|
|
13423
13468
|
}
|
|
13424
13469
|
function buildRcFileSuggestionsPayload(requestId, query) {
|
|
13425
13470
|
return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
|
|
@@ -13521,15 +13566,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
|
|
|
13521
13566
|
const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
|
|
13522
13567
|
return result.ok ? { ...result, requestId } : result;
|
|
13523
13568
|
}
|
|
13524
|
-
async function readRcSessionFile(deps, sessionId,
|
|
13525
|
-
if (
|
|
13569
|
+
async function readRcSessionFile(deps, sessionId, path42, options) {
|
|
13570
|
+
if (path42 === "") {
|
|
13526
13571
|
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" };
|
|
13527
13572
|
}
|
|
13528
13573
|
if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
|
|
13529
13574
|
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" };
|
|
13530
13575
|
}
|
|
13531
13576
|
const requestId = deps.newUuid();
|
|
13532
|
-
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId,
|
|
13577
|
+
const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path42, options), `read ${path42} from session ${sessionId}`);
|
|
13533
13578
|
return result.ok ? { ...result, requestId } : result;
|
|
13534
13579
|
}
|
|
13535
13580
|
async function suggestRcSessionFiles(deps, sessionId, query) {
|
|
@@ -13698,11 +13743,11 @@ function createRcControlHandler(deps) {
|
|
|
13698
13743
|
path: "read-file",
|
|
13699
13744
|
read: (body) => {
|
|
13700
13745
|
const session = bodyString(body, "session");
|
|
13701
|
-
const
|
|
13746
|
+
const path42 = bodyString(body, "path");
|
|
13702
13747
|
const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
|
|
13703
13748
|
const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
|
|
13704
|
-
const refused2 = session === void 0 ||
|
|
13705
|
-
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,
|
|
13749
|
+
const refused2 = session === void 0 || path42 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
|
|
13750
|
+
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 } }) };
|
|
13706
13751
|
}
|
|
13707
13752
|
},
|
|
13708
13753
|
{
|
|
@@ -14012,9 +14057,9 @@ function requestIdOfBody(body) {
|
|
|
14012
14057
|
}
|
|
14013
14058
|
function frontDoorRcControl(transport, token) {
|
|
14014
14059
|
const headers = { authorization: `Bearer ${token}` };
|
|
14015
|
-
const listAnswerOf = async (
|
|
14060
|
+
const listAnswerOf = async (path42, what) => {
|
|
14016
14061
|
try {
|
|
14017
|
-
return await transport.request({ method: "GET", path:
|
|
14062
|
+
return await transport.request({ method: "GET", path: path42, headers });
|
|
14018
14063
|
} catch (error) {
|
|
14019
14064
|
throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
|
|
14020
14065
|
}
|
|
@@ -14086,10 +14131,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
14086
14131
|
}
|
|
14087
14132
|
return pending;
|
|
14088
14133
|
};
|
|
14089
|
-
const writeOf = async (
|
|
14134
|
+
const writeOf = async (path42, body, describeFailure2) => {
|
|
14090
14135
|
let answer;
|
|
14091
14136
|
try {
|
|
14092
|
-
answer = await transport.request({ method: "POST", path:
|
|
14137
|
+
answer = await transport.request({ method: "POST", path: path42, headers: { ...headers, "content-type": "application/json" }, body });
|
|
14093
14138
|
} catch (error) {
|
|
14094
14139
|
return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
|
|
14095
14140
|
}
|
|
@@ -14120,10 +14165,10 @@ function frontDoorRcControl(transport, token) {
|
|
|
14120
14165
|
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}`),
|
|
14121
14166
|
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}`),
|
|
14122
14167
|
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}`),
|
|
14123
|
-
readFile: async (sessionId,
|
|
14168
|
+
readFile: async (sessionId, path42, options) => await writeOf(
|
|
14124
14169
|
`${CONTROL_PATH_PREFIX}/read-file`,
|
|
14125
|
-
JSON.stringify({ session: sessionId, path:
|
|
14126
|
-
(status, message) => `reading ${
|
|
14170
|
+
JSON.stringify({ session: sessionId, path: path42, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
|
|
14171
|
+
(status, message) => `reading ${path42} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
|
|
14127
14172
|
),
|
|
14128
14173
|
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}`),
|
|
14129
14174
|
keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
|
|
@@ -14282,12 +14327,12 @@ function tlsFacts(options) {
|
|
|
14282
14327
|
}
|
|
14283
14328
|
function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
14284
14329
|
const agent = new ExemptTlsAgent();
|
|
14285
|
-
const post = async (
|
|
14330
|
+
const post = async (path42, headers, body) => await new Promise((resolve, reject) => {
|
|
14286
14331
|
const options = {
|
|
14287
14332
|
host: target.host,
|
|
14288
14333
|
port: target.port,
|
|
14289
14334
|
method: "POST",
|
|
14290
|
-
path:
|
|
14335
|
+
path: path42,
|
|
14291
14336
|
// 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.
|
|
14292
14337
|
headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
|
|
14293
14338
|
agent
|
|
@@ -14352,12 +14397,12 @@ function lateRcStreamDial(resolve) {
|
|
|
14352
14397
|
}
|
|
14353
14398
|
function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
|
|
14354
14399
|
const agent = new ExemptTlsAgent();
|
|
14355
|
-
const request4 = async (method,
|
|
14400
|
+
const request4 = async (method, path42, headers, body, signal) => await new Promise((resolve, reject) => {
|
|
14356
14401
|
const options = {
|
|
14357
14402
|
host: target.host,
|
|
14358
14403
|
port: target.port,
|
|
14359
14404
|
method,
|
|
14360
|
-
path:
|
|
14405
|
+
path: path42,
|
|
14361
14406
|
// 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.
|
|
14362
14407
|
headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
|
|
14363
14408
|
agent,
|
|
@@ -14399,9 +14444,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
|
|
|
14399
14444
|
return { status, body: await readAll(response) };
|
|
14400
14445
|
},
|
|
14401
14446
|
openStream: async (sessionId, headers, resume, signal) => {
|
|
14402
|
-
const
|
|
14447
|
+
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)}`;
|
|
14403
14448
|
const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
|
|
14404
|
-
const { status, response } = await request4("GET",
|
|
14449
|
+
const { status, response } = await request4("GET", path42, streamHeaders, void 0, signal);
|
|
14405
14450
|
if (!isSuccessful2(status)) {
|
|
14406
14451
|
await readAll(response);
|
|
14407
14452
|
return { status, chunks: NO_CHUNKS };
|
|
@@ -15394,19 +15439,19 @@ function writePools(paths, pools) {
|
|
|
15394
15439
|
applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
|
|
15395
15440
|
}
|
|
15396
15441
|
function poolCycleOf(pools, name) {
|
|
15397
|
-
const walk2 = (current,
|
|
15442
|
+
const walk2 = (current, path42) => {
|
|
15398
15443
|
for (const entry of pools[current]?.identities ?? []) {
|
|
15399
15444
|
const nested = poolNameOf(poolMemberIdentity(entry));
|
|
15400
15445
|
if (nested === void 0) {
|
|
15401
15446
|
continue;
|
|
15402
15447
|
}
|
|
15403
15448
|
if (nested === name) {
|
|
15404
|
-
return [...
|
|
15449
|
+
return [...path42, nested];
|
|
15405
15450
|
}
|
|
15406
|
-
if (
|
|
15451
|
+
if (path42.includes(nested)) {
|
|
15407
15452
|
continue;
|
|
15408
15453
|
}
|
|
15409
|
-
const found = walk2(nested, [...
|
|
15454
|
+
const found = walk2(nested, [...path42, nested]);
|
|
15410
15455
|
if (found !== void 0) {
|
|
15411
15456
|
return found;
|
|
15412
15457
|
}
|
|
@@ -17640,6 +17685,7 @@ init_providersStore();
|
|
|
17640
17685
|
|
|
17641
17686
|
// src/frontdoor/configSchemas.ts
|
|
17642
17687
|
init_schema();
|
|
17688
|
+
init_statusline();
|
|
17643
17689
|
import { z as z30 } from "zod";
|
|
17644
17690
|
var RemovalConfirmationSchema = z30.boolean();
|
|
17645
17691
|
var CredentialWriteSchema = (targets) => z30.strictObject({
|
|
@@ -17693,6 +17739,13 @@ var ConfigIdentitySetInputSchema = z30.strictObject({
|
|
|
17693
17739
|
var ConfigIdentitySetOutputSchema = storedMutationOutput("identity", "updated", IdentityValueSchema);
|
|
17694
17740
|
var ConfigIdentityRemoveInputSchema = z30.strictObject({ name: z30.string().min(1), confirm: RemovalConfirmationSchema });
|
|
17695
17741
|
var ConfigIdentityRemoveOutputSchema = mutationOutput("identity", "removed");
|
|
17742
|
+
var ConfigStatuslineSetSchema = z30.record(z30.string(), z30.unknown()).superRefine((settings, context) => {
|
|
17743
|
+
for (const key of Object.keys(settings)) {
|
|
17744
|
+
if (key === STATUSLINE_EXTRA_GROUP || key.startsWith(`${STATUSLINE_EXTRA_GROUP}.`)) {
|
|
17745
|
+
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` });
|
|
17746
|
+
}
|
|
17747
|
+
}
|
|
17748
|
+
});
|
|
17696
17749
|
var ConfigIdentityUseOutputSchema = mutationOutput("identity", "selected");
|
|
17697
17750
|
var ConfigProfileAddInputSchema = z30.strictObject({
|
|
17698
17751
|
name: z30.string().min(1),
|
|
@@ -17718,7 +17771,7 @@ var ConfigProfileSetInputSchema = z30.strictObject({
|
|
|
17718
17771
|
explain: z30.boolean().optional(),
|
|
17719
17772
|
proxyBypass: z30.union([z30.array(z30.string().min(1)), z30.literal(false)]).optional(),
|
|
17720
17773
|
statusline: z30.strictObject({
|
|
17721
|
-
set:
|
|
17774
|
+
set: ConfigStatuslineSetSchema.optional(),
|
|
17722
17775
|
unset: z30.array(z30.string()).optional()
|
|
17723
17776
|
}).optional()
|
|
17724
17777
|
}).optional()
|
|
@@ -17844,7 +17897,7 @@ function profileValue(name, paths) {
|
|
|
17844
17897
|
function createConfigApiRouter(deps) {
|
|
17845
17898
|
const authed = doorApiAuth(deps.expectedToken);
|
|
17846
17899
|
const { paths } = deps;
|
|
17847
|
-
const route = (
|
|
17900
|
+
const route = (path42, summary) => authed.meta(openapi3({ method: "POST", path: path42, summary, tags: [CONFIG_API_TAG] }));
|
|
17848
17901
|
return {
|
|
17849
17902
|
config: {
|
|
17850
17903
|
identity: {
|
|
@@ -20495,6 +20548,85 @@ function mintRcSelfHostCredential(deps) {
|
|
|
20495
20548
|
|
|
20496
20549
|
// src/index.ts
|
|
20497
20550
|
init_ensure2();
|
|
20551
|
+
|
|
20552
|
+
// src/frontdoor/liveSessionRegistry.ts
|
|
20553
|
+
init_capability();
|
|
20554
|
+
init_state();
|
|
20555
|
+
import path33 from "node:path";
|
|
20556
|
+
function sameStat(recorded, current) {
|
|
20557
|
+
return recorded?.mtimeMs === current.mtimeMs && recorded.sizeBytes === current.sizeBytes;
|
|
20558
|
+
}
|
|
20559
|
+
function createLiveSessionRegistry(ports) {
|
|
20560
|
+
const { fs: fs14, sessionsDir } = ports;
|
|
20561
|
+
const known = /* @__PURE__ */ new Map();
|
|
20562
|
+
let tokens = /* @__PURE__ */ new Set();
|
|
20563
|
+
let bySessionId = /* @__PURE__ */ new Map();
|
|
20564
|
+
const recordNames = () => fs14.readdir(sessionsDir).filter(isSessionRecordName);
|
|
20565
|
+
const rebuildIndexes = () => {
|
|
20566
|
+
const records = [...known.values()].flatMap(({ record }) => record === void 0 ? [] : [record]);
|
|
20567
|
+
tokens = new Set(records.map((record) => record.token));
|
|
20568
|
+
bySessionId = new Map(records.flatMap((record) => record.sessionId === void 0 ? [] : [[record.sessionId, record]]));
|
|
20569
|
+
};
|
|
20570
|
+
const load = (name, stat) => {
|
|
20571
|
+
known.set(name, { stat: { mtimeMs: stat.mtimeMs, sizeBytes: stat.sizeBytes }, record: readFrontDoorSessionRecord(fs14, sessionsDir, name) });
|
|
20572
|
+
};
|
|
20573
|
+
const statOf = (name) => fs14.lstat(path33.join(sessionsDir, name));
|
|
20574
|
+
const reconcile = () => {
|
|
20575
|
+
const names = new Set(recordNames());
|
|
20576
|
+
let changed = false;
|
|
20577
|
+
for (const name of known.keys()) {
|
|
20578
|
+
if (!names.has(name)) {
|
|
20579
|
+
known.delete(name);
|
|
20580
|
+
changed = true;
|
|
20581
|
+
}
|
|
20582
|
+
}
|
|
20583
|
+
for (const name of names) {
|
|
20584
|
+
const held = known.get(name);
|
|
20585
|
+
const stat = statOf(name);
|
|
20586
|
+
if (stat === void 0) {
|
|
20587
|
+
changed = known.delete(name) || changed;
|
|
20588
|
+
} else if (!sameStat(held?.stat, stat)) {
|
|
20589
|
+
load(name, stat);
|
|
20590
|
+
changed = true;
|
|
20591
|
+
}
|
|
20592
|
+
}
|
|
20593
|
+
if (changed) {
|
|
20594
|
+
rebuildIndexes();
|
|
20595
|
+
}
|
|
20596
|
+
return changed;
|
|
20597
|
+
};
|
|
20598
|
+
return {
|
|
20599
|
+
admits: (token) => {
|
|
20600
|
+
if (isLiveCapability(token, tokens)) {
|
|
20601
|
+
return true;
|
|
20602
|
+
}
|
|
20603
|
+
return reconcile() && isLiveCapability(token, tokens);
|
|
20604
|
+
},
|
|
20605
|
+
modelsOf: (sessionId) => {
|
|
20606
|
+
const held = bySessionId.get(sessionId) ?? (reconcile() ? bySessionId.get(sessionId) : void 0);
|
|
20607
|
+
return held?.models;
|
|
20608
|
+
},
|
|
20609
|
+
rescan: () => {
|
|
20610
|
+
known.clear();
|
|
20611
|
+
for (const name of recordNames()) {
|
|
20612
|
+
const stat = statOf(name);
|
|
20613
|
+
if (stat !== void 0) {
|
|
20614
|
+
load(name, stat);
|
|
20615
|
+
}
|
|
20616
|
+
}
|
|
20617
|
+
rebuildIndexes();
|
|
20618
|
+
return [...known.values()].flatMap(({ record }) => record === void 0 ? [] : [summaryOf(record)]).sort((a, b) => a.pid - b.pid);
|
|
20619
|
+
},
|
|
20620
|
+
forget: (pids) => {
|
|
20621
|
+
for (const pid of pids) {
|
|
20622
|
+
known.delete(sessionRecordName(pid));
|
|
20623
|
+
}
|
|
20624
|
+
rebuildIndexes();
|
|
20625
|
+
}
|
|
20626
|
+
};
|
|
20627
|
+
}
|
|
20628
|
+
|
|
20629
|
+
// src/index.ts
|
|
20498
20630
|
init_supervisor();
|
|
20499
20631
|
init_read();
|
|
20500
20632
|
init_schema2();
|
|
@@ -20504,7 +20636,7 @@ init_plan2();
|
|
|
20504
20636
|
init_poolPick();
|
|
20505
20637
|
|
|
20506
20638
|
// src/agents/read.ts
|
|
20507
|
-
import
|
|
20639
|
+
import path34 from "node:path";
|
|
20508
20640
|
import { z as z34 } from "zod";
|
|
20509
20641
|
var PROJECTS_DIR = "projects";
|
|
20510
20642
|
var TASKS_DIR = "tasks";
|
|
@@ -20530,15 +20662,15 @@ function parseEntry2(project, entry) {
|
|
|
20530
20662
|
}
|
|
20531
20663
|
function listSessions2(fs14, configDir) {
|
|
20532
20664
|
const found = [];
|
|
20533
|
-
for (const project of fs14.readdir(
|
|
20534
|
-
const projectDir =
|
|
20665
|
+
for (const project of fs14.readdir(path34.join(configDir, PROJECTS_DIR))) {
|
|
20666
|
+
const projectDir = path34.join(configDir, PROJECTS_DIR, project);
|
|
20535
20667
|
const entries = /* @__PURE__ */ new Set();
|
|
20536
20668
|
for (const name of fs14.readdir(projectDir)) {
|
|
20537
20669
|
if (name.endsWith(TRANSCRIPT_SUFFIX)) {
|
|
20538
20670
|
entries.add(name.slice(0, -TRANSCRIPT_SUFFIX.length));
|
|
20539
20671
|
continue;
|
|
20540
20672
|
}
|
|
20541
|
-
const children = fs14.readdir(
|
|
20673
|
+
const children = fs14.readdir(path34.join(projectDir, name));
|
|
20542
20674
|
if (children.includes(SUBAGENTS_DIR) || children.includes(WORKFLOWS_DIR)) {
|
|
20543
20675
|
entries.add(name);
|
|
20544
20676
|
}
|
|
@@ -20558,8 +20690,8 @@ function locateAgents(fs14, configDir, relativeDir, workflowRunId, report) {
|
|
|
20558
20690
|
const id = name.slice(AGENT_FILE_PREFIX.length, -META_SUFFIX.length);
|
|
20559
20691
|
located.push({
|
|
20560
20692
|
id,
|
|
20561
|
-
metaPath:
|
|
20562
|
-
transcriptPath:
|
|
20693
|
+
metaPath: path34.join(relativeDir, name),
|
|
20694
|
+
transcriptPath: path34.join(relativeDir, `${AGENT_FILE_PREFIX}${id}${TRANSCRIPT_SUFFIX}`),
|
|
20563
20695
|
workflowRunId
|
|
20564
20696
|
});
|
|
20565
20697
|
}
|
|
@@ -20602,7 +20734,7 @@ function describeFailure(error) {
|
|
|
20602
20734
|
}
|
|
20603
20735
|
function readFileOrReport(fs14, configDir, relative, report) {
|
|
20604
20736
|
try {
|
|
20605
|
-
return fs14.readFileUtf8(
|
|
20737
|
+
return fs14.readFileUtf8(path34.join(configDir, relative));
|
|
20606
20738
|
} catch (error) {
|
|
20607
20739
|
report({ path: relative, reason: `could not be read: ${describeFailure(error)}` });
|
|
20608
20740
|
return void 0;
|
|
@@ -20610,7 +20742,7 @@ function readFileOrReport(fs14, configDir, relative, report) {
|
|
|
20610
20742
|
}
|
|
20611
20743
|
function listDirOrReport(fs14, configDir, relative, report) {
|
|
20612
20744
|
try {
|
|
20613
|
-
return fs14.readdir(
|
|
20745
|
+
return fs14.readdir(path34.join(configDir, relative));
|
|
20614
20746
|
} catch (error) {
|
|
20615
20747
|
report({ path: relative, reason: `could not be listed: ${describeFailure(error)}` });
|
|
20616
20748
|
return [];
|
|
@@ -20634,18 +20766,18 @@ var WorkflowRunFileSchema = z34.object({
|
|
|
20634
20766
|
summary: z34.string().optional()
|
|
20635
20767
|
});
|
|
20636
20768
|
function summariseSession(fs14, configDir, ref) {
|
|
20637
|
-
const sessionRelative =
|
|
20638
|
-
const subagentsRelative =
|
|
20639
|
-
const workflowsUnderSubagents =
|
|
20769
|
+
const sessionRelative = path34.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
20770
|
+
const subagentsRelative = path34.join(sessionRelative, SUBAGENTS_DIR);
|
|
20771
|
+
const workflowsUnderSubagents = path34.join(subagentsRelative, WORKFLOWS_DIR);
|
|
20640
20772
|
const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
|
|
20641
|
-
let agentCount = fs14.readdir(
|
|
20642
|
-
for (const runDir of fs14.readdir(
|
|
20773
|
+
let agentCount = fs14.readdir(path34.join(configDir, subagentsRelative)).filter(isMeta).length;
|
|
20774
|
+
for (const runDir of fs14.readdir(path34.join(configDir, workflowsUnderSubagents))) {
|
|
20643
20775
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
20644
|
-
agentCount += fs14.readdir(
|
|
20776
|
+
agentCount += fs14.readdir(path34.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
|
|
20645
20777
|
}
|
|
20646
20778
|
}
|
|
20647
|
-
const workflowRunCount = fs14.readdir(
|
|
20648
|
-
const transcript = fs14.lstat(
|
|
20779
|
+
const workflowRunCount = fs14.readdir(path34.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
|
|
20780
|
+
const transcript = fs14.lstat(path34.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
|
|
20649
20781
|
return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
|
|
20650
20782
|
}
|
|
20651
20783
|
function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
@@ -20653,13 +20785,13 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
|
20653
20785
|
const report = (problem) => {
|
|
20654
20786
|
problems.push(problem);
|
|
20655
20787
|
};
|
|
20656
|
-
const sessionRelative =
|
|
20657
|
-
const subagentsRelative =
|
|
20658
|
-
const workflowsUnderSubagents =
|
|
20788
|
+
const sessionRelative = path34.join(PROJECTS_DIR, ref.project, ref.entry);
|
|
20789
|
+
const subagentsRelative = path34.join(sessionRelative, SUBAGENTS_DIR);
|
|
20790
|
+
const workflowsUnderSubagents = path34.join(subagentsRelative, WORKFLOWS_DIR);
|
|
20659
20791
|
const located = locateAgents(fs14, configDir, subagentsRelative, void 0, report);
|
|
20660
20792
|
for (const runDir of listDirOrReport(fs14, configDir, workflowsUnderSubagents, report)) {
|
|
20661
20793
|
if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
|
|
20662
|
-
located.push(...locateAgents(fs14, configDir,
|
|
20794
|
+
located.push(...locateAgents(fs14, configDir, path34.join(workflowsUnderSubagents, runDir), runDir, report));
|
|
20663
20795
|
}
|
|
20664
20796
|
}
|
|
20665
20797
|
const agents = /* @__PURE__ */ new Map();
|
|
@@ -20700,7 +20832,7 @@ function readSessionAgentTree(fs14, configDir, ref, options = {}) {
|
|
|
20700
20832
|
superseded: ref.superseded,
|
|
20701
20833
|
agents: roots.sort().map(build),
|
|
20702
20834
|
tasks: readTasks(fs14, configDir, ownTaskLists(ref.sessionId), [.../* @__PURE__ */ new Set([...teamNames, ...options.taskListIds ?? []])].filter((id) => !ownTaskLists(ref.sessionId).includes(id)), report),
|
|
20703
|
-
workflowRuns: readWorkflowRuns(fs14, configDir,
|
|
20835
|
+
workflowRuns: readWorkflowRuns(fs14, configDir, path34.join(sessionRelative, WORKFLOWS_DIR), report),
|
|
20704
20836
|
problems
|
|
20705
20837
|
};
|
|
20706
20838
|
}
|
|
@@ -20765,12 +20897,12 @@ function ownTaskLists(sessionId) {
|
|
|
20765
20897
|
function readTasks(fs14, configDir, ownLists, sharedLists, report) {
|
|
20766
20898
|
const tasks = [];
|
|
20767
20899
|
[...ownLists, ...sharedLists].forEach((scope, index) => {
|
|
20768
|
-
const relativeDir =
|
|
20900
|
+
const relativeDir = path34.join(TASKS_DIR, scope);
|
|
20769
20901
|
for (const name of [...listDirOrReport(fs14, configDir, relativeDir, report)].sort()) {
|
|
20770
20902
|
if (name.startsWith(".") || !name.endsWith(JSON_SUFFIX)) {
|
|
20771
20903
|
continue;
|
|
20772
20904
|
}
|
|
20773
|
-
const relative =
|
|
20905
|
+
const relative = path34.join(relativeDir, name);
|
|
20774
20906
|
const text = readFileOrReport(fs14, configDir, relative, report);
|
|
20775
20907
|
const parsed = TaskFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
20776
20908
|
if (parsed.success) {
|
|
@@ -20788,7 +20920,7 @@ function readWorkflowRuns(fs14, configDir, relativeDir, report) {
|
|
|
20788
20920
|
if (!name.startsWith(WORKFLOW_RUN_PREFIX) || !name.endsWith(JSON_SUFFIX)) {
|
|
20789
20921
|
continue;
|
|
20790
20922
|
}
|
|
20791
|
-
const relative =
|
|
20923
|
+
const relative = path34.join(relativeDir, name);
|
|
20792
20924
|
const text = readFileOrReport(fs14, configDir, relative, report);
|
|
20793
20925
|
const parsed = WorkflowRunFileSchema.safeParse(text === void 0 ? void 0 : parseJson2(text));
|
|
20794
20926
|
if (!parsed.success) {
|
|
@@ -20805,7 +20937,7 @@ function readWorkflowRuns(fs14, configDir, relativeDir, report) {
|
|
|
20805
20937
|
|
|
20806
20938
|
// src/agents/sessions.ts
|
|
20807
20939
|
init_cliError();
|
|
20808
|
-
import
|
|
20940
|
+
import path35 from "node:path";
|
|
20809
20941
|
var SessionLookupError = class extends CliError {
|
|
20810
20942
|
constructor(message) {
|
|
20811
20943
|
super(message);
|
|
@@ -20813,13 +20945,13 @@ var SessionLookupError = class extends CliError {
|
|
|
20813
20945
|
}
|
|
20814
20946
|
};
|
|
20815
20947
|
function identityConfigDir(identitiesDir, identity) {
|
|
20816
|
-
return
|
|
20948
|
+
return path35.join(identitiesDir, identity);
|
|
20817
20949
|
}
|
|
20818
20950
|
function historyStores(fs14, identitiesDir, identities) {
|
|
20819
20951
|
const byRealPath = /* @__PURE__ */ new Map();
|
|
20820
20952
|
for (const identity of identities) {
|
|
20821
20953
|
const configDir = identityConfigDir(identitiesDir, identity);
|
|
20822
|
-
const real = fs14.realpath(
|
|
20954
|
+
const real = fs14.realpath(path35.join(configDir, "projects"));
|
|
20823
20955
|
if (real === void 0) {
|
|
20824
20956
|
continue;
|
|
20825
20957
|
}
|
|
@@ -21224,6 +21356,7 @@ export {
|
|
|
21224
21356
|
createLaunchEventPublisher,
|
|
21225
21357
|
createLeafCache,
|
|
21226
21358
|
createLifecycleApiRouter,
|
|
21359
|
+
createLiveSessionRegistry,
|
|
21227
21360
|
createProfile,
|
|
21228
21361
|
createQuotaExpiringPublisher,
|
|
21229
21362
|
createRcApiNodeHandler,
|