mini-coder 0.0.22 → 0.0.23

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/mc.js CHANGED
@@ -3,10 +3,10 @@
3
3
 
4
4
  // src/index.ts
5
5
  import { writeSync } from "fs";
6
- import * as c24 from "yoctocolors";
6
+ import * as c23 from "yoctocolors";
7
7
 
8
8
  // src/agent/agent.ts
9
- import * as c13 from "yoctocolors";
9
+ import * as c12 from "yoctocolors";
10
10
 
11
11
  // src/cli/load-markdown-configs.ts
12
12
  import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync3, statSync as statSync2 } from "fs";
@@ -14,13 +14,13 @@ import { homedir as homedir4 } from "os";
14
14
  import { basename, join as join5 } from "path";
15
15
 
16
16
  // src/cli/config-conflicts.ts
17
- import * as c9 from "yoctocolors";
17
+ import * as c8 from "yoctocolors";
18
18
 
19
19
  // src/cli/output.ts
20
20
  import { existsSync as existsSync3 } from "fs";
21
21
  import { homedir as homedir3 } from "os";
22
22
  import { join as join4 } from "path";
23
- import * as c8 from "yoctocolors";
23
+ import * as c7 from "yoctocolors";
24
24
 
25
25
  // src/cli/custom-commands.ts
26
26
  import { existsSync, readFileSync } from "fs";
@@ -290,159 +290,6 @@ function parseAppError(err) {
290
290
  return { headline: firstLine };
291
291
  }
292
292
 
293
- // src/cli/live-output.ts
294
- import * as c from "yoctocolors";
295
-
296
- // src/cli/terminal-io.ts
297
- class TerminalIO {
298
- rawModeEnabled = false;
299
- interruptHandler = null;
300
- setInterruptHandler(handler) {
301
- this.interruptHandler = handler;
302
- }
303
- beforeWriteCallback = null;
304
- setBeforeWriteCallback(cb) {
305
- this.beforeWriteCallback = cb;
306
- }
307
- skipCallback = false;
308
- stdoutWrite(text) {
309
- if (text && this.beforeWriteCallback && !this.skipCallback) {
310
- this.skipCallback = true;
311
- this.beforeWriteCallback();
312
- this.skipCallback = false;
313
- }
314
- this.doStdoutWrite(text);
315
- }
316
- doStdoutWrite(text) {
317
- process.stdout.write(text);
318
- }
319
- stderrWrite(text) {
320
- if (text && this.beforeWriteCallback && !this.skipCallback) {
321
- this.skipCallback = true;
322
- this.beforeWriteCallback();
323
- this.skipCallback = false;
324
- }
325
- this.doStderrWrite(text);
326
- }
327
- doStderrWrite(text) {
328
- process.stderr.write(text);
329
- }
330
- get isTTY() {
331
- return process.stdin.isTTY;
332
- }
333
- get isStdoutTTY() {
334
- return process.stdout.isTTY;
335
- }
336
- get isStderrTTY() {
337
- return process.stderr.isTTY;
338
- }
339
- get stdoutColumns() {
340
- return process.stdout.columns ?? 0;
341
- }
342
- setRawMode(enable) {
343
- if (this.isTTY) {
344
- process.stdin.setRawMode(enable);
345
- this.rawModeEnabled = enable;
346
- }
347
- }
348
- restoreTerminal() {
349
- try {
350
- if (this.isStderrTTY) {
351
- this.stderrWrite("\x1B[?25h");
352
- this.stderrWrite("\r\x1B[2K");
353
- }
354
- } catch {}
355
- try {
356
- if (this.rawModeEnabled) {
357
- this.setRawMode(false);
358
- }
359
- } catch {}
360
- }
361
- registerCleanup() {
362
- const cleanup = () => this.restoreTerminal();
363
- process.on("exit", cleanup);
364
- process.on("SIGTERM", () => {
365
- cleanup();
366
- process.exit(143);
367
- });
368
- process.on("SIGINT", () => {
369
- if (this.interruptHandler) {
370
- this.interruptHandler();
371
- } else {
372
- cleanup();
373
- process.exit(130);
374
- }
375
- });
376
- process.on("uncaughtException", (err) => {
377
- cleanup();
378
- throw err;
379
- });
380
- process.on("unhandledRejection", (reason) => {
381
- cleanup();
382
- throw reason instanceof Error ? reason : new Error(String(reason));
383
- });
384
- }
385
- onStdinData(handler) {
386
- process.stdin.on("data", handler);
387
- return () => process.stdin.off("data", handler);
388
- }
389
- }
390
- var terminal = new TerminalIO;
391
-
392
- // src/cli/live-output.ts
393
- var LIVE_OUTPUT_PREFIX = ` ${c.dim("\u2502")} `;
394
- function write(text) {
395
- terminal.stdoutWrite(text);
396
- }
397
- function writeln(text = "") {
398
- terminal.stdoutWrite(`${text}
399
- `);
400
- }
401
-
402
- class LiveOutputBlock {
403
- pending = "";
404
- lineOpen = false;
405
- append(chunk) {
406
- if (!chunk)
407
- return;
408
- this.pending += chunk.replace(/\r\n/g, `
409
- `).replace(/\r/g, `
410
- `);
411
- this.flushCompleteLines();
412
- }
413
- finish() {
414
- if (this.pending.length > 0) {
415
- this.openLine();
416
- write(this.pending);
417
- this.pending = "";
418
- }
419
- if (this.lineOpen) {
420
- writeln();
421
- this.lineOpen = false;
422
- }
423
- }
424
- flushCompleteLines() {
425
- let boundary = this.pending.indexOf(`
426
- `);
427
- while (boundary !== -1) {
428
- const line = this.pending.slice(0, boundary);
429
- this.openLine();
430
- write(line);
431
- writeln();
432
- this.lineOpen = false;
433
- this.pending = this.pending.slice(boundary + 1);
434
- boundary = this.pending.indexOf(`
435
- `);
436
- }
437
- }
438
- openLine() {
439
- if (this.lineOpen)
440
- return;
441
- write(LIVE_OUTPUT_PREFIX);
442
- this.lineOpen = true;
443
- }
444
- }
445
-
446
293
  // src/cli/skills.ts
