claude-use 11.28.0 → 11.30.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.mjs CHANGED
@@ -267,7 +267,9 @@ var init_schema = __esm({
267
267
  /** How long the launcher waits after its own output before it starts claude, so that output can be read before Claude Code takes over the terminal (`5s`, `500ms`). Applies only when a terminal is watching. */
268
268
  delay: z.string().regex(DURATION_RE, "must be a duration such as 5s or 500ms").optional(),
269
269
  /** Whether the launcher waits for a key press after its own output before it starts claude. Takes the place of `delay` when both are set. Applies only when a terminal is watching. */
270
- pause: z.boolean().optional()
270
+ pause: z.boolean().optional(),
271
+ /** Whether the launcher's report, for a launch that picks from a pool, lists every member the pick ranked with why each stands where it does, and not only the member it picked. */
272
+ explain: z.boolean().optional()
271
273
  });
272
274
  CREDENTIAL_TARGETS = ["bearer", "apiKey", "oauthToken"];
273
275
  PROVIDER_CREDENTIAL_TARGETS = ["bearer", "apiKey"];
@@ -1376,6 +1378,9 @@ function flattenLayers(layers, options) {
1376
1378
  if (layer.launch.pause !== void 0) {
1377
1379
  launch.pause = layer.launch.pause;
1378
1380
  }
1381
+ if (layer.launch.explain !== void 0) {
1382
+ launch.explain = layer.launch.explain;
1383
+ }
1379
1384
  }
