mu-agent 0.1.7 → 0.1.10

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.
Files changed (198) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +34 -29
  3. package/dist/bundle/chunks/anthropic-messages-4PAJY4R6.js +6 -0
  4. package/dist/bundle/chunks/anthropic.js +2 -2
  5. package/dist/bundle/chunks/azure-openai-responses-Y4BBWQ3N.js +2 -0
  6. package/dist/bundle/chunks/bedrock-converse-stream.js +12 -9
  7. package/dist/bundle/chunks/{chunk-TRDNDS6A.js → chunk-3V45WARH.js} +6 -3
  8. package/dist/bundle/chunks/{chunk-XDUWOHPL.js → chunk-5AGIVGSV.js} +3 -3
  9. package/dist/bundle/chunks/chunk-6QGV3IWD.js +6 -0
  10. package/dist/bundle/chunks/chunk-7CBJINYJ.js +20 -0
  11. package/dist/bundle/chunks/{chunk-DRQDKNXA.js → chunk-7DDKXS2Q.js} +1 -1
  12. package/dist/bundle/chunks/chunk-BSS6T6KQ.js +2 -0
  13. package/dist/bundle/chunks/chunk-CF5GWZHW.js +31 -0
  14. package/dist/bundle/chunks/chunk-DNNHZBQR.js +4 -0
  15. package/dist/bundle/chunks/chunk-FN6OEZYR.js +2 -0
  16. package/dist/bundle/chunks/chunk-FTJT2X6E.js +2 -0
  17. package/dist/bundle/chunks/chunk-HZNN636Z.js +130 -0
  18. package/dist/bundle/chunks/{chunk-4L3WN2XY.js → chunk-JXWJOIH4.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-4O2SCVYF.js → chunk-KIDDRTZP.js} +4 -4
  20. package/dist/bundle/chunks/chunk-LMNWTX2L.js +11 -0
  21. package/dist/bundle/chunks/chunk-LPXNMA2W.js +2 -0
  22. package/dist/bundle/chunks/{chunk-6CYCI3EJ.js → chunk-LVVZS2NO.js} +1 -1
  23. package/dist/bundle/chunks/chunk-NN4BEPYX.js +2 -0
  24. package/dist/bundle/chunks/chunk-O7IPTASE.js +1221 -0
  25. package/dist/bundle/chunks/chunk-PMRZO46Y.js +2 -0
  26. package/dist/bundle/chunks/chunk-QOEEJKS4.js +9 -0
  27. package/dist/bundle/chunks/chunk-R4VPBBDS.js +2 -0
  28. package/dist/bundle/chunks/chunk-RAQ6TU76.js +2 -0
  29. package/dist/bundle/chunks/chunk-RDZVAGPR.js +2 -0
  30. package/dist/bundle/chunks/chunk-SGOTYFMT.js +91 -0
  31. package/dist/bundle/chunks/chunk-TMTOQ7H7.js +2 -0
  32. package/dist/bundle/chunks/chunk-UKVNB6C4.js +2 -0
  33. package/dist/bundle/chunks/chunk-VJLOQZKR.js +9 -0
  34. package/dist/bundle/chunks/chunk-WCGU75WO.js +11 -0
  35. package/dist/bundle/chunks/chunk-X234222Q.js +64 -0
  36. package/dist/bundle/chunks/cli-722OL3K5.js +51 -0
  37. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-MEZHQVNP.js +2 -0
  38. package/dist/bundle/chunks/codemode-worker.js +478 -0
  39. package/dist/bundle/chunks/easter-egg-3d-6H34EDGX.js +2 -0
  40. package/dist/bundle/chunks/execute-KVSEIDWL.js +499 -0
  41. package/dist/bundle/chunks/github-copilot.js +1 -1
  42. package/dist/bundle/chunks/{google-generative-ai-C44KRRZ4.js → google-generative-ai-D2VJQBTK.js} +1 -1
  43. package/dist/bundle/chunks/{google-vertex-25DUXPTJ.js → google-vertex-SQG2BO6C.js} +1 -1
  44. package/dist/bundle/chunks/https-proxy-agent-LVOO5TPL.js +13 -0
  45. package/dist/bundle/chunks/image-resize-worker.js +1 -1
  46. package/dist/bundle/chunks/{jiti-loader-C3NU2SDH.js → jiti-loader-GL4HJFAD.js} +1 -1
  47. package/dist/bundle/chunks/{jiti-static-loader-E6ANQD5T.js → jiti-static-loader-2RCDI6B4.js} +1 -1
  48. package/dist/bundle/chunks/{lib-HGQMNYVT.js → lib-4AVRLBHM.js} +2 -2
  49. package/dist/bundle/chunks/llama-cpp-classify-5YHLY3RC.js +22 -0
  50. package/dist/bundle/chunks/mistral-conversations-BDARVJTT.js +5 -0
  51. package/dist/bundle/chunks/{multipart-parser-SQ6GDJL7.js → multipart-parser-FMGQ7342.js} +1 -1
  52. package/dist/bundle/chunks/{node-TWVVAGPO.js → node-AUOGOBCN.js} +1 -1
  53. package/dist/bundle/chunks/node-KCMANYC2.js +16 -0
  54. package/dist/bundle/chunks/openai-chatgpt.js +86 -0
  55. package/dist/bundle/chunks/openai-codex-responses-CECGTDYD.js +10 -0
  56. package/dist/bundle/chunks/openai-codex.js +2 -2
  57. package/dist/bundle/chunks/openai-completions-UOA7MELD.js +7 -0
  58. package/dist/bundle/chunks/openai-decisions-HLM372N6.js +5 -0
  59. package/dist/bundle/chunks/openai-responses-TII7ZY5X.js +3 -0
  60. package/dist/bundle/chunks/{openrouter-images-JVEJN44Q.js → openrouter-images-7T452AS5.js} +1 -1
  61. package/dist/bundle/chunks/openrouter.js +2 -2
  62. package/dist/bundle/chunks/{pi-messages-TM5SOOIW.js → pi-messages-2UDKLKOO.js} +1 -1
  63. package/dist/bundle/chunks/radius.js +2 -2
  64. package/dist/bundle/chunks/runtime-O3ELDOM7.js +2 -0
  65. package/dist/bundle/chunks/{src-UK77SYZE.js → src-QKGKDFSU.js} +1 -1
  66. package/dist/bundle/chunks/typesafe-system-one-KNCICMO5.js +2 -0
  67. package/dist/bundle/chunks/virtual-modules-IKEARUOZ.js +2 -0
  68. package/dist/bundle/cli-runtime.js +1 -1
  69. package/dist/bundle/index.js +1 -1
  70. package/dist/bundle/native/darwin/prebuilds/darwin-arm64/darwin-platform.node +0 -0
  71. package/dist/bundle/native/darwin/prebuilds/darwin-x64/darwin-platform.node +0 -0
  72. package/dist/bundle/rpc-entry.js +1 -1
  73. package/dist/core/export-html/template.js +37 -16
  74. package/dist/modes/interactive/theme/dark.json +60 -73
  75. package/dist/modes/interactive/theme/light.json +58 -70
  76. package/dist/modes/interactive/theme/system-theme.d.ts +55 -0
  77. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
  78. package/dist/modes/interactive/theme/system-theme.js +546 -0
  79. package/dist/modes/interactive/theme/system-theme.js.map +1 -0
  80. package/dist/modes/interactive/theme/theme-controller.d.ts +43 -9
  81. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  82. package/dist/modes/interactive/theme/theme-controller.js +121 -79
  83. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  84. package/dist/modes/interactive/theme/theme-schema.d.ts +28 -0
  85. package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  86. package/dist/modes/interactive/theme/theme-schema.js +105 -0
  87. package/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  88. package/dist/modes/interactive/theme/theme-tokens.d.ts +257 -0
  89. package/dist/modes/interactive/theme/theme-tokens.d.ts.map +1 -0
  90. package/dist/modes/interactive/theme/theme-tokens.js +94 -0
  91. package/dist/modes/interactive/theme/theme-tokens.js.map +1 -0
  92. package/dist/modes/interactive/theme/theme.d.ts +47 -56
  93. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  94. package/dist/modes/interactive/theme/theme.js +149 -143
  95. package/dist/modes/interactive/theme/theme.js.map +1 -1
  96. package/dist/native/darwin/prebuilds/darwin-arm64/darwin-platform.node +0 -0
  97. package/dist/native/darwin/prebuilds/darwin-x64/darwin-platform.node +0 -0
  98. package/docs/cli-integration.md +1 -1
  99. package/docs/cli.md +78 -13
  100. package/docs/codemode.md +230 -0
  101. package/docs/compaction.md +5 -5
  102. package/docs/configuration.md +2 -0
  103. package/docs/custom-provider.md +53 -1
  104. package/docs/docs.json +21 -1
  105. package/docs/environment-variables.md +5 -3
  106. package/docs/extensions.md +172 -10
  107. package/docs/index.md +1 -1
  108. package/docs/json.md +3 -3
  109. package/docs/keybindings.md +7 -6
  110. package/docs/llama-cpp.md +21 -1
  111. package/docs/mcp.md +272 -0
  112. package/docs/message-types.md +22 -4
  113. package/docs/models-configuration.md +187 -0
  114. package/docs/models.md +100 -2
  115. package/docs/nvidia-rtx-llama-cpp.md +96 -0
  116. package/docs/packages.md +1 -1
  117. package/docs/providers.md +66 -6
  118. package/docs/quickstart.md +16 -2
  119. package/docs/rpc-commands.md +9 -3
  120. package/docs/rpc.md +3 -1
  121. package/docs/sdk.md +8 -3
  122. package/docs/security.md +2 -0
  123. package/docs/session-format.md +5 -1
  124. package/docs/sessions.md +1 -1
  125. package/docs/settings.md +30 -8
  126. package/docs/terminal-setup.md +14 -0
  127. package/docs/themes.md +31 -7
  128. package/docs/tui.md +71 -1
  129. package/docs/usage.md +2 -2
  130. package/docs/virtual-models.md +114 -0
  131. package/docs/windows.md +2 -0
  132. package/examples/README.md +1 -4
  133. package/examples/extensions/README.md +1 -0
  134. package/examples/extensions/built-in-tool-renderer.ts +16 -40
  135. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  136. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  137. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  138. package/examples/extensions/custom-provider-gitlab-duo/test.ts +5 -5
  139. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  140. package/examples/extensions/gondolin/package-lock.json +2 -2
  141. package/examples/extensions/gondolin/package.json +1 -1
  142. package/examples/extensions/jev-router.ts +113 -0
  143. package/examples/extensions/minimal-mode.ts +28 -101
  144. package/examples/extensions/overlay-test.ts +2 -2
  145. package/examples/extensions/plan-mode/index.ts +6 -2
  146. package/examples/extensions/sandbox/package-lock.json +2 -2
  147. package/examples/extensions/sandbox/package.json +1 -1
  148. package/examples/extensions/subagent/index.ts +4 -6
  149. package/examples/extensions/with-deps/package-lock.json +2 -2
  150. package/examples/extensions/with-deps/package.json +1 -1
  151. package/examples/rpc-client.ts +1 -1
  152. package/examples/rpc-extension-ui.ts +1 -1
  153. package/examples/sdk/14-codemode-mcp.ts +61 -0
  154. package/examples/sdk/README.md +2 -1
  155. package/judge/THIRD_PARTY_NOTICES.md +63 -0
  156. package/judge/dist/auth.js +169 -123
  157. package/judge/dist/import.js +36 -30
  158. package/judge/dist/setup.js +250 -120
  159. package/judge/manifest.json +1008 -316
  160. package/judge/{dist/kyrn-judge.js → mu/index.js} +6933 -5995
  161. package/judge/themes/mu-dark.json +80 -0
  162. package/judge/themes/mu-light.json +80 -0
  163. package/kyrn/bin/kyrn-doctor +75 -25
  164. package/kyrn/bin/kyrn-judge-local +2 -2
  165. package/kyrn/bin/kyrn-ledger +1 -1
  166. package/kyrn/bin/mu.mjs +149 -107
  167. package/package.json +4 -5
  168. package/dist/bundle/chunks/anthropic-messages-VMESUHQ7.js +0 -6
  169. package/dist/bundle/chunks/azure-openai-responses-K232MQFF.js +0 -2
  170. package/dist/bundle/chunks/chunk-A3JYRWB6.js +0 -2
  171. package/dist/bundle/chunks/chunk-AYFRR3OD.js +0 -2
  172. package/dist/bundle/chunks/chunk-DTD7JQ7Y.js +0 -42
  173. package/dist/bundle/chunks/chunk-FU4XQUSL.js +0 -11
  174. package/dist/bundle/chunks/chunk-GNYZK6XN.js +0 -2
  175. package/dist/bundle/chunks/chunk-HEMXN7VJ.js +0 -1653
  176. package/dist/bundle/chunks/chunk-MVPXOVOJ.js +0 -2
  177. package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
  178. package/dist/bundle/chunks/chunk-V7IXECST.js +0 -11
  179. package/dist/bundle/chunks/chunk-XNGRGP62.js +0 -2
  180. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-NR2TDCXU.js +0 -2
  181. package/dist/bundle/chunks/https-proxy-agent-2VXB7436.js +0 -13
  182. package/dist/bundle/chunks/mistral-conversations-6IHQOR4R.js +0 -5
  183. package/dist/bundle/chunks/node-O3RIBJRH.js +0 -16
  184. package/dist/bundle/chunks/openai-codex-responses-3UAYOSSR.js +0 -10
  185. package/dist/bundle/chunks/openai-completions-FIEQGWAH.js +0 -7
  186. package/dist/bundle/chunks/openai-responses-OZJXLHFC.js +0 -2
  187. package/dist/bundle/chunks/typesafe-system-one-VKYX4OGY.js +0 -2
  188. package/dist/bundle/chunks/virtual-modules-V7SXVVLP.js +0 -2
  189. package/dist/modes/interactive/theme/theme-json.d.ts +0 -85
  190. package/dist/modes/interactive/theme/theme-json.d.ts.map +0 -1
  191. package/dist/modes/interactive/theme/theme-json.js +0 -132
  192. package/dist/modes/interactive/theme/theme-json.js.map +0 -1
  193. package/dist/modes/interactive/theme/theme-schema.json +0 -361
  194. package/examples/plugins/pi-example-plugin/README.md +0 -38
  195. package/examples/plugins/pi-example-plugin/package.json +0 -10
  196. package/examples/plugins/pi-example-plugin/src/contract.ts +0 -13
  197. package/examples/plugins/pi-example-plugin/src/session.ts +0 -24
  198. package/examples/plugins/pi-example-plugin/src/tui.ts +0 -31