447
294
  import {
448
295
  closeSync,
@@ -567,7 +414,7 @@ function warnInvalidSkill(filePath, reason) {
567
414
  if (warnedInvalidSkills.has(key))
568
415
  return;
569
416
  warnedInvalidSkills.add(key);
570
- writeln2(`${G.warn} skipping invalid skill ${filePath}: ${reason}`);
417
+ writeln(`${G.warn} skipping invalid skill ${filePath}: ${reason}`);
571
418
  }
572
419
  function validateSkill(candidate) {
573
420
  const meta = getCandidateFrontmatter(candidate);
@@ -639,7 +486,105 @@ function loadSkillContent(name, cwd, homeDir) {
639
486
  }
640
487
 
641
488
  // src/cli/spinner.ts
642
- import * as c2 from "yoctocolors";
489
+ import * as c from "yoctocolors";
490
+
491
+ // src/cli/terminal-io.ts
492
+ class TerminalIO {
493
+ rawModeEnabled = false;
494
+ interruptHandler = null;
495
+ setInterruptHandler(handler) {
496
+ this.interruptHandler = handler;
497
+ }
498
+ beforeWriteCallback = null;
499
+ setBeforeWriteCallback(cb) {
500
+ this.beforeWriteCallback = cb;
501
+ }
502
+ skipCallback = false;
503
+ stdoutWrite(text) {
504
+ if (text && this.beforeWriteCallback && !this.skipCallback) {
505
+ this.skipCallback = true;
506
+ this.beforeWriteCallback();
507
+ this.skipCallback = false;
508
+ }
509
+ this.doStdoutWrite(text);
510
+ }
511
+ doStdoutWrite(text) {
512
+ process.stdout.write(text);
513
+ }
514
+ stderrWrite(text) {
515
+ if (text && this.beforeWriteCallback && !this.skipCallback) {
516
+ this.skipCallback = true;
517
+ this.beforeWriteCallback();
518
+ this.skipCallback = false;
519
+ }
520
+ this.doStderrWrite(text);
521
+ }
522
+ doStderrWrite(text) {
523
+ process.stderr.write(text);
524
+ }
525
+ get isTTY() {
526
+ return process.stdin.isTTY;
527
+ }
528
+ get isStdoutTTY() {
529
+ return process.stdout.isTTY;
530
+ }
531
+ get isStderrTTY() {
532
+ return process.stderr.isTTY;
533
+ }
534
+ get stdoutColumns() {
535
+ return process.stdout.columns ?? 0;
536
+ }
537
+ setRawMode(enable) {
538
+ if (this.isTTY) {
539
+ process.stdin.setRawMode(enable);
540
+ this.rawModeEnabled = enable;
541
+ }
542
+ }
543
+ restoreTerminal() {
544
+ try {
545
+ if (this.isStderrTTY) {
546
+ this.stderrWrite("\x1B[?25h");
547
+ this.stderrWrite("\r\x1B[2K");
548
+ }
549
+ } catch {}
550
+ try {
551
+ if (this.rawModeEnabled) {
552
+ this.setRawMode(false);
553
+ }
554
+ } catch {}
555
+ }
556
+ registerCleanup() {
557
+ const cleanup = () => this.restoreTerminal();
558
+ process.on("exit", cleanup);
559
+ process.on("SIGTERM", () => {
560
+ cleanup();
561
+ process.exit(143);
562
+ });
563
+ process.on("SIGINT", () => {
564
+ if (this.interruptHandler) {
565
+ this.interruptHandler();
566
+ } else {
567
+ cleanup();
568
+ process.exit(130);
569
+ }
570
+ });
571
+ process.on("uncaughtException", (err) => {
572
+ cleanup();
573
+ throw err;
574
+ });
575
+ process.on("unhandledRejection", (reason) => {
576
+ cleanup();
577
+ throw reason instanceof Error ? reason : new Error(String(reason));
578
+ });
579
+ }
580
+ onStdinData(handler) {
581
+ process.stdin.on("data", handler);
582
+ return () => process.stdin.off("data", handler);
583
+ }
584
+ }
585
+ var terminal = new TerminalIO;
586
+
587
+ // src/cli/spinner.ts
643
588
  var SPINNER_FRAMES = ["\u28FE", "\u28FD", "\u28FB", "\u28BF", "\u287F", "\u28DF", "\u28EF", "\u28F7"];
644
589
 
645
590
  class Spinner {
@@ -675,15 +620,15 @@ class Spinner {
675
620
  }
676
621
  _tick() {
677
622
  const f = SPINNER_FRAMES[this.frame++ % SPINNER_FRAMES.length] ?? "\u28FE";
678
- const label = this.label ? c2.dim(` ${this.label}`) : "";
679
- terminal.stderrWrite(`\r${c2.dim(f)}${label}`);
623
+ const label = this.label ? c.dim(` ${this.label}`) : "";
624
+ terminal.stderrWrite(`\r${c.dim(f)}${label}`);
680
625
  }
681
626
  }
682
627
 
683
628
  // src/cli/status-bar.ts
684
- import * as c3 from "yoctocolors";
629
+ import * as c2 from "yoctocolors";
685
630
  var ANSI_ESCAPE = "\x1B";
686
- var STATUS_SEP = c3.dim(" \xB7 ");
631
+ var STATUS_SEP = c2.dim(" \xB7 ");
687
632
  function stripAnsi(s) {
688
633
  if (!s.includes(ANSI_ESCAPE))
689
634
  return s;
@@ -705,12 +650,12 @@ function buildContextSegment(opts) {
705
650
  if (opts.contextTokens <= 0)
706
651
  return null;
707
652
  if (opts.contextWindow === null) {
708
- return c3.dim(`ctx ${fmtTokens(opts.contextTokens)}`);
653
+ return c2.dim(`ctx ${fmtTokens(opts.contextTokens)}`);
709
654
  }
710
655
  const pct = Math.round(opts.contextTokens / opts.contextWindow * 100);
711
656
  const pctStr = `${pct}%`;
712
- const pctColored = pct >= 90 ? c3.red(pctStr) : pct >= 75 ? c3.yellow(pctStr) : c3.dim(pctStr);
713
- return c3.dim(`ctx ${fmtTokens(opts.contextTokens)}/${fmtTokens(opts.contextWindow)} `) + pctColored;
657
+ const pctColored = pct >= 90 ? c2.red(pctStr) : pct >= 75 ? c2.yellow(pctStr) : c2.dim(pctStr);
658
+ return c2.dim(`ctx ${fmtTokens(opts.contextTokens)}/${fmtTokens(opts.contextWindow)} `) + pctColored;
714
659
  }
715
660
  function renderStatusLine(segments) {
716
661
  return segments.join(STATUS_SEP);
@@ -747,26 +692,26 @@ function fitStatusSegments(required, optional, cols) {
747
692
  return truncatePlainText(fixedPrefix, cols);
748
693
  const maxTailLen = Math.max(8, cols - fixedPrefix.length - sepLen);
749
694
  const truncatedTail = truncatePlainText(plainRequired[1] ?? "", maxTailLen);
750
- return `${required[0]}${STATUS_SEP}${c3.dim(truncatedTail)}`;
695
+ return `${required[0]}${STATUS_SEP}${c2.dim(truncatedTail)}`;
751
696
  }
752
697
  function renderStatusBar(opts) {
753
698
  const cols = Math.max(20, terminal.stdoutColumns || 80);
754
699
  const required = [
755
- c3.cyan(opts.model),
756
- c3.dim(`#${opts.sessionId.slice(0, 8)}`)
700
+ c2.cyan(opts.model),
701
+ c2.dim(`#${opts.sessionId.slice(0, 8)}`)
757
702
  ];
758
703
  const optional = [];
759
704
  if (opts.provider && opts.provider !== "zen") {
760
- optional.push(c3.dim(opts.provider));
705
+ optional.push(c2.dim(opts.provider));
761
706
  }
762
707
  if (opts.activeAgent)
763
- optional.push(c3.green(`@${opts.activeAgent}`));
708
+ optional.push(c2.green(`@${opts.activeAgent}`));
764
709
  if (opts.thinkingEffort)
765
- optional.push(c3.dim(`\u2726 ${opts.thinkingEffort}`));
710
+ optional.push(c2.dim(`\u2726 ${opts.thinkingEffort}`));
766
711
  if (opts.gitBranch)
767
- optional.push(c3.dim(`\u2387 ${opts.gitBranch}`));
712
+ optional.push(c2.dim(`\u2387 ${opts.gitBranch}`));
768
713
  if (opts.inputTokens > 0 || opts.outputTokens > 0) {
769
- optional.push(c3.dim(`tok ${fmtTokens(opts.inputTokens)}/${fmtTokens(opts.outputTokens)}`));
714
+ optional.push(c2.dim(`tok ${fmtTokens(opts.inputTokens)}/${fmtTokens(opts.outputTokens)}`));
770
715
  }
771
716
  const contextSegment = buildContextSegment({
772
717
  contextTokens: opts.contextTokens,
@@ -774,14 +719,14 @@ function renderStatusBar(opts) {
774
719
  });
775
720
  if (contextSegment)
776
721
  optional.push(contextSegment);
777
- optional.push(c3.dim(opts.cwd));
722
+ optional.push(c2.dim(opts.cwd));
778
723
  const out = fitStatusSegments(required, optional, cols);
779
724
  terminal.stdoutWrite(`${out}
780
725
  `);
781
726
  }
782
727
 
783
728
  // src/cli/stream-render.ts
784
- import * as c7 from "yoctocolors";
729
+ import * as c6 from "yoctocolors";
785
730
 
786
731
  // src/llm-api/model-routing.ts
787
732
  function parseModelString(modelString) {
@@ -866,7 +811,7 @@ function isToolCallPart(part) {
866
811
  function hasObjectToolCallInput(part) {
867
812
  return isToolCallPart(part) && "input" in part && isRecord(part.input) && !Array.isArray(part.input);
868
813
  }
869
- var TOOL_RUNTIME_INPUT_KEYS = new Set(["cwd", "onOutput"]);
814
+ var TOOL_RUNTIME_INPUT_KEYS = new Set(["cwd"]);
870
815
  function stripToolRuntimeInputFields(messages) {
871
816
  let mutated = false;
872
817
  const result = messages.map((message) => {
@@ -1181,9 +1126,9 @@ function extractAssistantText(newMessages) {
1181
1126
  }
1182
1127
 
1183
1128
  // src/cli/live-reasoning.ts
1184
- import * as c4 from "yoctocolors";
1129
+ import * as c3 from "yoctocolors";
1185
1130
  function styleReasoningText(text) {
1186
- return c4.italic(c4.dim(text));
1131
+ return c3.italic(c3.dim(text));
1187
1132
  }
1188
1133
 
1189
1134
  class LiveReasoningBlock {
@@ -1209,27 +1154,27 @@ class LiveReasoningBlock {
1209
1154
  if (!this.blockOpen)
1210
1155
  return;
1211
1156
  if (this.lineOpen)
1212
- writeln2();
1157
+ writeln();
1213
1158
  this.blockOpen = false;
1214
1159
  this.lineOpen = false;
1215
1160
  }
1216
1161
  openBlock() {
1217
1162
  if (this.blockOpen)
1218
1163
  return;
1219
- writeln2(`${G.info} ${c4.dim("reasoning")}`);
1164
+ writeln(`${G.info} ${c3.dim("reasoning")}`);
1220
1165
  this.blockOpen = true;
1221
1166
  }
1222
1167
  writeText(text) {
1223
1168
  if (!this.lineOpen) {
1224
- write2(" ");
1169
+ write(" ");
1225
1170
  this.lineOpen = true;
1226
1171
  }
1227
- write2(styleReasoningText(text));
1172
+ write(styleReasoningText(text));
1228
1173
  }
1229
1174
  endLine() {
1230
1175
  if (!this.lineOpen)
1231
- write2(" ");
1232
- writeln2();
1176
+ write(" ");
1177
+ writeln();
1233
1178
  this.lineOpen = false;
1234
1179
  }
1235
1180
  }
@@ -1288,14 +1233,17 @@ class StreamRenderContent {
1288
1233
  return this.inText;
1289
1234
  }
1290
1235
  appendTextDelta(delta, renderedVisibleOutput) {
1291
- const text = delta ?? "";
1236
+ let text = delta ?? "";
1292
1237
  if (!text)
1293
1238
  return;
1294
1239
  if (!this.inText) {
1240
+ text = text.trimStart();
1241
+ if (!text)
1242
+ return;
1295
1243
  this.spinner.stop();
1296
1244
  if (renderedVisibleOutput)
1297
- writeln2();
1298
- write2(`${G.reply} `);
1245
+ writeln();
1246
+ write(`${G.reply} `);
1299
1247
  this.inText = true;
1300
1248
  if (terminal.isStdoutTTY)
1301
1249
  this.highlighter = createHighlighter();
@@ -1310,10 +1258,10 @@ class StreamRenderContent {
1310
1258
  if (isFirstLine && colored.startsWith("\x1B[2K\r")) {
1311
1259
  colored = `\x1B[2K\r${G.reply} ${colored.slice(5)}`;
1312
1260
  }
1313
- write2(colored);
1261
+ write(colored);
1314
1262
  }
1315
1263
  } else {
1316
- write2(text);
1264
+ write(text);
1317
1265
  }
1318
1266
  }
1319
1267
  appendReasoningDelta(delta) {
@@ -1340,43 +1288,43 @@ ${text}`;
1340
1288
  if (isFirstLine && finalColored.startsWith("\x1B[2K\r")) {
1341
1289
  finalColored = `\x1B[2K\r${G.reply} ${finalColored.slice(5)}`;
1342
1290
  }
1343
- write2(finalColored);
1291
+ write(finalColored);
1344
1292
  }
1345
1293
  }
1346
- writeln2();
1294
+ writeln();
1347
1295
  this.inText = false;
1348
1296
  }
1349
1297
  }
1350
1298
 
1351
1299
  // src/cli/tool-render.ts
1352
- import * as c6 from "yoctocolors";
1300
+ import * as c5 from "yoctocolors";
1353
1301
 
1354
1302
  // src/cli/tool-result-renderers.ts
1355
- import * as c5 from "yoctocolors";
1303
+ import * as c4 from "yoctocolors";
1356
1304
  function writePreviewLines(opts) {
1357
1305
  if (!opts.value.trim())
1358
1306
  return;
1359
1307
  const lines = opts.value.split(`
1360
1308
  `);
1361
- writeln2(` ${c5.dim(opts.label)} ${c5.dim(`(${lines.length} lines)`)}`);
1309
+ writeln(` ${c4.dim(opts.label)} ${c4.dim(`(${lines.length} lines)`)}`);
1362
1310
  if (!Number.isFinite(opts.maxLines) || lines.length <= opts.maxLines) {
1363
1311
  for (const line of lines) {
1364
- writeln2(` ${opts.lineColor("\u2502")} ${line}`);
1312
+ writeln(` ${opts.lineColor("\u2502")} ${line}`);
1365
1313
  }
1366
1314
  return;
1367
1315
  }
1368
1316
  const headCount = Math.max(1, Math.ceil(opts.maxLines / 2));
1369
1317
  const tailCount = Math.max(0, Math.floor(opts.maxLines / 2));
1370
1318
  for (const line of lines.slice(0, headCount)) {
1371
- writeln2(` ${opts.lineColor("\u2502")} ${line}`);
1319
+ writeln(` ${opts.lineColor("\u2502")} ${line}`);
1372
1320
  }
1373
1321
  const hiddenLines = Math.max(0, lines.length - (headCount + tailCount));
1374
1322
  if (hiddenLines > 0) {
1375
- writeln2(` ${opts.lineColor("\u2502")} ${c5.dim(`\u2026 +${hiddenLines} lines`)}`);
1323
+ writeln(` ${opts.lineColor("\u2502")} ${c4.dim(`\u2026 +${hiddenLines} lines`)}`);
1376
1324
  }
1377
1325
  if (tailCount > 0) {
1378
1326
  for (const line of lines.slice(-tailCount)) {
1379
- writeln2(` ${opts.lineColor("\u2502")} ${line}`);
1327
+ writeln(` ${opts.lineColor("\u2502")} ${line}`);
1380
1328
  }
1381
1329
  }
1382
1330
  }
@@ -1401,15 +1349,6 @@ function getSingleShellLine(value) {
1401
1349
  }
1402
1350
  function buildShellSummaryParts(opts) {
1403
1351
  const parts = [`exit ${opts.exitCode}`];
1404
- if (opts.streamedOutput) {
1405
- if (opts.stdoutLines === 0 && opts.stderrLines === 0) {
1406
- parts.push("no output");
1407
- }
1408
- if (opts.stderrLines > 0) {
1409
- parts.push(`stderr ${opts.stderrLines}L`);
1410
- }
1411
- return parts;
1412
- }
1413
1352
  if (opts.stderrLines === 0 && opts.stdoutSingleLine !== null && opts.stdoutSingleLine.length > 0) {
1414
1353
  parts.push(`out: ${truncateOneLine(opts.stdoutSingleLine, 100, opts.verboseOutput)}`);
1415
1354
  return parts;
@@ -1437,28 +1376,23 @@ function renderShellResult(result, opts) {
1437
1376
  if (!r || typeof r.stdout !== "string" || typeof r.stderr !== "string") {
1438
1377
  return false;
1439
1378
  }
1440
- const streamedOutput = r.streamedOutput === true;
1441
1379
  const verboseOutput = opts?.verboseOutput === true;
1442
1380
  const stdoutLines = countShellLines(r.stdout);
1443
1381
  const stderrLines = countShellLines(r.stderr);
1444
1382
  const stdoutSingleLine = getSingleShellLine(r.stdout);
1445
- const badge = r.timedOut ? c5.yellow("timeout") : r.success ? c5.green("done") : c5.red("error");
1383
+ const badge = r.timedOut ? c4.yellow("timeout") : r.success ? c4.green("done") : c4.red("error");
1446
1384
  const parts = buildShellSummaryParts({
1447
1385
  exitCode: r.exitCode,
1448
1386
  stdoutLines,
1449
1387
  stderrLines,
1450
1388
  stdoutSingleLine,
1451
- streamedOutput,
1452
1389
  verboseOutput
1453
1390
  });
1454
- writeln2(` ${badge} ${c5.dim(parts.join(" \xB7 "))}`);
1455
- if (streamedOutput) {
1456
- return true;
1457
- }
1391
+ writeln(` ${badge} ${c4.dim(parts.join(" \xB7 "))}`);
1458
1392
  writePreviewLines({
1459
1393
  label: "stderr",
1460
1394
  value: r.stderr,
1461
- lineColor: c5.red,
1395
+ lineColor: c4.red,
1462
1396
  maxLines: verboseOutput ? Number.POSITIVE_INFINITY : 10
1463
1397
  });
1464
1398
  if (shouldPreviewShellStdout({
@@ -1470,7 +1404,7 @@ function renderShellResult(result, opts) {
1470
1404
  writePreviewLines({
1471
1405
  label: "stdout",
1472
1406
  value: r.stdout,
1473
- lineColor: c5.dim,
1407
+ lineColor: c4.dim,
1474
1408
  maxLines: verboseOutput ? Number.POSITIVE_INFINITY : 20
1475
1409
  });
1476
1410
  }
@@ -1480,8 +1414,8 @@ function renderSubagentResult(result, _opts) {
1480
1414
  const r = result;
1481
1415
  if (!r || typeof r !== "object")
1482
1416
  return false;
1483
- const label = r.agentName ? ` ${c5.dim(c5.cyan(`[@${r.agentName}]`))}` : "";
1484
- writeln2(` ${G.agent}${label} ${c5.dim(`subagent done (${r.inputTokens ?? 0}in / ${r.outputTokens ?? 0}out tokens)`)}`);
1417
+ const label = r.agentName ? ` ${c4.dim(c4.cyan(`[@${r.agentName}]`))}` : "";
1418
+ writeln(` ${G.agent}${label} ${c4.dim(`subagent done (${r.inputTokens ?? 0}in / ${r.outputTokens ?? 0}out tokens)`)}`);
1485
1419
  return true;
1486
1420
  }
1487
1421
  function buildSkillDescriptionPart(description, verboseOutput = false) {
@@ -1489,21 +1423,21 @@ function buildSkillDescriptionPart(description, verboseOutput = false) {
1489
1423
  if (!trimmed)
1490
1424
  return "";
1491
1425
  if (verboseOutput)
1492
- return ` ${c5.dim("\xB7")} ${c5.dim(trimmed)}`;
1493
- return ` ${c5.dim("\xB7")} ${c5.dim(trimmed.length > 60 ? `${trimmed.slice(0, 57)}\u2026` : trimmed)}`;
1426
+ return ` ${c4.dim("\xB7")} ${c4.dim(trimmed)}`;
1427
+ return ` ${c4.dim("\xB7")} ${c4.dim(trimmed.length > 60 ? `${trimmed.slice(0, 57)}\u2026` : trimmed)}`;
1494
1428
  }
1495
1429
  function renderSkillSummaryLine(skill, opts) {
1496
1430
  const name = skill.name ?? "(unknown)";
1497
1431
  const source = skill.source ?? "unknown";
1498
- const labelPrefix = opts?.label ? `${c5.dim(opts.label)} ` : "";
1499
- writeln2(` ${G.info} ${labelPrefix}${name} ${c5.dim("\xB7")} ${c5.dim(source)}${buildSkillDescriptionPart(skill.description, opts?.verboseOutput === true)}`);
1432
+ const labelPrefix = opts?.label ? `${c4.dim(opts.label)} ` : "";
1433
+ writeln(` ${G.info} ${labelPrefix}${name} ${c4.dim("\xB7")} ${c4.dim(source)}${buildSkillDescriptionPart(skill.description, opts?.verboseOutput === true)}`);
1500
1434
  }
1501
1435
  function renderListSkillsResult(result, opts) {
1502
1436
  const r = result;
1503
1437
  if (!Array.isArray(r?.skills))
1504
1438
  return false;
1505
1439
  if (r.skills.length === 0) {
1506
- writeln2(` ${G.info} ${c5.dim("no skills")}`);
1440
+ writeln(` ${G.info} ${c4.dim("no skills")}`);
1507
1441
  return true;
1508
1442
  }
1509
1443
  const maxSkills = opts?.verboseOutput ? r.skills.length : 6;
@@ -1513,7 +1447,7 @@ function renderListSkillsResult(result, opts) {
1513
1447
  });
1514
1448
  }
1515
1449
  if (r.skills.length > maxSkills) {
1516
- writeln2(` ${c5.dim(`+${r.skills.length - maxSkills} more skills`)}`);
1450
+ writeln(` ${c4.dim(`+${r.skills.length - maxSkills} more skills`)}`);
1517
1451
  }
1518
1452
  return true;
1519
1453
  }
@@ -1522,7 +1456,7 @@ function renderReadSkillResult(result, _opts) {
1522
1456
  if (!r || typeof r !== "object")
1523
1457
  return false;
1524
1458
  if (!r.skill) {
1525
- writeln2(` ${G.info} ${c5.dim("skill")} ${c5.dim("(not found)")}`);
1459
+ writeln(` ${G.info} ${c4.dim("skill")} ${c4.dim("(not found)")}`);
1526
1460
  return true;
1527
1461
  }
1528
1462
  renderSkillSummaryLine(r.skill, {
@@ -1536,19 +1470,19 @@ function renderWebSearchResult(result, opts) {
1536
1470
  if (!Array.isArray(r?.results))
1537
1471
  return false;
1538
1472
  if (r.results.length === 0) {
1539
- writeln2(` ${G.info} ${c5.dim("no results")}`);
1473
+ writeln(` ${G.info} ${c4.dim("no results")}`);
1540
1474
  return true;
1541
1475
  }
1542
1476
  const maxResults = opts?.verboseOutput ? r.results.length : 5;
1543
1477
  for (const item of r.results.slice(0, maxResults)) {
1544
1478
  const title = (item.title?.trim() || item.url || "(untitled)").replace(/\s+/g, " ");
1545
- const score = typeof item.score === "number" ? c5.dim(` (${item.score.toFixed(2)})`) : "";
1546
- writeln2(` ${c5.dim("\u2022")} ${title}${score}`);
1479
+ const score = typeof item.score === "number" ? c4.dim(` (${item.score.toFixed(2)})`) : "";
1480
+ writeln(` ${c4.dim("\u2022")} ${title}${score}`);
1547
1481
  if (item.url)
1548
- writeln2(` ${c5.dim(item.url)}`);
1482
+ writeln(` ${c4.dim(item.url)}`);
1549
1483
  }
1550
1484
  if (r.results.length > maxResults) {
1551
- writeln2(` ${c5.dim(` +${r.results.length - maxResults} more`)}`);
1485
+ writeln(` ${c4.dim(` +${r.results.length - maxResults} more`)}`);
1552
1486
  }
1553
1487
  return true;
1554
1488
  }
@@ -1557,23 +1491,23 @@ function renderWebContentResult(result, opts) {
1557
1491
  if (!Array.isArray(r?.results))
1558
1492
  return false;
1559
1493
  if (r.results.length === 0) {
1560
- writeln2(` ${G.info} ${c5.dim("no pages")}`);
1494
+ writeln(` ${G.info} ${c4.dim("no pages")}`);
1561
1495
  return true;
1562
1496
  }
1563
1497
  const maxPages = opts?.verboseOutput ? r.results.length : 3;
1564
1498
  for (const item of r.results.slice(0, maxPages)) {
1565
1499
  const title = (item.title?.trim() || item.url || "(untitled)").replace(/\s+/g, " ");
1566
- writeln2(` ${c5.dim("\u2022")} ${title}`);
1500
+ writeln(` ${c4.dim("\u2022")} ${title}`);
1567
1501
  if (item.url)
1568
- writeln2(` ${c5.dim(item.url)}`);
1502
+ writeln(` ${c4.dim(item.url)}`);
1569
1503
  const preview = (item.text ?? "").replace(/\s+/g, " ").trim();
1570
1504
  if (preview) {
1571
1505
  const trimmed = opts?.verboseOutput || preview.length <= 220 ? preview : `${preview.slice(0, 217)}\u2026`;
1572
- writeln2(` ${c5.dim(trimmed)}`);
1506
+ writeln(` ${c4.dim(trimmed)}`);
1573
1507
  }
1574
1508
  }
1575
1509
  if (r.results.length > maxPages) {
1576
- writeln2(` ${c5.dim(` +${r.results.length - maxPages} more`)}`);
1510
+ writeln(` ${c4.dim(` +${r.results.length - maxPages} more`)}`);
1577
1511
  }
1578
1512
  return true;
1579
1513
  }
@@ -1586,7 +1520,7 @@ function renderMcpResult(result, opts) {
1586
1520
  const lines = block.text.split(`
1587
1521
  `).slice(0, maxLines);
1588
1522
  for (const line of lines)
1589
- writeln2(` ${c5.dim("\u2502")} ${line}`);
1523
+ writeln(` ${c4.dim("\u2502")} ${line}`);
1590
1524
  }
1591
1525
  }
1592
1526
  return true;
@@ -1629,40 +1563,40 @@ function buildToolCallLine(name, args) {
1629
1563
  const prompt = typeof a.prompt === "string" ? a.prompt : "";
1630
1564
  const short = prompt.length > 60 ? `${prompt.slice(0, 57)}\u2026` : prompt;
1631
1565
  const agentName = typeof a.agentName === "string" && a.agentName ? a.agentName : "";
1632
- const label = agentName ? ` ${c6.dim(c6.cyan(`[@${agentName}]`))}` : "";
1633
- return `${G.agent}${label} ${c6.dim("\u2014")} ${short}`;
1566
+ const label = agentName ? ` ${c5.dim(c5.cyan(`[@${agentName}]`))}` : "";
1567
+ return `${G.agent}${label} ${c5.dim("\u2014")} ${short}`;
1634
1568
  }
1635
1569
  if (name === "shell") {
1636
1570
  const cmd = String(a.command ?? "").trim();
1637
1571
  if (!cmd)
1638
- return `${G.run} ${c6.dim("shell")}`;
1572
+ return `${G.run} ${c5.dim("shell")}`;
1639
1573
  const shortCmd = cmd.length > 72 ? `${cmd.slice(0, 69)}\u2026` : cmd;
1640
1574
  return `${G.run} ${shortCmd}`;
1641
1575
  }
1642
1576
  if (name === "listSkills") {
1643
- return `${G.search} ${c6.dim("list skills")}`;
1577
+ return `${G.search} ${c5.dim("list skills")}`;
1644
1578
  }
1645
1579
  if (name === "readSkill") {
1646
1580
  const skillName = typeof a.name === "string" ? a.name : "";
1647
- return `${G.read} ${c6.dim("read skill")}${skillName ? ` ${skillName}` : ""}`;
1581
+ return `${G.read} ${c5.dim("read skill")}${skillName ? ` ${skillName}` : ""}`;
1648
1582
  }
1649
1583
  if (name.startsWith("mcp_")) {
1650
- return `${G.mcp} ${c6.dim(name)}`;
1584
+ return `${G.mcp} ${c5.dim(name)}`;
1651
1585
  }
1652
- return `${toolGlyph(name)} ${c6.dim(name)}`;
1586
+ return `${toolGlyph(name)} ${c5.dim(name)}`;
1653
1587
  }
1654
1588
  function renderToolCall(toolName, args) {
1655
- writeln2(` ${buildToolCallLine(toolName, args)}`);
1589
+ writeln(` ${buildToolCallLine(toolName, args)}`);
1656
1590
  }
1657
1591
  function formatErrorBadge(result) {
1658
1592
  const msg = typeof result === "string" ? result : result instanceof Error ? result.message : JSON.stringify(result);
1659
1593
  const oneLiner = msg.split(`
1660
1594
  `)[0] ?? msg;
1661
- return `${G.err} ${c6.red(oneLiner)}`;
1595
+ return `${G.err} ${c5.red(oneLiner)}`;
1662
1596
  }
1663
1597
  function renderToolResult(toolName, result, isError, opts) {
1664
1598
  if (isError) {
1665
- writeln2(` ${formatErrorBadge(result)}`);
1599
+ writeln(` ${formatErrorBadge(result)}`);
1666
1600
  return;
1667
1601
  }
1668
1602
  if (renderToolResultByName(toolName, result, opts)) {
@@ -1670,10 +1604,10 @@ function renderToolResult(toolName, result, isError, opts) {
1670
1604
  }
1671
1605
  const text = JSON.stringify(result);
1672
1606
  if (opts?.verboseOutput || text.length <= 120) {
1673
- writeln2(` ${c6.dim(text)}`);
1607
+ writeln(` ${c5.dim(text)}`);
1674
1608
  return;
1675
1609
  }
1676
- writeln2(` ${c6.dim(`${text.slice(0, 117)}\u2026`)}`);
1610
+ writeln(` ${c5.dim(`${text.slice(0, 117)}\u2026`)}`);
1677
1611
  }
1678
1612
 
1679
1613
  // src/cli/stream-render.ts
@@ -1702,7 +1636,7 @@ async function renderTurn(events, spinner, opts) {
1702
1636
  case "text-delta": {
1703
1637
  liveReasoning.finish();
1704
1638
  content.appendTextDelta(event.delta, renderedVisibleOutput);
1705
- if (event.delta)
1639
+ if (content.hasOpenContent())
1706
1640
  renderedVisibleOutput = true;
1707
1641
  break;
1708
1642
  }
@@ -1713,7 +1647,7 @@ async function renderTurn(events, spinner, opts) {
1713
1647
  if (showReasoning && delta) {
1714
1648
  spinner.stop();
1715
1649
  if (renderedVisibleOutput && !liveReasoning.isOpen())
1716
- writeln2();
1650
+ writeln();
1717
1651
  liveReasoning.append(delta);
1718
1652
  renderedVisibleOutput = true;
1719
1653
  }
@@ -1728,7 +1662,7 @@ async function renderTurn(events, spinner, opts) {
1728
1662
  content.flushOpenContent();
1729
1663
  spinner.stop();
1730
1664
  if (renderedVisibleOutput)
1731
- writeln2();
1665
+ writeln();
1732
1666
  renderToolCall(event.toolName, event.args);
1733
1667
  renderedVisibleOutput = true;
1734
1668
  spinner.start(event.toolName);
@@ -1750,7 +1684,7 @@ async function renderTurn(events, spinner, opts) {
1750
1684
  content.flushOpenContent();
1751
1685
  spinner.stop();
1752
1686
  const removedKb = (event.removedBytes / 1024).toFixed(1);
1753
- writeln2(`${G.info} ${c7.dim("context pruned")} ${c7.dim(event.mode)} ${c7.dim(`\u2013${event.removedMessageCount} messages`)} ${c7.dim(`\u2013${removedKb} KB`)}`);
1687
+ writeln(`${G.info} ${c6.dim("context pruned")} ${c6.dim(event.mode)} ${c6.dim(`\u2013${event.removedMessageCount} messages`)} ${c6.dim(`\u2013${removedKb} KB`)}`);
1754
1688
  renderedVisibleOutput = true;
1755
1689
  break;
1756
1690
  }
@@ -1759,7 +1693,7 @@ async function renderTurn(events, spinner, opts) {
1759
1693
  content.flushOpenContent();
1760
1694
  spinner.stop();
1761
1695
  if (!renderedVisibleOutput)
1762
- writeln2();
1696
+ writeln();
1763
1697
  inputTokens = event.inputTokens;
1764
1698
  outputTokens = event.outputTokens;
1765
1699
  contextTokens = event.contextTokens;
@@ -1791,7 +1725,7 @@ async function renderTurn(events, spinner, opts) {
1791
1725
 
1792
1726
  // src/cli/output.ts
1793
1727
  var HOME = homedir3();
1794
- var PACKAGE_VERSION = "0.0.22";
1728
+ var PACKAGE_VERSION = "0.0.23";
1795
1729
  function tildePath(p) {
1796
1730
  return p.startsWith(HOME) ? `~${p.slice(HOME.length)}` : p;
1797
1731
  }
@@ -1801,38 +1735,38 @@ function restoreTerminal() {
1801
1735
  function registerTerminalCleanup() {
1802
1736
  terminal.registerCleanup();
1803
1737
  }
1804
- function writeln2(text = "") {
1738
+ function writeln(text = "") {
1805
1739
  terminal.stdoutWrite(`${text}
1806
1740
  `);
1807
1741
  }
1808
- function write2(text) {
1742
+ function write(text) {
1809
1743
  terminal.stdoutWrite(text);
1810
1744
  }
1811
1745
  function renderUserMessage(text) {
1812
1746
  const lines = text.split(`
1813
1747
  `);
1814
1748
  if (lines.length === 0) {
1815
- writeln2(`${G.prompt}`);
1749
+ writeln(`${G.prompt}`);
1816
1750
  return;
1817
1751
  }
1818
- writeln2(`${G.prompt} ${lines[0] ?? ""}`);
1752
+ writeln(`${G.prompt} ${lines[0] ?? ""}`);
1819
1753
  for (const line of lines.slice(1)) {
1820
- writeln2(` ${line}`);
1754
+ writeln(` ${line}`);
1821
1755
  }
1822
1756
  }
1823
1757
  var G = {
1824
- prompt: c8.green("\u203A"),
1825
- reply: c8.cyan("\u25C6"),
1826
- search: c8.yellow("?"),
1827
- read: c8.dim("\u2190"),
1828
- write: c8.green("\u270E"),
1829
- run: c8.dim("$"),
1830
- agent: c8.cyan("\u21E2"),
1831
- mcp: c8.yellow("\u2699"),
1832
- ok: c8.green("\u2714"),
1833
- err: c8.red("\u2716"),
1834
- warn: c8.yellow("!"),
1835
- info: c8.dim("\xB7")
1758
+ prompt: c7.green("\u203A"),
1759
+ reply: c7.cyan("\u25C6"),
1760
+ search: c7.yellow("?"),
1761
+ read: c7.dim("\u2190"),
1762
+ write: c7.green("\u270E"),
1763
+ run: c7.dim("$"),
1764
+ agent: c7.cyan("\u21E2"),
1765
+ mcp: c7.yellow("\u2699"),
1766
+ ok: c7.green("\u2714"),
1767
+ err: c7.red("\u2716"),
1768
+ warn: c7.yellow("!"),
1769
+ info: c7.dim("\xB7")
1836
1770
  };
1837
1771
  var PREFIX = {
1838
1772
  user: G.prompt,
@@ -1854,9 +1788,9 @@ class RenderedError extends Error {
1854
1788
  function renderError(err, context = "render") {
1855
1789
  logError(err, context);
1856
1790
  const parsed = parseAppError(err);
1857
- writeln2(`${G.err} ${c8.red(parsed.headline)}`);
1791
+ writeln(`${G.err} ${c7.red(parsed.headline)}`);
1858
1792
  if (parsed.hint) {
1859
- writeln2(` ${c8.dim(parsed.hint)}`);
1793
+ writeln(` ${c7.dim(parsed.hint)}`);
1860
1794
  }
1861
1795
  }
1862
1796
  function discoverContextFiles(cwd) {
@@ -1876,11 +1810,11 @@ function discoverContextFiles(cwd) {
1876
1810
  return found;
1877
1811
  }
1878
1812
  function renderBanner(model, cwd) {
1879
- writeln2();
1813
+ writeln();
1880
1814
  const title = PACKAGE_VERSION ? `mini-coder \xB7 v${PACKAGE_VERSION}` : "mini-coder";
1881
- writeln2(` ${c8.cyan("mc")} ${c8.dim(title)}`);
1882
- writeln2(` ${c8.dim(model)} ${c8.dim("\xB7")} ${c8.dim(tildePath(cwd))}`);
1883
- writeln2(` ${c8.dim("/help for commands \xB7 esc cancel \xB7 ctrl+c/ctrl+d exit")}`);
1815
+ writeln(` ${c7.cyan("mc")} ${c7.dim(title)}`);
1816
+ writeln(` ${c7.dim(model)} ${c7.dim("\xB7")} ${c7.dim(tildePath(cwd))}`);
1817
+ writeln(` ${c7.dim("/help for commands \xB7 esc cancel \xB7 ctrl+c/ctrl+d exit")}`);
1884
1818
  const items = [];
1885
1819
  const contextFiles = discoverContextFiles(cwd);
1886
1820
  if (contextFiles.length > 0)
@@ -1895,27 +1829,19 @@ function renderBanner(model, cwd) {
1895
1829
  if (commands.size > 0)
1896
1830
  items.push(`${commands.size} custom cmd${commands.size > 1 ? "s" : ""}`);
1897
1831
  if (items.length > 0) {
1898
- writeln2(` ${c8.dim(items.join(" \xB7 "))}`);
1832
+ writeln(` ${c7.dim(items.join(" \xB7 "))}`);
1899
1833
  }
1900
- writeln2();
1834
+ writeln();
1901
1835
  }
1902
1836
 
1903
1837
  class CliReporter {
1904
1838
  spinner = new Spinner;
1905
- liveOutput = new LiveOutputBlock;
1906
- haltSpinner() {
1839
+ info(msg) {
1907
1840
  this.spinner.stop();
1841
+ writeln(`${G.info} ${c7.dim(msg)}`);
1908
1842
  }
1909
- haltSpinnerAndFlushLiveOutput() {
1843
+ error(msg, hint) {
1910
1844
  this.spinner.stop();
1911
- this.liveOutput.finish();
1912
- }
1913
- info(msg) {
1914
- this.haltSpinnerAndFlushLiveOutput();
1915
- writeln2(`${G.info} ${c8.dim(msg)}`);
1916
- }
1917
- error(msg, hint) {
1918
- this.haltSpinnerAndFlushLiveOutput();
1919
1845
  if (typeof msg === "string") {
1920
1846
  renderError(msg, hint);
1921
1847
  } else {
@@ -1923,29 +1849,23 @@ class CliReporter {
1923
1849
  }
1924
1850
  }
1925
1851
  warn(msg) {
1926
- this.haltSpinnerAndFlushLiveOutput();
1927
- writeln2(`${G.warn} ${msg}`);
1852
+ this.spinner.stop();
1853
+ writeln(`${G.warn} ${msg}`);
1928
1854
  }
1929
1855
  writeText(text) {
1930
- this.haltSpinnerAndFlushLiveOutput();
1931
- writeln2(text);
1932
- }
1933
- streamChunk(text) {
1934
- this.haltSpinner();
1935
- this.liveOutput.append(text);
1856
+ this.spinner.stop();
1857
+ writeln(text);
1936
1858
  }
1937
1859
  startSpinner(label) {
1938
1860
  this.spinner.start(label);
1939
1861
  }
1940
1862
  stopSpinner() {
1941
- this.haltSpinner();
1863
+ this.spinner.stop();
1942
1864
  }
1943
1865
  async renderTurn(events, opts) {
1944
- this.liveOutput.finish();
1945
1866
  return renderTurn(events, this.spinner, opts);
1946
1867
  }
1947
1868
  renderStatusBar(data) {
1948
- this.liveOutput.finish();
1949
1869
  renderStatusBar(data);
1950
1870
  }
1951
1871
  restoreTerminal() {
@@ -1965,8 +1885,8 @@ function warnConventionConflicts(kind, scope, agentsNames, claudeNames) {
1965
1885
  if (conflicts.length === 0)
1966
1886
  return;
1967
1887
  conflicts.sort((a, b) => a.localeCompare(b));
1968
- const list = conflicts.map((n) => c9.cyan(n)).join(c9.dim(", "));
1969
- writeln2(`${G.warn} conflicting ${kind} in ${scope} .agents and .claude: ${list} ${c9.dim("\u2014 using .agents version")}`);
1888
+ const list = conflicts.map((n) => c8.cyan(n)).join(c8.dim(", "));
1889
+ writeln(`${G.warn} conflicting ${kind} in ${scope} .agents and .claude: ${list} ${c8.dim("\u2014 using .agents version")}`);
1970
1890
  }
1971
1891
 
1972
1892
  // src/cli/frontmatter.ts
@@ -2627,10 +2547,10 @@ function setPreferredGoogleCachedContent(contentId) {
2627
2547
  }
2628
2548
  }
2629
2549
  // src/agent/session-runner.ts
2630
- import * as c12 from "yoctocolors";
2550
+ import * as c11 from "yoctocolors";
2631
2551
 
2632
2552
  // src/cli/input.ts
2633
- import * as c10 from "yoctocolors";
2553
+ import * as c9 from "yoctocolors";
2634
2554
 
2635
2555
  // src/cli/input-buffer.ts
2636
2556
  var PASTE_TOKEN_START = 57344;
@@ -3064,7 +2984,7 @@ function watchForCancel(abortController, options) {
3064
2984
  process.stdin.on("data", onData);
3065
2985
  return cleanup;
3066
2986
  }
3067
- var PROMPT = c10.green("\u25B6 ");
2987
+ var PROMPT = c9.green("\u25B6 ");
3068
2988
  var PROMPT_RAW_LEN = 2;
3069
2989
  async function readline(opts) {
3070
2990
  const cwd = opts.cwd ?? process.cwd();
@@ -3113,7 +3033,7 @@ async function readline(opts) {
3113
3033
  process.stdout.write(`${CLEAR_LINE}${prompt}${display}${CSI}${PROMPT_RAW_LEN + displayCursor + 1}G`);
3114
3034
  }
3115
3035
  function renderSearchPrompt() {
3116
- process.stdout.write(`${CLEAR_LINE}${c10.cyan("search:")} ${searchQuery}\u2588`);
3036
+ process.stdout.write(`${CLEAR_LINE}${c9.cyan("search:")} ${searchQuery}\u2588`);
3117
3037
  }
3118
3038
  function applyHistory() {
3119
3039
  if (histIdx < history.length) {
@@ -4565,10 +4485,6 @@ function normalizeUnknownError(error) {
4565
4485
  return new Error(stringifyUnknown(error));
4566
4486
  }
4567
4487
 
4568
- // src/llm-api/turn-anthropic-oauth.ts
4569
- import Anthropic from "@anthropic-ai/sdk";
4570
- import { zodSchema } from "ai";
4571
-
4572
4488
  // src/llm-api/turn-context.ts
4573
4489
  import { pruneMessages } from "ai";
4574
4490
  var DEFAULT_TOOL_RESULT_PAYLOAD_CAP_BYTES = 16 * 1024;
@@ -4769,994 +4685,184 @@ function annotateAnthropicCacheBreakpoints(turnMessages, systemPrompt) {
4769
4685
  };
4770
4686
  }
4771
4687
 
4772
- // src/llm-api/turn-request.ts
4773
- import { stepCountIs } from "ai";
4688
+ // src/llm-api/turn-execution.ts
4689
+ import { dynamicTool, jsonSchema } from "ai";
4774
4690
 
4775
- // src/llm-api/provider-options.ts
4776
- var ANTHROPIC_BUDGET = {
4777
- low: 4096,
4778
- medium: 8192,
4779
- high: 16384,
4780
- xhigh: 32768
4781
- };
4782
- var GEMINI_BUDGET = {
4783
- low: 4096,
4784
- medium: 8192,
4785
- high: 16384,
4786
- xhigh: 24575
4787
- };
4788
- function clampEffort(effort, max) {
4789
- const ORDER = ["low", "medium", "high", "xhigh"];
4790
- const effortIdx = ORDER.indexOf(effort);
4791
- const maxIdx = ORDER.indexOf(max);
4792
- return ORDER[Math.min(effortIdx, maxIdx)];
4691
+ // src/llm-api/turn-stream-events.ts
4692
+ function shouldLogStreamChunk(c10) {
4693
+ return c10.type !== "text-delta" && c10.type !== "reasoning" && c10.type !== "reasoning-delta";
4793
4694
  }
4794
- function getAnthropicThinkingOptions(modelId, effort) {
4795
- const isAdaptive = /^claude-3-7/.test(modelId) || /^claude-sonnet-4/.test(modelId) || /^claude-opus-4/.test(modelId);
4796
- if (isAdaptive) {
4797
- const isOpus = /^claude-opus-4/.test(modelId);
4798
- const mapped = effort === "xhigh" ? isOpus ? "max" : "high" : effort;
4799
- return { anthropic: { thinking: { type: "adaptive" }, effort: mapped } };
4800
- }
4801
- return {
4802
- anthropic: {
4803
- thinking: { type: "enabled", budgetTokens: ANTHROPIC_BUDGET[effort] },
4804
- betas: ["interleaved-thinking-2025-05-14"]
4695
+ function extractToolArgs(c10) {
4696
+ return c10.input ?? c10.args;
4697
+ }
4698
+ function hasRenderableToolArgs(args) {
4699
+ if (args === null || args === undefined)
4700
+ return false;
4701
+ if (typeof args === "string")
4702
+ return args.trim().length > 0;
4703
+ if (Array.isArray(args))
4704
+ return args.length > 0;
4705
+ if (typeof args === "object")
4706
+ return Object.keys(args).length > 0;
4707
+ return true;
4708
+ }
4709
+ function mapStreamChunkToTurnEvent(c10) {
4710
+ switch (c10.type) {
4711
+ case "text-delta": {
4712
+ const delta = typeof c10.text === "string" ? c10.text : "";
4713
+ return {
4714
+ type: "text-delta",
4715
+ delta
4716
+ };
4805
4717
  }
4806
- };
4718
+ case "reasoning-delta":
4719
+ case "reasoning": {
4720
+ const delta = getReasoningDeltaFromStreamChunk(c10);
4721
+ if (delta === null)
4722
+ return null;
4723
+ return {
4724
+ type: "reasoning-delta",
4725
+ delta
4726
+ };
4727
+ }
4728
+ case "tool-input-start": {
4729
+ const args = extractToolArgs(c10);
4730
+ const hasStableToolCallId = typeof c10.toolCallId === "string" && c10.toolCallId.trim().length > 0;
4731
+ if (hasStableToolCallId && !hasRenderableToolArgs(args))
4732
+ return null;
4733
+ return {
4734
+ type: "tool-call-start",
4735
+ toolCallId: String(c10.toolCallId ?? ""),
4736
+ toolName: String(c10.toolName ?? ""),
4737
+ args
4738
+ };
4739
+ }
4740
+ case "tool-call": {
4741
+ return {
4742
+ type: "tool-call-start",
4743
+ toolCallId: String(c10.toolCallId ?? ""),
4744
+ toolName: String(c10.toolName ?? ""),
4745
+ args: extractToolArgs(c10)
4746
+ };
4747
+ }
4748
+ case "tool-result": {
4749
+ return {
4750
+ type: "tool-result",
4751
+ toolCallId: String(c10.toolCallId ?? ""),
4752
+ toolName: String(c10.toolName ?? ""),
4753
+ result: "output" in c10 ? c10.output : ("result" in c10) ? c10.result : undefined,
4754
+ isError: "isError" in c10 ? Boolean(c10.isError) : false
4755
+ };
4756
+ }
4757
+ case "tool-error":
4758
+ return {
4759
+ type: "tool-result",
4760
+ toolCallId: String(c10.toolCallId ?? ""),
4761
+ toolName: String(c10.toolName ?? ""),
4762
+ result: c10.error ?? "Tool execution failed",
4763
+ isError: true
4764
+ };
4765
+ case "error": {
4766
+ throw normalizeUnknownError(c10.error);
4767
+ }
4768
+ default:
4769
+ return null;
4770
+ }
4807
4771
  }
4808
- function getOpenAIThinkingOptions(modelId, effort) {
4809
- const supportsXhigh = /^gpt-5\.[2-9]/.test(modelId) || /^o4/.test(modelId);
4810
- const clamped = supportsXhigh ? effort : clampEffort(effort, "high");
4811
- return { openai: { reasoningEffort: clamped, reasoningSummary: "auto" } };
4772
+
4773
+ // src/llm-api/turn-execution.ts
4774
+ function isZodSchema(s) {
4775
+ return s !== null && typeof s === "object" && "_def" in s;
4812
4776
  }
4813
- function getGeminiThinkingOptions(modelId, effort) {
4814
- if (/^gemini-3/.test(modelId)) {
4815
- return {
4816
- google: {
4817
- thinkingConfig: {
4818
- includeThoughts: true,
4819
- thinkingLevel: clampEffort(effort, "high")
4820
- }
4777
+ function toCoreTool(def) {
4778
+ const schema = isZodSchema(def.schema) ? def.schema : jsonSchema(def.schema);
4779
+ return dynamicTool({
4780
+ description: def.description,
4781
+ inputSchema: schema,
4782
+ execute: async (input) => {
4783
+ try {
4784
+ return await def.execute(input);
4785
+ } catch (err) {
4786
+ throw normalizeUnknownError(err);
4821
4787
  }
4822
- };
4788
+ }
4789
+ });
4790
+ }
4791
+ function buildToolSet(tools) {
4792
+ const toolSet = {};
4793
+ for (const def of tools) {
4794
+ toolSet[def.name] = toCoreTool(def);
4823
4795
  }
4796
+ return toolSet;
4797
+ }
4798
+ function createTurnStepTracker(opts) {
4799
+ let stepCount = 0;
4800
+ let inputTokens = 0;
4801
+ let outputTokens = 0;
4802
+ let contextTokens = 0;
4803
+ let partialMessages = [];
4824
4804
  return {
4825
- google: {
4826
- thinkingConfig: {
4827
- includeThoughts: true,
4828
- thinkingBudget: GEMINI_BUDGET[effort]
4829
- }
4830
- }
4805
+ onStepFinish: (step) => {
4806
+ opts.onStepLog({
4807
+ stepNumber: stepCount + 1,
4808
+ finishReason: step.finishReason,
4809
+ usage: step.usage
4810
+ });
4811
+ inputTokens += step.usage?.inputTokens ?? 0;
4812
+ outputTokens += step.usage?.outputTokens ?? 0;
4813
+ contextTokens = step.usage?.inputTokens ?? contextTokens;
4814
+ stepCount += 1;
4815
+ const s = step;
4816
+ partialMessages = s.response?.messages ?? s.messages ?? partialMessages;
4817
+ },
4818
+ getState: () => ({
4819
+ stepCount,
4820
+ inputTokens,
4821
+ outputTokens,
4822
+ contextTokens,
4823
+ partialMessages
4824
+ })
4831
4825
  };
4832
4826
  }
4833
- var THINKING_STRATEGIES = [
4834
- {
4835
- supports: isAnthropicModelFamily,
4836
- build: getAnthropicThinkingOptions
4837
- },
4838
- {
4839
- supports: isOpenAIReasoningModelFamily,
4840
- build: getOpenAIThinkingOptions
4841
- },
4842
- {
4843
- supports: isGeminiModelFamily,
4844
- build: getGeminiThinkingOptions
4845
- }
4846
- ];
4847
- function getThinkingProviderOptions(modelString, effort) {
4848
- if (!supportsThinking(modelString))
4827
+ var TOOL_RESULT_CHUNK_TYPES = new Set(["tool-result", "tool-error"]);
4828
+ function normalizeToolCallId(raw) {
4829
+ if (typeof raw !== "string")
4849
4830
  return null;
4850
- const { modelId } = parseModelString(modelString);
4851
- for (const strategy of THINKING_STRATEGIES) {
4852
- if (!strategy.supports(modelString))
4853
- continue;
4854
- return strategy.build(modelId, effort);
4855
- }
4856
- return null;
4831
+ const trimmed = raw.trim();
4832
+ return trimmed ? trimmed : null;
4857
4833
  }
4858
- var CACHE_FAMILY_RULES = [
4859
- [isAnthropicModelFamily, "anthropic"],
4860
- [isGeminiModelFamily, "google"]
4861
- ];
4862
- function getCacheFamily(modelString) {
4863
- for (const [match, family] of CACHE_FAMILY_RULES) {
4864
- if (match(modelString))
4865
- return family;
4866
- }
4867
- return "none";
4834
+ function normalizeToolName(raw) {
4835
+ if (typeof raw !== "string")
4836
+ return "tool";
4837
+ const trimmed = raw.trim();
4838
+ return trimmed || "tool";
4868
4839
  }
4869
- function getCachingProviderOptions(modelString, opts) {
4870
- if (!opts.enabled)
4840
+ function isRecord5(value) {
4841
+ return value !== null && typeof value === "object";
4842
+ }
4843
+ function normalizeTextPartId(raw) {
4844
+ if (typeof raw !== "string")
4871
4845
  return null;
4872
- const family = getCacheFamily(modelString);
4873
- if (family === "google" && opts.googleCachedContent && opts.googleExplicitCachingCompatible !== false) {
4874
- return { google: { cachedContent: opts.googleCachedContent } };
4875
- }
4876
- return null;
4877
- }
4878
-
4879
- // src/llm-api/turn-prepare-messages.ts
4880
- function prepareTurnMessages(input) {
4881
- const {
4882
- messages,
4883
- modelString,
4884
- toolCount,
4885
- systemPrompt,
4886
- pruningMode,
4887
- toolResultPayloadCapBytes,
4888
- promptCachingEnabled
4889
- } = input;
4890
- const apiLogOn = isApiLogEnabled();
4891
- const strippedRuntimeToolFields = stripToolRuntimeInputFields(messages);
4892
- if (strippedRuntimeToolFields !== messages && apiLogOn) {
4893
- logApiEvent("runtime tool input fields stripped", { modelString });
4894
- }
4895
- const geminiResult = sanitizeGeminiToolMessagesWithMetadata(strippedRuntimeToolFields, modelString, toolCount > 0);
4896
- if (geminiResult.repaired && apiLogOn) {
4897
- logApiEvent("gemini tool history repaired", {
4898
- modelString,
4899
- reason: geminiResult.reason,
4900
- repairedFromIndex: geminiResult.repairedFromIndex,
4901
- droppedMessageCount: geminiResult.droppedMessageCount,
4902
- tailOnlyAffected: geminiResult.tailOnlyAffected
4903
- });
4904
- }
4905
- const openaiStripped = stripOpenAIHistoryTransforms(geminiResult.messages, modelString);
4906
- if (openaiStripped !== geminiResult.messages && apiLogOn) {
4907
- logApiEvent("openai history transforms applied", { modelString });
4908
- }
4909
- const normalised = normalizeOpenAICompatibleToolCallInputs(openaiStripped, modelString);
4910
- if (normalised !== openaiStripped && apiLogOn) {
4911
- logApiEvent("openai-compatible tool input normalized", { modelString });
4912
- }
4913
- const preStats = apiLogOn ? getMessageDiagnostics(normalised) : getMessageStats(normalised);
4914
- if (apiLogOn)
4915
- logApiEvent("turn context pre-prune", preStats);
4916
- const pruned = applyContextPruning(normalised, pruningMode);
4917
- const postStats = apiLogOn ? getMessageDiagnostics(pruned) : getMessageStats(pruned);
4918
- if (apiLogOn)
4919
- logApiEvent("turn context post-prune", postStats);
4920
- const compacted = compactToolResultPayloads(pruned, toolResultPayloadCapBytes);
4921
- if (compacted !== pruned && apiLogOn) {
4922
- logApiEvent("turn context post-compaction", {
4923
- capBytes: toolResultPayloadCapBytes,
4924
- diagnostics: getMessageDiagnostics(compacted)
4925
- });
4926
- }
4927
- let finalMessages = compacted;
4928
- let finalSystemPrompt = systemPrompt;
4929
- const cacheFamily = getCacheFamily(modelString);
4930
- if (cacheFamily === "anthropic" && promptCachingEnabled) {
4931
- const annotated = annotateAnthropicCacheBreakpoints(compacted, systemPrompt);
4932
- finalMessages = annotated.messages;
4933
- finalSystemPrompt = annotated.systemPrompt;
4934
- if (apiLogOn) {
4935
- logApiEvent("Anthropic prompt caching", annotated.diagnostics);
4936
- }
4937
- }
4938
- if (isAnthropicModelFamily(modelString) && isAnthropicOAuth()) {
4939
- const prefix = `You are Claude Code, Anthropic's official CLI for Claude.
4940
- `;
4941
- if (finalSystemPrompt) {
4942
- finalSystemPrompt = prefix + finalSystemPrompt;
4943
- } else {
4944
- const sysMsg = finalMessages.find((m) => m.role === "system");
4945
- if (sysMsg && typeof sysMsg.content === "string") {
4946
- const idx = finalMessages.indexOf(sysMsg);
4947
- finalMessages[idx] = { ...sysMsg, content: prefix + sysMsg.content };
4948
- }
4949
- }
4950
- }
4951
- const wasPruned = (pruningMode === "balanced" || pruningMode === "aggressive") && (postStats.messageCount < preStats.messageCount || postStats.totalBytes < preStats.totalBytes);
4952
- return {
4953
- messages: finalMessages,
4954
- systemPrompt: finalSystemPrompt,
4955
- pruned: wasPruned,
4956
- prePruneMessageCount: preStats.messageCount,
4957
- prePruneTotalBytes: preStats.totalBytes,
4958
- postPruneMessageCount: postStats.messageCount,
4959
- postPruneTotalBytes: postStats.totalBytes
4960
- };
4961
- }
4962
-
4963
- // src/llm-api/turn-provider-options.ts
4964
- function isRecord5(value) {
4965
- return value !== null && typeof value === "object";
4966
- }
4967
- function mergeDeep(target, source) {
4968
- const output = { ...target };
4969
- for (const key in source) {
4970
- const sVal = source[key];
4971
- const tVal = target[key];
4972
- output[key] = isRecord5(sVal) && isRecord5(tVal) ? { ...tVal, ...sVal } : sVal;
4973
- }
4974
- return output;
4975
- }
4976
- function buildTurnProviderOptions(input) {
4977
- const {
4978
- modelString,
4979
- thinkingEffort,
4980
- promptCachingEnabled,
4981
- openaiPromptCacheRetention,
4982
- googleCachedContent,
4983
- toolCount,
4984
- hasSystemPrompt
4985
- } = input;
4986
- const thinkingOpts = thinkingEffort ? getThinkingProviderOptions(modelString, thinkingEffort) : null;
4987
- const reasoningSummaryRequested = isRecord5(thinkingOpts) && isRecord5(thinkingOpts.openai) && typeof thinkingOpts.openai.reasoningSummary === "string";
4988
- const cacheFamily = getCacheFamily(modelString);
4989
- const cacheOpts = getCachingProviderOptions(modelString, {
4990
- enabled: promptCachingEnabled,
4991
- openaiRetention: openaiPromptCacheRetention,
4992
- googleCachedContent,
4993
- googleExplicitCachingCompatible: toolCount === 0 && !hasSystemPrompt
4994
- });
4995
- const baseProviderOpts = {
4996
- ...thinkingOpts ?? {},
4997
- ...isOpenAIGPT(modelString) ? {
4998
- openai: {
4999
- store: false,
5000
- ...isRecord5(thinkingOpts?.openai) ? thinkingOpts.openai : {}
5001
- }
5002
- } : {}
5003
- };
5004
- const providerOptions = cacheOpts ? mergeDeep(baseProviderOpts, cacheOpts) : baseProviderOpts;
5005
- return {
5006
- cacheFamily,
5007
- thinkingOpts,
5008
- cacheOpts,
5009
- providerOptions,
5010
- reasoningSummaryRequested
5011
- };
5012
- }
5013
-
5014
- // src/llm-api/turn-request.ts
5015
- function buildTurnPreparation(input) {
5016
- const providerOptionsResult = buildTurnProviderOptions({
5017
- modelString: input.modelString,
5018
- thinkingEffort: input.thinkingEffort,
5019
- promptCachingEnabled: input.promptCachingEnabled,
5020
- openaiPromptCacheRetention: input.openaiPromptCacheRetention,
5021
- googleCachedContent: input.googleCachedContent,
5022
- toolCount: input.toolCount,
5023
- hasSystemPrompt: Boolean(input.systemPrompt)
5024
- });
5025
- const prepared = prepareTurnMessages({
5026
- messages: input.messages,
5027
- modelString: input.modelString,
5028
- toolCount: input.toolCount,
5029
- systemPrompt: input.systemPrompt,
5030
- pruningMode: input.pruningMode,
5031
- toolResultPayloadCapBytes: input.toolResultPayloadCapBytes,
5032
- promptCachingEnabled: input.promptCachingEnabled
5033
- });
5034
- return { providerOptionsResult, prepared };
5035
- }
5036
- function buildStreamTextRequest(input) {
5037
- return {
5038
- model: input.model,
5039
- maxOutputTokens: 16384,
5040
- messages: input.prepared.messages,
5041
- tools: input.toolSet,
5042
- stopWhen: stepCountIs(input.maxSteps),
5043
- onStepFinish: input.onStepFinish,
5044
- prepareStep: ({ stepNumber }) => {
5045
- if (stepNumber >= input.maxSteps - 1) {
5046
- return { activeTools: [] };
5047
- }
5048
- return;
5049
- },
5050
- ...input.prepared.systemPrompt ? { system: input.prepared.systemPrompt } : {},
5051
- ...Object.keys(input.providerOptions).length > 0 ? {
5052
- providerOptions: input.providerOptions
5053
- } : {},
5054
- ...input.signal ? { abortSignal: input.signal } : {},
5055
- onError: () => {},
5056
- timeout: { chunkMs: 120000 }
5057
- };
5058
- }
5059
-
5060
- // src/llm-api/turn-anthropic-oauth.ts
5061
- var MAX_STEPS = 50;
5062
- var MAX_OUTPUT_TOKENS = 16384;
5063
- var CC_VERSION = "2.1.75";
5064
- var cachedClient = null;
5065
- function getClient(token) {
5066
- if (cachedClient?.token === token && cachedClient.client)
5067
- return cachedClient.client;
5068
- const client = new Anthropic({
5069
- apiKey: null,
5070
- authToken: token,
5071
- maxRetries: 5,
5072
- dangerouslyAllowBrowser: true,
5073
- defaultHeaders: {
5074
- accept: "application/json",
5075
- "anthropic-dangerous-direct-browser-access": "true",
5076
- "anthropic-beta": "claude-code-20250219,oauth-2025-04-20",
5077
- "user-agent": `claude-cli/${CC_VERSION}`,
5078
- "x-app": "cli"
5079
- }
5080
- });
5081
- cachedClient = { token, client };
5082
- return client;
5083
- }
5084
- function supportsAdaptiveThinking(modelId) {
5085
- return modelId.includes("opus-4-6") || modelId.includes("sonnet-4-6");
5086
- }
5087
- function mapEffort(effort, modelId) {
5088
- if (!effort)
5089
- return;
5090
- const map = {
5091
- low: "low",
5092
- medium: "medium",
5093
- high: "high",
5094
- xhigh: modelId.includes("opus-4-6") ? "max" : "high"
5095
- };
5096
- return map[effort];
5097
- }
5098
- function coreToAnthropicMessages(messages) {
5099
- let systemPrompt;
5100
- const params = [];
5101
- const toolUseIds = new Set;
5102
- for (const msg of messages) {
5103
- if (msg.role !== "assistant" || !Array.isArray(msg.content))
5104
- continue;
5105
- for (const part of msg.content) {
5106
- if (part.type === "tool-call" && part.toolCallId) {
5107
- toolUseIds.add(part.toolCallId);
5108
- }
5109
- }
5110
- }
5111
- for (const msg of messages) {
5112
- if (msg.role === "system") {
5113
- systemPrompt = typeof msg.content === "string" ? msg.content : Array.isArray(msg.content) ? msg.content.filter((p) => p.type === "text").map((p) => p.text).join(`
5114
- `) : undefined;
5115
- continue;
5116
- }
5117
- if (msg.role === "user") {
5118
- if (typeof msg.content === "string") {
5119
- if (msg.content.trim())
5120
- params.push({ role: "user", content: msg.content });
5121
- continue;
5122
- }
5123
- if (Array.isArray(msg.content)) {
5124
- const blocks = [];
5125
- for (const part of msg.content) {
5126
- if (part.type === "text" && part.text?.trim()) {
5127
- blocks.push({ type: "text", text: part.text });
5128
- } else if (part.type === "tool-result") {
5129
- if (!toolUseIds.has(part.toolCallId))
5130
- continue;
5131
- blocks.push({
5132
- type: "tool_result",
5133
- tool_use_id: part.toolCallId,
5134
- content: typeof part.result === "string" ? part.result : JSON.stringify(part.result ?? part.output ?? ""),
5135
- is_error: part.isError ?? false
5136
- });
5137
- } else if (part.type === "image") {
5138
- blocks.push({
5139
- type: "image",
5140
- source: {
5141
- type: "base64",
5142
- media_type: part.mimeType ?? "image/png",
5143
- data: part.data
5144
- }
5145
- });
5146
- }
5147
- }
5148
- if (blocks.length > 0)
5149
- params.push({ role: "user", content: blocks });
5150
- }
5151
- continue;
5152
- }
5153
- if (msg.role === "assistant") {
5154
- if (typeof msg.content === "string") {
5155
- if (msg.content.trim())
5156
- params.push({ role: "assistant", content: msg.content });
5157
- continue;
5158
- }
5159
- if (Array.isArray(msg.content)) {
5160
- const blocks = [];
5161
- for (const part of msg.content) {
5162
- if (part.type === "text" && part.text?.trim()) {
5163
- blocks.push({ type: "text", text: part.text });
5164
- } else if (part.type === "tool-call") {
5165
- blocks.push({
5166
- type: "tool_use",
5167
- id: part.toolCallId,
5168
- name: part.toolName,
5169
- input: part.args ?? {}
5170
- });
5171
- } else if (part.type === "thinking") {
5172
- if (part.redacted && part.signature) {
5173
- blocks.push({
5174
- type: "redacted_thinking",
5175
- data: part.signature
5176
- });
5177
- } else if (part.text?.trim() && part.signature?.trim()) {
5178
- blocks.push({
5179
- type: "thinking",
5180
- thinking: part.text,
5181
- signature: part.signature
5182
- });
5183
- }
5184
- }
5185
- }
5186
- if (blocks.length > 0)
5187
- params.push({ role: "assistant", content: blocks });
5188
- }
5189
- }
5190
- }
5191
- return { system: systemPrompt, params };
5192
- }
5193
- function convertTools(tools) {
5194
- return tools.map((tool) => {
5195
- const schema = zodSchema(tool.schema).jsonSchema;
5196
- return {
5197
- name: tool.name,
5198
- description: tool.description,
5199
- input_schema: {
5200
- type: "object",
5201
- properties: schema.properties ?? {},
5202
- required: schema.required ?? []
5203
- }
5204
- };
5205
- });
5206
- }
5207
- function buildCoreMessages(assistantText, thinkingBlocks, toolCalls, toolResults) {
5208
- const messages = [];
5209
- const parts = [];
5210
- for (const tb of thinkingBlocks) {
5211
- if (tb.redacted) {
5212
- parts.push({
5213
- type: "thinking",
5214
- text: "[Reasoning redacted]",
5215
- signature: tb.signature,
5216
- redacted: true
5217
- });
5218
- } else {
5219
- parts.push({
5220
- type: "thinking",
5221
- text: tb.text,
5222
- signature: tb.signature
5223
- });
5224
- }
5225
- }
5226
- if (assistantText.trim()) {
5227
- parts.push({ type: "text", text: assistantText });
5228
- }
5229
- for (const tc of toolCalls) {
5230
- parts.push({
5231
- type: "tool-call",
5232
- toolCallId: tc.id,
5233
- toolName: tc.name,
5234
- args: tc.args
5235
- });
5236
- }
5237
- if (parts.length > 0) {
5238
- messages.push({
5239
- role: "assistant",
5240
- content: parts
5241
- });
5242
- }
5243
- if (toolResults.length > 0) {
5244
- const resultParts = toolResults.map((tr) => ({
5245
- type: "tool-result",
5246
- toolCallId: tr.toolCallId,
5247
- toolName: tr.toolName,
5248
- result: tr.result,
5249
- isError: tr.isError
5250
- }));
5251
- messages.push({
5252
- role: "user",
5253
- content: resultParts
5254
- });
5255
- }
5256
- return messages;
5257
- }
5258
- function parseStreamingJson(partial) {
5259
- try {
5260
- return JSON.parse(partial);
5261
- } catch {
5262
- try {
5263
- let fixed = partial;
5264
- const opens = (fixed.match(/{/g) || []).length;
5265
- const closes = (fixed.match(/}/g) || []).length;
5266
- for (let i = 0;i < opens - closes; i++)
5267
- fixed += "}";
5268
- return JSON.parse(fixed);
5269
- } catch {
5270
- return {};
5271
- }
5272
- }
5273
- }
5274
- async function* runTurnAnthropicOAuth(options) {
5275
- const {
5276
- token,
5277
- modelString,
5278
- messages,
5279
- tools,
5280
- systemPrompt,
5281
- signal,
5282
- thinkingEffort,
5283
- pruningMode = "balanced",
5284
- promptCachingEnabled = true,
5285
- toolResultPayloadCapBytes = DEFAULT_TOOL_RESULT_PAYLOAD_CAP_BYTES
5286
- } = options;
5287
- const modelId = modelString.replace(/^anthropic\//, "");
5288
- const client = getClient(token);
5289
- const anthropicTools = convertTools(tools);
5290
- const toolExecutors = new Map(tools.map((t) => [t.name, t.execute]));
5291
- let totalInputTokens = 0;
5292
- let totalOutputTokens = 0;
5293
- let contextTokens = 0;
5294
- let stepCount = 0;
5295
- const allNewMessages = [];
5296
- try {
5297
- const { prepared } = buildTurnPreparation({
5298
- modelString,
5299
- messages,
5300
- thinkingEffort,
5301
- promptCachingEnabled,
5302
- openaiPromptCacheRetention: "in_memory",
5303
- googleCachedContent: null,
5304
- toolCount: tools.length,
5305
- systemPrompt,
5306
- pruningMode,
5307
- toolResultPayloadCapBytes
5308
- });
5309
- logApiEvent("turn start", {
5310
- modelString,
5311
- messageCount: messages.length,
5312
- reasoningSummaryRequested: false,
5313
- pruningMode,
5314
- toolResultPayloadCapBytes
5315
- });
5316
- if (prepared.pruned) {
5317
- yield {
5318
- type: "context-pruned",
5319
- mode: pruningMode,
5320
- beforeMessageCount: prepared.prePruneMessageCount,
5321
- afterMessageCount: prepared.postPruneMessageCount,
5322
- removedMessageCount: prepared.prePruneMessageCount - prepared.postPruneMessageCount,
5323
- beforeTotalBytes: prepared.prePruneTotalBytes,
5324
- afterTotalBytes: prepared.postPruneTotalBytes,
5325
- removedBytes: prepared.prePruneTotalBytes - prepared.postPruneTotalBytes
5326
- };
5327
- }
5328
- const { system: extractedSystem, params: anthropicMessages } = coreToAnthropicMessages(prepared.messages);
5329
- const ccPrefix = "You are Claude Code, Anthropic's official CLI for Claude.";
5330
- const sysText = prepared.systemPrompt ?? extractedSystem;
5331
- const systemBlocks = [
5332
- {
5333
- type: "text",
5334
- text: ccPrefix,
5335
- cache_control: { type: "ephemeral" }
5336
- }
5337
- ];
5338
- if (sysText) {
5339
- const clean = sysText.startsWith(ccPrefix) ? sysText.slice(ccPrefix.length).replace(/^\n/, "") : sysText;
5340
- if (clean.trim()) {
5341
- systemBlocks.push({
5342
- type: "text",
5343
- text: clean,
5344
- cache_control: { type: "ephemeral" }
5345
- });
5346
- }
5347
- }
5348
- const currentMessages = [...anthropicMessages];
5349
- while (stepCount < MAX_STEPS) {
5350
- stepCount++;
5351
- const isLastStep = stepCount >= MAX_STEPS;
5352
- const params = {
5353
- model: modelId,
5354
- max_tokens: MAX_OUTPUT_TOKENS,
5355
- system: systemBlocks,
5356
- messages: currentMessages,
5357
- tools: isLastStep ? [] : anthropicTools,
5358
- stream: true
5359
- };
5360
- if (thinkingEffort && supportsAdaptiveThinking(modelId)) {
5361
- params.thinking = { type: "adaptive" };
5362
- const effort = mapEffort(thinkingEffort, modelId);
5363
- if (effort) {
5364
- params.output_config = {
5365
- effort
5366
- };
5367
- }
5368
- }
5369
- for (const m of currentMessages) {
5370
- if (!Array.isArray(m.content))
5371
- continue;
5372
- for (const block of m.content) {
5373
- if (typeof block === "object" && block !== null) {
5374
- delete block.cache_control;
5375
- }
5376
- }
5377
- }
5378
- const lastMsg = currentMessages.length > 0 ? currentMessages[currentMessages.length - 1] : undefined;
5379
- if (lastMsg && lastMsg.role === "user" && Array.isArray(lastMsg.content)) {
5380
- const lastBlock = lastMsg.content[lastMsg.content.length - 1];
5381
- if (lastBlock && typeof lastBlock === "object") {
5382
- lastBlock.cache_control = {
5383
- type: "ephemeral"
5384
- };
5385
- }
5386
- }
5387
- if (isApiLogEnabled()) {
5388
- logApiEvent("Provider Request", {
5389
- url: "https://api.anthropic.com/v1/messages",
5390
- method: "POST",
5391
- model: modelId,
5392
- messageCount: currentMessages.length,
5393
- toolCount: params.tools?.length ?? 0
5394
- });
5395
- }
5396
- const stream = client.messages.stream(params, { signal });
5397
- let assistantText = "";
5398
- const thinkingBlocks = [];
5399
- const toolCalls = [];
5400
- let partialJson = "";
5401
- let currentToolId = "";
5402
- let currentToolName = "";
5403
- let stepInputTokens = 0;
5404
- let stepOutputTokens = 0;
5405
- let stopReason;
5406
- for await (const event of stream) {
5407
- if (event.type === "message_start") {
5408
- stepInputTokens = event.message.usage.input_tokens || 0;
5409
- stepOutputTokens = event.message.usage.output_tokens || 0;
5410
- } else if (event.type === "content_block_start") {
5411
- if (event.content_block.type === "text") {} else if (event.content_block.type === "thinking") {
5412
- thinkingBlocks.push({
5413
- text: "",
5414
- signature: ""
5415
- });
5416
- } else if (event.content_block.type === "redacted_thinking") {
5417
- thinkingBlocks.push({
5418
- text: "[Reasoning redacted]",
5419
- signature: event.content_block.data,
5420
- redacted: true
5421
- });
5422
- } else if (event.content_block.type === "tool_use") {
5423
- currentToolId = event.content_block.id;
5424
- currentToolName = event.content_block.name;
5425
- partialJson = "";
5426
- }
5427
- } else if (event.type === "content_block_delta") {
5428
- if (event.delta.type === "text_delta") {
5429
- assistantText += event.delta.text;
5430
- yield { type: "text-delta", delta: event.delta.text };
5431
- } else if (event.delta.type === "thinking_delta") {
5432
- const tb = thinkingBlocks[thinkingBlocks.length - 1];
5433
- if (tb)
5434
- tb.text += event.delta.thinking;
5435
- yield {
5436
- type: "reasoning-delta",
5437
- delta: event.delta.thinking
5438
- };
5439
- } else if (event.delta.type === "input_json_delta") {
5440
- partialJson += event.delta.partial_json;
5441
- } else if (event.delta.type === "signature_delta") {
5442
- const tb = thinkingBlocks[thinkingBlocks.length - 1];
5443
- if (tb)
5444
- tb.signature += event.delta.signature;
5445
- }
5446
- } else if (event.type === "content_block_stop") {
5447
- if (currentToolId && currentToolName) {
5448
- const args = parseStreamingJson(partialJson);
5449
- toolCalls.push({
5450
- id: currentToolId,
5451
- name: currentToolName,
5452
- args
5453
- });
5454
- yield {
5455
- type: "tool-call-start",
5456
- toolCallId: currentToolId,
5457
- toolName: currentToolName,
5458
- args
5459
- };
5460
- currentToolId = "";
5461
- currentToolName = "";
5462
- partialJson = "";
5463
- }
5464
- } else if (event.type === "message_delta") {
5465
- if (event.delta.stop_reason) {
5466
- stopReason = event.delta.stop_reason;
5467
- }
5468
- if (event.usage.output_tokens != null) {
5469
- stepOutputTokens = event.usage.output_tokens;
5470
- }
5471
- }
5472
- }
5473
- totalInputTokens += stepInputTokens;
5474
- totalOutputTokens += stepOutputTokens;
5475
- contextTokens = stepInputTokens;
5476
- logApiEvent("step finish", {
5477
- stepNumber: stepCount,
5478
- finishReason: stopReason,
5479
- usage: {
5480
- inputTokens: stepInputTokens,
5481
- outputTokens: stepOutputTokens
5482
- }
5483
- });
5484
- const toolResults = [];
5485
- if (stopReason === "tool_use" && toolCalls.length > 0) {
5486
- for (const tc of toolCalls) {
5487
- const executor = toolExecutors.get(tc.name);
5488
- let result;
5489
- let isError = false;
5490
- if (!executor) {
5491
- result = `Unknown tool: ${tc.name}`;
5492
- isError = true;
5493
- } else {
5494
- try {
5495
- result = await executor(tc.args);
5496
- } catch (err) {
5497
- result = normalizeUnknownError(err).message;
5498
- isError = true;
5499
- }
5500
- }
5501
- toolResults.push({
5502
- toolCallId: tc.id,
5503
- toolName: tc.name,
5504
- result,
5505
- isError
5506
- });
5507
- yield {
5508
- type: "tool-result",
5509
- toolCallId: tc.id,
5510
- toolName: tc.name,
5511
- result,
5512
- isError
5513
- };
5514
- }
5515
- }
5516
- const stepMessages = buildCoreMessages(assistantText, thinkingBlocks, toolCalls, toolResults);
5517
- allNewMessages.push(...stepMessages);
5518
- if (stopReason !== "tool_use" || toolCalls.length === 0) {
5519
- break;
5520
- }
5521
- const assistantBlocks = [];
5522
- for (const tb of thinkingBlocks) {
5523
- if (tb.redacted) {
5524
- assistantBlocks.push({
5525
- type: "redacted_thinking",
5526
- data: tb.signature
5527
- });
5528
- } else if (tb.text.trim() && tb.signature.trim()) {
5529
- assistantBlocks.push({
5530
- type: "thinking",
5531
- thinking: tb.text,
5532
- signature: tb.signature
5533
- });
5534
- }
5535
- }
5536
- if (assistantText.trim()) {
5537
- assistantBlocks.push({ type: "text", text: assistantText });
5538
- }
5539
- for (const tc of toolCalls) {
5540
- assistantBlocks.push({
5541
- type: "tool_use",
5542
- id: tc.id,
5543
- name: tc.name,
5544
- input: tc.args
5545
- });
5546
- }
5547
- currentMessages.push({
5548
- role: "assistant",
5549
- content: assistantBlocks
5550
- });
5551
- const resultBlocks = toolResults.map((tr) => ({
5552
- type: "tool_result",
5553
- tool_use_id: tr.toolCallId,
5554
- content: typeof tr.result === "string" ? tr.result : JSON.stringify(tr.result ?? ""),
5555
- is_error: tr.isError
5556
- }));
5557
- currentMessages.push({ role: "user", content: resultBlocks });
5558
- }
5559
- logApiEvent("turn complete", {
5560
- newMessagesCount: allNewMessages.length,
5561
- inputTokens: totalInputTokens,
5562
- outputTokens: totalOutputTokens
5563
- });
5564
- yield {
5565
- type: "turn-complete",
5566
- inputTokens: totalInputTokens,
5567
- outputTokens: totalOutputTokens,
5568
- contextTokens,
5569
- messages: allNewMessages
5570
- };
5571
- } catch (err) {
5572
- const normalizedError = normalizeUnknownError(err);
5573
- logApiEvent("turn error", normalizedError);
5574
- yield {
5575
- type: "turn-error",
5576
- error: normalizedError,
5577
- partialMessages: allNewMessages
5578
- };
5579
- }
5580
- }
5581
-
5582
- // src/llm-api/turn-execution.ts
5583
- import { dynamicTool, jsonSchema } from "ai";
5584
-
5585
- // src/llm-api/turn-stream-events.ts
5586
- function shouldLogStreamChunk(c11) {
5587
- return c11.type !== "text-delta" && c11.type !== "reasoning" && c11.type !== "reasoning-delta";
5588
- }
5589
- function extractToolArgs(c11) {
5590
- return c11.input ?? c11.args;
5591
- }
5592
- function hasRenderableToolArgs(args) {
5593
- if (args === null || args === undefined)
5594
- return false;
5595
- if (typeof args === "string")
5596
- return args.trim().length > 0;
5597
- if (Array.isArray(args))
5598
- return args.length > 0;
5599
- if (typeof args === "object")
5600
- return Object.keys(args).length > 0;
5601
- return true;
5602
- }
5603
- function mapStreamChunkToTurnEvent(c11) {
5604
- switch (c11.type) {
5605
- case "text-delta": {
5606
- const delta = typeof c11.text === "string" ? c11.text : "";
5607
- return {
5608
- type: "text-delta",
5609
- delta
5610
- };
5611
- }
5612
- case "reasoning-delta":
5613
- case "reasoning": {
5614
- const delta = getReasoningDeltaFromStreamChunk(c11);
5615
- if (delta === null)
5616
- return null;
5617
- return {
5618
- type: "reasoning-delta",
5619
- delta
5620
- };
5621
- }
5622
- case "tool-input-start": {
5623
- const args = extractToolArgs(c11);
5624
- const hasStableToolCallId = typeof c11.toolCallId === "string" && c11.toolCallId.trim().length > 0;
5625
- if (hasStableToolCallId && !hasRenderableToolArgs(args))
5626
- return null;
5627
- return {
5628
- type: "tool-call-start",
5629
- toolCallId: String(c11.toolCallId ?? ""),
5630
- toolName: String(c11.toolName ?? ""),
5631
- args
5632
- };
5633
- }
5634
- case "tool-call": {
5635
- return {
5636
- type: "tool-call-start",
5637
- toolCallId: String(c11.toolCallId ?? ""),
5638
- toolName: String(c11.toolName ?? ""),
5639
- args: extractToolArgs(c11)
5640
- };
5641
- }
5642
- case "tool-result": {
5643
- return {
5644
- type: "tool-result",
5645
- toolCallId: String(c11.toolCallId ?? ""),
5646
- toolName: String(c11.toolName ?? ""),
5647
- result: "output" in c11 ? c11.output : ("result" in c11) ? c11.result : undefined,
5648
- isError: "isError" in c11 ? Boolean(c11.isError) : false
5649
- };
5650
- }
5651
- case "tool-error":
5652
- return {
5653
- type: "tool-result",
5654
- toolCallId: String(c11.toolCallId ?? ""),
5655
- toolName: String(c11.toolName ?? ""),
5656
- result: c11.error ?? "Tool execution failed",
5657
- isError: true
5658
- };
5659
- case "error": {
5660
- throw normalizeUnknownError(c11.error);
5661
- }
5662
- default:
5663
- return null;
5664
- }
5665
- }
5666
-
5667
- // src/llm-api/turn-execution.ts
5668
- function isZodSchema(s) {
5669
- return s !== null && typeof s === "object" && "_def" in s;
5670
- }
5671
- function toCoreTool(def) {
5672
- const schema = isZodSchema(def.schema) ? def.schema : jsonSchema(def.schema);
5673
- return dynamicTool({
5674
- description: def.description,
5675
- inputSchema: schema,
5676
- execute: async (input) => {
5677
- try {
5678
- return await def.execute(input);
5679
- } catch (err) {
5680
- throw normalizeUnknownError(err);
5681
- }
5682
- }
5683
- });
5684
- }
5685
- function buildToolSet(tools) {
5686
- const toolSet = {};
5687
- for (const def of tools) {
5688
- toolSet[def.name] = toCoreTool(def);
5689
- }
5690
- return toolSet;
5691
- }
5692
- function createTurnStepTracker(opts) {
5693
- let stepCount = 0;
5694
- let inputTokens = 0;
5695
- let outputTokens = 0;
5696
- let contextTokens = 0;
5697
- let partialMessages = [];
5698
- return {
5699
- onStepFinish: (step) => {
5700
- opts.onStepLog({
5701
- stepNumber: stepCount + 1,
5702
- finishReason: step.finishReason,
5703
- usage: step.usage
5704
- });
5705
- inputTokens += step.usage?.inputTokens ?? 0;
5706
- outputTokens += step.usage?.outputTokens ?? 0;
5707
- contextTokens = step.usage?.inputTokens ?? contextTokens;
5708
- stepCount += 1;
5709
- const s = step;
5710
- partialMessages = s.response?.messages ?? s.messages ?? partialMessages;
5711
- },
5712
- getState: () => ({
5713
- stepCount,
5714
- inputTokens,
5715
- outputTokens,
5716
- contextTokens,
5717
- partialMessages
5718
- })
5719
- };
5720
- }
5721
- var TOOL_RESULT_CHUNK_TYPES = new Set(["tool-result", "tool-error"]);
5722
- function normalizeToolCallId(raw) {
5723
- if (typeof raw !== "string")
5724
- return null;
5725
- const trimmed = raw.trim();
5726
- return trimmed ? trimmed : null;
5727
- }
5728
- function normalizeToolName(raw) {
5729
- if (typeof raw !== "string")
5730
- return "tool";
5731
- const trimmed = raw.trim();
5732
- return trimmed || "tool";
5733
- }
5734
- function isRecord6(value) {
5735
- return value !== null && typeof value === "object";
5736
- }
5737
- function normalizeTextPartId(raw) {
5738
- if (typeof raw !== "string")
5739
- return null;
5740
- const trimmed = raw.trim();
5741
- return trimmed ? trimmed : null;
5742
- }
5743
- function getOpenAITextPhase2(chunk) {
5744
- const providerData = isRecord6(chunk.providerMetadata) ? chunk.providerMetadata : isRecord6(chunk.providerOptions) ? chunk.providerOptions : null;
5745
- if (!providerData)
5746
- return null;
5747
- const openai = providerData.openai;
5748
- if (!isRecord6(openai))
5749
- return null;
5750
- return openai.phase === "commentary" || openai.phase === "final_answer" ? openai.phase : null;
5751
- }
5752
- function extractTextDelta(chunk) {
5753
- if (typeof chunk.text === "string")
5754
- return chunk.text;
5755
- if (typeof chunk.textDelta === "string")
5756
- return chunk.textDelta;
5757
- if (typeof chunk.delta === "string")
5758
- return chunk.delta;
5759
- return "";
4846
+ const trimmed = raw.trim();
4847
+ return trimmed ? trimmed : null;
4848
+ }
4849
+ function getOpenAITextPhase2(chunk) {
4850
+ const providerData = isRecord5(chunk.providerMetadata) ? chunk.providerMetadata : isRecord5(chunk.providerOptions) ? chunk.providerOptions : null;
4851
+ if (!providerData)
4852
+ return null;
4853
+ const openai = providerData.openai;
4854
+ if (!isRecord5(openai))
4855
+ return null;
4856
+ return openai.phase === "commentary" || openai.phase === "final_answer" ? openai.phase : null;
4857
+ }
4858
+ function extractTextDelta(chunk) {
4859
+ if (typeof chunk.text === "string")
4860
+ return chunk.text;
4861
+ if (typeof chunk.textDelta === "string")
4862
+ return chunk.textDelta;
4863
+ if (typeof chunk.delta === "string")
4864
+ return chunk.delta;
4865
+ return "";
5760
4866
  }
5761
4867
 
5762
4868
  class StreamTextPhaseTracker {
@@ -5857,84 +4963,376 @@ class StreamToolCallTracker {
5857
4963
  }
5858
4964
  return { chunk, suppressTurnEvent: false };
5859
4965
  }
5860
- trackRenderableStart(chunk, toolName, existingToolCallId) {
5861
- const toolCallId = existingToolCallId ?? this.nextSyntheticToolCallId();
5862
- this.trackStart(toolName, toolCallId);
5863
- if (toolCallId === chunk.toolCallId)
5864
- return chunk;
5865
- return { ...chunk, toolCallId };
4966
+ trackRenderableStart(chunk, toolName, existingToolCallId) {
4967
+ const toolCallId = existingToolCallId ?? this.nextSyntheticToolCallId();
4968
+ this.trackStart(toolName, toolCallId);
4969
+ if (toolCallId === chunk.toolCallId)
4970
+ return chunk;
4971
+ return { ...chunk, toolCallId };
4972
+ }
4973
+ nextSyntheticToolCallId() {
4974
+ this.syntheticCount += 1;
4975
+ return `synthetic-tool-call-${this.syntheticCount}`;
4976
+ }
4977
+ trackStart(toolName, toolCallId) {
4978
+ const pending = this.pendingByTool.get(toolName) ?? [];
4979
+ pending.push(toolCallId);
4980
+ this.pendingByTool.set(toolName, pending);
4981
+ }
4982
+ trackDeferredStart(toolName) {
4983
+ this.deferredStartsByTool.set(toolName, (this.deferredStartsByTool.get(toolName) ?? 0) + 1);
4984
+ }
4985
+ consumeDeferredStart(toolName) {
4986
+ const count = this.deferredStartsByTool.get(toolName) ?? 0;
4987
+ if (count <= 0)
4988
+ return;
4989
+ if (count === 1) {
4990
+ this.deferredStartsByTool.delete(toolName);
4991
+ return;
4992
+ }
4993
+ this.deferredStartsByTool.set(toolName, count - 1);
4994
+ }
4995
+ consumeTracked(toolName, toolCallId) {
4996
+ const pending = this.pendingByTool.get(toolName);
4997
+ if (!pending || pending.length === 0)
4998
+ return;
4999
+ const idx = pending.indexOf(toolCallId);
5000
+ if (idx === -1)
5001
+ return;
5002
+ pending.splice(idx, 1);
5003
+ if (pending.length === 0)
5004
+ this.pendingByTool.delete(toolName);
5005
+ }
5006
+ consumeNextTracked(toolName) {
5007
+ const pending = this.pendingByTool.get(toolName);
5008
+ if (!pending || pending.length === 0)
5009
+ return null;
5010
+ const toolCallId = pending.shift() ?? null;
5011
+ if (pending.length === 0)
5012
+ this.pendingByTool.delete(toolName);
5013
+ return toolCallId;
5014
+ }
5015
+ }
5016
+ async function* mapFullStreamToTurnEvents(stream, opts) {
5017
+ const toolCallTracker = new StreamToolCallTracker;
5018
+ const textPhaseTracker = new StreamTextPhaseTracker;
5019
+ for await (const originalChunk of stream) {
5020
+ const prepared = toolCallTracker.prepare(originalChunk);
5021
+ const chunk = prepared.chunk;
5022
+ const route = textPhaseTracker.route(chunk);
5023
+ if (!prepared.suppressTurnEvent && route !== "skip" && shouldLogStreamChunk(chunk)) {
5024
+ opts.onChunk?.(chunk);
5025
+ }
5026
+ if (prepared.suppressTurnEvent || route === "skip")
5027
+ continue;
5028
+ const event = route === "reasoning" ? mapCommentaryChunkToTurnEvent(chunk) : mapStreamChunkToTurnEvent(chunk);
5029
+ if (event)
5030
+ yield event;
5031
+ }
5032
+ }
5033
+
5034
+ // src/llm-api/turn-request.ts
5035
+ import { stepCountIs } from "ai";
5036
+
5037
+ // src/llm-api/provider-options.ts
5038
+ var ANTHROPIC_BUDGET = {
5039
+ low: 4096,
5040
+ medium: 8192,
5041
+ high: 16384,
5042
+ xhigh: 32768
5043
+ };
5044
+ var GEMINI_BUDGET = {
5045
+ low: 4096,
5046
+ medium: 8192,
5047
+ high: 16384,
5048
+ xhigh: 24575
5049
+ };
5050
+ function clampEffort(effort, max) {
5051
+ const ORDER = ["low", "medium", "high", "xhigh"];
5052
+ const effortIdx = ORDER.indexOf(effort);
5053
+ const maxIdx = ORDER.indexOf(max);
5054
+ return ORDER[Math.min(effortIdx, maxIdx)];
5055
+ }
5056
+ function getAnthropicThinkingOptions(modelId, effort) {
5057
+ const isAdaptive = /^claude-3-7/.test(modelId) || /^claude-sonnet-4/.test(modelId) || /^claude-opus-4/.test(modelId);
5058
+ if (isAdaptive) {
5059
+ const isOpus = /^claude-opus-4/.test(modelId);
5060
+ const mapped = effort === "xhigh" ? isOpus ? "max" : "high" : effort;
5061
+ return { anthropic: { thinking: { type: "adaptive" }, effort: mapped } };
5062
+ }
5063
+ return {
5064
+ anthropic: {
5065
+ thinking: { type: "enabled", budgetTokens: ANTHROPIC_BUDGET[effort] },
5066
+ betas: ["interleaved-thinking-2025-05-14"]
5067
+ }
5068
+ };
5069
+ }
5070
+ function getOpenAIThinkingOptions(modelId, effort) {
5071
+ const supportsXhigh = /^gpt-5\.[2-9]/.test(modelId) || /^o4/.test(modelId);
5072
+ const clamped = supportsXhigh ? effort : clampEffort(effort, "high");
5073
+ return { openai: { reasoningEffort: clamped, reasoningSummary: "auto" } };
5074
+ }
5075
+ function getGeminiThinkingOptions(modelId, effort) {
5076
+ if (/^gemini-3/.test(modelId)) {
5077
+ return {
5078
+ google: {
5079
+ thinkingConfig: {
5080
+ includeThoughts: true,
5081
+ thinkingLevel: clampEffort(effort, "high")
5082
+ }
5083
+ }
5084
+ };
5085
+ }
5086
+ return {
5087
+ google: {
5088
+ thinkingConfig: {
5089
+ includeThoughts: true,
5090
+ thinkingBudget: GEMINI_BUDGET[effort]
5091
+ }
5092
+ }
5093
+ };
5094
+ }
5095
+ var THINKING_STRATEGIES = [
5096
+ {
5097
+ supports: isAnthropicModelFamily,
5098
+ build: getAnthropicThinkingOptions
5099
+ },
5100
+ {
5101
+ supports: isOpenAIReasoningModelFamily,
5102
+ build: getOpenAIThinkingOptions
5103
+ },
5104
+ {
5105
+ supports: isGeminiModelFamily,
5106
+ build: getGeminiThinkingOptions
5107
+ }
5108
+ ];
5109
+ function getThinkingProviderOptions(modelString, effort) {
5110
+ if (!supportsThinking(modelString))
5111
+ return null;
5112
+ const { modelId } = parseModelString(modelString);
5113
+ for (const strategy of THINKING_STRATEGIES) {
5114
+ if (!strategy.supports(modelString))
5115
+ continue;
5116
+ return strategy.build(modelId, effort);
5117
+ }
5118
+ return null;
5119
+ }
5120
+ var CACHE_FAMILY_RULES = [
5121
+ [isAnthropicModelFamily, "anthropic"],
5122
+ [isGeminiModelFamily, "google"]
5123
+ ];
5124
+ function getCacheFamily(modelString) {
5125
+ for (const [match, family] of CACHE_FAMILY_RULES) {
5126
+ if (match(modelString))
5127
+ return family;
5128
+ }
5129
+ return "none";
5130
+ }
5131
+ function getCachingProviderOptions(modelString, opts) {
5132
+ if (!opts.enabled)
5133
+ return null;
5134
+ const family = getCacheFamily(modelString);
5135
+ if (family === "google" && opts.googleCachedContent && opts.googleExplicitCachingCompatible !== false) {
5136
+ return { google: { cachedContent: opts.googleCachedContent } };
5137
+ }
5138
+ return null;
5139
+ }
5140
+
5141
+ // src/llm-api/turn-prepare-messages.ts
5142
+ function prepareTurnMessages(input) {
5143
+ const {
5144
+ messages,
5145
+ modelString,
5146
+ toolCount,
5147
+ systemPrompt,
5148
+ pruningMode,
5149
+ toolResultPayloadCapBytes,
5150
+ promptCachingEnabled
5151
+ } = input;
5152
+ const apiLogOn = isApiLogEnabled();
5153
+ const strippedRuntimeToolFields = stripToolRuntimeInputFields(messages);
5154
+ if (strippedRuntimeToolFields !== messages && apiLogOn) {
5155
+ logApiEvent("runtime tool input fields stripped", { modelString });
5156
+ }
5157
+ const geminiResult = sanitizeGeminiToolMessagesWithMetadata(strippedRuntimeToolFields, modelString, toolCount > 0);
5158
+ if (geminiResult.repaired && apiLogOn) {
5159
+ logApiEvent("gemini tool history repaired", {
5160
+ modelString,
5161
+ reason: geminiResult.reason,
5162
+ repairedFromIndex: geminiResult.repairedFromIndex,
5163
+ droppedMessageCount: geminiResult.droppedMessageCount,
5164
+ tailOnlyAffected: geminiResult.tailOnlyAffected
5165
+ });
5866
5166
  }
5867
- nextSyntheticToolCallId() {
5868
- this.syntheticCount += 1;
5869
- return `synthetic-tool-call-${this.syntheticCount}`;
5167
+ const openaiStripped = stripOpenAIHistoryTransforms(geminiResult.messages, modelString);
5168
+ if (openaiStripped !== geminiResult.messages && apiLogOn) {
5169
+ logApiEvent("openai history transforms applied", { modelString });
5870
5170
  }
5871
- trackStart(toolName, toolCallId) {
5872
- const pending = this.pendingByTool.get(toolName) ?? [];
5873
- pending.push(toolCallId);
5874
- this.pendingByTool.set(toolName, pending);
5171
+ const normalised = normalizeOpenAICompatibleToolCallInputs(openaiStripped, modelString);
5172
+ if (normalised !== openaiStripped && apiLogOn) {
5173
+ logApiEvent("openai-compatible tool input normalized", { modelString });
5875
5174
  }
5876
- trackDeferredStart(toolName) {
5877
- this.deferredStartsByTool.set(toolName, (this.deferredStartsByTool.get(toolName) ?? 0) + 1);
5175
+ const preStats = apiLogOn ? getMessageDiagnostics(normalised) : getMessageStats(normalised);
5176
+ if (apiLogOn)
5177
+ logApiEvent("turn context pre-prune", preStats);
5178
+ const pruned = applyContextPruning(normalised, pruningMode);
5179
+ const postStats = apiLogOn ? getMessageDiagnostics(pruned) : getMessageStats(pruned);
5180
+ if (apiLogOn)
5181
+ logApiEvent("turn context post-prune", postStats);
5182
+ const compacted = compactToolResultPayloads(pruned, toolResultPayloadCapBytes);
5183
+ if (compacted !== pruned && apiLogOn) {
5184
+ logApiEvent("turn context post-compaction", {
5185
+ capBytes: toolResultPayloadCapBytes,
5186
+ diagnostics: getMessageDiagnostics(compacted)
5187
+ });
5878
5188
  }
5879
- consumeDeferredStart(toolName) {
5880
- const count = this.deferredStartsByTool.get(toolName) ?? 0;
5881
- if (count <= 0)
5882
- return;
5883
- if (count === 1) {
5884
- this.deferredStartsByTool.delete(toolName);
5885
- return;
5189
+ let finalMessages = compacted;
5190
+ let finalSystemPrompt = systemPrompt;
5191
+ const cacheFamily = getCacheFamily(modelString);
5192
+ if (cacheFamily === "anthropic" && promptCachingEnabled) {
5193
+ const annotated = annotateAnthropicCacheBreakpoints(compacted, systemPrompt);
5194
+ finalMessages = annotated.messages;
5195
+ finalSystemPrompt = annotated.systemPrompt;
5196
+ if (apiLogOn) {
5197
+ logApiEvent("Anthropic prompt caching", annotated.diagnostics);
5886
5198
  }
5887
- this.deferredStartsByTool.set(toolName, count - 1);
5888
- }
5889
- consumeTracked(toolName, toolCallId) {
5890
- const pending = this.pendingByTool.get(toolName);
5891
- if (!pending || pending.length === 0)
5892
- return;
5893
- const idx = pending.indexOf(toolCallId);
5894
- if (idx === -1)
5895
- return;
5896
- pending.splice(idx, 1);
5897
- if (pending.length === 0)
5898
- this.pendingByTool.delete(toolName);
5899
5199
  }
5900
- consumeNextTracked(toolName) {
5901
- const pending = this.pendingByTool.get(toolName);
5902
- if (!pending || pending.length === 0)
5903
- return null;
5904
- const toolCallId = pending.shift() ?? null;
5905
- if (pending.length === 0)
5906
- this.pendingByTool.delete(toolName);
5907
- return toolCallId;
5200
+ if (isAnthropicModelFamily(modelString) && isAnthropicOAuth()) {
5201
+ const ccIdentity = "You are Claude Code, Anthropic's official CLI for Claude.";
5202
+ const ccSystemMsg = {
5203
+ role: "system",
5204
+ content: ccIdentity,
5205
+ providerOptions: {
5206
+ anthropic: { cacheControl: { type: "ephemeral" } }
5207
+ }
5208
+ };
5209
+ if (finalSystemPrompt) {
5210
+ finalMessages = [ccSystemMsg, ...finalMessages];
5211
+ } else {
5212
+ const sysIdx = finalMessages.findIndex((m) => m.role === "system");
5213
+ if (sysIdx >= 0) {
5214
+ finalMessages = [
5215
+ ...finalMessages.slice(0, sysIdx),
5216
+ ccSystemMsg,
5217
+ ...finalMessages.slice(sysIdx)
5218
+ ];
5219
+ } else {
5220
+ finalMessages = [ccSystemMsg, ...finalMessages];
5221
+ }
5222
+ }
5908
5223
  }
5224
+ const wasPruned = (pruningMode === "balanced" || pruningMode === "aggressive") && (postStats.messageCount < preStats.messageCount || postStats.totalBytes < preStats.totalBytes);
5225
+ return {
5226
+ messages: finalMessages,
5227
+ systemPrompt: finalSystemPrompt,
5228
+ pruned: wasPruned,
5229
+ prePruneMessageCount: preStats.messageCount,
5230
+ prePruneTotalBytes: preStats.totalBytes,
5231
+ postPruneMessageCount: postStats.messageCount,
5232
+ postPruneTotalBytes: postStats.totalBytes
5233
+ };
5909
5234
  }
5910
- async function* mapFullStreamToTurnEvents(stream, opts) {
5911
- const toolCallTracker = new StreamToolCallTracker;
5912
- const textPhaseTracker = new StreamTextPhaseTracker;
5913
- for await (const originalChunk of stream) {
5914
- const prepared = toolCallTracker.prepare(originalChunk);
5915
- const chunk = prepared.chunk;
5916
- const route = textPhaseTracker.route(chunk);
5917
- if (!prepared.suppressTurnEvent && route !== "skip" && shouldLogStreamChunk(chunk)) {
5918
- opts.onChunk?.(chunk);
5919
- }
5920
- if (prepared.suppressTurnEvent || route === "skip")
5921
- continue;
5922
- const event = route === "reasoning" ? mapCommentaryChunkToTurnEvent(chunk) : mapStreamChunkToTurnEvent(chunk);
5923
- if (event)
5924
- yield event;
5235
+
5236
+ // src/llm-api/turn-provider-options.ts
5237
+ function isRecord6(value) {
5238
+ return value !== null && typeof value === "object";
5239
+ }
5240
+ function mergeDeep(target, source) {
5241
+ const output = { ...target };
5242
+ for (const key in source) {
5243
+ const sVal = source[key];
5244
+ const tVal = target[key];
5245
+ output[key] = isRecord6(sVal) && isRecord6(tVal) ? { ...tVal, ...sVal } : sVal;
5925
5246
  }
5247
+ return output;
5248
+ }
5249
+ function buildTurnProviderOptions(input) {
5250
+ const {
5251
+ modelString,
5252
+ thinkingEffort,
5253
+ promptCachingEnabled,
5254
+ openaiPromptCacheRetention,
5255
+ googleCachedContent,
5256
+ toolCount,
5257
+ hasSystemPrompt
5258
+ } = input;
5259
+ const thinkingOpts = thinkingEffort ? getThinkingProviderOptions(modelString, thinkingEffort) : null;
5260
+ const reasoningSummaryRequested = isRecord6(thinkingOpts) && isRecord6(thinkingOpts.openai) && typeof thinkingOpts.openai.reasoningSummary === "string";
5261
+ const cacheFamily = getCacheFamily(modelString);
5262
+ const cacheOpts = getCachingProviderOptions(modelString, {
5263
+ enabled: promptCachingEnabled,
5264
+ openaiRetention: openaiPromptCacheRetention,
5265
+ googleCachedContent,
5266
+ googleExplicitCachingCompatible: toolCount === 0 && !hasSystemPrompt
5267
+ });
5268
+ const baseProviderOpts = {
5269
+ ...thinkingOpts ?? {},
5270
+ ...isOpenAIGPT(modelString) ? {
5271
+ openai: {
5272
+ store: false,
5273
+ ...isRecord6(thinkingOpts?.openai) ? thinkingOpts.openai : {}
5274
+ }
5275
+ } : {}
5276
+ };
5277
+ const providerOptions = cacheOpts ? mergeDeep(baseProviderOpts, cacheOpts) : baseProviderOpts;
5278
+ return {
5279
+ cacheFamily,
5280
+ thinkingOpts,
5281
+ cacheOpts,
5282
+ providerOptions,
5283
+ reasoningSummaryRequested
5284
+ };
5285
+ }
5286
+
5287
+ // src/llm-api/turn-request.ts
5288
+ function buildTurnPreparation(input) {
5289
+ const providerOptionsResult = buildTurnProviderOptions({
5290
+ modelString: input.modelString,
5291
+ thinkingEffort: input.thinkingEffort,
5292
+ promptCachingEnabled: input.promptCachingEnabled,
5293
+ openaiPromptCacheRetention: input.openaiPromptCacheRetention,
5294
+ googleCachedContent: input.googleCachedContent,
5295
+ toolCount: input.toolCount,
5296
+ hasSystemPrompt: Boolean(input.systemPrompt)
5297
+ });
5298
+ const prepared = prepareTurnMessages({
5299
+ messages: input.messages,
5300
+ modelString: input.modelString,
5301
+ toolCount: input.toolCount,
5302
+ systemPrompt: input.systemPrompt,
5303
+ pruningMode: input.pruningMode,
5304
+ toolResultPayloadCapBytes: input.toolResultPayloadCapBytes,
5305
+ promptCachingEnabled: input.promptCachingEnabled
5306
+ });
5307
+ return { providerOptionsResult, prepared };
5308
+ }
5309
+ function buildStreamTextRequest(input) {
5310
+ return {
5311
+ model: input.model,
5312
+ maxOutputTokens: 16384,
5313
+ messages: input.prepared.messages,
5314
+ tools: input.toolSet,
5315
+ stopWhen: stepCountIs(input.maxSteps),
5316
+ onStepFinish: input.onStepFinish,
5317
+ prepareStep: ({ stepNumber }) => {
5318
+ if (stepNumber >= input.maxSteps - 1) {
5319
+ return { activeTools: [] };
5320
+ }
5321
+ return;
5322
+ },
5323
+ ...input.prepared.systemPrompt ? { system: input.prepared.systemPrompt } : {},
5324
+ ...Object.keys(input.providerOptions).length > 0 ? {
5325
+ providerOptions: input.providerOptions
5326
+ } : {},
5327
+ ...input.signal ? { abortSignal: input.signal } : {},
5328
+ onError: () => {},
5329
+ timeout: { chunkMs: 120000 }
5330
+ };
5926
5331
  }
5927
5332
 
5928
5333
  // src/llm-api/turn.ts
5929
- var MAX_STEPS2 = 50;
5334
+ var MAX_STEPS = 50;
5930
5335
  async function* runTurn(options) {
5931
- if (options.modelString.startsWith("anthropic/") && isLoggedIn("anthropic")) {
5932
- const token = await getAccessToken("anthropic");
5933
- if (token) {
5934
- yield* runTurnAnthropicOAuth({ ...options, token });
5935
- return;
5936
- }
5937
- }
5938
5336
  const {
5939
5337
  model,
5940
5338
  modelString,
@@ -6006,7 +5404,7 @@ async function* runTurn(options) {
6006
5404
  onStepFinish: stepTracker.onStepFinish,
6007
5405
  signal,
6008
5406
  providerOptions: providerOptionsResult.providerOptions,
6009
- maxSteps: MAX_STEPS2
5407
+ maxSteps: MAX_STEPS
6010
5408
  }));
6011
5409
  result.response.catch(() => {});
6012
5410
  for await (const event of mapFullStreamToTurnEvents(result.fullStream, {
@@ -6049,7 +5447,7 @@ async function* runTurn(options) {
6049
5447
  }
6050
5448
 
6051
5449
  // src/session/manager.ts
6052
- import * as c11 from "yoctocolors";
5450
+ import * as c10 from "yoctocolors";
6053
5451
  function newSession(model, cwd) {
6054
5452
  const id = generateSessionId();
6055
5453
  const row = createSession({ id, cwd, model });
@@ -6068,19 +5466,19 @@ function touchActiveSession(session) {
6068
5466
  function printSessionList() {
6069
5467
  const sessions = listSessions(20);
6070
5468
  if (sessions.length === 0) {
6071
- writeln2(c11.dim("No sessions found."));
5469
+ writeln(c10.dim("No sessions found."));
6072
5470
  return;
6073
5471
  }
6074
- writeln2(`
6075
- ${c11.bold("Recent sessions:")}`);
5472
+ writeln(`
5473
+ ${c10.bold("Recent sessions:")}`);
6076
5474
  for (const s of sessions) {
6077
5475
  const date = new Date(s.updated_at).toLocaleString();
6078
5476
  const cwd = tildePath(s.cwd);
6079
- const title = s.title || c11.dim("(untitled)");
6080
- writeln2(` ${c11.dim(s.id.padEnd(14))} ${title.padEnd(30)} ${c11.cyan(s.model.split("/").pop() ?? s.model).padEnd(20)} ${c11.dim(cwd)} ${c11.dim(date)}`);
5477
+ const title = s.title || c10.dim("(untitled)");
5478
+ writeln(` ${c10.dim(s.id.padEnd(14))} ${title.padEnd(30)} ${c10.cyan(s.model.split("/").pop() ?? s.model).padEnd(20)} ${c10.dim(cwd)} ${c10.dim(date)}`);
6081
5479
  }
6082
- writeln2(`
6083
- ${c11.dim("Use")} mc --resume <id> ${c11.dim("to continue a session.")}`);
5480
+ writeln(`
5481
+ ${c10.dim("Use")} mc --resume <id> ${c10.dim("to continue a session.")}`);
6084
5482
  }
6085
5483
  function getMostRecentSession() {
6086
5484
  const sessions = listSessions(1);
@@ -6310,7 +5708,7 @@ class SessionRunner {
6310
5708
  }
6311
5709
  this.session = resumed;
6312
5710
  this.currentModel = this.session.model;
6313
- this.reporter.info(`Resumed session ${this.session.id} (${c12.cyan(this.currentModel)})`);
5711
+ this.reporter.info(`Resumed session ${this.session.id} (${c11.cyan(this.currentModel)})`);
6314
5712
  } else {
6315
5713
  this.session = newSession(this.currentModel, this.cwd);
6316
5714
  }
@@ -6774,13 +6172,12 @@ ${input.command}`], {
6774
6172
  reader.cancel().catch(() => {});
6775
6173
  }
6776
6174
  }, timeout);
6777
- async function collectStream(stream, onChunk) {
6175
+ async function collectStream(stream) {
6778
6176
  const reader = stream.getReader();
6779
6177
  readers.push(reader);
6780
6178
  const chunks = [];
6781
6179
  let totalBytes = 0;
6782
6180
  let truncated = false;
6783
- const decoder = new TextDecoder;
6784
6181
  while (true) {
6785
6182
  try {
6786
6183
  const { done, value } = await reader.read();
@@ -6788,7 +6185,6 @@ ${input.command}`], {
6788
6185
  break;
6789
6186
  if (!value)
6790
6187
  continue;
6791
- onChunk?.(decoder.decode(value, { stream: true }));
6792
6188
  if (totalBytes + value.length > MAX_OUTPUT_BYTES) {
6793
6189
  chunks.push(value.slice(0, MAX_OUTPUT_BYTES - totalBytes));
6794
6190
  truncated = true;
@@ -6808,28 +6204,11 @@ ${input.command}`], {
6808
6204
  let stdout = "";
6809
6205
  let stderr = "";
6810
6206
  let exitCode = 1;
6811
- const onOutput = input.onOutput;
6812
- const hasOutputHandler = typeof onOutput === "function";
6813
- let streamedAnyOutput = false;
6814
- let streamedEndsWithNewline = true;
6815
- const emitOutput = (chunk) => {
6816
- if (!chunk || !hasOutputHandler)
6817
- return;
6818
- const handled = onOutput(chunk);
6819
- if (handled === false)
6820
- return;
6821
- streamedAnyOutput = true;
6822
- streamedEndsWithNewline = /[\r\n]$/.test(chunk);
6823
- };
6824
6207
  try {
6825
6208
  [stdout, stderr] = await Promise.all([
6826
- collectStream(proc.stdout, hasOutputHandler ? emitOutput : undefined),
6827
- collectStream(proc.stderr, hasOutputHandler ? emitOutput : undefined)
6209
+ collectStream(proc.stdout),
6210
+ collectStream(proc.stderr)
6828
6211
  ]);
6829
- if (streamedAnyOutput && !streamedEndsWithNewline) {
6830
- emitOutput(`
6831
- `);
6832
- }
6833
6212
  exitCode = await proc.exited;
6834
6213
  } finally {
6835
6214
  clearTimeout(timer);
@@ -6845,8 +6224,7 @@ ${input.command}`], {
6845
6224
  stderr: stderr.trimEnd(),
6846
6225
  exitCode,
6847
6226
  success: exitCode === 0,
6848
- timedOut,
6849
- streamedOutput: streamedAnyOutput
6227
+ timedOut
6850
6228
  };
6851
6229
  }
6852
6230
  var shellTool = {
@@ -6919,22 +6297,9 @@ function withCwdDefault(tool, cwd) {
6919
6297
  }
6920
6298
  };
6921
6299
  }
6922
- function withShellOutput(tool, onOutput) {
6923
- const originalExecute = tool.execute;
6924
- return {
6925
- ...tool,
6926
- execute: async (input) => {
6927
- const patched = {
6928
- ...typeof input === "object" && input !== null ? input : {},
6929
- onOutput
6930
- };
6931
- return originalExecute(patched);
6932
- }
6933
- };
6934
- }
6935
6300
  function buildToolSet2(opts) {
6936
- const { cwd, onShellOutput } = opts;
6937
- const shell = onShellOutput ? withShellOutput(withCwdDefault(shellTool, cwd), onShellOutput) : withCwdDefault(shellTool, cwd);
6301
+ const { cwd } = opts;
6302
+ const shell = withCwdDefault(shellTool, cwd);
6938
6303
  const tools = [
6939
6304
  shell,
6940
6305
  withCwdDefault(listSkillsTool, cwd),
@@ -6963,17 +6328,10 @@ async function initAgent(opts) {
6963
6328
  const cwd = opts.cwd;
6964
6329
  let currentModel = opts.model;
6965
6330
  const { runSubagent, killAll } = createSubagentRunner(cwd, () => currentModel);
6966
- let verboseOutputEnabled = opts.initialVerboseOutput;
6967
6331
  const agents = loadAgents(cwd);
6968
6332
  const tools = buildToolSet2({
6969
6333
  cwd,
6970
6334
  runSubagent,
6971
- onShellOutput: (chunk) => {
6972
- if (!verboseOutputEnabled)
6973
- return false;
6974
- opts.reporter.streamChunk(chunk);
6975
- return true;
6976
- },
6977
6335
  availableAgents: subagentAgents(agents)
6978
6336
  });
6979
6337
  const mcpTools = [];
@@ -6997,7 +6355,7 @@ async function initAgent(opts) {
6997
6355
  for (const row of listMcpServers()) {
6998
6356
  try {
6999
6357
  await connectAndAddMcp(row.name);
7000
- opts.reporter.info(`MCP: connected ${c13.cyan(row.name)}`);
6358
+ opts.reporter.info(`MCP: connected ${c12.cyan(row.name)}`);
7001
6359
  } catch (e) {
7002
6360
  opts.reporter.error(`MCP: failed to connect ${row.name}: ${String(e)}`);
7003
6361
  }
@@ -7062,7 +6420,6 @@ async function initAgent(opts) {
7062
6420
  },
7063
6421
  setVerboseOutput: (verbose) => {
7064
6422
  runner.verboseOutput = verbose;
7065
- verboseOutputEnabled = verbose;
7066
6423
  setPreferredVerboseOutput(verbose);
7067
6424
  },
7068
6425
  get pruningMode() {
@@ -7120,7 +6477,7 @@ async function initAgent(opts) {
7120
6477
  }
7121
6478
 
7122
6479
  // src/cli/args.ts
7123
- import * as c14 from "yoctocolors";
6480
+ import * as c13 from "yoctocolors";
7124
6481
  function parseArgs(argv) {
7125
6482
  const args = {
7126
6483
  model: null,
@@ -7184,11 +6541,11 @@ function parseArgs(argv) {
7184
6541
  return args;
7185
6542
  }
7186
6543
  function printHelp() {
7187
- writeln2(`${c14.bold("mini-coder")} \u2014 a small, fast CLI coding agent
6544
+ writeln(`${c13.bold("mini-coder")} \u2014 a small, fast CLI coding agent
7188
6545
  `);
7189
- writeln2(`${c14.bold("Usage:")} mc [options] [prompt]
6546
+ writeln(`${c13.bold("Usage:")} mc [options] [prompt]
7190
6547
  `);
7191
- writeln2(`${c14.bold("Options:")}`);
6548
+ writeln(`${c13.bold("Options:")}`);
7192
6549
  const opts = [
7193
6550
  ["-m, --model <id>", "Model to use (e.g. zen/claude-sonnet-4-6)"],
7194
6551
  ["-c, --continue", "Continue the most recent session"],
@@ -7198,10 +6555,10 @@ function printHelp() {
7198
6555
  ["-h, --help", "Show this help"]
7199
6556
  ];
7200
6557
  for (const [flag, desc] of opts) {
7201
- writeln2(` ${c14.cyan((flag ?? "").padEnd(22))} ${c14.dim(desc ?? "")}`);
6558
+ writeln(` ${c13.cyan((flag ?? "").padEnd(22))} ${c13.dim(desc ?? "")}`);
7202
6559
  }
7203
- writeln2(`
7204
- ${c14.bold("Provider env vars:")}`);
6560
+ writeln(`
6561
+ ${c13.bold("Provider env vars:")}`);
7205
6562
  const envs = [
7206
6563
  ["OPENCODE_API_KEY", "OpenCode Zen (recommended)"],
7207
6564
  ["ANTHROPIC_API_KEY", "Anthropic direct"],
@@ -7212,22 +6569,22 @@ ${c14.bold("Provider env vars:")}`);
7212
6569
  ["OLLAMA_BASE_URL", "Ollama base URL (default: http://localhost:11434)"]
7213
6570
  ];
7214
6571
  for (const [env, desc] of envs) {
7215
- writeln2(` ${c14.yellow((env ?? "").padEnd(22))} ${c14.dim(desc ?? "")}`);
6572
+ writeln(` ${c13.yellow((env ?? "").padEnd(22))} ${c13.dim(desc ?? "")}`);
7216
6573
  }
7217
- writeln2(`
7218
- ${c14.bold("Examples:")}`);
7219
- writeln2(` mc ${c14.dim("# interactive session")}`);
7220
- writeln2(` mc "explain this codebase" ${c14.dim("# one-shot prompt then exit")}`);
7221
- writeln2(` mc -c ${c14.dim("# continue last session")}`);
7222
- writeln2(` mc -m ollama/llama3.2 ${c14.dim("# use local Ollama model")}`);
7223
- writeln2(` mc -l ${c14.dim("# list sessions")}`);
6574
+ writeln(`
6575
+ ${c13.bold("Examples:")}`);
6576
+ writeln(` mc ${c13.dim("# interactive session")}`);
6577
+ writeln(` mc "explain this codebase" ${c13.dim("# one-shot prompt then exit")}`);
6578
+ writeln(` mc -c ${c13.dim("# continue last session")}`);
6579
+ writeln(` mc -m ollama/llama3.2 ${c13.dim("# use local Ollama model")}`);
6580
+ writeln(` mc -l ${c13.dim("# list sessions")}`);
7224
6581
  }
7225
6582
 
7226
6583
  // src/cli/bootstrap.ts
7227
6584
  import { existsSync as existsSync8, mkdirSync as mkdirSync4, writeFileSync as writeFileSync3 } from "fs";
7228
6585
  import { homedir as homedir8 } from "os";
7229
6586
  import { join as join12 } from "path";
7230
- import * as c15 from "yoctocolors";
6587
+ import * as c14 from "yoctocolors";
7231
6588
  var REVIEW_COMMAND_CONTENT = `---
7232
6589
  description: Review recent changes for correctness, code quality, and performance
7233
6590
  context: fork
@@ -7251,7 +6608,7 @@ function bootstrapGlobalDefaults() {
7251
6608
  if (!existsSync8(reviewPath)) {
7252
6609
  mkdirSync4(commandsDir, { recursive: true });
7253
6610
  writeFileSync3(reviewPath, REVIEW_COMMAND_CONTENT, "utf-8");
7254
- writeln2(`${c15.green("\u2713")} created ${c15.dim("~/.agents/commands/review.md")} ${c15.dim("(edit it to customise your reviews)")}`);
6611
+ writeln(`${c14.green("\u2713")} created ${c14.dim("~/.agents/commands/review.md")} ${c14.dim("(edit it to customise your reviews)")}`);
7255
6612
  }
7256
6613
  }
7257
6614
 
@@ -7316,7 +6673,6 @@ class HeadlessReporter {
7316
6673
  error(_msg, _hint) {}
7317
6674
  warn(_msg) {}
7318
6675
  writeText(_text) {}
7319
- streamChunk(_text) {}
7320
6676
  startSpinner(_label) {}
7321
6677
  stopSpinner() {}
7322
6678
  async renderTurn(events, _opts) {
@@ -7366,7 +6722,7 @@ class HeadlessReporter {
7366
6722
  }
7367
6723
 
7368
6724
  // src/cli/input-loop.ts
7369
- import * as c23 from "yoctocolors";
6725
+ import * as c22 from "yoctocolors";
7370
6726
 
7371
6727
  // src/cli/cli-helpers.ts
7372
6728
  async function getGitBranch(cwd) {
@@ -7387,67 +6743,67 @@ async function getGitBranch(cwd) {
7387
6743
  }
7388
6744
 
7389
6745
  // src/cli/commands.ts
7390
- import * as c22 from "yoctocolors";
6746
+ import * as c21 from "yoctocolors";
7391
6747
 
7392
6748
  // src/cli/commands-agent.ts
7393
- import * as c16 from "yoctocolors";
6749
+ import * as c15 from "yoctocolors";
7394
6750
  function handleAgentCommand(ctx, args) {
7395
6751
  const raw = args.trim();
7396
6752
  const agents = loadAgents(ctx.cwd);
7397
6753
  if (!raw) {
7398
6754
  if (agents.size === 0) {
7399
- writeln2(c16.dim(" no agents found (~/.agents/agents/ or .agents/agents/)"));
7400
- writeln2(c16.dim(" /agent <name> to activate \xB7 /agent off to deactivate"));
6755
+ writeln(c15.dim(" no agents found (~/.agents/agents/ or .agents/agents/)"));
6756
+ writeln(c15.dim(" /agent <name> to activate \xB7 /agent off to deactivate"));
7401
6757
  return;
7402
6758
  }
7403
- writeln2();
7404
- writeln2(c16.dim(" agents:"));
6759
+ writeln();
6760
+ writeln(c15.dim(" agents:"));
7405
6761
  for (const agent2 of agents.values()) {
7406
- const modeTag = agent2.mode ? c16.dim(` [${agent2.mode}]`) : "";
7407
- const srcTag = agent2.source === "local" ? c16.dim(" (local)") : c16.dim(" (global)");
7408
- const active = ctx.activeAgent === agent2.name ? c16.cyan(" \u25C0 active") : "";
7409
- writeln2(` ${c16.magenta(`@${agent2.name}`.padEnd(26))} ${c16.dim(agent2.description)}${modeTag}${srcTag}${active}`);
7410
- }
7411
- writeln2();
7412
- writeln2(c16.dim(" /agent <name> to activate \xB7 /agent off to deactivate"));
7413
- writeln2();
6762
+ const modeTag = agent2.mode ? c15.dim(` [${agent2.mode}]`) : "";
6763
+ const srcTag = agent2.source === "local" ? c15.dim(" (local)") : c15.dim(" (global)");
6764
+ const active = ctx.activeAgent === agent2.name ? c15.cyan(" \u25C0 active") : "";
6765
+ writeln(` ${c15.magenta(`@${agent2.name}`.padEnd(26))} ${c15.dim(agent2.description)}${modeTag}${srcTag}${active}`);
6766
+ }
6767
+ writeln();
6768
+ writeln(c15.dim(" /agent <name> to activate \xB7 /agent off to deactivate"));
6769
+ writeln();
7414
6770
  return;
7415
6771
  }
7416
6772
  if (raw.toLowerCase() === "off" || raw.toLowerCase() === "none") {
7417
6773
  ctx.setActiveAgent(null);
7418
- writeln2(`${PREFIX.info} ${c16.dim("active agent cleared")}`);
6774
+ writeln(`${PREFIX.info} ${c15.dim("active agent cleared")}`);
7419
6775
  return;
7420
6776
  }
7421
6777
  const agent = agents.get(raw);
7422
6778
  if (!agent) {
7423
- writeln2(`${PREFIX.error} agent ${c16.cyan(raw)} not found`);
6779
+ writeln(`${PREFIX.error} agent ${c15.cyan(raw)} not found`);
7424
6780
  return;
7425
6781
  }
7426
6782
  ctx.setActiveAgent(raw, agent.systemPrompt);
7427
- writeln2(`${PREFIX.success} active agent \u2192 ${c16.cyan(raw)} ${c16.dim("(instructions appended to system prompt)")}`);
6783
+ writeln(`${PREFIX.success} active agent \u2192 ${c15.cyan(raw)} ${c15.dim("(instructions appended to system prompt)")}`);
7428
6784
  }
7429
6785
 
7430
6786
  // src/cli/commands-config.ts
7431
- import * as c17 from "yoctocolors";
6787
+ import * as c16 from "yoctocolors";
7432
6788
  function handleBooleanToggleCommand(opts) {
7433
6789
  const mode = opts.args.trim().toLowerCase();
7434
6790
  if (!mode) {
7435
6791
  const nextValue = !opts.current;
7436
6792
  opts.set(nextValue);
7437
- writeln2(`${PREFIX.success} ${opts.label} ${nextValue ? c17.green("on") : c17.dim("off")}`);
6793
+ writeln(`${PREFIX.success} ${opts.label} ${nextValue ? c16.green("on") : c16.dim("off")}`);
7438
6794
  return;
7439
6795
  }
7440
6796
  if (mode === "on") {
7441
6797
  opts.set(true);
7442
- writeln2(`${PREFIX.success} ${opts.label} ${c17.green("on")}`);
6798
+ writeln(`${PREFIX.success} ${opts.label} ${c16.green("on")}`);
7443
6799
  return;
7444
6800
  }
7445
6801
  if (mode === "off") {
7446
6802
  opts.set(false);
7447
- writeln2(`${PREFIX.success} ${opts.label} ${c17.dim("off")}`);
6803
+ writeln(`${PREFIX.success} ${opts.label} ${c16.dim("off")}`);
7448
6804
  return;
7449
6805
  }
7450
- writeln2(`${PREFIX.error} usage: ${opts.usage}`);
6806
+ writeln(`${PREFIX.error} usage: ${opts.usage}`);
7451
6807
  }
7452
6808
  function handleReasoningCommand(ctx, args) {
7453
6809
  handleBooleanToggleCommand({
@@ -7471,105 +6827,105 @@ function handleContextCommand(ctx, args) {
7471
6827
  const [subcommand, value] = args.trim().split(/\s+/, 2);
7472
6828
  if (!subcommand) {
7473
6829
  const capText = ctx.toolResultPayloadCapBytes <= 0 ? "off" : `${Math.round(ctx.toolResultPayloadCapBytes / 1024)}KB (${ctx.toolResultPayloadCapBytes} bytes)`;
7474
- writeln2(`${PREFIX.info} pruning=${c17.cyan(ctx.pruningMode)} tool-result-cap=${c17.cyan(capText)}`);
7475
- writeln2(c17.dim(" usage: /context prune <off|balanced|aggressive>"));
7476
- writeln2(c17.dim(" /context cap <off|bytes|kb>"));
6830
+ writeln(`${PREFIX.info} pruning=${c16.cyan(ctx.pruningMode)} tool-result-cap=${c16.cyan(capText)}`);
6831
+ writeln(c16.dim(" usage: /context prune <off|balanced|aggressive>"));
6832
+ writeln(c16.dim(" /context cap <off|bytes|kb>"));
7477
6833
  return;
7478
6834
  }
7479
6835
  if (subcommand === "prune") {
7480
6836
  if (value === "off" || value === "balanced" || value === "aggressive") {
7481
6837
  ctx.setPruningMode(value);
7482
- writeln2(`${PREFIX.success} context pruning \u2192 ${c17.cyan(value)}`);
6838
+ writeln(`${PREFIX.success} context pruning \u2192 ${c16.cyan(value)}`);
7483
6839
  return;
7484
6840
  }
7485
- writeln2(`${PREFIX.error} usage: /context prune <off|balanced|aggressive>`);
6841
+ writeln(`${PREFIX.error} usage: /context prune <off|balanced|aggressive>`);
7486
6842
  return;
7487
6843
  }
7488
6844
  if (subcommand !== "cap") {
7489
- writeln2(`${PREFIX.error} usage: /context <prune|cap> ...`);
6845
+ writeln(`${PREFIX.error} usage: /context <prune|cap> ...`);
7490
6846
  return;
7491
6847
  }
7492
6848
  if (!value) {
7493
- writeln2(`${PREFIX.error} usage: /context cap <off|bytes|kb>`);
6849
+ writeln(`${PREFIX.error} usage: /context cap <off|bytes|kb>`);
7494
6850
  return;
7495
6851
  }
7496
6852
  if (value === "off") {
7497
6853
  ctx.setToolResultPayloadCapBytes(0);
7498
- writeln2(`${PREFIX.success} tool-result payload cap disabled`);
6854
+ writeln(`${PREFIX.success} tool-result payload cap disabled`);
7499
6855
  return;
7500
6856
  }
7501
6857
  const capMatch = value.match(/^(\d+)(kb)?$/i);
7502
6858
  if (!capMatch) {
7503
- writeln2(`${PREFIX.error} invalid cap: ${c17.cyan(value)}`);
6859
+ writeln(`${PREFIX.error} invalid cap: ${c16.cyan(value)}`);
7504
6860
  return;
7505
6861
  }
7506
6862
  const base = Number.parseInt(capMatch[1] ?? "", 10);
7507
6863
  const capBytes = (capMatch[2] ?? "").toLowerCase() === "kb" ? base * 1024 : base;
7508
6864
  if (!Number.isFinite(capBytes) || capBytes < 0) {
7509
- writeln2(`${PREFIX.error} invalid cap: ${c17.cyan(value)}`);
6865
+ writeln(`${PREFIX.error} invalid cap: ${c16.cyan(value)}`);
7510
6866
  return;
7511
6867
  }
7512
6868
  ctx.setToolResultPayloadCapBytes(capBytes);
7513
- writeln2(`${PREFIX.success} tool-result payload cap \u2192 ${c17.cyan(`${capBytes} bytes`)}`);
6869
+ writeln(`${PREFIX.success} tool-result payload cap \u2192 ${c16.cyan(`${capBytes} bytes`)}`);
7514
6870
  }
7515
6871
  function handleCacheCommand(ctx, args) {
7516
6872
  const [subcommand, value] = args.trim().split(/\s+/, 2);
7517
6873
  if (!subcommand) {
7518
- const geminiCache = ctx.googleCachedContent ? c17.cyan(ctx.googleCachedContent) : "off";
7519
- writeln2(`${PREFIX.info} prompt-caching=${ctx.promptCachingEnabled ? c17.green("on") : c17.dim("off")} openai-retention=${c17.cyan(ctx.openaiPromptCacheRetention)} gemini-cache=${geminiCache}`);
7520
- writeln2(c17.dim(" usage: /cache <on|off>"));
7521
- writeln2(c17.dim(" /cache openai <in_memory|24h>"));
7522
- writeln2(c17.dim(" /cache gemini <off|cachedContents/...>"));
6874
+ const geminiCache = ctx.googleCachedContent ? c16.cyan(ctx.googleCachedContent) : "off";
6875
+ writeln(`${PREFIX.info} prompt-caching=${ctx.promptCachingEnabled ? c16.green("on") : c16.dim("off")} openai-retention=${c16.cyan(ctx.openaiPromptCacheRetention)} gemini-cache=${geminiCache}`);
6876
+ writeln(c16.dim(" usage: /cache <on|off>"));
6877
+ writeln(c16.dim(" /cache openai <in_memory|24h>"));
6878
+ writeln(c16.dim(" /cache gemini <off|cachedContents/...>"));
7523
6879
  return;
7524
6880
  }
7525
6881
  if (subcommand === "on" || subcommand === "off") {
7526
6882
  ctx.setPromptCachingEnabled(subcommand === "on");
7527
- writeln2(`${PREFIX.success} prompt caching \u2192 ${subcommand === "on" ? c17.green("on") : c17.dim("off")}`);
6883
+ writeln(`${PREFIX.success} prompt caching \u2192 ${subcommand === "on" ? c16.green("on") : c16.dim("off")}`);
7528
6884
  return;
7529
6885
  }
7530
6886
  if (subcommand === "openai") {
7531
6887
  if (value === "in_memory" || value === "24h") {
7532
6888
  ctx.setOpenAIPromptCacheRetention(value);
7533
- writeln2(`${PREFIX.success} openai prompt cache retention \u2192 ${c17.cyan(value)}`);
6889
+ writeln(`${PREFIX.success} openai prompt cache retention \u2192 ${c16.cyan(value)}`);
7534
6890
  return;
7535
6891
  }
7536
- writeln2(`${PREFIX.error} usage: /cache openai <in_memory|24h>`);
6892
+ writeln(`${PREFIX.error} usage: /cache openai <in_memory|24h>`);
7537
6893
  return;
7538
6894
  }
7539
6895
  if (subcommand !== "gemini") {
7540
- writeln2(`${PREFIX.error} usage: /cache <on|off|openai|gemini> ...`);
6896
+ writeln(`${PREFIX.error} usage: /cache <on|off|openai|gemini> ...`);
7541
6897
  return;
7542
6898
  }
7543
6899
  if (!value) {
7544
- writeln2(`${PREFIX.error} usage: /cache gemini <off|cachedContents/...>`);
6900
+ writeln(`${PREFIX.error} usage: /cache gemini <off|cachedContents/...>`);
7545
6901
  return;
7546
6902
  }
7547
6903
  if (value === "off") {
7548
6904
  ctx.setGoogleCachedContent(null);
7549
- writeln2(`${PREFIX.success} gemini cached content \u2192 ${c17.dim("off")}`);
6905
+ writeln(`${PREFIX.success} gemini cached content \u2192 ${c16.dim("off")}`);
7550
6906
  return;
7551
6907
  }
7552
6908
  ctx.setGoogleCachedContent(value);
7553
- writeln2(`${PREFIX.success} gemini cached content \u2192 ${c17.cyan(value)}`);
6909
+ writeln(`${PREFIX.success} gemini cached content \u2192 ${c16.cyan(value)}`);
7554
6910
  }
7555
6911
 
7556
6912
  // src/cli/commands-help.ts
7557
- import * as c18 from "yoctocolors";
6913
+ import * as c17 from "yoctocolors";
7558
6914
  function renderEntries(entries) {
7559
6915
  for (const [label, description] of entries) {
7560
- writeln2(` ${c18.cyan(label.padEnd(28))} ${c18.dim(description)}`);
6916
+ writeln(` ${c17.cyan(label.padEnd(28))} ${c17.dim(description)}`);
7561
6917
  }
7562
6918
  }
7563
6919
  function renderHelpCommand(ctx, custom) {
7564
- writeln2();
7565
- writeln2(` ${c18.dim("session")}`);
6920
+ writeln();
6921
+ writeln(` ${c17.dim("session")}`);
7566
6922
  renderEntries([
7567
6923
  ["/new", "start a fresh session"],
7568
6924
  ["/undo", "remove the last conversation turn"],
7569
6925
  ["/exit", "quit"]
7570
6926
  ]);
7571
- writeln2();
7572
- writeln2(` ${c18.dim("model + context")}`);
6927
+ writeln();
6928
+ writeln(` ${c17.dim("model + context")}`);
7573
6929
  renderEntries([
7574
6930
  ["/model [id]", "list or switch models"],
7575
6931
  ["/reasoning [on|off]", "toggle reasoning display"],
@@ -7584,8 +6940,8 @@ function renderHelpCommand(ctx, custom) {
7584
6940
  ["/logout <provider>", "clear OAuth tokens"],
7585
6941
  ["/help", "show this help"]
7586
6942
  ]);
7587
- writeln2();
7588
- writeln2(` ${c18.dim("prompt")}`);
6943
+ writeln();
6944
+ writeln(` ${c17.dim("prompt")}`);
7589
6945
  renderEntries([
7590
6946
  ["ask normally", "send a prompt to the current agent"],
7591
6947
  ["!cmd", "run a shell command and keep the result in context"],
@@ -7593,63 +6949,63 @@ function renderHelpCommand(ctx, custom) {
7593
6949
  ["@skill", "inject a skill into the prompt (Tab to complete)"]
7594
6950
  ]);
7595
6951
  if (custom.size > 0) {
7596
- writeln2();
7597
- writeln2(` ${c18.dim("custom commands")}`);
6952
+ writeln();
6953
+ writeln(` ${c17.dim("custom commands")}`);
7598
6954
  for (const cmd of custom.values()) {
7599
- const source = cmd.source === "local" ? c18.dim("local") : c18.dim("global");
7600
- writeln2(` ${c18.green(`/${cmd.name}`.padEnd(28))} ${c18.dim(cmd.description)} ${c18.dim("\xB7")} ${source}`);
6955
+ const source = cmd.source === "local" ? c17.dim("local") : c17.dim("global");
6956
+ writeln(` ${c17.green(`/${cmd.name}`.padEnd(28))} ${c17.dim(cmd.description)} ${c17.dim("\xB7")} ${source}`);
7601
6957
  }
7602
6958
  }
7603
6959
  const agents = loadAgents(ctx.cwd);
7604
6960
  if (agents.size > 0) {
7605
- writeln2();
7606
- writeln2(` ${c18.dim("agents")}`);
6961
+ writeln();
6962
+ writeln(` ${c17.dim("agents")}`);
7607
6963
  for (const agent of agents.values()) {
7608
- const mode = agent.mode ? c18.dim(agent.mode) : c18.dim("agent");
7609
- const source = agent.source === "local" ? c18.dim("local") : c18.dim("global");
7610
- writeln2(` ${c18.magenta(agent.name.padEnd(28))} ${c18.dim(agent.description)} ${c18.dim("\xB7")} ${mode} ${c18.dim("\xB7")} ${source}`);
6964
+ const mode = agent.mode ? c17.dim(agent.mode) : c17.dim("agent");
6965
+ const source = agent.source === "local" ? c17.dim("local") : c17.dim("global");
6966
+ writeln(` ${c17.magenta(agent.name.padEnd(28))} ${c17.dim(agent.description)} ${c17.dim("\xB7")} ${mode} ${c17.dim("\xB7")} ${source}`);
7611
6967
  }
7612
6968
  }
7613
6969
  const skills = loadSkillsIndex(ctx.cwd);
7614
6970
  if (skills.size > 0) {
7615
- writeln2();
7616
- writeln2(` ${c18.dim("skills")}`);
6971
+ writeln();
6972
+ writeln(` ${c17.dim("skills")}`);
7617
6973
  for (const skill of skills.values()) {
7618
- const source = skill.source === "local" ? c18.dim("local") : c18.dim("global");
7619
- writeln2(` ${c18.yellow(`@${skill.name}`.padEnd(28))} ${c18.dim(skill.description)} ${c18.dim("\xB7")} ${source}`);
6974
+ const source = skill.source === "local" ? c17.dim("local") : c17.dim("global");
6975
+ writeln(` ${c17.yellow(`@${skill.name}`.padEnd(28))} ${c17.dim(skill.description)} ${c17.dim("\xB7")} ${source}`);
7620
6976
  }
7621
6977
  }
7622
- writeln2();
7623
- writeln2(` ${c18.dim("keys")} ${c18.dim("esc")} cancel response ${c18.dim("\xB7")} ${c18.dim("ctrl+c / ctrl+d")} exit ${c18.dim("\xB7")} ${c18.dim("ctrl+r")} history search ${c18.dim("\xB7")} ${c18.dim("\u2191\u2193")} history`);
7624
- writeln2();
6978
+ writeln();
6979
+ writeln(` ${c17.dim("keys")} ${c17.dim("esc")} cancel response ${c17.dim("\xB7")} ${c17.dim("ctrl+c / ctrl+d")} exit ${c17.dim("\xB7")} ${c17.dim("ctrl+r")} history search ${c17.dim("\xB7")} ${c17.dim("\u2191\u2193")} history`);
6980
+ writeln();
7625
6981
  }
7626
6982
 
7627
6983
  // src/cli/commands-login.ts
7628
- import * as c19 from "yoctocolors";
6984
+ import * as c18 from "yoctocolors";
7629
6985
  function renderLoginHelp() {
7630
- writeln2();
7631
- writeln2(` ${c19.dim("usage:")}`);
7632
- writeln2(` /login ${c19.dim("show login status")}`);
7633
- writeln2(` /login <provider> ${c19.dim("login via OAuth")}`);
7634
- writeln2(` /logout <provider> ${c19.dim("clear saved tokens")}`);
7635
- writeln2();
7636
- writeln2(` ${c19.dim("providers:")}`);
6986
+ writeln();
6987
+ writeln(` ${c18.dim("usage:")}`);
6988
+ writeln(` /login ${c18.dim("show login status")}`);
6989
+ writeln(` /login <provider> ${c18.dim("login via OAuth")}`);
6990
+ writeln(` /logout <provider> ${c18.dim("clear saved tokens")}`);
6991
+ writeln();
6992
+ writeln(` ${c18.dim("providers:")}`);
7637
6993
  for (const p of getOAuthProviders()) {
7638
- const status = isLoggedIn(p.id) ? c19.green("logged in") : c19.dim("not logged in");
7639
- writeln2(` ${c19.cyan(p.id.padEnd(20))} ${p.name} ${c19.dim("\xB7")} ${status}`);
6994
+ const status = isLoggedIn(p.id) ? c18.green("logged in") : c18.dim("not logged in");
6995
+ writeln(` ${c18.cyan(p.id.padEnd(20))} ${p.name} ${c18.dim("\xB7")} ${status}`);
7640
6996
  }
7641
- writeln2();
6997
+ writeln();
7642
6998
  }
7643
6999
  function renderStatus() {
7644
7000
  const loggedIn = listLoggedInProviders();
7645
7001
  if (loggedIn.length === 0) {
7646
- writeln2(`${PREFIX.info} ${c19.dim("no OAuth logins \u2014 use")} /login <provider>`);
7002
+ writeln(`${PREFIX.info} ${c18.dim("no OAuth logins \u2014 use")} /login <provider>`);
7647
7003
  return;
7648
7004
  }
7649
7005
  for (const id of loggedIn) {
7650
7006
  const provider = getOAuthProvider(id);
7651
7007
  const name = provider?.name ?? id;
7652
- writeln2(`${PREFIX.success} ${c19.cyan(id)} ${c19.dim(name)}`);
7008
+ writeln(`${PREFIX.success} ${c18.cyan(id)} ${c18.dim(name)}`);
7653
7009
  }
7654
7010
  }
7655
7011
  async function handleLoginCommand(ctx, args) {
@@ -7664,13 +7020,13 @@ async function handleLoginCommand(ctx, args) {
7664
7020
  }
7665
7021
  const provider = getOAuthProvider(providerId);
7666
7022
  if (!provider) {
7667
- writeln2(`${PREFIX.error} unknown provider "${providerId}" \u2014 available: ${getOAuthProviders().map((p) => p.id).join(", ")}`);
7023
+ writeln(`${PREFIX.error} unknown provider "${providerId}" \u2014 available: ${getOAuthProviders().map((p) => p.id).join(", ")}`);
7668
7024
  return;
7669
7025
  }
7670
7026
  if (isLoggedIn(providerId)) {
7671
7027
  const token = await getAccessToken(providerId);
7672
7028
  if (token) {
7673
- writeln2(`${PREFIX.success} already logged in to ${c19.cyan(provider.name)}`);
7029
+ writeln(`${PREFIX.success} already logged in to ${c18.cyan(provider.name)}`);
7674
7030
  return;
7675
7031
  }
7676
7032
  }
@@ -7679,43 +7035,43 @@ async function handleLoginCommand(ctx, args) {
7679
7035
  await login(providerId, {
7680
7036
  onOpenUrl: (url, instructions) => {
7681
7037
  ctx.stopSpinner();
7682
- writeln2(`${PREFIX.info} ${instructions}`);
7683
- writeln2();
7684
- writeln2(` ${c19.cyan(url)}`);
7685
- writeln2();
7038
+ writeln(`${PREFIX.info} ${instructions}`);
7039
+ writeln();
7040
+ writeln(` ${c18.cyan(url)}`);
7041
+ writeln();
7686
7042
  const open = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
7687
7043
  Bun.spawn([open, url], { stdout: "ignore", stderr: "ignore" });
7688
7044
  ctx.startSpinner("waiting for browser callback");
7689
7045
  },
7690
7046
  onProgress: (msg) => {
7691
7047
  ctx.stopSpinner();
7692
- writeln2(`${PREFIX.info} ${c19.dim(msg)}`);
7048
+ writeln(`${PREFIX.info} ${c18.dim(msg)}`);
7693
7049
  ctx.startSpinner("exchanging tokens");
7694
7050
  }
7695
7051
  });
7696
7052
  ctx.stopSpinner();
7697
- writeln2(`${PREFIX.success} logged in to ${c19.cyan(provider.name)}`);
7053
+ writeln(`${PREFIX.success} logged in to ${c18.cyan(provider.name)}`);
7698
7054
  } catch (err) {
7699
7055
  ctx.stopSpinner();
7700
- writeln2(`${PREFIX.error} login failed: ${err.message}`);
7056
+ writeln(`${PREFIX.error} login failed: ${err.message}`);
7701
7057
  }
7702
7058
  }
7703
7059
  function handleLogoutCommand(_ctx, args) {
7704
7060
  const providerId = args.trim().toLowerCase();
7705
7061
  if (!providerId) {
7706
- writeln2(`${PREFIX.error} usage: /logout <provider>`);
7062
+ writeln(`${PREFIX.error} usage: /logout <provider>`);
7707
7063
  return;
7708
7064
  }
7709
7065
  if (!isLoggedIn(providerId)) {
7710
- writeln2(`${PREFIX.info} ${c19.dim("not logged in to")} ${providerId}`);
7066
+ writeln(`${PREFIX.info} ${c18.dim("not logged in to")} ${providerId}`);
7711
7067
  return;
7712
7068
  }
7713
7069
  logout(providerId);
7714
- writeln2(`${PREFIX.success} logged out of ${c19.cyan(providerId)}`);
7070
+ writeln(`${PREFIX.success} logged out of ${c18.cyan(providerId)}`);
7715
7071
  }
7716
7072
 
7717
7073
  // src/cli/commands-mcp.ts
7718
- import * as c20 from "yoctocolors";
7074
+ import * as c19 from "yoctocolors";
7719
7075
  async function handleMcpCommand(ctx, args) {
7720
7076
  const parts = args.trim().split(/\s+/);
7721
7077
  const sub = parts[0] ?? "list";
@@ -7723,28 +7079,28 @@ async function handleMcpCommand(ctx, args) {
7723
7079
  case "list": {
7724
7080
  const servers = listMcpServers();
7725
7081
  if (servers.length === 0) {
7726
- writeln2(c20.dim(" no MCP servers configured"));
7727
- writeln2(c20.dim(" /mcp add <name> http <url> \xB7 /mcp add <name> stdio <cmd> [args...]"));
7082
+ writeln(c19.dim(" no MCP servers configured"));
7083
+ writeln(c19.dim(" /mcp add <name> http <url> \xB7 /mcp add <name> stdio <cmd> [args...]"));
7728
7084
  return;
7729
7085
  }
7730
- writeln2();
7086
+ writeln();
7731
7087
  for (const s of servers) {
7732
- const detail = s.url ? c20.dim(` ${s.url}`) : s.command ? c20.dim(` ${s.command}`) : "";
7733
- writeln2(` ${c20.yellow("\u2699")} ${c20.bold(s.name)} ${c20.dim(s.transport)}${detail}`);
7088
+ const detail = s.url ? c19.dim(` ${s.url}`) : s.command ? c19.dim(` ${s.command}`) : "";
7089
+ writeln(` ${c19.yellow("\u2699")} ${c19.bold(s.name)} ${c19.dim(s.transport)}${detail}`);
7734
7090
  }
7735
7091
  return;
7736
7092
  }
7737
7093
  case "add": {
7738
7094
  const [, name, transport, ...rest] = parts;
7739
7095
  if (!name || !transport || rest.length === 0) {
7740
- writeln2(`${PREFIX.error} usage: /mcp add <name> http <url>`);
7741
- writeln2(`${PREFIX.error} /mcp add <name> stdio <cmd> [args...]`);
7096
+ writeln(`${PREFIX.error} usage: /mcp add <name> http <url>`);
7097
+ writeln(`${PREFIX.error} /mcp add <name> stdio <cmd> [args...]`);
7742
7098
  return;
7743
7099
  }
7744
7100
  if (transport === "http") {
7745
7101
  const url = rest[0];
7746
7102
  if (!url) {
7747
- writeln2(`${PREFIX.error} usage: /mcp add <name> http <url>`);
7103
+ writeln(`${PREFIX.error} usage: /mcp add <name> http <url>`);
7748
7104
  return;
7749
7105
  }
7750
7106
  upsertMcpServer({
@@ -7758,7 +7114,7 @@ async function handleMcpCommand(ctx, args) {
7758
7114
  } else if (transport === "stdio") {
7759
7115
  const [command, ...cmdArgs] = rest;
7760
7116
  if (!command) {
7761
- writeln2(`${PREFIX.error} usage: /mcp add <name> stdio <cmd> [args...]`);
7117
+ writeln(`${PREFIX.error} usage: /mcp add <name> stdio <cmd> [args...]`);
7762
7118
  return;
7763
7119
  }
7764
7120
  upsertMcpServer({
@@ -7770,14 +7126,14 @@ async function handleMcpCommand(ctx, args) {
7770
7126
  env: null
7771
7127
  });
7772
7128
  } else {
7773
- writeln2(`${PREFIX.error} unknown transport: ${transport} (use http or stdio)`);
7129
+ writeln(`${PREFIX.error} unknown transport: ${transport} (use http or stdio)`);
7774
7130
  return;
7775
7131
  }
7776
7132
  try {
7777
7133
  await ctx.connectMcpServer(name);
7778
- writeln2(`${PREFIX.success} mcp server ${c20.cyan(name)} added and connected`);
7134
+ writeln(`${PREFIX.success} mcp server ${c19.cyan(name)} added and connected`);
7779
7135
  } catch (e) {
7780
- writeln2(`${PREFIX.success} mcp server ${c20.cyan(name)} saved ${c20.dim(`(connection failed: ${String(e)})`)}`);
7136
+ writeln(`${PREFIX.success} mcp server ${c19.cyan(name)} saved ${c19.dim(`(connection failed: ${String(e)})`)}`);
7781
7137
  }
7782
7138
  return;
7783
7139
  }
@@ -7785,21 +7141,21 @@ async function handleMcpCommand(ctx, args) {
7785
7141
  case "rm": {
7786
7142
  const [, name] = parts;
7787
7143
  if (!name) {
7788
- writeln2(`${PREFIX.error} usage: /mcp remove <name>`);
7144
+ writeln(`${PREFIX.error} usage: /mcp remove <name>`);
7789
7145
  return;
7790
7146
  }
7791
7147
  deleteMcpServer(name);
7792
- writeln2(`${PREFIX.success} mcp server ${c20.cyan(name)} removed`);
7148
+ writeln(`${PREFIX.success} mcp server ${c19.cyan(name)} removed`);
7793
7149
  return;
7794
7150
  }
7795
7151
  default:
7796
- writeln2(`${PREFIX.error} unknown: /mcp ${sub}`);
7797
- writeln2(c20.dim(" subcommands: list \xB7 add \xB7 remove"));
7152
+ writeln(`${PREFIX.error} unknown: /mcp ${sub}`);
7153
+ writeln(c19.dim(" subcommands: list \xB7 add \xB7 remove"));
7798
7154
  }
7799
7155
  }
7800
7156
 
7801
7157
  // src/cli/commands-model.ts
7802
- import * as c21 from "yoctocolors";
7158
+ import * as c20 from "yoctocolors";
7803
7159
  var THINKING_EFFORTS = ["low", "medium", "high", "xhigh"];
7804
7160
  function parseThinkingEffort(value) {
7805
7161
  return THINKING_EFFORTS.includes(value) ? value : null;
@@ -7818,21 +7174,21 @@ function renderModelUpdatedMessage(ctx, modelId, effortArg) {
7818
7174
  if (effortArg) {
7819
7175
  if (effortArg === "off") {
7820
7176
  ctx.setThinkingEffort(null);
7821
- writeln2(`${PREFIX.success} model \u2192 ${c21.cyan(modelId)} ${c21.dim("(thinking disabled)")}`);
7177
+ writeln(`${PREFIX.success} model \u2192 ${c20.cyan(modelId)} ${c20.dim("(thinking disabled)")}`);
7822
7178
  return;
7823
7179
  }
7824
7180
  const effort = parseThinkingEffort(effortArg);
7825
7181
  if (effort) {
7826
7182
  ctx.setThinkingEffort(effort);
7827
- writeln2(`${PREFIX.success} model \u2192 ${c21.cyan(modelId)} ${c21.dim(`(\u2726 ${effort})`)}`);
7183
+ writeln(`${PREFIX.success} model \u2192 ${c20.cyan(modelId)} ${c20.dim(`(\u2726 ${effort})`)}`);
7828
7184
  return;
7829
7185
  }
7830
- writeln2(`${PREFIX.success} model \u2192 ${c21.cyan(modelId)}`);
7831
- writeln2(`${PREFIX.error} unknown effort level ${c21.cyan(effortArg)} (use low, medium, high, xhigh, off)`);
7186
+ writeln(`${PREFIX.success} model \u2192 ${c20.cyan(modelId)}`);
7187
+ writeln(`${PREFIX.error} unknown effort level ${c20.cyan(effortArg)} (use low, medium, high, xhigh, off)`);
7832
7188
  return;
7833
7189
  }
7834
- const effortTag = ctx.thinkingEffort ? c21.dim(` (\u2726 ${ctx.thinkingEffort})`) : "";
7835
- writeln2(`${PREFIX.success} model \u2192 ${c21.cyan(modelId)}${effortTag}`);
7190
+ const effortTag = ctx.thinkingEffort ? c20.dim(` (\u2726 ${ctx.thinkingEffort})`) : "";
7191
+ writeln(`${PREFIX.success} model \u2192 ${c20.cyan(modelId)}${effortTag}`);
7836
7192
  }
7837
7193
  async function handleModelSet(ctx, args) {
7838
7194
  const parts = args.trim().split(/\s+/).filter(Boolean);
@@ -7845,7 +7201,7 @@ async function handleModelSet(ctx, args) {
7845
7201
  const snapshot = await fetchAvailableModels();
7846
7202
  const match = findModelIdByAlias(idArg, snapshot.models.map((model) => model.id));
7847
7203
  if (!match) {
7848
- writeln2(`${PREFIX.error} unknown model ${c21.cyan(idArg)} ${c21.dim("\u2014 run /models for the full list")}`);
7204
+ writeln(`${PREFIX.error} unknown model ${c20.cyan(idArg)} ${c20.dim("\u2014 run /models for the full list")}`);
7849
7205
  return;
7850
7206
  }
7851
7207
  modelId = match;
@@ -7856,30 +7212,30 @@ async function handleModelSet(ctx, args) {
7856
7212
  function handleModelEffort(ctx, effortArg) {
7857
7213
  if (effortArg === "off") {
7858
7214
  ctx.setThinkingEffort(null);
7859
- writeln2(`${PREFIX.success} thinking effort disabled`);
7215
+ writeln(`${PREFIX.success} thinking effort disabled`);
7860
7216
  return;
7861
7217
  }
7862
7218
  const effort = parseThinkingEffort(effortArg);
7863
7219
  if (!effort) {
7864
- writeln2(`${PREFIX.error} usage: /model effort <low|medium|high|xhigh|off>`);
7220
+ writeln(`${PREFIX.error} usage: /model effort <low|medium|high|xhigh|off>`);
7865
7221
  return;
7866
7222
  }
7867
7223
  ctx.setThinkingEffort(effort);
7868
- writeln2(`${PREFIX.success} thinking effort \u2192 ${c21.cyan(effort)}`);
7224
+ writeln(`${PREFIX.success} thinking effort \u2192 ${c20.cyan(effort)}`);
7869
7225
  }
7870
7226
  async function renderModelList(ctx) {
7871
7227
  ctx.startSpinner("fetching models");
7872
7228
  const snapshot = await fetchAvailableModels();
7873
7229
  ctx.stopSpinner();
7874
7230
  if (snapshot.models.length === 0) {
7875
- writeln2(`${PREFIX.error} No models found. Check your API keys or Ollama connection.`);
7876
- writeln2(c21.dim(" Set OPENCODE_API_KEY for Zen, or start Ollama for local models."));
7231
+ writeln(`${PREFIX.error} No models found. Check your API keys or Ollama connection.`);
7232
+ writeln(c20.dim(" Set OPENCODE_API_KEY for Zen, or start Ollama for local models."));
7877
7233
  return;
7878
7234
  }
7879
7235
  if (snapshot.stale) {
7880
7236
  const lastSync = snapshot.lastSyncAt ? new Date(snapshot.lastSyncAt).toLocaleString() : "never";
7881
7237
  const refreshTag = snapshot.refreshing ? " (refreshing in background)" : "";
7882
- writeln2(c21.dim(` model metadata is stale (last sync: ${lastSync})${refreshTag}`));
7238
+ writeln(c20.dim(` model metadata is stale (last sync: ${lastSync})${refreshTag}`));
7883
7239
  }
7884
7240
  const modelsByProvider = new Map;
7885
7241
  for (const model of snapshot.models) {
@@ -7890,22 +7246,22 @@ async function renderModelList(ctx) {
7890
7246
  modelsByProvider.set(model.provider, [model]);
7891
7247
  }
7892
7248
  }
7893
- writeln2();
7249
+ writeln();
7894
7250
  for (const [provider, providerModels] of modelsByProvider) {
7895
- writeln2(c21.bold(` ${provider}`));
7251
+ writeln(c20.bold(` ${provider}`));
7896
7252
  for (const model of providerModels) {
7897
7253
  const isCurrent = ctx.currentModel === model.id;
7898
- const freeTag = model.free ? c21.green(" free") : "";
7899
- const contextTag = model.context ? c21.dim(` ${Math.round(model.context / 1000)}k`) : "";
7900
- const effortTag = isCurrent && ctx.thinkingEffort ? c21.dim(` \u2726 ${ctx.thinkingEffort}`) : "";
7901
- const currentTag = isCurrent ? c21.cyan(" \u25C0") : "";
7902
- writeln2(` ${c21.dim("\xB7")} ${model.displayName}${freeTag}${contextTag}${currentTag}${effortTag}`);
7903
- writeln2(` ${c21.dim(model.id)}`);
7254
+ const freeTag = model.free ? c20.green(" free") : "";
7255
+ const contextTag = model.context ? c20.dim(` ${Math.round(model.context / 1000)}k`) : "";
7256
+ const effortTag = isCurrent && ctx.thinkingEffort ? c20.dim(` \u2726 ${ctx.thinkingEffort}`) : "";
7257
+ const currentTag = isCurrent ? c20.cyan(" \u25C0") : "";
7258
+ writeln(` ${c20.dim("\xB7")} ${model.displayName}${freeTag}${contextTag}${currentTag}${effortTag}`);
7259
+ writeln(` ${c20.dim(model.id)}`);
7904
7260
  }
7905
7261
  }
7906
- writeln2();
7907
- writeln2(c21.dim(" /model <id> to switch \xB7 e.g. /model zen/claude-sonnet-4-6"));
7908
- writeln2(c21.dim(" /model effort <low|medium|high|xhigh|off> to set thinking effort"));
7262
+ writeln();
7263
+ writeln(c20.dim(" /model <id> to switch \xB7 e.g. /model zen/claude-sonnet-4-6"));
7264
+ writeln(c20.dim(" /model effort <low|medium|high|xhigh|off> to set thinking effort"));
7909
7265
  }
7910
7266
  async function handleModelCommand(ctx, args) {
7911
7267
  const parts = args.trim().split(/\s+/).filter(Boolean);
@@ -7926,9 +7282,9 @@ async function handleUndo(ctx) {
7926
7282
  try {
7927
7283
  const ok = await ctx.undoLastTurn();
7928
7284
  if (ok) {
7929
- writeln2(`${PREFIX.success} ${c22.dim("last conversation turn removed")}`);
7285
+ writeln(`${PREFIX.success} ${c21.dim("last conversation turn removed")}`);
7930
7286
  } else {
7931
- writeln2(`${PREFIX.info} ${c22.dim("nothing to undo")}`);
7287
+ writeln(`${PREFIX.info} ${c21.dim("nothing to undo")}`);
7932
7288
  }
7933
7289
  } finally {
7934
7290
  ctx.stopSpinner();
@@ -7941,11 +7297,11 @@ function handleNew(ctx) {
7941
7297
  }
7942
7298
  async function handleCustomCommand(cmd, args, ctx) {
7943
7299
  const prompt = await expandTemplate(cmd.template, args, ctx.cwd);
7944
- const label = c22.cyan(cmd.name);
7300
+ const label = c21.cyan(cmd.name);
7945
7301
  const srcPath = cmd.source === "local" ? `.agents/commands/${cmd.name}.md` : `~/.agents/commands/${cmd.name}.md`;
7946
- const src = c22.dim(`[${srcPath}]`);
7947
- writeln2(`${PREFIX.info} ${label} ${src}`);
7948
- writeln2();
7302
+ const src = c21.dim(`[${srcPath}]`);
7303
+ writeln(`${PREFIX.info} ${label} ${src}`);
7304
+ writeln();
7949
7305
  const fork = cmd.context === "fork" || cmd.subtask === true;
7950
7306
  if (!fork) {
7951
7307
  return { type: "inject-user-message", text: prompt };
@@ -7957,8 +7313,8 @@ async function handleCustomCommand(cmd, args, ctx) {
7957
7313
  try {
7958
7314
  ctx.startSpinner("subagent");
7959
7315
  const output = await ctx.runSubagent(prompt, cmd.agent, cmd.model, abortController.signal);
7960
- write2(output.result);
7961
- writeln2();
7316
+ write(output.result);
7317
+ writeln();
7962
7318
  return {
7963
7319
  type: "inject-user-message",
7964
7320
  text: `/${cmd.name} output:
@@ -7971,7 +7327,7 @@ ${output.result}
7971
7327
  if (isAbortError(e)) {
7972
7328
  return { type: "handled" };
7973
7329
  }
7974
- writeln2(`${PREFIX.error} /${cmd.name} failed: ${String(e)}`);
7330
+ writeln(`${PREFIX.error} /${cmd.name} failed: ${String(e)}`);
7975
7331
  return { type: "handled" };
7976
7332
  } finally {
7977
7333
  stopWatcher();
@@ -8028,7 +7384,7 @@ async function handleCommand(command, args, ctx) {
8028
7384
  case "q":
8029
7385
  return { type: "exit" };
8030
7386
  default: {
8031
- writeln2(`${PREFIX.error} unknown: /${command} ${c22.dim("\u2014 /help for commands")}`);
7387
+ writeln(`${PREFIX.error} unknown: /${command} ${c21.dim("\u2014 /help for commands")}`);
8032
7388
  return { type: "unknown", command };
8033
7389
  }
8034
7390
  }
@@ -8124,7 +7480,7 @@ async function runInputLoop(opts) {
8124
7480
  }
8125
7481
  switch (input.type) {
8126
7482
  case "eof":
8127
- reporter.writeText(c23.dim("Goodbye."));
7483
+ reporter.writeText(c22.dim("Goodbye."));
8128
7484
  return;
8129
7485
  case "interrupt":
8130
7486
  gitBranchCache.refreshInBackground();
@@ -8132,7 +7488,7 @@ async function runInputLoop(opts) {
8132
7488
  case "command": {
8133
7489
  const result = await handleCommand(input.command, input.args, cmdCtx);
8134
7490
  if (result.type === "exit") {
8135
- reporter.writeText(c23.dim("Goodbye."));
7491
+ reporter.writeText(c22.dim("Goodbye."));
8136
7492
  return;
8137
7493
  }
8138
7494
  if (result.type === "inject-user-message") {
@@ -8150,13 +7506,7 @@ async function runInputLoop(opts) {
8150
7506
  const result = await runShellCommand({
8151
7507
  command: input.command,
8152
7508
  timeout: 30000,
8153
- cwd,
8154
- ...cmdCtx.verboseOutput ? {
8155
- onOutput: (chunk) => {
8156
- reporter.streamChunk(chunk);
8157
- return true;
8158
- }
8159
- } : {}
7509
+ cwd
8160
7510
  });
8161
7511
  renderToolResult("shell", result, false, {
8162
7512
  verboseOutput: cmdCtx.verboseOutput
@@ -8211,8 +7561,8 @@ async function resolvePromptInput(promptArg, opts) {
8211
7561
 
8212
7562
  // src/cli/structured-output.ts
8213
7563
  import { createTwoFilesPatch } from "diff";
8214
- function writeJsonLine(write3, payload) {
8215
- write3(`${JSON.stringify(payload)}
7564
+ function writeJsonLine(write2, payload) {
7565
+ write2(`${JSON.stringify(payload)}
8216
7566
  `);
8217
7567
  }
8218
7568
 
@@ -8268,7 +7618,7 @@ async function main() {
8268
7618
  if (last) {
8269
7619
  sessionId = last.id;
8270
7620
  } else {
8271
- writeln2(c24.dim("No previous session found, starting fresh."));
7621
+ writeln(c23.dim("No previous session found, starting fresh."));
8272
7622
  }
8273
7623
  } else if (args.sessionId) {
8274
7624
  sessionId = args.sessionId;
@@ -8335,7 +7685,7 @@ async function main() {
8335
7685
  const { text: resolvedText, images: refImages } = await resolveFileRefs(prompt, args.cwd);
8336
7686
  await runner.processUserInput(resolvedText, refImages);
8337
7687
  const { totalIn, totalOut } = runner.getStatusInfo();
8338
- writeln2(`${G.info} ${c24.dim(`${totalIn.toLocaleString()} in / ${totalOut.toLocaleString()} out tokens`)}`);
7688
+ writeln(`${G.info} ${c23.dim(`${totalIn.toLocaleString()} in / ${totalOut.toLocaleString()} out tokens`)}`);
8339
7689
  return;
8340
7690
  }
8341
7691
  await runInputLoop({