1380
1385
  if (layer.entries === void 0) {
1381
1386
  continue;
@@ -1474,11 +1479,15 @@ var init_flatten = __esm({
1474
1479
  });
1475
1480
 
1476
1481
  // src/resolve/decide.ts
1477
- function unclassifiedEntryMessage(names) {
1482
+ function unclassifiedEntrySummary(names) {
1478
1483
  const quoted = names.map((name) => `"${name}"`).join(", ");
1479
- const subject = names.length === 1 ? `${quoted} is not` : `${String(names.length)} entries are not`;
1480
- const excluded = names.length === 1 ? "it is excluded" : `they are excluded: ${quoted}`;
1481
- return `${subject} in the category map, so ${excluded}. Run \`agent-shim configure\` to classify ${names.length === 1 ? "it" : "them"}, which records the answer in the local overlay without touching the shipped default map.`;
1484
+ return names.length === 1 ? `${quoted} is not in the category map, so it is excluded` : `${String(names.length)} entries are not in the category map, so they are excluded: ${quoted}`;
1485
+ }
1486
+ function unclassifiedEntryFix(names) {
1487
+ return `Run \`agent-shim configure\` to classify ${names.length === 1 ? "it" : "them"}`;
1488
+ }
1489
+ function unclassifiedEntryMessage(names) {
1490
+ return `${unclassifiedEntrySummary(names)}. ${unclassifiedEntryFix(names)}.`;
1482
1491
  }
1483
1492
  function selectRule(relPath, flattened, context) {
1484
1493
  const eliminated = [];
@@ -2950,7 +2959,7 @@ var init_package = __esm({
2950
2959
  "package.json"() {
2951
2960
  package_default = {
2952
2961
  name: "claude-use",
2953
- version: "11.28.0",
2962
+ version: "11.30.0",
2954
2963
  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.",
2955
2964
  license: "MIT",
2956
2965
  author: "Joseph Mearman <joseph@mearman.co.uk>",
@@ -4115,21 +4124,54 @@ var init_supervisor = __esm({
4115
4124
  }
4116
4125
  });
4117
4126
 
4127
+ // src/launcher/report.ts
4128
+ function renderReport(rows, style) {
4129
+ if (rows.length === 0) {
4130
+ return [];
4131
+ }
4132
+ const labelWidth = Math.max(...rows.map((row) => row.label.length));
4133
+ const indent = " ".repeat(COLUMN_GAP.length);
4134
+ const lines = [style(["bold"], REPORT_HEADING)];
4135
+ for (const row of rows) {
4136
+ const detail = row.detail === void 0 ? "" : ` ${style(["dim"], `(${row.detail})`)}`;
4137
+ lines.push(`${indent}${style(["dim"], row.label.padEnd(labelWidth))}${COLUMN_GAP}${row.value}${detail}`);
4138
+ for (const note of row.notes ?? []) {
4139
+ lines.push(`${indent}${" ".repeat(labelWidth)}${COLUMN_GAP}${style(["dim"], note)}`);
4140
+ }
4141
+ }
4142
+ return lines;
4143
+ }
4144
+ var REPORT_HEADING, COLUMN_GAP;
4145
+ var init_report = __esm({
4146
+ "src/launcher/report.ts"() {
4147
+ "use strict";
4148
+ REPORT_HEADING = "agent-shim";
4149
+ COLUMN_GAP = " ";
4150
+ }
4151
+ });
4152
+
4118
4153
  // src/logStyle.ts
4119
4154
  import { styleText } from "node:util";
4120
- function styledDiagnostic(style, colour, line) {
4121
- const lead = DIAGNOSTIC_LEAD.exec(line);
4122
- if (lead === null) {
4123
- return style([colour], line);
4124
- }
4125
- const [whole, prefix = "", code = "", separator = ""] = lead;
4126
- return `${style([colour], prefix)}${style([colour, "bold"], code)}${style([colour], `${separator}${line.slice(whole.length)}`)}`;
4155
+ function styledDiagnostic(style, colour, text) {
4156
+ return text.split("\n").map((line, index) => {
4157
+ const lead = index === 0 ? DIAGNOSTIC_LEAD.exec(line) : null;
4158
+ if (lead === null) {
4159
+ return style([colour], line);
4160
+ }
4161
+ const [whole, prefix = "", code = "", separator = ""] = lead;
4162
+ return `${style([colour], prefix)}${style([colour, "bold"], code)}${style([colour], `${separator}${line.slice(whole.length)}`)}`;
4163
+ }).join("\n");
4127
4164
  }
4128
4165
  function createLogPort(sinks, styleFor) {
4129
4166
  return {
4130
4167
  info: (message) => {
4131
4168
  sinks.out(styleFor.out(["dim"], message));
4132
4169
  },
4170
+ report: (rows) => {
4171
+ for (const line of renderReport(rows, styleFor.out)) {
4172
+ sinks.out(line);
4173
+ }
4174
+ },
4133
4175
  warn: (message) => {
4134
4176
  sinks.warn(styledDiagnostic(styleFor.err, "yellow", message));
4135
4177
  },
@@ -4145,6 +4187,7 @@ var DIAGNOSTIC_LEAD;
4145
4187
  var init_logStyle = __esm({
4146
4188
  "src/logStyle.ts"() {
4147
4189
  "use strict";
4190
+ init_report();
4148
4191
  DIAGNOSTIC_LEAD = /^(agent-shim: )([A-Z][A-Z0-9_]*)(: )/;
4149
4192
  }
4150
4193
  });
@@ -7513,7 +7556,8 @@ var init_argv = __esm({
7513
7556
  { flag: "--skip-permissions", key: "skipPermissions" },
7514
7557
  { flag: "--remote-control", key: "remoteControl" },
7515
7558
  { flag: "--wait", key: "wait" },
7516
- { flag: "--pause", key: "pause" }
7559
+ { flag: "--pause", key: "pause" },
7560
+ { flag: "--explain", key: "explain" }
7517
7561
  ];
7518
7562
  LAUNCHER_FLAG_NAMES = [
7519
7563
  ...VALUED_FLAGS,
@@ -7703,6 +7747,7 @@ function resolveLaunchFlags(params) {
7703
7747
  headroom: params.flags?.headroom ?? parseEnvBool("AGENT_SHIM_HEADROOM", params.env.AGENT_SHIM_HEADROOM) ?? params.cascade?.headroom ?? false,
7704
7748
  trackUsage: params.flags?.trackUsage ?? parseEnvBool("AGENT_SHIM_TRACK_USAGE", params.env.AGENT_SHIM_TRACK_USAGE) ?? params.cascade?.trackUsage ?? true,
7705
7749
  pause: params.flags?.pause ?? parseEnvBool("AGENT_SHIM_PAUSE", params.env.AGENT_SHIM_PAUSE) ?? params.cascade?.pause ?? false,
7750
+ explain: params.flags?.explain ?? parseEnvBool("AGENT_SHIM_EXPLAIN", params.env.AGENT_SHIM_EXPLAIN) ?? params.cascade?.explain ?? false,
7706
7751
  delayMs: resolveDelayMs(params)
7707
7752
  };
7708
7753
  }
@@ -7986,7 +8031,9 @@ function diagnosticLines(diagnostics) {
7986
8031
  if (diagnostic.code === "UNCLASSIFIED_ENTRY") {
7987
8032
  if (!unclassifiedReported) {
7988
8033
  unclassifiedReported = true;
7989
- lines.push({ severity: diagnostic.severity, text: `agent-shim: ${diagnostic.code}: ${unclassifiedEntryMessage(unclassified.filter((name) => name !== void 0))}` });
8034
+ const names = unclassified.filter((name) => name !== void 0);
8035
+ lines.push({ severity: diagnostic.severity, text: `agent-shim: ${diagnostic.code}: ${unclassifiedEntrySummary(names)}
8036
+ ${unclassifiedEntryFix(names)}.` });
7990
8037
  }
7991
8038
  continue;
7992
8039
  }
@@ -7994,8 +8041,8 @@ function diagnosticLines(diagnostics) {
7994
8041
  }
7995
8042
  return lines;
7996
8043
  }
7997
- function reportDiagnostics(log, diagnostics, options) {
7998
- for (const line of diagnosticLines(diagnostics)) {
8044
+ function printDiagnosticLines(log, lines, options) {
8045
+ for (const line of lines) {
7999
8046
  if (line.severity === "error" && !options.errorsAsWarnings) {
8000
8047
  log.error(line.text);
8001
8048
  } else {
@@ -8003,6 +8050,9 @@ function reportDiagnostics(log, diagnostics, options) {
8003
8050
  }
8004
8051
  }
8005
8052
  }
8053
+ function reportDiagnostics(log, diagnostics, options) {
8054
+ printDiagnosticLines(log, diagnosticLines(diagnostics), options);
8055
+ }
8006
8056
  var init_diagnostics = __esm({
8007
8057
  "src/launcher/diagnostics.ts"() {
8008
8058
  "use strict";
@@ -8035,6 +8085,79 @@ var init_hold = __esm({
8035
8085
  }
8036
8086
  });
8037
8087
 
8088
+ // src/usage/candidateText.ts
8089
+ function candidateHeading(candidate) {
8090
+ const score = candidate.score === void 0 ? "" : ` score ${candidate.score.toFixed(2)}${candidate.scoreWindow === "fiveHour" ? " by 5h reset" : " by 7d reset"}`;
8091
+ const dry = candidate.feasible ? "" : " (5h would run dry)";
8092
+ return `[${candidate.class}${score}]${dry}`;
8093
+ }
8094
+ var init_candidateText = __esm({
8095
+ "src/usage/candidateText.ts"() {
8096
+ "use strict";
8097
+ }
8098
+ });
8099
+
8100
+ // src/launcher/launchReport.ts
8101
+ function poolDetail(pool) {
8102
+ const [reason] = pool.reasons;
8103
+ if (pool.movedOff !== void 0) {
8104
+ return { detail: `moved off ${pool.movedOff.identity}: ${pool.movedOff.reason}`, ...reason === void 0 ? {} : { notes: [reason] } };
8105
+ }
8106
+ return reason === void 0 ? {} : { detail: reason };
8107
+ }
8108
+ function rankingNotes(ranking, picked) {
8109
+ return ranking.flatMap((candidate, index) => [
8110
+ `${String(index + 1)}. ${candidate.identity} ${candidateHeading(candidate)}${candidate.identity === picked ? " (picked)" : ""}`,
8111
+ ` ${candidate.reasons.join("; ")}`
8112
+ ]);
8113
+ }
8114
+ function decisionRows(facts) {
8115
+ return [
8116
+ { label: "identity", value: facts.identity ?? "(none)", detail: facts.identitySource },
8117
+ ...facts.pool === void 0 ? [] : [
8118
+ {
8119
+ label: "pool",
8120
+ value: facts.pool.name,
8121
+ ...poolDetail(facts.pool),
8122
+ ...facts.ranking === void 0 ? {} : { notes: rankingNotes(facts.ranking, facts.identity) }
8123
+ }
8124
+ ],
8125
+ ...facts.profile === void 0 ? [] : [{ label: "profile", value: facts.profile.name, detail: facts.profile.source }],
8126
+ ...facts.provider === void 0 ? [] : [{ label: "provider", value: facts.provider.name, detail: `credential ${facts.provider.credential}` }],
8127
+ ...facts.identityCredential === void 0 ? [] : [{ label: "credential", value: facts.identityCredential, detail: "the identity's own" }]
8128
+ ];
8129
+ }
8130
+ function pinnedVersionRow(version, source) {
8131
+ return { label: "claude", value: version, detail: `pinned by ${source}` };
8132
+ }
8133
+ function routingRows(facts) {
8134
+ if (facts.frontDoor === void 0) {
8135
+ return [];
8136
+ }
8137
+ return [
8138
+ {
8139
+ label: "routing",
8140
+ value: `front door 127.0.0.1:${String(facts.frontDoor.port)}`,
8141
+ ...facts.provider ? {} : { detail: `OAuth via CONNECT 127.0.0.1:${String(facts.frontDoor.connectPort)}` }
8142
+ },
8143
+ ...facts.headroom === void 0 ? [] : [{ label: "headroom", value: "on", detail: `project ${facts.headroom.projectId}` }]
8144
+ ];
8145
+ }
8146
+ function farmRow(links, builtDirectories, adopted) {
8147
+ const counted = (count, singular, plural) => `${String(count)} ${count === 1 ? singular : plural}`;
8148
+ const parts = [counted(links, "link", "links"), counted(builtDirectories, "built directory", "built directories"), ...adopted === 0 ? [] : [`${String(adopted)} adopted`]];
8149
+ return { label: "farm", value: "resynced", detail: parts.join(", ") };
8150
+ }
8151
+ function noteRow(text) {
8152
+ return { label: "note", value: text };
8153
+ }
8154
+ var init_launchReport = __esm({
8155
+ "src/launcher/launchReport.ts"() {
8156
+ "use strict";
8157
+ init_candidateText();
8158
+ }
8159
+ });
8160
+
8038
8161
  // src/antigravity/cloudUpstream.ts
8039
8162
  var init_cloudUpstream = __esm({
8040
8163
  "src/antigravity/cloudUpstream.ts"() {
@@ -8417,6 +8540,7 @@ function resolvePoolLaunch(params) {
8417
8540
  identity: pick.identity,
8418
8541
  explanation: `pool ${poolName}: ${move}${pick.reasons.slice(0, REASONS_LOGGED).join("; ")}`,
8419
8542
  reasons: pick.reasons,
8543
+ candidates: graph.ranking.candidates,
8420
8544
  ...movedOff === void 0 ? {} : { movedOff }
8421
8545
  };
8422
8546
  }
@@ -8562,7 +8686,7 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
8562
8686
  }
8563
8687
  if (params.supervised?.member !== void 0) {
8564
8688
  const reasons = ["resumed here by the supervising launcher after the previous member ran out of quota"];
8565
- return { identityDecision: { ...decided, name: params.supervised.member }, poolExplanation: `pool ${decided.pool}: ${reasons.join("; ")}`, poolPick: { name: decided.pool, reasons } };
8689
+ return { identityDecision: { ...decided, name: params.supervised.member }, poolPick: { name: decided.pool, reasons } };
8566
8690
  }
8567
8691
  const farmRuntime = params.farm;
8568
8692
  if (farmRuntime === void 0) {
@@ -8593,8 +8717,8 @@ function pickFromPool(decided, params, parsedArgv, readOnly) {
8593
8717
  }
8594
8718
  return {
8595
8719
  identityDecision: { ...decided, name: resolution.identity },
8596
- poolExplanation: resolution.explanation,
8597
- poolPick: { name: decided.pool, reasons: resolution.reasons, ...resolution.movedOff === void 0 ? {} : { movedOff: resolution.movedOff } }
8720
+ poolPick: { name: decided.pool, reasons: resolution.reasons, ...resolution.movedOff === void 0 ? {} : { movedOff: resolution.movedOff } },
8721
+ poolRanking: resolution.candidates
8598
8722
  };
8599
8723
  }
8600
8724
  function decideLaunch(params, readOnly) {
@@ -8621,7 +8745,7 @@ function decideLaunch(params, readOnly) {
8621
8745
  return trimmed === "" ? void 0 : trimmed;
8622
8746
  }
8623
8747
  });
8624
- const { identityDecision, poolExplanation, poolPick } = pickFromPool(decidedIdentity, params, parsedArgv, readOnly);
8748
+ const { identityDecision, poolPick, poolRanking } = pickFromPool(decidedIdentity, params, parsedArgv, readOnly);
8625
8749
  const farmIdentity = configDirEscapeHatchApplies ? void 0 : identityDecision.name;
8626
8750
  const farm = farmIdentity === void 0 ? void 0 : params.farm;
8627
8751
  if (!readOnly && farm !== void 0 && farmIdentity !== void 0) {
@@ -8757,19 +8881,21 @@ function decideLaunch(params, readOnly) {
8757
8881
  ...parsedArgv.headroom === void 0 ? {} : { headroom: parsedArgv.headroom },
8758
8882
  ...parsedArgv.trackUsage === void 0 ? {} : { trackUsage: parsedArgv.trackUsage },
8759
8883
  ...parsedArgv.pause === void 0 ? {} : { pause: parsedArgv.pause },
8884
+ ...parsedArgv.explain === void 0 ? {} : { explain: parsedArgv.explain },
8760
8885
  ...parsedArgv.delay === void 0 ? {} : { delay: parsedArgv.delay }
8761
8886
  }
8762
8887
  });
8763
8888
  const loginlessProvider = requestedFlags.remoteControl && selectedProvider !== void 0 && farmIdentity !== void 0 && params.hasStoredLogin?.(farmIdentity) === false ? { identity: farmIdentity, provider: selectedProvider.name } : void 0;
8764
- if (loginlessProvider !== void 0 && !readOnly) {
8765
- log.info(`agent-shim: identity ${loginlessProvider.identity} has no stored login, so Remote Control, which needs one, is off for this launch; provider ${loginlessProvider.provider} runs without it`);
8889
+ const notes = [];
8890
+ if (loginlessProvider !== void 0) {
8891
+ notes.push(`${loginlessProvider.identity} has no stored login, so Remote Control is off; provider ${loginlessProvider.provider} runs without it`);
8766
8892
  }
8767
8893
  const flags = loginlessProvider === void 0 ? requestedFlags : { ...requestedFlags, remoteControl: false };
8768
8894
  const catalogue = selectedProvider === void 0 ? void 0 : parseCatalogueCache(params.fs.readFileUtf8(catalogueCachePath(paths, selectedProvider.name)));
8769
8895
  const pickerSettings = selectedProvider === void 0 ? void 0 : modelPickerSettings(selectedProvider.definition, catalogue?.models);
8770
8896
  const callerSettings = hasSettingsArgument(parsedArgv.rest);
8771
- if (pickerSettings !== void 0 && callerSettings && !readOnly) {
8772
- log.info("agent-shim: this launch passes its own --settings, so /model keeps Claude Code's own model names instead of listing the provider's models");
8897
+ if (pickerSettings !== void 0 && callerSettings) {
8898
+ notes.push("--settings was passed, so /model keeps Claude Code's own model names");
8773
8899
  }
8774
8900
  const launcherSettings = mergeSettings([params.supervised?.settings, callerSettings ? void 0 : pickerSettings]);
8775
8901
  const args = buildArgv({
@@ -8791,8 +8917,9 @@ function decideLaunch(params, readOnly) {
8791
8917
  return {
8792
8918
  parsedArgv,
8793
8919
  identityDecision,
8794
- poolExplanation,
8795
8920
  poolPick,
8921
+ poolRanking,
8922
+ notes,
8796
8923
  configDirEscapeHatch: configDirEscapeHatchApplies,
8797
8924
  farmIdentity,
8798
8925
  farmContext,
@@ -8812,10 +8939,19 @@ function prepareLaunch(params) {
8812
8939
  const { paths, proc, log } = params;
8813
8940
  const { env } = proc;
8814
8941
  const decided = decideLaunch(params, false);
8815
- const { identityDecision, configProfileDecision, resolvedProvider, identityCredential, poolExplanation, flags: resolvedFlags, args: finalArgv, configDirEscapeHatch: configDirEscapeHatchApplies, decision } = decided;
8816
- log.info(
8817
- `agent-shim: identity ${identityDecision.name ?? "(none)"} (${identityDecision.source}${poolExplanation === void 0 ? "" : `, ${poolExplanation}`}), config profile ${configProfileDecision.name ?? "(none)"} (${configProfileDecision.source})` + (resolvedProvider === void 0 ? "" : `, provider ${resolvedProvider.name} (credential ${resolvedProvider.credential.target} from ${describeSource(resolvedProvider.credential.source)})`) + (identityCredential === void 0 ? "" : `, identity credential ${identityCredential.target} from ${describeSource(identityCredential.source)}`)
8818
- );
8942
+ const { identityDecision, configProfileDecision, resolvedProvider, identityCredential, poolPick, poolRanking, notes, flags: resolvedFlags, args: finalArgv, configDirEscapeHatch: configDirEscapeHatchApplies, decision } = decided;
8943
+ const rows = [
8944
+ ...decisionRows({
8945
+ identity: identityDecision.name,
8946
+ identitySource: identityDecision.source,
8947
+ pool: poolPick,
8948
+ ranking: resolvedFlags.explain ? poolRanking : void 0,
8949
+ profile: configProfileDecision.name === void 0 ? void 0 : { name: configProfileDecision.name, source: configProfileDecision.source },
8950
+ provider: resolvedProvider === void 0 ? void 0 : { name: resolvedProvider.name, credential: `${resolvedProvider.credential.target} from ${describeSource(resolvedProvider.credential.source)}` },
8951
+ identityCredential: identityCredential === void 0 ? void 0 : `${identityCredential.target} from ${describeSource(identityCredential.source)}`
8952
+ })
8953
+ ];
8954
+ let warnings = [];
8819
8955
  const updateCheck = runLaunchUpdateCheck({
8820
8956
  mode: params.updateMode ?? "off",
8821
8957
  checkPath: path39.join(paths.root, "update.check"),
@@ -8850,15 +8986,13 @@ function prepareLaunch(params) {
8850
8986
  }
8851
8987
  throw error;
8852
8988
  }
8853
- reportDiagnostics(log, result.diagnostics, { errorsAsWarnings: false });
8989
+ warnings = diagnosticLines(result.diagnostics);
8854
8990
  if (!result.noOp) {
8855
- log.info(
8856
- `agent-shim: farm at ${result.farmRoot} resynced (${String(result.manifest.links.length)} link(s), ${String(result.manifest.materialised.length)} built director(ies)${result.adopted.length === 0 ? "" : `, ${String(result.adopted.length)} adopted into ${resyncFarmRuntime.claudeHome}`})`
8857
- );
8991
+ rows.push(farmRow(result.manifest.links.length, result.manifest.materialised.length, result.adopted.length));
8858
8992
  }
8859
8993
  }
8860
8994
  if (decided.pinnedVersion !== void 0) {
8861
- log.info(`agent-shim: Claude Code ${decided.pinnedVersion.version} (pinned by ${decided.pinnedVersion.source})`);
8995
+ rows.push(pinnedVersionRow(decided.pinnedVersion.version, decided.pinnedVersion.source));
8862
8996
  }
8863
8997
  const frontDoorPort = params.frontdoor;
8864
8998
  const frontDoorEngaged = resolvedProvider !== void 0 || resolvedFlags.headroom || resolvedFlags.trackUsage;
@@ -8874,14 +9008,11 @@ function prepareLaunch(params) {
8874
9008
  const headroomPort = params.headroom;
8875
9009
  if (resolvedFlags.headroom && headroomPort !== void 0) {
8876
9010
  headroom = headroomPort.ensure({ routesProvider: resolvedProvider !== void 0 });
8877
- const via = resolvedProvider === void 0 ? `OAuth via the door's CONNECT surface on 127.0.0.1:${String(frontDoor?.connectPort ?? 0)}` : `provider ${resolvedProvider.name}`;
8878
- log.info(`agent-shim: routing through the front door on 127.0.0.1:${String(frontDoor?.port ?? 0)} with headroom on unix socket ${headroom.socketPath} (${via}, project ${headroom.projectId})`);
8879
9011
  } else if (resolvedFlags.headroom) {
8880
9012
  log.error("agent-shim: headroom routing was requested but this launcher has no headroom port wired; refusing to launch without it.");
8881
9013
  proc.exit(1);
8882
- } else if (frontDoor !== void 0) {
8883
- log.info(`agent-shim: routing through the front door on 127.0.0.1:${String(frontDoor.port)}${resolvedProvider === void 0 ? ` (OAuth via the door's CONNECT surface on 127.0.0.1:${String(frontDoor.connectPort)}, usage recorded)` : ` (provider ${resolvedProvider.name})`}`);
8884
9014
  }
9015
+ rows.push(...routingRows({ frontDoor, headroom, provider: resolvedProvider !== void 0 }));
8885
9016
  const frontDoorRelease = frontDoor === void 0 ? void 0 : frontDoorPort?.release;
8886
9017
  const sessionId = params.supervised?.sessionId ?? randomUUID4();
8887
9018
  const finalEnv = buildEnv({
@@ -8902,6 +9033,9 @@ function prepareLaunch(params) {
8902
9033
  registered();
8903
9034
  }
8904
9035
  };
9036
+ rows.push(...notes.map(noteRow));
9037
+ log.report(rows);
9038
+ printDiagnosticLines(log, warnings, { errorsAsWarnings: false });
8905
9039
  const hold = () => holdBeforeLaunch({ delayMs: resolvedFlags.delayMs, pause: resolvedFlags.pause }, params.hold, log);
8906
9040
  return { bin: decided.bin, args: finalArgv, env: finalEnv, sessionId, release, markChildStarted: updateCheck.markChildStarted, hold, decision };
8907
9041
  }
@@ -8967,6 +9101,7 @@ var init_launcher = __esm({
8967
9101
  init_claudeSession();
8968
9102
  init_diagnostics();
8969
9103
  init_hold();
9104
+ init_launchReport();
8970
9105
  init_modelPicker();
8971
9106
  init_providerCatalogue();
8972
9107
  init_pool();
@@ -9193,6 +9328,7 @@ function prepareClaudeLaunch(options) {
9193
9328
  const refusals = [];
9194
9329
  const log = {
9195
9330
  info: () => void 0,
9331
+ report: () => void 0,
9196
9332
  warn: () => void 0,
9197
9333
  error: (message) => {
9198
9334
  refusals.push(message);
@@ -9214,6 +9350,7 @@ function resolveClaudeLaunch(options) {
9214
9350
  const warnings = [];
9215
9351
  const log = {
9216
9352
  info: () => void 0,
9353
+ report: () => void 0,
9217
9354
  warn: (message) => {
9218
9355
  warnings.push(message);
9219
9356
  },
@@ -9419,6 +9556,7 @@ async function withIdentityClaude(params, identity, flags, use) {
9419
9556
  },
9420
9557
  log: {
9421
9558
  info: () => void 0,
9559
+ report: () => void 0,
9422
9560
  warn: () => void 0,
9423
9561
  error: (message) => {
9424
9562
  refusals.push(message);
@@ -13430,6 +13568,9 @@ function applyProfileChange(paths, name, change) {
13430
13568
  if (change.launchPause !== void 0) {
13431
13569
  launchPatch.pause = change.launchPause;
13432
13570
  }
13571
+ if (change.launchExplain !== void 0) {
13572
+ launchPatch.explain = change.launchExplain;
13573
+ }
13433
13574
  if (Object.keys(launchPatch).length > 0) {
13434
13575
  setProfileLaunchFlags(paths, name, launchPatch);
13435
13576
  touched = true;
@@ -15647,7 +15788,8 @@ var ConfigProfileSetInputSchema = z24.strictObject({
15647
15788
  provider: z24.union([z24.string().min(1), z24.literal(false)]).optional(),
15648
15789
  claudeVersion: z24.union([z24.string().min(1), z24.literal(false)]).optional(),
15649
15790
  delay: z24.union([z24.string().regex(DURATION_RE), z24.literal(false)]).optional(),
15650
- pause: z24.boolean().optional()
15791
+ pause: z24.boolean().optional(),
15792
+ explain: z24.boolean().optional()
15651
15793
  }).optional()
15652
15794
  });
15653
15795
  var ConfigProfileSetOutputSchema = storedMutationOutput("profile", "updated", ProfileValueSchema);
@@ -15859,7 +16001,8 @@ function createConfigApiRouter(deps) {
15859
16001
  ...launch?.provider === void 0 ? {} : { launchProvider: launch.provider },
15860
16002
  ...launch?.claudeVersion === void 0 ? {} : { launchClaudeVersion: launch.claudeVersion },
15861
16003
  ...launch?.delay === void 0 ? {} : { launchDelay: launch.delay },
15862
- ...launch?.pause === void 0 ? {} : { launchPause: launch.pause }
16004
+ ...launch?.pause === void 0 ? {} : { launchPause: launch.pause },
16005
+ ...launch?.explain === void 0 ? {} : { launchExplain: launch.explain }
15863
16006
  });
15864
16007
  return { action: "updated", kind: "profile", name: input.name, value: profileValue(input.name, paths) };
15865
16008
  })
@@ -16169,6 +16312,7 @@ var LaunchFlagsSchema = z26.strictObject({
16169
16312
  headroom: z26.boolean(),
16170
16313
  trackUsage: z26.boolean(),
16171
16314
  pause: z26.boolean(),
16315
+ explain: z26.boolean(),
16172
16316
  /** How long the launch waits after its own output before it starts claude, in milliseconds. */
16173
16317
  delayMs: z26.number()
16174
16318
  });