@@ -46,12 +46,24 @@ function muHome(home = homedir()) {
46
46
  var DEFAULT_CONFIG = {
47
47
  tiers: ["jev"],
48
48
  judges: {},
49
- modes: { default: "shadow" },
49
+ // Verdicts take effect out of the box; a point that should only watch is set to "shadow" on its own.
50
+ modes: { default: "active" },
50
51
  routes: {},
51
52
  features: {},
52
53
  recordState: false
53
54
  };
54
55
  var MODES = ["off", "shadow", "active"];
56
+ var JUDGE_TYPES = [
57
+ "jev",
58
+ "typesafe",
59
+ "clm",
60
+ "gateway",
61
+ "local",
62
+ "http",
63
+ "llm",
64
+ "classifier",
65
+ "mock"
66
+ ];
55
67
  function isRecord(value) {
56
68
  return typeof value === "object" && value !== null && !Array.isArray(value);
57
69
  }
@@ -81,7 +93,7 @@ function readJudges(value) {
81
93
  if (!isRecord(value)) return judges;
82
94
  for (const [name, config] of Object.entries(value)) {
83
95
  if (!isRecord(config) || typeof config.type !== "string") continue;
84
- if (!["jev", "typesafe", "clm", "gateway", "local", "http", "llm", "mock"].includes(config.type)) continue;
96
+ if (!JUDGE_TYPES.includes(config.type)) continue;
85
97
  judges[name] = config;
86
98
  }
87
99
  return judges;
@@ -211,10 +223,8 @@ var NumericKeyPattern = new RegExp(IntegerKey);
211
223
 
212
224
  // packages/ai/src/utils/event-stream.ts
213
225
  var FifoQueue = class {
214
- constructor() {
215
- this.incoming = [];
216
- this.outgoing = [];
217
- }
226
+ incoming = [];
227
+ outgoing = [];
218
228
  get length() {
219
229
  return this.incoming.length + this.outgoing.length;
220
230
  }
@@ -231,10 +241,14 @@ var FifoQueue = class {
231
241
  }
232
242
  };
233
243
  var EventStream = class {
244
+ queue = new FifoQueue();
245
+ waiting = new FifoQueue();
246
+ done = false;
247
+ finalResultPromise;
248
+ resolveFinalResult;
249
+ isComplete;
250
+ extractResult;
234
251
  constructor(isComplete, extractResult) {
235
- this.queue = new FifoQueue();
236
- this.waiting = new FifoQueue();
237
- this.done = false;
238
252
  this.isComplete = isComplete;
239
253
  this.extractResult = extractResult;
240
254
  this.finalResultPromise = new Promise((resolve2) => {
@@ -282,6 +296,8 @@ var EventStream = class {
282
296
  }
283
297
  };
284
298
  var AssistantMessageEventStream = class extends EventStream {
299
+ #startedAt = Date.now();
300
+ #startedAtMonotonic = performance.now();
285
301
  constructor() {
286
302
  super(
287
303
  (event) => event.type === "done" || event.type === "error",
@@ -295,10 +311,23 @@ var AssistantMessageEventStream = class extends EventStream {
295
311
  }
296
312
  );
297
313
  }
314
+ push(event) {
315
+ if (event.type === "done") this.#time(event.message);
316
+ else if (event.type === "error") this.#time(event.error);
317
+ super.push(event);
318
+ }
319
+ end(result) {
320
+ if (result !== void 0) this.#time(result);
321
+ super.end(result);
322
+ }
323
+ #time(message) {
324
+ if (this.done || message.durationMs !== void 0 || message.timestamp < this.#startedAt) return;
325
+ message.durationMs = Math.max(0, Math.round(performance.now() - this.#startedAtMonotonic));
326
+ }
298
327
  };
299
328
 
300
329
  // packages/ai/src/api/lazy.ts
301
- function createSetupErrorMessage(model, error) {
330
+ function createSetupErrorMessage(model, error, timestamp) {
302
331
  return {
303
332
  role: "assistant",
304
333
  content: [],
@@ -315,24 +344,40 @@ function createSetupErrorMessage(model, error) {
315
344
  },
316
345
  stopReason: "error",
317
346
  errorMessage: error instanceof Error ? error.message : String(error),
318
- timestamp: Date.now()
347
+ timestamp
319
348
  };
320
349
  }
321
350
  function hasResult(source) {
322
351
  return typeof source.result === "function";
323
352
  }
324
- async function forwardStream(target, source) {
353
+ async function forwardStream(target, source, observer, observeResult) {
354
+ let result;
325
355
  for await (const event of source) {
326
356
  target.push(event);
357
+ observer?.onEvent?.(event);
358
+ if (event.type === "done") result = event.message;
359
+ else if (event.type === "error") result = event.error;
327
360
  }
328
- target.end(hasResult(source) ? await source.result() : void 0);
361
+ if (hasResult(source)) result = await source.result();
362
+ target.end(result);
363
+ observeResult(result);
329
364
  }
330
- function lazyStream(model, setup) {
365
+ function lazyStream(model, setup, observer) {
366
+ const startedAt = Date.now();
331
367
  const outer = new AssistantMessageEventStream();
332
- setup().then((inner) => forwardStream(outer, inner)).catch((error) => {
333
- const message = createSetupErrorMessage(model, error);
334
- outer.push({ type: "error", reason: "error", error: message });
368
+ let observedResult = false;
369
+ const observeResult = (result) => {
370
+ if (observedResult) return;
371
+ observedResult = true;
372
+ observer?.onResult?.(result);
373
+ };
374
+ setup().then((inner) => forwardStream(outer, inner, observer, observeResult)).catch((error) => {
375
+ const message = createSetupErrorMessage(model, error, startedAt);
376
+ const event = { type: "error", reason: "error", error: message };
377
+ outer.push(event);
378
+ observer?.onEvent?.(event);
335
379
  outer.end(message);
380
+ observeResult(message);
336
381
  });
337
382
  return outer;
338
383
  }
@@ -358,110 +403,6 @@ function lazyApi(load, capabilities) {
358
403
  return api;
359
404
  }
360
405
 
361
- // packages/ai/src/auth/oauth/oauth-page.ts
362
- var MU_MARK_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none" aria-hidden="true"><defs><linearGradient id="mu-tile" x1="0" y1="0" x2="100" y2="100" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#F3C6FA"/><stop offset="0.5" stop-color="#B79CF7"/><stop offset="1" stop-color="#8680EB"/></linearGradient></defs><rect width="100" height="100" rx="27" fill="url(#mu-tile)"/><path d="M41 32 L35 74.4 M38.9 47 C37.77 55 41 59.4 47.6 59.4 C54.8 59.4 61.05 54.5 61.9 48.5 M64.25 32 L61.35 52.5 C60.6 58 62.3 61.2 66.4 60.4" stroke="#FFFFFF" stroke-width="9.8" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
363
- var MU_FAVICON = `data:image/svg+xml,${encodeURIComponent(MU_MARK_SVG)}`;
364
- function escapeHtml(value) {
365
- return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
366
- }
367
- function renderPage(options) {
368
- const title = escapeHtml(`${options.heading} \xB7 mu`);
369
- const heading = escapeHtml(options.heading);
370
- const message = escapeHtml(options.message);
371
- const details = options.details ? escapeHtml(options.details) : void 0;
372
- return `<!doctype html>
373
- <html lang="en">
374
- <head>
375
- <meta charset="utf-8" />
376
- <meta name="viewport" content="width=device-width, initial-scale=1" />
377
- <meta name="color-scheme" content="light dark" />
378
- <title>${title}</title>
379
- <link rel="icon" type="image/svg+xml" href="${MU_FAVICON}" />
380
- <style>
381
- :root {
382
- color-scheme: light dark;
383
- --text: #111111;
384
- --text-dim: #6b6b70;
385
- --page-bg: #ffffff;
386
- --font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
387
- --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
388
- }
389
- @media (prefers-color-scheme: dark) {
390
- :root {
391
- --text: #f4f4f5;
392
- --text-dim: #9a9aa1;
393
- --page-bg: #000000;
394
- }
395
- }
396
- * { box-sizing: border-box; }
397
- body {
398
- margin: 0;
399
- min-height: 100vh;
400
- display: flex;
401
- align-items: center;
402
- justify-content: center;
403
- padding: 24px;
404
- background: var(--page-bg);
405
- color: var(--text);
406
- font-family: var(--font-sans);
407
- text-align: center;
408
- }
409
- main {
410
- width: 100%;
411
- max-width: 520px;
412
- display: flex;
413
- flex-direction: column;
414
- align-items: center;
415
- justify-content: center;
416
- }
417
- .mark {
418
- width: 72px;
419
- height: 72px;
420
- display: block;
421
- margin-bottom: 28px;
422
- }
423
- .mark svg { display: block; width: 100%; height: 100%; }
424
- h1 {
425
- margin: 0 0 10px;
426
- font-size: 26px;
427
- line-height: 1.2;
428
- font-weight: 600;
429
- letter-spacing: -0.01em;
430
- color: var(--text);
431
- }
432
- p {
433
- margin: 0;
434
- line-height: 1.7;
435
- color: var(--text-dim);
436
- font-size: 15px;
437
- }
438
- .details {
439
- margin-top: 16px;
440
- font-family: var(--font-mono);
441
- font-size: 13px;
442
- color: var(--text-dim);
443
- white-space: pre-wrap;
444
- word-break: break-word;
445
- }
446
- </style>
447
- </head>
448
- <body>
449
- <main>
450
- <div class="mark">${MU_MARK_SVG}</div>
451
- <h1>${heading}</h1>
452
- <p>${message}</p>
453
- ${details ? `<div class="details">${details}</div>` : ""}
454
- </main>
455
- </body>
456
- </html>`;
457
- }
458
- function oauthSuccessHtml(message) {
459
- return renderPage({ heading: "Signed in", message });
460
- }
461
- function oauthErrorHtml(message, details) {
462
- return renderPage({ heading: "Sign-in did not complete", message, details });
463
- }
464
-
465
406
  // packages/ai/src/utils/diagnostics.ts
466
407
  function formatThrownValue(value) {
467
408
  if (value instanceof Error) return value.message || value.name;
@@ -471,6 +412,7 @@ function formatThrownValue(value) {
471
412
 
472
413
  // packages/ai/src/utils/models-error.ts
473
414
  var ModelsError = class extends Error {
415
+ code;
474
416
  constructor(code, message, options) {
475
417
  super(withCauseDetail(message, options?.cause), options);
476
418
  this.name = "ModelsError";
@@ -646,8 +588,112 @@ function createProvider(input) {
646
588
  return provider;
647
589
  }
648
590
 
591
+ // packages/ai/src/utils/oauth-page.ts
592
+ var MU_MARK_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" fill="none" aria-hidden="true"><defs><linearGradient id="mu-tile" x1="0" y1="0" x2="100" y2="100" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#F3C6FA"/><stop offset="0.5" stop-color="#B79CF7"/><stop offset="1" stop-color="#8680EB"/></linearGradient></defs><rect width="100" height="100" rx="27" fill="url(#mu-tile)"/><path d="M41 32 L35 74.4 M38.9 47 C37.77 55 41 59.4 47.6 59.4 C54.8 59.4 61.05 54.5 61.9 48.5 M64.25 32 L61.35 52.5 C60.6 58 62.3 61.2 66.4 60.4" stroke="#FFFFFF" stroke-width="9.8" stroke-linecap="round" stroke-linejoin="round"/></svg>`;
593
+ var MU_FAVICON = `data:image/svg+xml,${encodeURIComponent(MU_MARK_SVG)}`;
594
+ function escapeHtml(value) {
595
+ return value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&#39;");
596
+ }
597
+ function renderPage(options) {
598
+ const title = escapeHtml(`${options.heading} \xB7 mu`);
599
+ const heading = escapeHtml(options.heading);
600
+ const message = escapeHtml(options.message);
601
+ const details = options.details ? escapeHtml(options.details) : void 0;
602
+ return `<!doctype html>
603
+ <html lang="en">
604
+ <head>
605
+ <meta charset="utf-8" />
606
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
607
+ <meta name="color-scheme" content="light dark" />
608
+ <title>${title}</title>
609
+ <link rel="icon" type="image/svg+xml" href="${MU_FAVICON}" />
610
+ <style>
611
+ :root {
612
+ color-scheme: light dark;
613
+ --text: #111111;
614
+ --text-dim: #6b6b70;
615
+ --page-bg: #ffffff;
616
+ --font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", sans-serif;
617
+ --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
618
+ }
619
+ @media (prefers-color-scheme: dark) {
620
+ :root {
621
+ --text: #f4f4f5;
622
+ --text-dim: #9a9aa1;
623
+ --page-bg: #000000;
624
+ }
625
+ }
626
+ * { box-sizing: border-box; }
627
+ body {
628
+ margin: 0;
629
+ min-height: 100vh;
630
+ display: flex;
631
+ align-items: center;
632
+ justify-content: center;
633
+ padding: 24px;
634
+ background: var(--page-bg);
635
+ color: var(--text);
636
+ font-family: var(--font-sans);
637
+ text-align: center;
638
+ }
639
+ main {
640
+ width: 100%;
641
+ max-width: 520px;
642
+ display: flex;
643
+ flex-direction: column;
644
+ align-items: center;
645
+ justify-content: center;
646
+ }
647
+ .mark {
648
+ width: 72px;
649
+ height: 72px;
650
+ display: block;
651
+ margin-bottom: 28px;
652
+ }
653
+ .mark svg { display: block; width: 100%; height: 100%; }
654
+ h1 {
655
+ margin: 0 0 10px;
656
+ font-size: 26px;
657
+ line-height: 1.2;
658
+ font-weight: 600;
659
+ letter-spacing: -0.01em;
660
+ color: var(--text);
661
+ }
662
+ p {
663
+ margin: 0;
664
+ line-height: 1.7;
665
+ color: var(--text-dim);
666
+ font-size: 15px;
667
+ }
668
+ .details {
669
+ margin-top: 16px;
670
+ font-family: var(--font-mono);
671
+ font-size: 13px;
672
+ color: var(--text-dim);
673
+ white-space: pre-wrap;
674
+ word-break: break-word;
675
+ }
676
+ </style>
677
+ </head>
678
+ <body>
679
+ <main>
680
+ <div class="mark">${MU_MARK_SVG}</div>
681
+ <h1>${heading}</h1>
682
+ <p>${message}</p>
683
+ ${details ? `<div class="details">${details}</div>` : ""}
684
+ </main>
685
+ </body>
686
+ </html>`;
687
+ }
688
+ function oauthSuccessHtml(message) {
689
+ return renderPage({ heading: "Signed in", message });
690
+ }
691
+ function oauthErrorHtml(message, details) {
692
+ return renderPage({ heading: "Sign-in did not complete", message, details });
693
+ }
694
+
649
695
  // packages/ai/src/providers/data/google.json
650
- var google_default = { "google-generative-ai": { "chat:deep-research-max-preview-04-2026": { id: "deep-research-max-preview-04-2026", name: "Deep Research Max Preview (Apr-21-2026)", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:deep-research-preview-04-2026": { id: "deep-research-preview-04-2026", name: "Deep Research Preview (Apr-21-2026)", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-2.5-computer-use-preview-10-2025": { id: "gemini-2.5-computer-use-preview-10-2025", name: "Gemini 2.5 Computer Use Preview 10-2025", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0, cacheWrite: 0 }, contextWindow: 128e3, maxTokens: 64e3, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-2.5-flash": { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-2.5-flash-lite": { id: "gemini-2.5-flash-lite", name: "Gemini 2.5 Flash-Lite", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-2.5-pro": { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3-flash-preview": { id: "gemini-3-flash-preview", name: "Gemini 3 Flash Preview", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-flash-lite": { id: "gemini-3.1-flash-lite", name: "Gemini 3.1 Flash Lite", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-flash-lite-image": { id: "gemini-3.1-flash-lite-image", name: "Nano Banana 2 Lite", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: null, medium: null, high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.25, output: 30, cacheRead: 0, cacheWrite: 0 }, contextWindow: 65536, maxTokens: 4096, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-flash-lite-preview": { id: "gemini-3.1-flash-lite-preview", name: "Gemini 3.1 Flash Lite Preview", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-flash-live-preview": { id: "gemini-3.1-flash-live-preview", name: "Gemini 3.1 Flash Live Preview", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.75, output: 4.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-pro-preview": { id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro Preview", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-pro-preview-customtools": { id: "gemini-3.1-pro-preview-customtools", name: "Gemini 3.1 Pro Preview Custom Tools", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.5-flash": { id: "gemini-3.5-flash", name: "Gemini 3.5 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.5-flash-lite": { id: "gemini-3.5-flash-lite", name: "Gemini 3.5 Flash Lite", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.6-flash": { id: "gemini-3.6-flash", name: "Gemini 3.6 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.7-flash": { id: "gemini-3.7-flash", name: "Gemini 3.7 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.8-flash": { id: "gemini-3.8-flash", name: "Gemini 3.8 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-flash-latest": { id: "gemini-flash-latest", name: "Gemini Flash Latest", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-flash-lite-latest": { id: "gemini-flash-lite-latest", name: "Gemini Flash-Lite Latest", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemma-4-26b-a4b-it": { id: "gemma-4-26b-a4b-it", name: "Gemma 4 26B A4B IT", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "MINIMAL", low: null, medium: null, high: "HIGH" }, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemma-4-31b-it": { id: "gemma-4-31b-it", name: "Gemma 4 31B IT", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "MINIMAL", low: null, medium: null, high: "HIGH" }, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } } };
696
+ var google_default = { "google-generative-ai": { "chat:deep-research-max-preview-04-2026": { id: "deep-research-max-preview-04-2026", name: "Deep Research Max Preview (Apr-21-2026)", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 4, output: 18, cacheRead: 0.4, cacheWrite: 0 }] }, contextWindow: 131072, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:deep-research-preview-04-2026": { id: "deep-research-preview-04-2026", name: "Deep Research Preview (Apr-21-2026)", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 4, output: 18, cacheRead: 0.4, cacheWrite: 0 }] }, contextWindow: 131072, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-2.5-computer-use-preview-10-2025": { id: "gemini-2.5-computer-use-preview-10-2025", name: "Gemini 2.5 Computer Use Preview 10-2025", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 2.5, output: 15, cacheRead: 0, cacheWrite: 0 }] }, contextWindow: 128e3, maxTokens: 64e3, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-2.5-flash": { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-2.5-flash-lite": { id: "gemini-2.5-flash-lite", name: "Gemini 2.5 Flash-Lite", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 0.1, output: 0.4, cacheRead: 0.01, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-2.5-pro": { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, input: ["text", "image"], cost: { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 2.5, output: 15, cacheRead: 0.25, cacheWrite: 0 }] }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3-flash-preview": { id: "gemini-3-flash-preview", name: "Gemini 3 Flash Preview", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-flash-lite": { id: "gemini-3.1-flash-lite", name: "Gemini 3.1 Flash Lite", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-flash-lite-image": { id: "gemini-3.1-flash-lite-image", name: "Nano Banana 2 Lite", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: null, medium: null, high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.25, output: 30, cacheRead: 0, cacheWrite: 0 }, contextWindow: 65536, maxTokens: 4096, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-flash-lite-preview": { id: "gemini-3.1-flash-lite-preview", name: "Gemini 3.1 Flash Lite Preview", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-flash-live-preview": { id: "gemini-3.1-flash-live-preview", name: "Gemini 3.1 Flash Live Preview", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.75, output: 4.5, cacheRead: 0, cacheWrite: 0 }, contextWindow: 131072, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-pro-preview": { id: "gemini-3.1-pro-preview", name: "Gemini 3.1 Pro Preview", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 4, output: 18, cacheRead: 0.4, cacheWrite: 0 }] }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.1-pro-preview-customtools": { id: "gemini-3.1-pro-preview-customtools", name: "Gemini 3.1 Pro Preview Custom Tools", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 4, output: 18, cacheRead: 0.4, cacheWrite: 0 }] }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.5-flash": { id: "gemini-3.5-flash", name: "Gemini 3.5 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.5-flash-lite": { id: "gemini-3.5-flash-lite", name: "Gemini 3.5 Flash Lite", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.3, output: 2.5, cacheRead: 0.03, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.6-flash": { id: "gemini-3.6-flash", name: "Gemini 3.6 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.7-flash": { id: "gemini-3.7-flash", name: "Gemini 3.7 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-3.8-flash": { id: "gemini-3.8-flash", name: "Gemini 3.8 Flash", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.75, output: 3.75, cacheRead: 0.075, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-4-argon": { id: "gemini-4-argon", name: "Gemini 4 Argon", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 2, output: 10, cacheRead: 0.1, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 32768, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-flash-latest": { id: "gemini-flash-latest", name: "Gemini Flash Latest", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 1.5, output: 9, cacheRead: 0.15, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-flash-lite-latest": { id: "gemini-flash-lite-latest", name: "Gemini Flash-Lite Latest", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "minimal", low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 0.25, output: 1.5, cacheRead: 0.025, cacheWrite: 0 }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemini-pro-latest": { id: "gemini-pro-latest", name: "Gemini Pro Latest", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: null, low: "low", medium: "medium", high: "high", xhigh: null, max: null }, input: ["text", "image"], cost: { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0, tiers: [{ inputTokensAbove: 2e5, input: 4, output: 18, cacheRead: 0.4, cacheWrite: 0 }] }, contextWindow: 1048576, maxTokens: 65536, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemma-4-26b-a4b-it": { id: "gemma-4-26b-a4b-it", name: "Gemma 4 26B A4B IT", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "MINIMAL", low: null, medium: null, high: "HIGH" }, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" }, "chat:gemma-4-31b-it": { id: "gemma-4-31b-it", name: "Gemma 4 31B IT", api: "google-generative-ai", provider: "google", baseUrl: "https://generativelanguage.googleapis.com/v1beta", reasoning: true, thinkingLevelMap: { off: null, minimal: "MINIMAL", low: null, medium: null, high: "HIGH" }, input: ["text", "image"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 262144, maxTokens: 32768, inputLimits: { maxRequestBytes: 20971520, images: { maxPerRequest: 3600, resize: { maxWidth: 2e3, maxHeight: 2e3, maxBytes: 4718592, jpegQuality: 80 } } }, type: "chat" } } };
651
697
 
652
698
  // packages/ai/src/model-catalog.ts
653
699
  function flattenModelCatalog(groups, type) {
@@ -1262,7 +1308,7 @@ async function runAuth(argv, options) {
1262
1308
  return 0;
1263
1309
  }
1264
1310
  if (!provider) throw new Error(USAGE);
1265
- if (!offered.includes(provider)) throw new Error(`Signing in to ${provider} is not available in this mu`);
1311
+ if (!offered.includes(provider)) throw new Error(`This version of mu can't sign in to ${provider}`);
1266
1312
  if (mode === "logout") {
1267
1313
  const stored = (await runtime.listCredentials()).find((credential) => credential.providerId === provider);
1268
1314
  if (stored?.type === "oauth") await runtime.logout(provider);
@@ -5,6 +5,11 @@ import { readFileSync } from "node:fs";
5
5
  import { homedir as homedir3 } from "node:os";
6
6
  import { join as join3, sep } from "node:path";
7
7
 
8
+ // packages/kyrn-judge/src/language.ts
9
+ function count(n, one, many = `${one}s`) {
10
+ return `${n} ${n === 1 ? one : many}`;
11
+ }
12
+
8
13
  // packages/kyrn-judge/src/import/index.ts
9
14
  import { mkdirSync, readdirSync as readdirSync2, realpathSync, statSync as statSync4 } from "node:fs";
10
15
  import { homedir as homedir2 } from "node:os";
@@ -71,16 +76,16 @@ function readHead(path, visit, limit = 1024 * 1024) {
71
76
  let pending = Buffer.alloc(0);
72
77
  let read = 0;
73
78
  while (read < limit) {
74
- const count = readSync(fd, chunk, 0, Math.min(chunk.length, limit - read), null);
75
- if (count === 0) {
79
+ const count2 = readSync(fd, chunk, 0, Math.min(chunk.length, limit - read), null);
80
+ if (count2 === 0) {
76
81
  if (!blank(pending)) {
77
82
  const last = parse(pending);
78
83
  if ("value" in last) visit(last.value);
79
84
  }
80
85
  return;
81
86
  }
82
- read += count;
83
- pending = Buffer.concat([pending, chunk.subarray(0, count)]);
87
+ read += count2;
88
+ pending = Buffer.concat([pending, chunk.subarray(0, count2)]);
84
89
  let start = 0;
85
90
  for (let newline = pending.indexOf(10, start); newline !== -1; newline = pending.indexOf(10, start)) {
86
91
  const line = pending.subarray(start, newline);
@@ -330,21 +335,22 @@ var ZERO_USAGE = {
330
335
  };
331
336
  var IMAGE = { type: "image", data: "", mimeType: "image/png" };
332
337
  var SessionBuilder = class {
338
+ tool;
339
+ counts = emptyCounts();
340
+ items = [];
341
+ /** Messages that arrived while calls were still waiting for their results. */
342
+ held = [];
343
+ /** Calls of the last assistant message without a result yet, by id. */
344
+ pending = /* @__PURE__ */ new Map();
345
+ /** Every call seen, by id: a result may name its call only by the id. */
346
+ calls = /* @__PURE__ */ new Map();
347
+ answered = /* @__PURE__ */ new Set();
333
348
  constructor(tool) {
334
- this.counts = emptyCounts();
335
- this.items = [];
336
- /** Messages that arrived while calls were still waiting for their results. */
337
- this.held = [];
338
- /** Calls of the last assistant message without a result yet, by id. */
339
- this.pending = /* @__PURE__ */ new Map();
340
- /** Every call seen, by id: a result may name its call only by the id. */
341
- this.calls = /* @__PURE__ */ new Map();
342
- this.answered = /* @__PURE__ */ new Set();
343
349
  this.tool = tool;
344
350
  }
345
- drop(reason, count = 1) {
346
- if (count <= 0) return;
347
- this.counts.dropped[reason] = (this.counts.dropped[reason] ?? 0) + count;
351
+ drop(reason, count2 = 1) {
352
+ if (count2 <= 0) return;
353
+ this.counts.dropped[reason] = (this.counts.dropped[reason] ?? 0) + count2;
348
354
  }
349
355
  /** Whether anything a person said or a model answered is in it: a transcript without either is not imported. */
350
356
  get hasConversation() {
@@ -1611,16 +1617,16 @@ async function importTranscripts(paths, options) {
1611
1617
 
1612
1618
  // packages/kyrn-judge/src/import/command.ts
1613
1619
  var USAGE = [
1614
- "mu import: bring Claude Code and Codex conversations into mu, to continue them here.",
1620
+ "mu import: import Claude Code and Codex conversations so you can continue them in mu.",
1615
1621
  "",
1616
- " mu import --list [--json] [--cwd <dir>] the conversations on this machine (only <dir>'s with --cwd)",
1622
+ " mu import --list [--json] [--cwd <dir>] list conversations on this machine (with --cwd, only <dir>'s)",
1617
1623
  " mu import <file>... [--json] import these transcripts; each becomes a mu session",
1618
1624
  "",
1619
1625
  " --agent-dir <dir> mu's agent folder (default: MU_CODING_AGENT_DIR, else ~/.mu/agent)",
1620
- " --sub-agents also list the threads sub-agents ran",
1626
+ " --sub-agents also list subagent threads",
1621
1627
  "",
1622
1628
  "Looks in ~/.claude/projects (CLAUDE_CONFIG_DIR) and ~/.codex/sessions (CODEX_HOME).",
1623
- "A conversation that was imported before is not imported again."
1629
+ "Conversations that were already imported are skipped."
1624
1630
  ].join("\n");
1625
1631
  function parseArgs(argv) {
1626
1632
  const parsed = { help: false, list: false, json: false, subAgents: false, files: [] };
@@ -1646,7 +1652,7 @@ function parseArgs(argv) {
1646
1652
  } else if (arg.startsWith("--")) return { error: `unknown option ${arg}` };
1647
1653
  else parsed.files.push(arg);
1648
1654
  }
1649
- if (parsed.list && parsed.files.length > 0) return { error: "--list takes no files" };
1655
+ if (parsed.list && parsed.files.length > 0) return { error: "--list doesn't take files" };
1650
1656
  return parsed;
1651
1657
  }
1652
1658
  function storeFor(agentDirArg, io) {
@@ -1698,7 +1704,7 @@ function formatList(conversations, home) {
1698
1704
  const toolWidth = Math.max(...Object.values(TOOL_NAMES).map((name) => name.length));
1699
1705
  for (const [cwd, group] of groups) {
1700
1706
  if (lines.length > 0) lines.push("");
1701
- lines.push(cwd ? tilde(cwd, home) : "(folder unknown)");
1707
+ lines.push(cwd ? tilde(cwd, home) : "(unknown folder)");
1702
1708
  for (const conversation of group) {
1703
1709
  const title = conversation.title || "(no message found)";
1704
1710
  const mark = conversation.importedAs ? " (imported)" : "";
@@ -1708,25 +1714,25 @@ function formatList(conversations, home) {
1708
1714
  lines.push(`${" ".repeat(20)}${tilde(conversation.path, home)}`);
1709
1715
  }
1710
1716
  }
1711
- const count = conversations.length;
1712
- lines.push("", `${count} conversation${count === 1 ? "" : "s"}. Import one with: mu import <file>`);
1717
+ const count2 = conversations.length;
1718
+ lines.push("", `${count2} conversation${count2 === 1 ? "" : "s"}. Import one with: mu import <file>`);
1713
1719
  return lines.join("\n");
1714
1720
  }
1715
1721
  function formatResult(result, home) {
1716
- if (result.status === "failed") return `Could not import ${tilde(result.source, home)}: ${result.error}`;
1722
+ if (result.status === "failed") return `Couldn't import ${tilde(result.source, home)}: ${result.error}`;
1717
1723
  if (result.status === "already-imported")
1718
1724
  return [
1719
1725
  `Already imported: ${tilde(result.source, home)}`,
1720
- ` it is the session ${tilde(result.sessionFile, home)}`
1726
+ ` as session ${tilde(result.sessionFile, home)}`
1721
1727
  ].join("\n");
1722
1728
  const { counts } = result;
1723
- const left = Object.entries(counts.dropped).sort((a, b) => b[1] - a[1]).map(([reason, count]) => `${reason} ${count}`);
1729
+ const left = Object.entries(counts.dropped).sort((a, b) => b[1] - a[1]).map(([reason, count2]) => `${reason} ${count2}`);
1724
1730
  return [
1725
1731
  `Imported from ${TOOL_NAMES[result.tool]}: "${result.name}"`,
1726
1732
  ` ${tilde(result.sessionFile, home)}`,
1727
- ` ${counts.user} messages from you, ${counts.assistant} answers, ${counts.toolCalls} tool calls${counts.compactions > 0 ? `, ${counts.compactions} compactions` : ""}`,
1728
- ...left.length > 0 ? [` left out: ${left.join(", ")}`] : [],
1729
- ` continue it: mu --session ${result.sessionFile}`
1733
+ ` ${count(counts.user, "message")} from you, ${count(counts.assistant, "reply", "replies")}, ${count(counts.toolCalls, "tool call")}${counts.compactions > 0 ? `, ${count(counts.compactions, "compaction")}` : ""}`,
1734
+ ...left.length > 0 ? [` skipped: ${left.join(", ")}`] : [],
1735
+ ` to continue: mu --session ${result.sessionFile}`
1730
1736
  ].join("\n");
1731
1737
  }
1732
1738
  async function main(argv, io) {