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/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(SEGMENTER.segment(text), (part) => part.segment);
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: path41, keys }) => `${path41.length === 0 ? "" : `${path41.map(String).join(".")}.`}${keys.join(", ")}`);
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: path41, values } of ignored) {
1303
+ for (const { path: path42, values } of ignored) {
1272
1304
  let holder = restored;
1273
- for (const step of path41) {
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, `${String(session.pid)}.json`), `${JSON.stringify(session, null, 2)}
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
- if (!name.endsWith(".json")) {
3911
- continue;
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, `${String(pid)}.json`));
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 = listFrontDoorSessions(fs14, paths.frontdoorSessionsDir);
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(path41) {
4261
- return path41?.startsWith(ROUTED_PATH_PREFIX) === true;
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.64.1",
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, path41) {
7956
+ function valueAt(source, path42) {
7914
7957
  let current = source;
7915
- for (const part of path41) {
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(path41, declared) {
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: path41.join("."), description: declared.description ?? "", defaultValue: valueAt(STATUSLINE_DEFAULTS, path41), optional };
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
- throw new TypeError(`statusline setting ${path41.join(".")} has a kind the key listing does not describe`);
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(path41) {
7967
- const found = statuslineKeys().find((key) => key.path === path41);
8012
+ function keyNamed(path42) {
8013
+ const found = statuslineKeys().find((key) => key.path === path42);
7968
8014
  if (found === void 0) {
7969
- throw new UsageError(`"${path41}" is not a statusline setting; \`agent-shim statusline keys\` lists them.`);
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, path41, value) {
7974
- const [head, ...rest] = path41;
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, path41) {
7988
- const [head, ...rest] = path41;
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 [path41, value] of Object.entries(change.set ?? {})) {
8007
- keyNamed(path41);
8008
- setAt(draft, path41.split("."), value);
8052
+ for (const [path42, value] of Object.entries(change.set ?? {})) {
8053
+ keyNamed(path42);
8054
+ setAt(draft, path42.split("."), value);
8009
8055
  }
8010
- for (const path41 of change.unset ?? []) {
8011
- keyNamed(path41);
8012
- removeAt(draft, path41.split("."));
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 = import_node_path35.default.join(params.identitiesDir, params.resolvedIdentityName);
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 import_node_path35, LOOPBACK_HOSTS, PROVIDER_SESSION_PLACEHOLDER;
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
- import_node_path35 = __toESM(require("node:path"), 1);
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 = import_node_path36.default.join(projectDir, name);
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 = import_node_path36.default.join(params.claudeHome, "projects", projectDirNameOf(params.cwd));
10970
- const file = target.kind === "id" ? import_node_path36.default.join(projectDir, `${target.id}.jsonl`) : newestTranscript(fs14, projectDir);
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 import_node_path36;
11020
+ var import_node_path37;
10975
11021
  var init_resumeContext = __esm({
10976
11022
  "src/usage/resumeContext.ts"() {
10977
11023
  "use strict";
10978
- import_node_path36 = __toESM(require("node:path"), 1);
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 : import_node_path37.default.join(paths.identitiesDir, identityDecision.name);
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: import_node_path37.default.join(paths.root, "update.check"),
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, import_node_path37;
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
- import_node_path37 = __toESM(require("node:path"), 1);
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 import_node_path38.default.join(distDir, OWN_CLI_FILE_NAME);
11952
+ return import_node_path39.default.join(distDir, OWN_CLI_FILE_NAME);
11907
11953
  }
11908
- var import_node_path38, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
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
- import_node_path38 = __toESM(require("node:path"), 1);
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 === "" || import_node_path39.default.resolve(inherited) === import_node_path39.default.resolve(caCertFile)) {
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 = import_node_path39.default.join(bundlesDir, `${(0, import_node_crypto12.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
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, import_node_path39, BUNDLE_NAME_HEX_DIGITS;
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
- import_node_path39 = __toESM(require("node:path"), 1);
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: import_node_path40.default.join(paths.identitiesDir, identity), hasCredentialBlock: false }).state !== "signed-out",
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, import_node_path40, import_node_crypto13, LaunchRefusedError;
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
- import_node_path40 = __toESM(require("node:path"), 1);
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 path41 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
13441
- if (!path41.startsWith(RC_SESSIONS_PATH_PREFIX)) {
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 = path41.slice(RC_SESSIONS_PATH_PREFIX.length);
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 summaryOf = ({ id, createdAt, lastSeenAt }) => ({ id, createdAt, lastSeenAt });
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(summaryOf);
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) => ({ ...summaryOf(entry), workerState: entry.workerState, workerIdleSeconds: entry.workerIdleSeconds, pending: pendingSorted(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, path41, options) {
13835
- return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path41, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
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, path41, options) {
13938
- if (path41 === "") {
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, path41, options), `read ${path41} from session ${sessionId}`);
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 path41 = bodyString(body, "path");
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 || path41 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === 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, path41, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
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 (path41, what) => {
14475
+ const listAnswerOf = async (path42, what) => {
14429
14476
  try {
14430
- return await transport.request({ method: "GET", path: path41, headers });
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 (path41, body, describeFailure2) => {
14549
+ const writeOf = async (path42, body, describeFailure2) => {
14503
14550
  let answer;
14504
14551
  try {
14505
- answer = await transport.request({ method: "POST", path: path41, headers: { ...headers, "content-type": "application/json" }, body });
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, path41, options) => await writeOf(
14583
+ readFile: async (sessionId, path42, options) => await writeOf(
14537
14584
  `${CONTROL_PATH_PREFIX}/read-file`,
14538
- JSON.stringify({ session: sessionId, path: path41, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
14539
- (status, message) => `reading ${path41} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
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 (path41, headers, body) => await new Promise((resolve, reject) => {
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: path41,
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, path41, headers, body, signal) => await new Promise((resolve, reject) => {
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: path41,
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 path41 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
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", path41, streamHeaders, void 0, signal);
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, path41) => {
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 [...path41, nested];
15864
+ return [...path42, nested];
15818
15865
  }
15819
- if (path41.includes(nested)) {
15866
+ if (path42.includes(nested)) {
15820
15867
  continue;
15821
15868
  }
15822
- const found = walk2(nested, [...path41, 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: import_zod30.z.record(import_zod30.z.string(), import_zod30.z.unknown()).optional(),
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 = (path41, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path41, summary, tags: [CONFIG_API_TAG] }));
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 import_node_path33 = __toESM(require("node:path"), 1);
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(import_node_path33.default.join(configDir, PROJECTS_DIR))) {
20947
- const projectDir = import_node_path33.default.join(configDir, PROJECTS_DIR, project);
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(import_node_path33.default.join(projectDir, name));
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: import_node_path33.default.join(relativeDir, name),
20975
- transcriptPath: import_node_path33.default.join(relativeDir, `${AGENT_FILE_PREFIX}${id}${TRANSCRIPT_SUFFIX}`),
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(import_node_path33.default.join(configDir, relative));
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(import_node_path33.default.join(configDir, relative));
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 = import_node_path33.default.join(PROJECTS_DIR, ref.project, ref.entry);
21051
- const subagentsRelative = import_node_path33.default.join(sessionRelative, SUBAGENTS_DIR);
21052
- const workflowsUnderSubagents = import_node_path33.default.join(subagentsRelative, WORKFLOWS_DIR);
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(import_node_path33.default.join(configDir, subagentsRelative)).filter(isMeta).length;
21055
- for (const runDir of fs14.readdir(import_node_path33.default.join(configDir, workflowsUnderSubagents))) {
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(import_node_path33.default.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
21191
+ agentCount += fs14.readdir(import_node_path34.default.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
21058
21192
  }
21059
21193
  }
21060
- const workflowRunCount = fs14.readdir(import_node_path33.default.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
21061
- const transcript = fs14.lstat(import_node_path33.default.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
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 = import_node_path33.default.join(PROJECTS_DIR, ref.project, ref.entry);
21070
- const subagentsRelative = import_node_path33.default.join(sessionRelative, SUBAGENTS_DIR);
21071
- const workflowsUnderSubagents = import_node_path33.default.join(subagentsRelative, WORKFLOWS_DIR);
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, import_node_path33.default.join(workflowsUnderSubagents, runDir), runDir, report));
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, import_node_path33.default.join(sessionRelative, WORKFLOWS_DIR), report),
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 = import_node_path33.default.join(TASKS_DIR, scope);
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 = import_node_path33.default.join(relativeDir, name);
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 = import_node_path33.default.join(relativeDir, name);
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 import_node_path34 = __toESM(require("node:path"), 1);
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 import_node_path34.default.join(identitiesDir, identity);
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(import_node_path34.default.join(configDir, "projects"));
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,