claude-use 9.16.0 → 9.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -2693,7 +2693,7 @@ var init_package = __esm({
2693
2693
  "package.json"() {
2694
2694
  package_default = {
2695
2695
  name: "claude-use",
2696
- version: "9.16.0",
2696
+ version: "9.18.0",
2697
2697
  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.",
2698
2698
  license: "MIT",
2699
2699
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4817,22 +4817,25 @@ function rankPool(input) {
4817
4817
  return { ...candidate, feasible: true };
4818
4818
  }
4819
4819
  const drySpots = [];
4820
+ const dryAfterMs = [];
4820
4821
  if (fiveHour !== void 0 && pace !== void 0) {
4821
4822
  const runsDryInMs = fiveHour.remaining / pace;
4822
4823
  if (runsDryInMs < fiveHour.untilResetMs) {
4824
+ dryAfterMs.push(runsDryInMs);
4823
4825
  drySpots.push(`5h window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(fiveHour.untilResetMs)}`);
4824
4826
  }
4825
4827
  }
4826
4828
  if (sevenDay !== void 0 && sevenDayBurn !== void 0) {
4827
4829
  const runsDryInMs = sevenDay.remaining / sevenDayBurn;
4828
4830
  if (runsDryInMs < sevenDay.untilResetMs) {
4831
+ dryAfterMs.push(runsDryInMs);
4829
4832
  drySpots.push(`7d window would run dry in ${formatAge(runsDryInMs)}, before it resets in ${formatAge(sevenDay.untilResetMs)}`);
4830
4833
  }
4831
4834
  }
4832
4835
  if (drySpots.length === 0) {
4833
4836
  return { ...candidate, feasible: true };
4834
4837
  }
4835
- return { ...candidate, feasible: false, reasons: [...drySpots, ...candidate.reasons] };
4838
+ return { ...candidate, feasible: false, runsDryAtMs: nowMs + Math.min(...dryAfterMs), reasons: [...drySpots, ...candidate.reasons] };
4836
4839
  });
4837
4840
  const ordered = input.preference === "listed" ? [...candidates] : [...candidates].sort(
4838
4841
  (left, right) => CLASS_ORDER[left.class] - CLASS_ORDER[right.class] || Number(left.policyDemoted ?? false) - Number(right.policyDemoted ?? false) || Number(right.feasible) - Number(left.feasible) || (right.headroom ?? 1) - (left.headroom ?? 1) || (right.score ?? 0) - (left.score ?? 0) || left.identity.localeCompare(right.identity)
@@ -4854,11 +4857,13 @@ function rankPool(input) {
4854
4857
  const pick = ordered.find((candidate) => candidate.class !== "ineligible");
4855
4858
  const returns = ordered.flatMap((candidate) => candidate.blockedUntilMs === void 0 ? [] : [{ identity: candidate.identity, atMs: candidate.blockedUntilMs }]);
4856
4859
  const earliestReturn = returns.length === 0 ? void 0 : returns.reduce((soonest, entry) => entry.atMs < soonest.atMs ? entry : soonest);
4860
+ const holdForReturn = pick?.runsDryAtMs === void 0 ? void 0 : returns.filter((entry) => entry.atMs < (pick.runsDryAtMs ?? 0)).reduce((soonest, entry) => soonest === void 0 || entry.atMs < soonest.atMs ? entry : soonest, void 0);
4857
4861
  return {
4858
4862
  candidates: ordered,
4859
4863
  ...pick === void 0 ? { ...earliestReturn === void 0 ? {} : { earliestReturn } } : { pick },
4860
4864
  ...movedOff === void 0 || pick === void 0 ? {} : { movedOff },
4861
- ...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } }
4865
+ ...pick?.planReturnsAtMs === void 0 ? {} : { planReturn: { identity: pick.identity, atMs: pick.planReturnsAtMs } },
4866
+ ...holdForReturn === void 0 ? {} : { holdForReturn }
4862
4867
  };
4863
4868
  }
4864
4869
  var MS_PER_SECOND4, MS_PER_HOUR2, HOURS_PER_DAY2, FIVE_HOURS, PROMPT_CACHE_TTL_HOURS, PERCENT, SEVEN_DAYS, FIVE_HOUR_WINDOW_MS, SEVEN_DAY_WINDOW_MS, PROMPT_CACHE_TTL_MS, CLASS_ORDER;
@@ -6687,7 +6692,7 @@ function buildEnv(params) {
6687
6692
  const parentCustomHeaders = params.baseEnv.ANTHROPIC_CUSTOM_HEADERS;
6688
6693
  let providerCustomHeaders;
6689
6694
  if (!params.configDirEscapeHatch && params.resolvedIdentityName !== void 0) {
6690
- env.CLAUDE_CONFIG_DIR = import_node_path34.default.join(params.identitiesDir, params.resolvedIdentityName);
6695
+ env.CLAUDE_CONFIG_DIR = import_node_path35.default.join(params.identitiesDir, params.resolvedIdentityName);
6691
6696
  }
6692
6697
  if (params.provider !== void 0) {
6693
6698
  const providerEnv = params.provider.definition.env ?? {};
@@ -6731,11 +6736,11 @@ function buildEnv(params) {
6731
6736
  }
6732
6737
  return env;
6733
6738
  }
6734
- var import_node_path34, LOOPBACK_HOSTS;
6739
+ var import_node_path35, LOOPBACK_HOSTS;
6735
6740
  var init_flags = __esm({
6736
6741
  "src/launcher/flags.ts"() {
6737
6742
  "use strict";
6738
- import_node_path34 = __toESM(require("node:path"), 1);
6743
+ import_node_path35 = __toESM(require("node:path"), 1);
6739
6744
  init_envBool();
6740
6745
  init_credential();
6741
6746
  init_headers();
@@ -6809,12 +6814,17 @@ function resolvePoolLaunch(params) {
6809
6814
  if (graph.ranking.candidates.length === 0) {
6810
6815
  return { ok: false, message: `agent-shim: no member of pool "${poolName}" is an existing identity.` };
6811
6816
  }
6812
- const { pick, earliestReturn, movedOff, planReturn } = graph.ranking;
6817
+ const { pick, earliestReturn, movedOff, planReturn, holdForReturn } = graph.ranking;
6813
6818
  if (pick !== void 0 && params.wait && planReturn !== void 0) {
6814
6819
  log.info(`agent-shim: pool "${poolName}" would continue ${planReturn.identity} on extra usage; waiting until ${new Date(planReturn.atMs).toISOString()} for its plan window`);
6815
6820
  params.sleep(Math.max(planReturn.atMs - nowMs, 0));
6816
6821
  continue;
6817
6822
  }
6823
+ if (pick !== void 0 && params.wait && holdForReturn !== void 0) {
6824
+ log.info(`agent-shim: pool "${poolName}" pick ${pick.identity} would run dry before its window resets; waiting until ${new Date(holdForReturn.atMs).toISOString()} for ${holdForReturn.identity}`);
6825
+ params.sleep(Math.max(holdForReturn.atMs - nowMs, 0));
6826
+ continue;
6827
+ }
6818
6828
  if (pick !== void 0) {
6819
6829
  if (params.recordPick) {
6820
6830
  recordStickyPick(params.usageFs, params.paths.usagePicksFile, params.cwd, pick.identity, nowMs);
@@ -7063,7 +7073,7 @@ function decideLaunch(params, readOnly) {
7063
7073
  identityDefaultConfigProfile: loadedIdentity?.config.defaultConfigProfile,
7064
7074
  globalDefaultConfigProfile: params.globalDefaultConfigProfile
7065
7075
  });
7066
- if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(import_node_path35.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
7076
+ if (configProfileDecision.name !== void 0 && params.allowMissingConfigProfile !== true && fs12.readConfigFile(import_node_path36.default.join(paths.configProfilesDir, `${configProfileDecision.name}.json`)) === void 0) {
7067
7077
  log.error(
7068
7078
  `agent-shim: no configuration profile named "${configProfileDecision.name}" (selected via ${configProfileDecision.source}). Run \`agent-shim profile add ${configProfileDecision.name}\` first.`
7069
7079
  );
@@ -7175,7 +7185,7 @@ function decideLaunch(params, readOnly) {
7175
7185
  extraFlags: splitExtraFlags(env.CLAUDE_EXTRA_FLAGS),
7176
7186
  passthrough: parsedArgv.rest
7177
7187
  });
7178
- const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path35.default.join(paths.identitiesDir, identityDecision.name);
7188
+ const configDir = configDirEscapeHatchApplies || identityDecision.name === void 0 ? env.CLAUDE_CONFIG_DIR : import_node_path36.default.join(paths.identitiesDir, identityDecision.name);
7179
7189
  const decision = {
7180
7190
  identitySource: identityDecision.source,
7181
7191
  configDirEscapeHatch: identityDecision.configDirEscapeHatch,
@@ -7216,7 +7226,7 @@ function prepareLaunch(params) {
7216
7226
  );
7217
7227
  const updateCheck = runLaunchUpdateCheck({
7218
7228
  mode: params.updateMode ?? "off",
7219
- checkPath: import_node_path35.default.join(paths.root, "update.check"),
7229
+ checkPath: import_node_path36.default.join(paths.root, "update.check"),
7220
7230
  currentVersion: package_default.version,
7221
7231
  port: params.update
7222
7232
  });
@@ -7347,12 +7357,12 @@ function runLaunchPlan(plan, spawn3) {
7347
7357
  function runLauncher(params) {
7348
7358
  params.proc.exit(runLaunchPlan(prepareLaunch(params), params.spawn));
7349
7359
  }
7350
- var import_node_crypto10, import_node_path35;
7360
+ var import_node_crypto10, import_node_path36;
7351
7361
  var init_launcher = __esm({
7352
7362
  "src/launcher.ts"() {
7353
7363
  "use strict";
7354
7364
  import_node_crypto10 = require("node:crypto");
7355
- import_node_path35 = __toESM(require("node:path"), 1);
7365
+ import_node_path36 = __toESM(require("node:path"), 1);
7356
7366
  init_package();
7357
7367
  init_envBool();
7358
7368
  init_argv();
@@ -7383,13 +7393,13 @@ function agentShimCliPath(distDir = typeof __AGENT_SHIM_DIST_DIR__ === "string"
7383
7393
  if (distDir === void 0) {
7384
7394
  throw new OwnCliPathUnknownError();
7385
7395
  }
7386
- return import_node_path36.default.join(distDir, OWN_CLI_FILE_NAME);
7396
+ return import_node_path37.default.join(distDir, OWN_CLI_FILE_NAME);
7387
7397
  }
7388
- var import_node_path36, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
7398
+ var import_node_path37, OWN_CLI_FILE_NAME, OwnCliPathUnknownError;
7389
7399
  var init_ownCli = __esm({
7390
7400
  "src/ownCli.ts"() {
7391
7401
  "use strict";
7392
- import_node_path36 = __toESM(require("node:path"), 1);
7402
+ import_node_path37 = __toESM(require("node:path"), 1);
7393
7403
  init_cliError();
7394
7404
  OWN_CLI_FILE_NAME = "cli.cjs";
7395
7405
  OwnCliPathUnknownError = class extends CliError {
@@ -7474,7 +7484,7 @@ request.on("error", (error) => finish(failed, (error.code ? error.code + ": " :
7474
7484
  // src/frontdoor/trust.ts
7475
7485
  function resolveTrustBundle(params) {
7476
7486
  const { caCertFile, bundlesDir, variable, inherited, fs: fs12 } = params;
7477
- if (inherited === void 0 || inherited === "" || import_node_path37.default.resolve(inherited) === import_node_path37.default.resolve(caCertFile)) {
7487
+ if (inherited === void 0 || inherited === "" || import_node_path38.default.resolve(inherited) === import_node_path38.default.resolve(caCertFile)) {
7478
7488
  return { path: caCertFile };
7479
7489
  }
7480
7490
  const caPem = fs12.readFileUtf8(caCertFile);
@@ -7492,19 +7502,19 @@ function resolveTrustBundle(params) {
7492
7502
  }
7493
7503
  const combined = `${inheritedPem.trimEnd()}
7494
7504
  ${caPem}`;
7495
- const bundle = import_node_path37.default.join(bundlesDir, `${(0, import_node_crypto11.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
7505
+ const bundle = import_node_path38.default.join(bundlesDir, `${(0, import_node_crypto11.createHash)("sha256").update(combined).digest("hex").slice(0, BUNDLE_NAME_HEX_DIGITS)}.pem`);
7496
7506
  if (!fs12.exists(bundle)) {
7497
7507
  fs12.mkdirp(bundlesDir);
7498
7508
  fs12.writeFileAtomic(bundle, combined);
7499
7509
  }
7500
7510
  return { path: bundle };
7501
7511
  }
7502
- var import_node_crypto11, import_node_path37, BUNDLE_NAME_HEX_DIGITS;
7512
+ var import_node_crypto11, import_node_path38, BUNDLE_NAME_HEX_DIGITS;
7503
7513
  var init_trust = __esm({
7504
7514
  "src/frontdoor/trust.ts"() {
7505
7515
  "use strict";
7506
7516
  import_node_crypto11 = require("node:crypto");
7507
- import_node_path37 = __toESM(require("node:path"), 1);
7517
+ import_node_path38 = __toESM(require("node:path"), 1);
7508
7518
  BUNDLE_NAME_HEX_DIGITS = 16;
7509
7519
  }
7510
7520
  });
@@ -7522,7 +7532,7 @@ function realEnsurePorts(paths, spawnDaemon) {
7522
7532
  process.kill(pid, "SIGTERM");
7523
7533
  },
7524
7534
  // Read fresh for each probe: a replacement supervisor may have regenerated an unparseable CA, and the probe must trust exactly what the serving door's leaf chains to.
7525
- verifyListener: (port) => probeFrontDoorSync(port, import_node_fs10.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7535
+ verifyListener: (port) => probeFrontDoorSync(port, import_node_fs11.default.readFileSync(paths.frontdoorCaCertFile, "utf8"))
7526
7536
  };
7527
7537
  }
7528
7538
  function realFrontDoorPort(paths, spawnDaemon) {
@@ -7543,21 +7553,21 @@ function realFrontDoorPort(paths, spawnDaemon) {
7543
7553
  }
7544
7554
  };
7545
7555
  }
7546
- var import_node_fs10, realTrustBundleFs;
7556
+ var import_node_fs11, realTrustBundleFs;
7547
7557
  var init_realFrontDoorPort = __esm({
7548
7558
  "src/frontdoor/realFrontDoorPort.ts"() {
7549
7559
  "use strict";
7550
- import_node_fs10 = __toESM(require("node:fs"), 1);
7560
+ import_node_fs11 = __toESM(require("node:fs"), 1);
7551
7561
  init_realPorts();
7552
7562
  init_ensure2();
7553
7563
  init_state();
7554
7564
  init_probe();
7555
7565
  init_trust();
7556
7566
  realTrustBundleFs = {
7557
- readFileUtf8: (file) => import_node_fs10.default.readFileSync(file, "utf8"),
7558
- exists: (file) => import_node_fs10.default.existsSync(file),
7567
+ readFileUtf8: (file) => import_node_fs11.default.readFileSync(file, "utf8"),
7568
+ exists: (file) => import_node_fs11.default.existsSync(file),
7559
7569
  mkdirp: (dir) => {
7560
- import_node_fs10.default.mkdirSync(dir, { recursive: true });
7570
+ import_node_fs11.default.mkdirSync(dir, { recursive: true });
7561
7571
  },
7562
7572
  writeFileAtomic: (file, contents) => {
7563
7573
  realFarmFs.writeFilePrivate(file, contents);
@@ -7894,11 +7904,11 @@ var init_identityClaude = __esm({
7894
7904
  });
7895
7905
 
7896
7906
  // src/usage/providerQuota.ts
7897
- var import_zod27, MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY4, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema;
7907
+ var import_zod28, MS_PER_SECOND7, SECONDS_PER_HOUR, HOURS_PER_DAY4, DAYS_PER_MONTH, ZAI_HOST, ZAI_QUOTA_URL, ZAI_UNIT_HOURS, ZAI_UNIT_MONTHS, ZAI_UNIT_MS, ZaiLimitSchema, ZaiResponseSchema, OPENROUTER_HOST, OPENROUTER_KEY_URL, OPENROUTER_CREDITS_URL, MS_PER_DAY3, OpenRouterKeySchema, OpenRouterCreditsSchema;
7898
7908
  var init_providerQuota = __esm({
7899
7909
  "src/usage/providerQuota.ts"() {
7900
7910
  "use strict";
7901
- import_zod27 = require("zod");
7911
+ import_zod28 = require("zod");
7902
7912
  init_schema2();
7903
7913
  MS_PER_SECOND7 = 1e3;
7904
7914
  SECONDS_PER_HOUR = 3600;
@@ -7912,35 +7922,35 @@ var init_providerQuota = __esm({
7912
7922
  [ZAI_UNIT_HOURS, SECONDS_PER_HOUR * MS_PER_SECOND7],
7913
7923
  [ZAI_UNIT_MONTHS, DAYS_PER_MONTH * HOURS_PER_DAY4 * SECONDS_PER_HOUR * MS_PER_SECOND7]
7914
7924
  ]);
7915
- ZaiLimitSchema = import_zod27.z.object({
7916
- type: import_zod27.z.string(),
7917
- unit: import_zod27.z.number().int(),
7918
- number: import_zod27.z.number().int().positive(),
7919
- percentage: import_zod27.z.number().nonnegative(),
7920
- nextResetTime: import_zod27.z.number().positive().optional(),
7921
- usage: import_zod27.z.number().nonnegative().optional(),
7922
- currentValue: import_zod27.z.number().nonnegative().optional(),
7923
- remaining: import_zod27.z.number().nonnegative().optional()
7925
+ ZaiLimitSchema = import_zod28.z.object({
7926
+ type: import_zod28.z.string(),
7927
+ unit: import_zod28.z.number().int(),
7928
+ number: import_zod28.z.number().int().positive(),
7929
+ percentage: import_zod28.z.number().nonnegative(),
7930
+ nextResetTime: import_zod28.z.number().positive().optional(),
7931
+ usage: import_zod28.z.number().nonnegative().optional(),
7932
+ currentValue: import_zod28.z.number().nonnegative().optional(),
7933
+ remaining: import_zod28.z.number().nonnegative().optional()
7924
7934
  });
7925
- ZaiResponseSchema = import_zod27.z.object({
7926
- success: import_zod27.z.boolean(),
7927
- msg: import_zod27.z.string().optional(),
7928
- data: import_zod27.z.object({ level: import_zod27.z.string().optional(), limits: import_zod27.z.array(ZaiLimitSchema) })
7935
+ ZaiResponseSchema = import_zod28.z.object({
7936
+ success: import_zod28.z.boolean(),
7937
+ msg: import_zod28.z.string().optional(),
7938
+ data: import_zod28.z.object({ level: import_zod28.z.string().optional(), limits: import_zod28.z.array(ZaiLimitSchema) })
7929
7939
  });
7930
7940
  OPENROUTER_HOST = "openrouter.ai";
7931
7941
  OPENROUTER_KEY_URL = `https://${OPENROUTER_HOST}/api/v1/key`;
7932
7942
  OPENROUTER_CREDITS_URL = `https://${OPENROUTER_HOST}/api/v1/credits`;
7933
7943
  MS_PER_DAY3 = HOURS_PER_DAY4 * SECONDS_PER_HOUR * MS_PER_SECOND7;
7934
- OpenRouterKeySchema = import_zod27.z.object({
7935
- data: import_zod27.z.object({
7936
- limit: import_zod27.z.number().nonnegative().nullable(),
7937
- limit_remaining: import_zod27.z.number().nullable(),
7938
- limit_reset: import_zod27.z.string().nullable(),
7939
- is_free_tier: import_zod27.z.boolean().optional(),
7940
- free_model_daily_requests: import_zod27.z.object({ used: import_zod27.z.number().nonnegative(), limit: import_zod27.z.number().nonnegative(), remaining: import_zod27.z.number() }).optional()
7944
+ OpenRouterKeySchema = import_zod28.z.object({
7945
+ data: import_zod28.z.object({
7946
+ limit: import_zod28.z.number().nonnegative().nullable(),
7947
+ limit_remaining: import_zod28.z.number().nullable(),
7948
+ limit_reset: import_zod28.z.string().nullable(),
7949
+ is_free_tier: import_zod28.z.boolean().optional(),
7950
+ free_model_daily_requests: import_zod28.z.object({ used: import_zod28.z.number().nonnegative(), limit: import_zod28.z.number().nonnegative(), remaining: import_zod28.z.number() }).optional()
7941
7951
  })
7942
7952
  });
7943
- OpenRouterCreditsSchema = import_zod27.z.object({ data: import_zod27.z.object({ total_credits: import_zod27.z.number().nonnegative(), total_usage: import_zod27.z.number().nonnegative() }) });
7953
+ OpenRouterCreditsSchema = import_zod28.z.object({ data: import_zod28.z.object({ total_credits: import_zod28.z.number().nonnegative(), total_usage: import_zod28.z.number().nonnegative() }) });
7944
7954
  }
7945
7955
  });
7946
7956
 
@@ -8029,6 +8039,10 @@ __export(index_exports, {
8029
8039
  AgentKindSchema: () => AgentKindSchema,
8030
8040
  AgentMetaSchema: () => AgentMetaSchema,
8031
8041
  AgentNodeSchema: () => AgentNodeSchema,
8042
+ AgentTreesListInputSchema: () => AgentTreesListInputSchema,
8043
+ AgentTreesListOutputSchema: () => AgentTreesListOutputSchema,
8044
+ AgentTreesShowInputSchema: () => AgentTreesShowInputSchema,
8045
+ AgentTreesShowOutputSchema: () => AgentTreesShowOutputSchema,
8032
8046
  CHECK_CREDENTIAL_APPLIES: () => CHECK_CREDENTIAL_APPLIES,
8033
8047
  CODEX_APP_SERVER_GENERATED_AGAINST: () => CODEX_APP_SERVER_GENERATED_AGAINST,
8034
8048
  CODEX_APP_SERVER_TIMEOUT_MS: () => CODEX_APP_SERVER_TIMEOUT_MS,
@@ -8176,6 +8190,8 @@ __export(index_exports, {
8176
8190
  ResetRowSchema: () => ResetRowSchema,
8177
8191
  ResetScheduleSchema: () => ResetScheduleSchema,
8178
8192
  SessionAgentTreeSchema: () => SessionAgentTreeSchema,
8193
+ SessionLookupError: () => SessionLookupError,
8194
+ SessionSummarySchema: () => SessionSummarySchema,
8179
8195
  TaskItemSchema: () => TaskItemSchema,
8180
8196
  USAGE_EVENT_SOURCE: () => USAGE_EVENT_SOURCE,
8181
8197
  UpdateCheckOutputSchema: () => UpdateCheckOutputSchema,
@@ -8223,6 +8239,8 @@ __export(index_exports, {
8223
8239
  collectFrontDoorStatus: () => collectFrontDoorStatus,
8224
8240
  collectPoolPick: () => collectPoolPick,
8225
8241
  collectResets: () => collectResets,
8242
+ collectSessionList: () => collectSessionList,
8243
+ createAgentTreesApiRouter: () => createAgentTreesApiRouter,
8226
8244
  createCodexApiRouter: () => createCodexApiRouter,
8227
8245
  createConfigApiRouter: () => createConfigApiRouter,
8228
8246
  createControlApiRouter: () => createControlApiRouter,
@@ -8291,6 +8309,7 @@ __export(index_exports, {
8291
8309
  listProviders: () => listProviders,
8292
8310
  listSessions: () => listSessions2,
8293
8311
  listUsageSnapshots: () => listUsageSnapshots,
8312
+ locateSession: () => locateSession,
8294
8313
  matchBranch: () => matchBranch,
8295
8314
  mintLeaf: () => mintLeaf,
8296
8315
  mintRcSelfHostCredential: () => mintRcSelfHostCredential,
@@ -8333,6 +8352,7 @@ __export(index_exports, {
8333
8352
  realRcEventDial: () => realRcEventDial,
8334
8353
  realRcStreamDial: () => realRcStreamDial,
8335
8354
  realRcWebFetch: () => realRcWebFetch,
8355
+ realSessionFs: () => realSessionFs,
8336
8356
  reconnectRcSessionMcpServer: () => reconnectRcSessionMcpServer,
8337
8357
  recoverFarm: () => recoverFarm,
8338
8358
  recoveryDiagnostics: () => recoveryDiagnostics,
@@ -8374,11 +8394,13 @@ __export(index_exports, {
8374
8394
  setProfileMetadata: () => setProfileMetadata,
8375
8395
  setRcSessionModel: () => setRcSessionModel,
8376
8396
  setRcSessionPermissionMode: () => setRcSessionPermissionMode,
8397
+ showSession: () => showSession,
8377
8398
  snapshotPath: () => snapshotPath,
8378
8399
  spawnClaude: () => spawnClaude,
8379
8400
  startConnectServer: () => startConnectServer,
8380
8401
  submitRcSessionMcpOAuthCallbackUrl: () => submitRcSessionMcpOAuthCallbackUrl,
8381
8402
  suggestRcSessionFiles: () => suggestRcSessionFiles,
8403
+ summariseSession: () => summariseSession,
8382
8404
  teleportRcSession: () => teleportRcSession,
8383
8405
  topLevelNames: () => topLevelNames,
8384
8406
  updateDirectoryRule: () => updateDirectoryRule,
@@ -8918,8 +8940,8 @@ function parseConnectTarget(authority) {
8918
8940
  function isInterceptedHost(host, interceptHosts) {
8919
8941
  return interceptHosts.includes(host);
8920
8942
  }
8921
- function servedByPipeline(path38) {
8922
- return path38?.startsWith(ROUTED_PATH_PREFIX) === true;
8943
+ function servedByPipeline(path39) {
8944
+ return path39?.startsWith(ROUTED_PATH_PREFIX) === true;
8923
8945
  }
8924
8946
  var HOP_BY_HOP_HEADERS = /* @__PURE__ */ new Set([
8925
8947
  "connection",
@@ -9454,11 +9476,11 @@ function createRcSessionTracker(deps) {
9454
9476
  };
9455
9477
  const observeExchange = (request4) => {
9456
9478
  const method = (request4.method ?? "").toUpperCase();
9457
- const path38 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
9458
- if (!path38.startsWith(RC_SESSIONS_PATH_PREFIX)) {
9479
+ const path39 = new URL(request4.url ?? "/", "http://127.0.0.1").pathname;
9480
+ if (!path39.startsWith(RC_SESSIONS_PATH_PREFIX)) {
9459
9481
  return void 0;
9460
9482
  }
9461
- const tail = path38.slice(RC_SESSIONS_PATH_PREFIX.length);
9483
+ const tail = path39.slice(RC_SESSIONS_PATH_PREFIX.length);
9462
9484
  const facts = {
9463
9485
  oauthAuthorization: oauthAuthorizationOf(request4.headers),
9464
9486
  anthropicVersion: singleHeader(request4.headers, "anthropic-version"),
@@ -9840,8 +9862,8 @@ var RC_READ_FILE_ENCODINGS = ["utf-8", "base64"];
9840
9862
  function isRcReadFileEncoding(value) {
9841
9863
  return RC_READ_FILE_ENCODINGS.some((encoding) => encoding === value);
9842
9864
  }
9843
- function buildRcReadFilePayload(requestId, path38, options) {
9844
- return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path38, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
9865
+ function buildRcReadFilePayload(requestId, path39, options) {
9866
+ return buildRcControlRequestPayload(requestId, { subtype: "read_file", path: path39, ...options?.maxBytes === void 0 ? {} : { max_bytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } });
9845
9867
  }
9846
9868
  function buildRcFileSuggestionsPayload(requestId, query) {
9847
9869
  return buildRcControlRequestPayload(requestId, { subtype: "file_suggestions", query });
@@ -9943,15 +9965,15 @@ async function getRcSessionContextUsage(deps, sessionId, detail) {
9943
9965
  const result = await deliverRcClientPayload(deps, sessionId, buildRcGetContextUsagePayload(requestId, detail), `request the context usage of session ${sessionId}`);
9944
9966
  return result.ok ? { ...result, requestId } : result;
9945
9967
  }
9946
- async function readRcSessionFile(deps, sessionId, path38, options) {
9947
- if (path38 === "") {
9968
+ async function readRcSessionFile(deps, sessionId, path39, options) {
9969
+ if (path39 === "") {
9948
9970
  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" };
9949
9971
  }
9950
9972
  if (options?.maxBytes !== void 0 && (!Number.isInteger(options.maxBytes) || options.maxBytes <= 0)) {
9951
9973
  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" };
9952
9974
  }
9953
9975
  const requestId = deps.newUuid();
9954
- const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path38, options), `read ${path38} from session ${sessionId}`);
9976
+ const result = await deliverRcClientPayload(deps, sessionId, buildRcReadFilePayload(requestId, path39, options), `read ${path39} from session ${sessionId}`);
9955
9977
  return result.ok ? { ...result, requestId } : result;
9956
9978
  }
9957
9979
  async function suggestRcSessionFiles(deps, sessionId, query) {
@@ -10120,11 +10142,11 @@ function createRcControlHandler(deps) {
10120
10142
  path: "read-file",
10121
10143
  read: (body) => {
10122
10144
  const session = bodyString(body, "session");
10123
- const path38 = bodyString(body, "path");
10145
+ const path39 = bodyString(body, "path");
10124
10146
  const maxBytes = "maxBytes" in body ? bodyPositiveInteger(body, "maxBytes") : void 0;
10125
10147
  const encoding = "encoding" in body && isRcReadFileEncoding(body.encoding) ? body.encoding : void 0;
10126
- const refused2 = session === void 0 || path38 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
10127
- 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, path38, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
10148
+ const refused2 = session === void 0 || path39 === void 0 || "maxBytes" in body && maxBytes === void 0 || "encoding" in body && encoding === void 0;
10149
+ 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, path39, { ...maxBytes === void 0 ? {} : { maxBytes }, ...encoding === void 0 ? {} : { encoding } }) };
10128
10150
  }
10129
10151
  },
10130
10152
  {
@@ -10434,9 +10456,9 @@ function requestIdOfBody(body) {
10434
10456
  }
10435
10457
  function frontDoorRcControl(transport, token) {
10436
10458
  const headers = { authorization: `Bearer ${token}` };
10437
- const listAnswerOf = async (path38, what) => {
10459
+ const listAnswerOf = async (path39, what) => {
10438
10460
  try {
10439
- return await transport.request({ method: "GET", path: path38, headers });
10461
+ return await transport.request({ method: "GET", path: path39, headers });
10440
10462
  } catch (error) {
10441
10463
  throw new Error(`${what}: could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}`, { cause: error });
10442
10464
  }
@@ -10508,10 +10530,10 @@ function frontDoorRcControl(transport, token) {
10508
10530
  }
10509
10531
  return pending;
10510
10532
  };
10511
- const writeOf = async (path38, body, describeFailure2) => {
10533
+ const writeOf = async (path39, body, describeFailure2) => {
10512
10534
  let answer;
10513
10535
  try {
10514
- answer = await transport.request({ method: "POST", path: path38, headers: { ...headers, "content-type": "application/json" }, body });
10536
+ answer = await transport.request({ method: "POST", path: path39, headers: { ...headers, "content-type": "application/json" }, body });
10515
10537
  } catch (error) {
10516
10538
  return { ok: false, message: `could not reach the front door's control listener: ${error instanceof Error ? error.message : String(error)}` };
10517
10539
  }
@@ -10542,10 +10564,10 @@ function frontDoorRcControl(transport, token) {
10542
10564
  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}`),
10543
10565
  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}`),
10544
10566
  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}`),
10545
- readFile: async (sessionId, path38, options) => await writeOf(
10567
+ readFile: async (sessionId, path39, options) => await writeOf(
10546
10568
  `${CONTROL_PATH_PREFIX}/read-file`,
10547
- JSON.stringify({ session: sessionId, path: path38, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
10548
- (status, message) => `reading ${path38} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
10569
+ JSON.stringify({ session: sessionId, path: path39, ...options?.maxBytes === void 0 ? {} : { maxBytes: options.maxBytes }, ...options?.encoding === void 0 ? {} : { encoding: options.encoding } }),
10570
+ (status, message) => `reading ${path39} from ${sessionId} failed (HTTP ${String(status)}): ${message}`
10549
10571
  ),
10550
10572
  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}`),
10551
10573
  keepAlive: async (sessionId) => await writeOf(`${CONTROL_PATH_PREFIX}/keep-alive`, JSON.stringify({ session: sessionId }), (status, message) => `keeping ${sessionId} alive failed (HTTP ${String(status)}): ${message}`),
@@ -10704,12 +10726,12 @@ function tlsFacts(options) {
10704
10726
  }
10705
10727
  function realRcEventDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
10706
10728
  const agent = new ExemptTlsAgent();
10707
- const post = async (path38, headers, body) => await new Promise((resolve, reject) => {
10729
+ const post = async (path39, headers, body) => await new Promise((resolve, reject) => {
10708
10730
  const options = {
10709
10731
  host: target.host,
10710
10732
  port: target.port,
10711
10733
  method: "POST",
10712
- path: path38,
10734
+ path: path39,
10713
10735
  // 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.
10714
10736
  headers: { ...headers, host: target.servername ?? target.host, "content-length": String(Buffer.byteLength(body, "utf8")) },
10715
10737
  agent
@@ -10774,12 +10796,12 @@ function lateRcStreamDial(resolve) {
10774
10796
  }
10775
10797
  function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_PORT }) {
10776
10798
  const agent = new ExemptTlsAgent();
10777
- const request4 = async (method, path38, headers, body, signal) => await new Promise((resolve, reject) => {
10799
+ const request4 = async (method, path39, headers, body, signal) => await new Promise((resolve, reject) => {
10778
10800
  const options = {
10779
10801
  host: target.host,
10780
10802
  port: target.port,
10781
10803
  method,
10782
- path: path38,
10804
+ path: path39,
10783
10805
  // 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.
10784
10806
  headers: { ...headers, host: target.servername ?? target.host, ...body === void 0 ? {} : { "content-length": String(Buffer.byteLength(body, "utf8")) } },
10785
10807
  agent,
@@ -10821,9 +10843,9 @@ function realRcStreamDial(target = { host: CONNECT_INTERCEPT_HOST, port: HTTPS_P
10821
10843
  return { status, body: await readAll(response) };
10822
10844
  },
10823
10845
  openStream: async (sessionId, headers, resume, signal) => {
10824
- const path38 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
10846
+ const path39 = resume === void 0 ? `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream` : `/v1/code/sessions/${encodeURIComponent(sessionId)}/events/stream?from_sequence_num=${String(resume.fromSequenceNum)}`;
10825
10847
  const streamHeaders = resume === void 0 ? headers : { ...headers, "last-event-id": String(resume.fromSequenceNum) };
10826
- const { status, response } = await request4("GET", path38, streamHeaders, void 0, signal);
10848
+ const { status, response } = await request4("GET", path39, streamHeaders, void 0, signal);
10827
10849
  if (!isSuccessful2(status)) {
10828
10850
  await readAll(response);
10829
10851
  return { status, chunks: NO_CHUNKS };
@@ -11290,6 +11312,7 @@ var RC_ORPC_PATH_PREFIX = "/__agent-shim/orpc";
11290
11312
  var RC_OPENAPI_DOC_PATH = "/openapi.json";
11291
11313
  var RC_SUBSCRIBER_BUFFER_EVENTS = 100;
11292
11314
  var READ_ONLY_OPERATION_EXTENSION = "x-agent-shim-read-only";
11315
+ var SESSION_HISTORY_TAG = "agent-trees";
11293
11316
  function doorApiBearer(headers) {
11294
11317
  const presented = headers.authorization;
11295
11318
  const bearerPrefix = "bearer ".length;
@@ -11704,8 +11727,8 @@ init_cliError();
11704
11727
  init_realPorts();
11705
11728
 
11706
11729
  // src/frontdoor/controlApi.ts
11707
- var import_client6 = require("@orpc/client");
11708
- var import_openapi7 = require("@orpc/openapi");
11730
+ var import_client7 = require("@orpc/client");
11731
+ var import_openapi8 = require("@orpc/openapi");
11709
11732
 
11710
11733
  // src/checkReport.ts
11711
11734
  var import_node_os5 = __toESM(require("node:os"), 1);
@@ -11974,19 +11997,19 @@ function writePools(paths, pools) {
11974
11997
  applyPatch(paths.globalConfigFile, GlobalConfigSchema, { pools }, { defaults: {} });
11975
11998
  }
11976
11999
  function poolCycleOf(pools, name) {
11977
- const walk = (current, path38) => {
12000
+ const walk = (current, path39) => {
11978
12001
  for (const entry of pools[current]?.identities ?? []) {
11979
12002
  const nested = poolNameOf(poolMemberIdentity(entry));
11980
12003
  if (nested === void 0) {
11981
12004
  continue;
11982
12005
  }
11983
12006
  if (nested === name) {
11984
- return [...path38, nested];
12007
+ return [...path39, nested];
11985
12008
  }
11986
- if (path38.includes(nested)) {
12009
+ if (path39.includes(nested)) {
11987
12010
  continue;
11988
12011
  }
11989
- const found = walk(nested, [...path38, nested]);
12012
+ const found = walk(nested, [...path39, nested]);
11990
12013
  if (found !== void 0) {
11991
12014
  return found;
11992
12015
  }
@@ -14120,7 +14143,7 @@ function profileValue(name, paths) {
14120
14143
  function createConfigApiRouter(deps) {
14121
14144
  const authed = doorApiAuth(deps.expectedToken);
14122
14145
  const { paths } = deps;
14123
- const route = (path38, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path38, summary, tags: [CONFIG_API_TAG] }));
14146
+ const route = (path39, summary) => authed.meta((0, import_openapi3.openapi)({ method: "POST", path: path39, summary, tags: [CONFIG_API_TAG] }));
14124
14147
  return {
14125
14148
  config: {
14126
14149
  identity: {
@@ -14562,6 +14585,166 @@ function createLaunchApiRouter(deps) {
14562
14585
  };
14563
14586
  }
14564
14587
 
14588
+ // src/frontdoor/agentTreesApi.ts
14589
+ var import_client6 = require("@orpc/client");
14590
+ var import_openapi7 = require("@orpc/openapi");
14591
+ var import_zod26 = require("zod");
14592
+
14593
+ // src/agents/schema.ts
14594
+ var import_zod25 = require("zod");
14595
+ var AgentMetaSchema = import_zod25.z.looseObject({
14596
+ agentType: import_zod25.z.string(),
14597
+ isFork: import_zod25.z.boolean().optional(),
14598
+ description: import_zod25.z.string().optional(),
14599
+ name: import_zod25.z.string().optional(),
14600
+ toolUseId: import_zod25.z.string().optional(),
14601
+ spawnDepth: import_zod25.z.number().int().nonnegative().optional(),
14602
+ parentAgentId: import_zod25.z.string().optional(),
14603
+ model: import_zod25.z.string().optional(),
14604
+ requestShape: import_zod25.z.string().optional(),
14605
+ requestNonInteractive: import_zod25.z.boolean().optional(),
14606
+ workflowPhase: import_zod25.z.string().optional(),
14607
+ taskKind: import_zod25.z.string().optional(),
14608
+ teamName: import_zod25.z.string().optional(),
14609
+ worktreePath: import_zod25.z.string().optional(),
14610
+ worktreeBranch: import_zod25.z.string().optional(),
14611
+ stoppedByUser: import_zod25.z.boolean().optional()
14612
+ });
14613
+ var AgentKindSchema = import_zod25.z.enum(["subagent", "fork", "workflow-agent", "teammate"]);
14614
+ var AgentNodeSchema = import_zod25.z.lazy(
14615
+ () => import_zod25.z.strictObject({
14616
+ id: import_zod25.z.string(),
14617
+ kind: AgentKindSchema,
14618
+ agentType: import_zod25.z.string(),
14619
+ description: import_zod25.z.string().optional(),
14620
+ name: import_zod25.z.string().optional(),
14621
+ toolUseId: import_zod25.z.string().optional(),
14622
+ spawnDepth: import_zod25.z.number().int().nonnegative().optional(),
14623
+ model: import_zod25.z.string().optional(),
14624
+ background: import_zod25.z.boolean().optional(),
14625
+ workflowRunId: import_zod25.z.string().optional(),
14626
+ workflowPhase: import_zod25.z.string().optional(),
14627
+ teamName: import_zod25.z.string().optional(),
14628
+ stoppedByUser: import_zod25.z.boolean().optional(),
14629
+ transcript: import_zod25.z.string(),
14630
+ children: import_zod25.z.array(AgentNodeSchema)
14631
+ })
14632
+ );
14633
+ var TaskItemSchema = import_zod25.z.strictObject({
14634
+ id: import_zod25.z.string(),
14635
+ subject: import_zod25.z.string(),
14636
+ description: import_zod25.z.string().optional(),
14637
+ status: import_zod25.z.string(),
14638
+ /** What a spinner shows while the task runs. */
14639
+ activeForm: import_zod25.z.string().optional(),
14640
+ /** The teammate or agent name the task is assigned to, as Agent Teams writes it. */
14641
+ owner: import_zod25.z.string().optional(),
14642
+ /** Free-form data the harness attaches to a task, kept as written. */
14643
+ metadata: import_zod25.z.record(import_zod25.z.string(), import_zod25.z.unknown()).optional(),
14644
+ blocks: import_zod25.z.array(import_zod25.z.string()),
14645
+ blockedBy: import_zod25.z.array(import_zod25.z.string()),
14646
+ /** The id of the shared task list this task belongs to (a team's name, or a custom list id), absent for the session's own list. */
14647
+ taskList: import_zod25.z.string().optional()
14648
+ });
14649
+ var WorkflowRunSchema = import_zod25.z.strictObject({
14650
+ runId: import_zod25.z.string(),
14651
+ workflowName: import_zod25.z.string().optional(),
14652
+ status: import_zod25.z.string().optional(),
14653
+ startTime: import_zod25.z.number().optional(),
14654
+ phases: import_zod25.z.array(import_zod25.z.string()),
14655
+ summary: import_zod25.z.string().optional()
14656
+ });
14657
+ var AgentTreeProblemSchema = import_zod25.z.strictObject({
14658
+ /** Relative to the identity's configuration directory. */
14659
+ path: import_zod25.z.string(),
14660
+ reason: import_zod25.z.string()
14661
+ });
14662
+ var SessionSummarySchema = import_zod25.z.strictObject({
14663
+ project: import_zod25.z.string(),
14664
+ sessionId: import_zod25.z.string(),
14665
+ superseded: import_zod25.z.boolean(),
14666
+ /** The directory and transcript stem exactly as on disk, which differs from `sessionId` for a superseded session. */
14667
+ entry: import_zod25.z.string(),
14668
+ agentCount: import_zod25.z.number().int().nonnegative(),
14669
+ workflowRunCount: import_zod25.z.number().int().nonnegative(),
14670
+ /** When the transcript was last written, as an ISO instant; absent when there is no transcript file. */
14671
+ updatedAt: import_zod25.z.iso.datetime().optional(),
14672
+ identities: import_zod25.z.array(import_zod25.z.string())
14673
+ });
14674
+ var SessionAgentTreeSchema = import_zod25.z.strictObject({
14675
+ project: import_zod25.z.string(),
14676
+ sessionId: import_zod25.z.string(),
14677
+ /** True for a session directory a resume superseded (`<session-id>.superseded-<epoch-ms>`). */
14678
+ superseded: import_zod25.z.boolean(),
14679
+ /** The agents the session itself spawned, each with its descendants. */
14680
+ agents: import_zod25.z.array(AgentNodeSchema),
14681
+ tasks: import_zod25.z.array(TaskItemSchema),
14682
+ workflowRuns: import_zod25.z.array(WorkflowRunSchema),
14683
+ problems: import_zod25.z.array(AgentTreeProblemSchema)
14684
+ });
14685
+
14686
+ // src/frontdoor/agentTreesApi.ts
14687
+ init_cliError();
14688
+ var AgentTreesListInputSchema = import_zod26.z.strictObject({
14689
+ /** Only this identity's sessions. */
14690
+ identity: import_zod26.z.string().optional(),
14691
+ /** Include sessions that spawned no agent and ran no workflow. */
14692
+ all: import_zod26.z.boolean().optional()
14693
+ });
14694
+ var AgentTreesListOutputSchema = import_zod26.z.array(SessionSummarySchema);
14695
+ var AgentTreesShowInputSchema = import_zod26.z.strictObject({
14696
+ /** A session id, or an unambiguous prefix of one. */
14697
+ session: import_zod26.z.string().min(1),
14698
+ /** Look only in this identity. */
14699
+ identity: import_zod26.z.string().optional()
14700
+ });
14701
+ var AgentTreesShowOutputSchema = import_zod26.z.strictObject({ identities: import_zod26.z.array(import_zod26.z.string()), ...SessionAgentTreeSchema.shape });
14702
+ function asBadRequest(error) {
14703
+ if (error instanceof CliError) {
14704
+ throw new import_client6.ORPCError("BAD_REQUEST", { message: error.message });
14705
+ }
14706
+ throw error;
14707
+ }
14708
+ function createAgentTreesApiRouter(deps) {
14709
+ const authed = doorApiAuth(deps.expectedToken);
14710
+ return {
14711
+ agentTrees: {
14712
+ list: authed.meta(
14713
+ (0, import_openapi7.openapi)({
14714
+ method: "POST",
14715
+ path: "/rest/agent-trees/list",
14716
+ summary: "List the sessions that spawned agents or ran workflows, newest transcript first",
14717
+ tags: [SESSION_HISTORY_TAG],
14718
+ // A POST because the filters are a body, but the answer changes nothing.
14719
+ spec: (current) => ({ ...current, [READ_ONLY_OPERATION_EXTENSION]: true })
14720
+ })
14721
+ ).input(AgentTreesListInputSchema).output(AgentTreesListOutputSchema).handler(({ input }) => {
14722
+ try {
14723
+ return deps.sessionList(input).map((session) => ({ ...session, identities: [...session.identities] }));
14724
+ } catch (error) {
14725
+ return asBadRequest(error);
14726
+ }
14727
+ }),
14728
+ show: authed.meta(
14729
+ (0, import_openapi7.openapi)({
14730
+ method: "POST",
14731
+ path: "/rest/agent-trees/show",
14732
+ summary: "Show one session's agent tree, task list and workflow runs",
14733
+ tags: [SESSION_HISTORY_TAG],
14734
+ spec: (current) => ({ ...current, [READ_ONLY_OPERATION_EXTENSION]: true })
14735
+ })
14736
+ ).input(AgentTreesShowInputSchema).output(AgentTreesShowOutputSchema).handler(({ input }) => {
14737
+ try {
14738
+ const view = deps.sessionShow(input.session, input.identity);
14739
+ return { identities: [...view.identities], ...view.tree };
14740
+ } catch (error) {
14741
+ return asBadRequest(error);
14742
+ }
14743
+ })
14744
+ }
14745
+ };
14746
+ }
14747
+
14565
14748
  // src/frontdoor/controlApi.ts
14566
14749
  var USAGE_API_TAG = "usage";
14567
14750
  var FRONTDOOR_API_TAG2 = "frontdoor";
@@ -14572,12 +14755,12 @@ function createControlApiRouter(deps) {
14572
14755
  const authed = doorApiAuth(deps.expectedToken);
14573
14756
  return {
14574
14757
  usage: {
14575
- list: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
14576
- resets: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/usage/resets", summary: "List every recorded quota window with when it resets", tags: [USAGE_API_TAG] })).output(ResetScheduleSchema).handler(() => collectResets(deps.usageSnapshots(), deps.now())),
14577
- effectiveWindow: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
14758
+ list: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/usage/snapshots", summary: "List every identity's usage snapshot", tags: [USAGE_API_TAG] })).output(UsageListOutputSchema).handler(() => ({ snapshots: deps.usageSnapshots() })),
14759
+ resets: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/usage/resets", summary: "List every recorded quota window with when it resets", tags: [USAGE_API_TAG] })).output(ResetScheduleSchema).handler(() => collectResets(deps.usageSnapshots(), deps.now())),
14760
+ effectiveWindow: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/usage/windows", summary: "Read one identity's effective quota windows", tags: [USAGE_API_TAG] })).input(UsageWindowsInputSchema).output(UsageWindowsOutputSchema).handler(({ input }) => {
14578
14761
  const snapshot = deps.usageSnapshotOf(input.identity);
14579
14762
  if (snapshot === void 0) {
14580
- throw new import_client6.ORPCError("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
14763
+ throw new import_client7.ORPCError("NOT_FOUND", { message: `identity ${input.identity} has no usage snapshot yet, so no quota window has been observed for it` });
14581
14764
  }
14582
14765
  const provider = input.provider ?? ANTHROPIC_PROVIDER;
14583
14766
  const rateLimit = snapshot.providers[provider]?.rateLimit;
@@ -14591,34 +14774,34 @@ function createControlApiRouter(deps) {
14591
14774
  ...unified?.sevenDay === void 0 ? {} : { sevenDay: effectiveWindow(unified.sevenDay, now) }
14592
14775
  };
14593
14776
  }),
14594
- live: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] })).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
14777
+ live: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/usage/live", summary: "Read the live rate-limit observations the event backbone files", tags: [USAGE_API_TAG] })).input(RcSessionQuerySchema).output(UsageLiveOutputSchema).handler(({ input }) => {
14595
14778
  const sessions = deps.liveRateLimits(input.session);
14596
14779
  if (input.session !== void 0 && sessions.length === 0) {
14597
14780
  if (deps.list().some((session) => session.id === input.session)) {
14598
- throw new import_client6.ORPCError("NOT_FOUND", { message: `session ${input.session} has filed no rate_limit_event on its stream yet: the worker emits one only once a turn has completed, so retry after this session's next turn` });
14781
+ throw new import_client7.ORPCError("NOT_FOUND", { message: `session ${input.session} has filed no rate_limit_event on its stream yet: the worker emits one only once a turn has completed, so retry after this session's next turn` });
14599
14782
  }
14600
- throw new import_client6.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
14783
+ throw new import_client7.ORPCError("NOT_FOUND", { message: rcSessionNotObservedMessage(input.session) });
14601
14784
  }
14602
14785
  return { latest: deps.latestRateLimit(), sessions };
14603
14786
  })
14604
14787
  },
14605
14788
  frontdoor: {
14606
- status: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
14607
- sessions: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
14789
+ status: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/frontdoor/status", summary: "Read the front door's status", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorStatusOutputSchema).handler(() => deps.frontDoorStatus()),
14790
+ sessions: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/frontdoor/sessions", summary: "Read the front door's session registry", tags: [FRONTDOOR_API_TAG2] })).output(FrontDoorSessionsOutputSchema).handler(() => ({ sessions: deps.frontDoorStatus().sessions }))
14608
14791
  },
14609
14792
  check: {
14610
14793
  // The report's own JSON shape is the contract (the same one `check --json` prints and `checkReportSchema.ts` defines), so the procedure returns exactly that conversion.
14611
- run: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] })).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
14794
+ run: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/check", summary: "Run the check report for one directory", tags: [CHECK_API_TAG] })).input(CheckRunInputSchema).output(CheckReportJsonSchema).handler(({ input }) => checkReportToJson(deps.checkReport(input.path, input.identity)))
14612
14795
  },
14613
14796
  doctor: {
14614
- run: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
14797
+ run: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/doctor", summary: "Run the doctor report", tags: [DOCTOR_API_TAG] })).output(DoctorRunOutputSchema).handler(() => deps.doctorReport())
14615
14798
  },
14616
14799
  pool: {
14617
- pick: authed.meta((0, import_openapi7.openapi)({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] })).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
14800
+ pick: authed.meta((0, import_openapi8.openapi)({ method: "GET", path: "/rest/pool/pick", summary: "Rank one pool exactly as a launch from a directory would right now", tags: [POOL_API_TAG] })).input(PoolPickInputSchema).output(PoolPickReportSchema).handler(({ input }) => {
14618
14801
  const report = deps.poolPick(input.pool, input.path);
14619
14802
  if (report === void 0) {
14620
14803
  const live = deps.poolNames();
14621
- throw new import_client6.ORPCError("NOT_FOUND", {
14804
+ throw new import_client7.ORPCError("NOT_FOUND", {
14622
14805
  message: live.length === 0 ? `no pools are configured, so none is named ${input.pool}` : `no pool is named ${input.pool}; the live pools are ${live.map((name) => `"${name}"`).join(", ")}`
14623
14806
  });
14624
14807
  }
@@ -14630,13 +14813,13 @@ function createControlApiRouter(deps) {
14630
14813
  function createDoorApiRouter(deps) {
14631
14814
  const control = createControlApiRouter(deps);
14632
14815
  const lifecycle = createLifecycleApiRouter(deps);
14633
- return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
14816
+ return { ...createRcApiRouter(deps), ...control, ...lifecycle, ...createConfigApiRouter(deps), ...createCodexApiRouter(deps), ...createLaunchApiRouter(deps), ...createAgentTreesApiRouter(deps), ...createEventsApiRouter(deps), frontdoor: { ...control.frontdoor, ...lifecycle.frontdoor } };
14634
14817
  }
14635
14818
  function createDoorApiNodeHandler(deps) {
14636
14819
  return doorApiNodeHandlerOf(createDoorApiRouter(deps), deps.expectedToken);
14637
14820
  }
14638
14821
  function frontDoorApiClient(port, ca, token) {
14639
- return (0, import_client6.createORPCClient)(frontDoorApiLink(port, ca, token));
14822
+ return (0, import_client7.createORPCClient)(frontDoorApiLink(port, ca, token));
14640
14823
  }
14641
14824
 
14642
14825
  // src/frontdoor/doorClient.ts
@@ -16698,90 +16881,7 @@ init_poolPick();
16698
16881
 
16699
16882
  // src/agents/read.ts
16700
16883
  var import_node_path33 = __toESM(require("node:path"), 1);
16701
- var import_zod26 = require("zod");
16702
-
16703
- // src/agents/schema.ts
16704
- var import_zod25 = require("zod");
16705
- var AgentMetaSchema = import_zod25.z.looseObject({
16706
- agentType: import_zod25.z.string(),
16707
- isFork: import_zod25.z.boolean().optional(),
16708
- description: import_zod25.z.string().optional(),
16709
- name: import_zod25.z.string().optional(),
16710
- toolUseId: import_zod25.z.string().optional(),
16711
- spawnDepth: import_zod25.z.number().int().nonnegative().optional(),
16712
- parentAgentId: import_zod25.z.string().optional(),
16713
- model: import_zod25.z.string().optional(),
16714
- requestShape: import_zod25.z.string().optional(),
16715
- requestNonInteractive: import_zod25.z.boolean().optional(),
16716
- workflowPhase: import_zod25.z.string().optional(),
16717
- taskKind: import_zod25.z.string().optional(),
16718
- teamName: import_zod25.z.string().optional(),
16719
- worktreePath: import_zod25.z.string().optional(),
16720
- worktreeBranch: import_zod25.z.string().optional(),
16721
- stoppedByUser: import_zod25.z.boolean().optional()
16722
- });
16723
- var AgentKindSchema = import_zod25.z.enum(["subagent", "fork", "workflow-agent", "teammate"]);
16724
- var AgentNodeSchema = import_zod25.z.lazy(
16725
- () => import_zod25.z.strictObject({
16726
- id: import_zod25.z.string(),
16727
- kind: AgentKindSchema,
16728
- agentType: import_zod25.z.string(),
16729
- description: import_zod25.z.string().optional(),
16730
- name: import_zod25.z.string().optional(),
16731
- toolUseId: import_zod25.z.string().optional(),
16732
- spawnDepth: import_zod25.z.number().int().nonnegative().optional(),
16733
- model: import_zod25.z.string().optional(),
16734
- background: import_zod25.z.boolean().optional(),
16735
- workflowRunId: import_zod25.z.string().optional(),
16736
- workflowPhase: import_zod25.z.string().optional(),
16737
- teamName: import_zod25.z.string().optional(),
16738
- stoppedByUser: import_zod25.z.boolean().optional(),
16739
- transcript: import_zod25.z.string(),
16740
- children: import_zod25.z.array(AgentNodeSchema)
16741
- })
16742
- );
16743
- var TaskItemSchema = import_zod25.z.strictObject({
16744
- id: import_zod25.z.string(),
16745
- subject: import_zod25.z.string(),
16746
- description: import_zod25.z.string().optional(),
16747
- status: import_zod25.z.string(),
16748
- /** What a spinner shows while the task runs. */
16749
- activeForm: import_zod25.z.string().optional(),
16750
- /** The teammate or agent name the task is assigned to, as Agent Teams writes it. */
16751
- owner: import_zod25.z.string().optional(),
16752
- /** Free-form data the harness attaches to a task, kept as written. */
16753
- metadata: import_zod25.z.record(import_zod25.z.string(), import_zod25.z.unknown()).optional(),
16754
- blocks: import_zod25.z.array(import_zod25.z.string()),
16755
- blockedBy: import_zod25.z.array(import_zod25.z.string()),
16756
- /** The id of the shared task list this task belongs to (a team's name, or a custom list id), absent for the session's own list. */
16757
- taskList: import_zod25.z.string().optional()
16758
- });
16759
- var WorkflowRunSchema = import_zod25.z.strictObject({
16760
- runId: import_zod25.z.string(),
16761
- workflowName: import_zod25.z.string().optional(),
16762
- status: import_zod25.z.string().optional(),
16763
- startTime: import_zod25.z.number().optional(),
16764
- phases: import_zod25.z.array(import_zod25.z.string()),
16765
- summary: import_zod25.z.string().optional()
16766
- });
16767
- var AgentTreeProblemSchema = import_zod25.z.strictObject({
16768
- /** Relative to the identity's configuration directory. */
16769
- path: import_zod25.z.string(),
16770
- reason: import_zod25.z.string()
16771
- });
16772
- var SessionAgentTreeSchema = import_zod25.z.strictObject({
16773
- project: import_zod25.z.string(),
16774
- sessionId: import_zod25.z.string(),
16775
- /** True for a session directory a resume superseded (`<session-id>.superseded-<epoch-ms>`). */
16776
- superseded: import_zod25.z.boolean(),
16777
- /** The agents the session itself spawned, each with its descendants. */
16778
- agents: import_zod25.z.array(AgentNodeSchema),
16779
- tasks: import_zod25.z.array(TaskItemSchema),
16780
- workflowRuns: import_zod25.z.array(WorkflowRunSchema),
16781
- problems: import_zod25.z.array(AgentTreeProblemSchema)
16782
- });
16783
-
16784
- // src/agents/read.ts
16884
+ var import_zod27 = require("zod");
16785
16885
  var PROJECTS_DIR = "projects";
16786
16886
  var TASKS_DIR = "tasks";
16787
16887
  var SUBAGENTS_DIR = "subagents";
@@ -16900,15 +17000,30 @@ function parseJson2(text) {
16900
17000
  return void 0;
16901
17001
  }
16902
17002
  }
16903
- var TaskFileSchema = import_zod26.z.object({ ...TaskItemSchema.omit({ taskList: true }).shape, blocks: import_zod26.z.array(import_zod26.z.string()).default([]), blockedBy: import_zod26.z.array(import_zod26.z.string()).default([]) });
16904
- var WorkflowRunFileSchema = import_zod26.z.object({
16905
- runId: import_zod26.z.string(),
16906
- workflowName: import_zod26.z.string().optional(),
16907
- status: import_zod26.z.string().optional(),
16908
- startTime: import_zod26.z.number().optional(),
16909
- phases: import_zod26.z.array(import_zod26.z.object({ title: import_zod26.z.string() })).default([]),
16910
- summary: import_zod26.z.string().optional()
17003
+ var TaskFileSchema = import_zod27.z.object({ ...TaskItemSchema.omit({ taskList: true }).shape, blocks: import_zod27.z.array(import_zod27.z.string()).default([]), blockedBy: import_zod27.z.array(import_zod27.z.string()).default([]) });
17004
+ var WorkflowRunFileSchema = import_zod27.z.object({
17005
+ runId: import_zod27.z.string(),
17006
+ workflowName: import_zod27.z.string().optional(),
17007
+ status: import_zod27.z.string().optional(),
17008
+ startTime: import_zod27.z.number().optional(),
17009
+ phases: import_zod27.z.array(import_zod27.z.object({ title: import_zod27.z.string() })).default([]),
17010
+ summary: import_zod27.z.string().optional()
16911
17011
  });
17012
+ function summariseSession(fs12, configDir, ref) {
17013
+ const sessionRelative = import_node_path33.default.join(PROJECTS_DIR, ref.project, ref.entry);
17014
+ const subagentsRelative = import_node_path33.default.join(sessionRelative, SUBAGENTS_DIR);
17015
+ const workflowsUnderSubagents = import_node_path33.default.join(subagentsRelative, WORKFLOWS_DIR);
17016
+ const isMeta = (name) => name.startsWith(AGENT_FILE_PREFIX) && name.endsWith(META_SUFFIX);
17017
+ let agentCount = fs12.readdir(import_node_path33.default.join(configDir, subagentsRelative)).filter(isMeta).length;
17018
+ for (const runDir of fs12.readdir(import_node_path33.default.join(configDir, workflowsUnderSubagents))) {
17019
+ if (runDir.startsWith(WORKFLOW_RUN_PREFIX)) {
17020
+ agentCount += fs12.readdir(import_node_path33.default.join(configDir, workflowsUnderSubagents, runDir)).filter(isMeta).length;
17021
+ }
17022
+ }
17023
+ const workflowRunCount = fs12.readdir(import_node_path33.default.join(configDir, sessionRelative, WORKFLOWS_DIR)).filter((name) => name.startsWith(WORKFLOW_RUN_PREFIX) && name.endsWith(JSON_SUFFIX)).length;
17024
+ const transcript = fs12.lstat(import_node_path33.default.join(configDir, PROJECTS_DIR, ref.project, `${ref.entry}${TRANSCRIPT_SUFFIX}`));
17025
+ return { ...ref, agentCount, workflowRunCount, ...transcript === void 0 ? {} : { updatedAt: new Date(transcript.mtimeMs).toISOString() } };
17026
+ }
16912
17027
  function readSessionAgentTree(fs12, configDir, ref, options = {}) {
16913
17028
  const problems = [];
16914
17029
  const report = (problem) => {
@@ -17064,6 +17179,94 @@ function readWorkflowRuns(fs12, configDir, relativeDir, report) {
17064
17179
  return runs;
17065
17180
  }
17066
17181
 
17182
+ // src/agents/sessions.ts
17183
+ var import_node_path34 = __toESM(require("node:path"), 1);
17184
+ init_cliError();
17185
+ var SessionLookupError = class extends CliError {
17186
+ constructor(message) {
17187
+ super(message);
17188
+ this.name = "SessionLookupError";
17189
+ }
17190
+ };
17191
+ function identityConfigDir(identitiesDir, identity) {
17192
+ return import_node_path34.default.join(identitiesDir, identity);
17193
+ }
17194
+ function historyStores(fs12, identitiesDir, identities) {
17195
+ const byRealPath = /* @__PURE__ */ new Map();
17196
+ for (const identity of identities) {
17197
+ const configDir = identityConfigDir(identitiesDir, identity);
17198
+ const real = fs12.realpath(import_node_path34.default.join(configDir, "projects"));
17199
+ if (real === void 0) {
17200
+ continue;
17201
+ }
17202
+ const store = byRealPath.get(real);
17203
+ if (store === void 0) {
17204
+ byRealPath.set(real, { configDir, identities: [identity] });
17205
+ } else {
17206
+ store.identities.push(identity);
17207
+ }
17208
+ }
17209
+ return [...byRealPath.values()];
17210
+ }
17211
+ function collectSessionList(fs12, identitiesDir, identities, filters) {
17212
+ const names = filters.identity === void 0 ? identities : identities.filter((name) => name === filters.identity);
17213
+ if (filters.identity !== void 0 && names.length === 0) {
17214
+ throw new SessionLookupError(`no identity named "${filters.identity}"`);
17215
+ }
17216
+ const sessions = [];
17217
+ for (const store of historyStores(fs12, identitiesDir, names)) {
17218
+ for (const ref of listSessions2(fs12, store.configDir)) {
17219
+ const summary = summariseSession(fs12, store.configDir, ref);
17220
+ if (filters.all === true || summary.agentCount > 0 || summary.workflowRunCount > 0) {
17221
+ sessions.push({ ...summary, identities: store.identities });
17222
+ }
17223
+ }
17224
+ }
17225
+ return sessions.sort((left, right) => (right.updatedAt ?? "").localeCompare(left.updatedAt ?? "") || left.sessionId.localeCompare(right.sessionId));
17226
+ }
17227
+ function locateSession(fs12, identitiesDir, identities, query, onlyIdentity) {
17228
+ const names = onlyIdentity === void 0 ? identities : identities.filter((name) => name === onlyIdentity);
17229
+ if (onlyIdentity !== void 0 && names.length === 0) {
17230
+ throw new SessionLookupError(`no identity named "${onlyIdentity}"`);
17231
+ }
17232
+ const matches = [];
17233
+ for (const store of historyStores(fs12, identitiesDir, names)) {
17234
+ for (const ref of listSessions2(fs12, store.configDir)) {
17235
+ if (ref.sessionId.startsWith(query)) {
17236
+ matches.push({ identities: store.identities, configDir: store.configDir, ref });
17237
+ }
17238
+ }
17239
+ }
17240
+ const exact = matches.filter((match) => match.ref.sessionId === query);
17241
+ const candidates = exact.length > 0 ? exact : matches;
17242
+ const only = candidates[0];
17243
+ if (candidates.length === 1 && only !== void 0) {
17244
+ return only;
17245
+ }
17246
+ if (candidates.length === 0) {
17247
+ throw new SessionLookupError(`no session matches "${query}"`);
17248
+ }
17249
+ throw new SessionLookupError(`"${query}" matches ${String(candidates.length)} sessions: ${candidates.map((match) => `${match.ref.sessionId} (${match.identities.join(", ")})`).join("; ")}; give more of the id or pass --identity`);
17250
+ }
17251
+ function showSession(fs12, identitiesDir, identities, query, onlyIdentity) {
17252
+ const located = locateSession(fs12, identitiesDir, identities, query, onlyIdentity);
17253
+ return { identities: located.identities, tree: readSessionAgentTree(fs12, located.configDir, located.ref) };
17254
+ }
17255
+
17256
+ // src/agents/realFs.ts
17257
+ var import_node_fs10 = __toESM(require("node:fs"), 1);
17258
+ init_realPorts();
17259
+ var realSessionFs = {
17260
+ ...realFarmFs,
17261
+ realpath: (candidate) => {
17262
+ try {
17263
+ return import_node_fs10.default.realpathSync(candidate);
17264
+ } catch {
17265
+ return void 0;
17266
+ }
17267
+ }
17268
+ };
17269
+
17067
17270
  // src/index.ts
17068
17271
  init_conditions();
17069
17272
  init_ensure();
@@ -17176,6 +17379,10 @@ init_ownCli();
17176
17379
  AgentKindSchema,
17177
17380
  AgentMetaSchema,
17178
17381
  AgentNodeSchema,
17382
+ AgentTreesListInputSchema,
17383
+ AgentTreesListOutputSchema,
17384
+ AgentTreesShowInputSchema,
17385
+ AgentTreesShowOutputSchema,
17179
17386
  CHECK_CREDENTIAL_APPLIES,
17180
17387
  CODEX_APP_SERVER_GENERATED_AGAINST,
17181
17388
  CODEX_APP_SERVER_TIMEOUT_MS,
@@ -17323,6 +17530,8 @@ init_ownCli();
17323
17530
  ResetRowSchema,
17324
17531
  ResetScheduleSchema,
17325
17532
  SessionAgentTreeSchema,
17533
+ SessionLookupError,
17534
+ SessionSummarySchema,
17326
17535
  TaskItemSchema,
17327
17536
  USAGE_EVENT_SOURCE,
17328
17537
  UpdateCheckOutputSchema,
@@ -17370,6 +17579,8 @@ init_ownCli();
17370
17579
  collectFrontDoorStatus,
17371
17580
  collectPoolPick,
17372
17581
  collectResets,
17582
+ collectSessionList,
17583
+ createAgentTreesApiRouter,
17373
17584
  createCodexApiRouter,
17374
17585
  createConfigApiRouter,
17375
17586
  createControlApiRouter,
@@ -17438,6 +17649,7 @@ init_ownCli();
17438
17649
  listProviders,
17439
17650
  listSessions,
17440
17651
  listUsageSnapshots,
17652
+ locateSession,
17441
17653
  matchBranch,
17442
17654
  mintLeaf,
17443
17655
  mintRcSelfHostCredential,
@@ -17480,6 +17692,7 @@ init_ownCli();
17480
17692
  realRcEventDial,
17481
17693
  realRcStreamDial,
17482
17694
  realRcWebFetch,
17695
+ realSessionFs,
17483
17696
  reconnectRcSessionMcpServer,
17484
17697
  recoverFarm,
17485
17698
  recoveryDiagnostics,
@@ -17521,11 +17734,13 @@ init_ownCli();
17521
17734
  setProfileMetadata,
17522
17735
  setRcSessionModel,
17523
17736
  setRcSessionPermissionMode,
17737
+ showSession,
17524
17738
  snapshotPath,
17525
17739
  spawnClaude,
17526
17740
  startConnectServer,
17527
17741
  submitRcSessionMcpOAuthCallbackUrl,
17528
17742
  suggestRcSessionFiles,
17743
+ summariseSession,
17529
17744
  teleportRcSession,
17530
17745
  topLevelNames,
17531
17746
  updateDirectoryRule,