mixdog 0.9.41 → 0.9.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/package.json +3 -2
  2. package/scripts/agent-tag-reuse-smoke.mjs +124 -10
  3. package/scripts/ansi-color-capability-test.mjs +90 -0
  4. package/scripts/anthropic-oauth-refresh-race-test.mjs +59 -0
  5. package/scripts/arg-guard-test.mjs +16 -0
  6. package/scripts/compact-pressure-test.mjs +256 -1
  7. package/scripts/generate-runtime-manifest.mjs +39 -22
  8. package/scripts/grok-oauth-refresh-race-test.mjs +198 -0
  9. package/scripts/internal-comms-bench.mjs +0 -1
  10. package/scripts/internal-comms-smoke.mjs +38 -39
  11. package/scripts/internal-tools-normalization-test.mjs +52 -0
  12. package/scripts/maintenance-default-routes-test.mjs +164 -0
  13. package/scripts/max-output-recovery-test.mjs +49 -0
  14. package/scripts/mcp-client-normalization-test.mjs +45 -0
  15. package/scripts/openai-oauth-ws-1006-retry-test.mjs +123 -0
  16. package/scripts/provider-toolcall-test.mjs +23 -0
  17. package/scripts/result-classification-test.mjs +75 -0
  18. package/scripts/routing-corpus.mjs +1 -1
  19. package/scripts/shell-jobs-windows-hide-test.mjs +164 -0
  20. package/scripts/smoke.mjs +1 -1
  21. package/scripts/submit-commandbusy-race-test.mjs +99 -7
  22. package/scripts/tui-transcript-jitter-harness-entry.jsx +302 -0
  23. package/scripts/tui-transcript-jitter-harness.mjs +58 -0
  24. package/scripts/tui-transcript-perf-test.mjs +56 -1
  25. package/src/agents/reviewer/AGENT.md +5 -3
  26. package/src/rules/lead/lead-brief.md +5 -4
  27. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.mjs +40 -3
  28. package/src/runtime/agent/orchestrator/config.mjs +29 -14
  29. package/src/runtime/agent/orchestrator/internal-tools.mjs +16 -3
  30. package/src/runtime/agent/orchestrator/mcp/client.mjs +17 -1
  31. package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +49 -6
  32. package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +14 -0
  33. package/src/runtime/agent/orchestrator/providers/grok-oauth.mjs +46 -21
  34. package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +59 -2
  35. package/src/runtime/agent/orchestrator/providers/retry-classifier.mjs +5 -1
  36. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +18 -0
  37. package/src/runtime/agent/orchestrator/session/context-utils.mjs +140 -81
  38. package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +23 -5
  39. package/src/runtime/agent/orchestrator/session/loop/termination.mjs +3 -0
  40. package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +12 -3
  41. package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +4 -2
  42. package/src/runtime/agent/orchestrator/session/result-classification.mjs +4 -1
  43. package/src/runtime/agent/orchestrator/session/tool-batch.mjs +7 -2
  44. package/src/runtime/agent/orchestrator/session/tool-envelope.mjs +8 -6
  45. package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +15 -3
  46. package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +1 -1
  47. package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +7 -5
  48. package/src/runtime/memory/data/runtime-manifest.json +11 -11
  49. package/src/runtime/memory/lib/runtime-fetcher.mjs +1 -2
  50. package/src/runtime/memory/tool-defs.mjs +4 -3
  51. package/src/runtime/shared/tool-surface.mjs +1 -2
  52. package/src/session-runtime/context-status.mjs +8 -2
  53. package/src/standalone/agent-tool/render.mjs +2 -0
  54. package/src/standalone/agent-tool.mjs +267 -72
  55. package/src/standalone/explore-tool.mjs +17 -16
  56. package/src/tui/app/provider-setup-picker.mjs +1 -0
  57. package/src/tui/app/use-transcript-window.mjs +5 -1
  58. package/src/tui/components/StatusLine.jsx +11 -32
  59. package/src/tui/dist/index.mjs +257 -106
  60. package/src/tui/engine/session-api.mjs +3 -0
  61. package/src/tui/engine/session-flow.mjs +19 -8
  62. package/src/tui/engine/turn.mjs +24 -2
  63. package/src/tui/engine.mjs +0 -1
  64. package/src/tui/index.jsx +3 -2
  65. package/src/tui/markdown/streaming-markdown.mjs +35 -9
  66. package/src/tui/statusline-ansi-bridge.mjs +17 -7
  67. package/src/ui/ansi.mjs +85 -5
  68. package/src/ui/statusline-agents.mjs +0 -8
  69. package/src/ui/statusline-format.mjs +7 -7
  70. package/src/ui/statusline.mjs +2 -4
  71. package/src/workflows/default/WORKFLOW.md +29 -20
  72. package/src/workflows/solo-review/WORKFLOW.md +47 -0
  73. package/src/workflows/bench/WORKFLOW.md +0 -60
@@ -2896,7 +2896,7 @@ function toolWorkUnit(name, args = {}, category = "") {
2896
2896
  case "memory": {
2897
2897
  const action = String(a.action || "").toLowerCase();
2898
2898
  const op = String(a.op || "").toLowerCase();
2899
- const isMutation = op === "add" || op === "edit" || op === "delete" || op === "promote" || op === "dismiss" || action === "core" && !op;
2899
+ const isMutation = op === "add" || op === "edit" || op === "delete" || op === "promote" || op === "dismiss";
2900
2900
  if (isMutation) return unitDescriptor("Memory", { count: queryCount(a, "entries", "items", "memories", "query", "text", "value") || 1, active: "Writing", done: "Wrote", noun: "memory item" });
2901
2901
  return unitDescriptor("Memory", { count: queryCount(a, "entries", "items", "memories", "query", "text", "value") || 1, active: "Checking", done: "Checked", noun: "memory item" });
2902
2902
  }
@@ -3729,8 +3729,110 @@ function Spinner({ verb = "Working", startedAt, outputTokens = 0, tokens = 0, th
3729
3729
  import React2, { useEffect as useEffect2, useRef as useRef3, useState as useState2 } from "react";
3730
3730
  import { Box as Box2, Text as Text2 } from "../../../vendor/ink/build/index.js";
3731
3731
 
3732
+ // src/ui/ansi.mjs
3733
+ import { stdout, env, platform } from "node:process";
3734
+ var COLOR_ENABLED = computeColorEnabled();
3735
+ function computeColorEnabled() {
3736
+ if (env.NO_COLOR !== void 0 && env.NO_COLOR !== "") return false;
3737
+ if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0" && env.FORCE_COLOR !== "") {
3738
+ return true;
3739
+ }
3740
+ return Boolean(stdout && stdout.isTTY);
3741
+ }
3742
+ var ESC = "\x1B[";
3743
+ var RESET = `${ESC}0m`;
3744
+ function supportsTruecolor(environment = env, platformName = platform) {
3745
+ const termProgram = String(environment?.TERM_PROGRAM || "").trim().toLowerCase();
3746
+ if (termProgram === "apple_terminal") return false;
3747
+ const colorTerm = String(environment?.COLORTERM || "").trim().toLowerCase();
3748
+ if (colorTerm === "truecolor" || colorTerm === "24bit") return true;
3749
+ if (environment?.WT_SESSION !== void 0 && environment.WT_SESSION !== "") return true;
3750
+ if (["iterm.app", "wezterm", "ghostty", "vscode"].includes(termProgram)) return true;
3751
+ if (/(?:direct|truecolor)/i.test(String(environment?.TERM || ""))) return true;
3752
+ if (platformName === "win32") return true;
3753
+ return true;
3754
+ }
3755
+ var ANSI_256_CUBE_LEVELS = Object.freeze([0, 95, 135, 175, 215, 255]);
3756
+ function colorByte(value) {
3757
+ const n = Number(value);
3758
+ return Number.isFinite(n) ? Math.max(0, Math.min(255, Math.round(n))) : 0;
3759
+ }
3760
+ function nearestCubeLevel(value) {
3761
+ let best = 0;
3762
+ let bestDistance = Infinity;
3763
+ for (let i = 0; i < ANSI_256_CUBE_LEVELS.length; i++) {
3764
+ const distance = Math.abs(value - ANSI_256_CUBE_LEVELS[i]);
3765
+ if (distance < bestDistance) {
3766
+ best = i;
3767
+ bestDistance = distance;
3768
+ }
3769
+ }
3770
+ return best;
3771
+ }
3772
+ function rgbToAnsi256(r, g, b) {
3773
+ const red2 = colorByte(r);
3774
+ const green2 = colorByte(g);
3775
+ const blue2 = colorByte(b);
3776
+ const redLevel = nearestCubeLevel(red2);
3777
+ const greenLevel = nearestCubeLevel(green2);
3778
+ const blueLevel = nearestCubeLevel(blue2);
3779
+ const cubeRed = ANSI_256_CUBE_LEVELS[redLevel];
3780
+ const cubeGreen = ANSI_256_CUBE_LEVELS[greenLevel];
3781
+ const cubeBlue = ANSI_256_CUBE_LEVELS[blueLevel];
3782
+ const cubeDistance = (red2 - cubeRed) ** 2 + (green2 - cubeGreen) ** 2 + (blue2 - cubeBlue) ** 2;
3783
+ const average = (red2 + green2 + blue2) / 3;
3784
+ const grayLevel = Math.max(0, Math.min(23, Math.round((average - 8) / 10)));
3785
+ const grayValue = 8 + grayLevel * 10;
3786
+ const grayDistance = (red2 - grayValue) ** 2 + (green2 - grayValue) ** 2 + (blue2 - grayValue) ** 2;
3787
+ if (grayDistance < cubeDistance) return 232 + grayLevel;
3788
+ return 16 + 36 * redLevel + 6 * greenLevel + blueLevel;
3789
+ }
3790
+ function rgbSgr(r, g, b, background = false) {
3791
+ const channel = background ? 48 : 38;
3792
+ if (supportsTruecolor()) return `${ESC}${channel};2;${r};${g};${b}m`;
3793
+ return `${ESC}${channel};5;${rgbToAnsi256(r, g, b)}m`;
3794
+ }
3795
+ function supportedSgrOpen(open) {
3796
+ const match = /^(38|48);2;([^;]+);([^;]+);([^;]+)$/.exec(String(open));
3797
+ if (!match || supportsTruecolor()) return open;
3798
+ return `${match[1]};5;${rgbToAnsi256(match[2], match[3], match[4])}`;
3799
+ }
3800
+ function sgr(open) {
3801
+ return (text) => {
3802
+ if (!COLOR_ENABLED) return String(text ?? "");
3803
+ const s = String(text ?? "");
3804
+ const openSeq = `${ESC}${supportedSgrOpen(open)}m`;
3805
+ return openSeq + s.replace(/\x1b\[0m/g, RESET + openSeq) + RESET;
3806
+ };
3807
+ }
3808
+ var bold = sgr("1");
3809
+ var dim = sgr("38;2;136;136;136");
3810
+ var italic = sgr("3");
3811
+ var underline = sgr("4");
3812
+ var inverse = sgr("7");
3813
+ var strike = sgr("9");
3814
+ var black = sgr("30");
3815
+ var red = sgr("38;2;220;70;88");
3816
+ var green = sgr("38;2;0;170;75");
3817
+ var yellow = sgr("38;2;255;193;7");
3818
+ var blue = sgr("38;2;77;159;255");
3819
+ var magenta = sgr("38;2;177;133;219");
3820
+ var cyan = sgr("38;2;136;136;136");
3821
+ var white = sgr("38;2;198;198;198");
3822
+ var gray = sgr("38;2;198;198;198");
3823
+ var brightRed = sgr("38;2;220;70;88");
3824
+ var brightGreen = sgr("38;2;0;185;88");
3825
+ var brightYellow = sgr("38;2;255;210;80");
3826
+ var brightBlue = sgr("38;2;93;173;255");
3827
+ var brightMagenta = sgr("38;2;190;150;230");
3828
+ var brightCyan = sgr("38;2;168;168;168");
3829
+ var brightWhite = sgr("38;2;220;220;220");
3830
+ var bgGray = sgr("100");
3831
+ var bgBlack = sgr("40");
3832
+ var bgBlue = sgr("44");
3833
+
3732
3834
  // src/tui/statusline-ansi-bridge.mjs
3733
- var RESET = "\x1B[0m";
3835
+ var RESET2 = "\x1B[0m";
3734
3836
  var STATUSLINE_CANONICAL_TRUECOLOR = Object.freeze({
3735
3837
  statusText: [198, 198, 198],
3736
3838
  subtle: [136, 136, 136],
@@ -3743,6 +3845,12 @@ var STATUSLINE_CANONICAL_TRUECOLOR = Object.freeze({
3743
3845
  function truecolorSgr(r, g, b) {
3744
3846
  return `\x1B[38;2;${r};${g};${b}m`;
3745
3847
  }
3848
+ function ansi256Sgr(r, g, b) {
3849
+ return `\x1B[38;5;${rgbToAnsi256(r, g, b)}m`;
3850
+ }
3851
+ function canonicalSgrVariants(rgb) {
3852
+ return [truecolorSgr(...rgb), ansi256Sgr(...rgb)];
3853
+ }
3746
3854
  function footerLocalNum(value) {
3747
3855
  const n = Number(value);
3748
3856
  return Number.isFinite(n) ? n : 0;
@@ -3793,7 +3901,7 @@ function statuslineFooterCacheKey({
3793
3901
  String(autoCompactTokenLimit)
3794
3902
  ].join("\0");
3795
3903
  }
3796
- function applyDefaultStatusForegroundAfterReset(text, STATUS, reset = RESET) {
3904
+ function applyDefaultStatusForegroundAfterReset(text, STATUS, reset = RESET2) {
3797
3905
  const src = String(text || "");
3798
3906
  if (!STATUS || !reset) return src;
3799
3907
  let out = "";
@@ -3821,13 +3929,13 @@ function applyDefaultStatusForegroundAfterReset(text, STATUS, reset = RESET) {
3821
3929
  function remapCanonicalStatuslineTruecolor(text, colors) {
3822
3930
  const c = STATUSLINE_CANONICAL_TRUECOLOR;
3823
3931
  const pairs = [
3824
- [truecolorSgr(...c.statusText), colors.STATUS],
3825
- [truecolorSgr(...c.subtle), colors.SUBTLE],
3826
- [truecolorSgr(...c.success), colors.SUCCESS],
3827
- [truecolorSgr(...c.successBright), colors.SUCCESS],
3828
- [truecolorSgr(...c.warning), colors.WARNING],
3829
- [truecolorSgr(...c.warningBright), colors.WARNING],
3830
- [truecolorSgr(...c.error), colors.ERROR]
3932
+ ...canonicalSgrVariants(c.statusText).map((from) => [from, colors.STATUS]),
3933
+ ...canonicalSgrVariants(c.subtle).map((from) => [from, colors.SUBTLE]),
3934
+ ...canonicalSgrVariants(c.success).map((from) => [from, colors.SUCCESS]),
3935
+ ...canonicalSgrVariants(c.successBright).map((from) => [from, colors.SUCCESS]),
3936
+ ...canonicalSgrVariants(c.warning).map((from) => [from, colors.WARNING]),
3937
+ ...canonicalSgrVariants(c.warningBright).map((from) => [from, colors.WARNING]),
3938
+ ...canonicalSgrVariants(c.error).map((from) => [from, colors.ERROR])
3831
3939
  ];
3832
3940
  let out = String(text || "");
3833
3941
  for (const [from, to] of pairs) {
@@ -3835,7 +3943,7 @@ function remapCanonicalStatuslineTruecolor(text, colors) {
3835
3943
  }
3836
3944
  return out;
3837
3945
  }
3838
- function normalizeStatuslineAnsi(text, colors, { reset = RESET } = {}) {
3946
+ function normalizeStatuslineAnsi(text, colors, { reset = RESET2 } = {}) {
3839
3947
  const { STATUS, SUBTLE, SUCCESS, WARNING, ERROR } = colors;
3840
3948
  let out = remapCanonicalStatuslineTruecolor(text, colors).replace(/\n+$/, "").replace(/\x1b\[1m/g, STATUS).replace(/\x1b\[2m/g, SUBTLE).replace(/\x1b\[31m/g, ERROR).replace(/\x1b\[32m/g, SUCCESS).replace(/\x1b\[33m/g, WARNING).replace(/\x1b\[36m/g, SUBTLE).replace(/\x1b\[90m/g, SUBTLE).replace(/^((?:\x1b\[[0-9;]*m)*)◆((?:\x1b\[[0-9;]*m)*)(\s?)/, `${STATUS}\u25C6$2$3`).replace(/(\x1b\[0m )(\d+(?:\.\d+)?%)(?= |$)/g, `$1${STATUS}$2${reset}`).replaceAll(`${reset} ${SUBTLE}\u2502${reset} `, ` ${SUBTLE}\u2502${reset} `);
3841
3949
  out = applyDefaultStatusForegroundAfterReset(out, STATUS, reset);
@@ -3853,7 +3961,7 @@ function loadStatuslineModule() {
3853
3961
  function resetStatuslineModuleLoad() {
3854
3962
  statuslineModulePromise = null;
3855
3963
  }
3856
- var RESET2 = "\x1B[0m";
3964
+ var RESET3 = "\x1B[0m";
3857
3965
  var STATUSLINE_RENDER_DEBOUNCE_MS = 150;
3858
3966
  var STATUSLINE_MODULE_PREWARM_DELAY_MS = 300;
3859
3967
  var statuslineModulePrewarmScheduled = false;
@@ -3921,15 +4029,15 @@ function scheduleBootFullRetry(backoffMsRef, nextAttemptAtRef) {
3921
4029
  function ansiRgb(value, fallback) {
3922
4030
  const match = /^rgb\((\d+),(\d+),(\d+)\)$/.exec(String(value || "").replace(/\s+/g, ""));
3923
4031
  if (!match) return fallback;
3924
- return `\x1B[38;2;${match[1]};${match[2]};${match[3]}m`;
4032
+ return rgbSgr(match[1], match[2], match[3]);
3925
4033
  }
3926
4034
  function statusColors() {
3927
4035
  return {
3928
- STATUS: ansiRgb(theme.statusText, "\x1B[38;2;198;198;198m"),
3929
- SUBTLE: ansiRgb(theme.statusSubtle, "\x1B[38;2;136;136;136m"),
3930
- SUCCESS: ansiRgb(theme.success, "\x1B[38;2;0;170;75m"),
3931
- WARNING: ansiRgb(theme.warning, "\x1B[38;2;255;193;7m"),
3932
- ERROR: ansiRgb(theme.error, "\x1B[38;2;220;70;88m")
4036
+ STATUS: ansiRgb(theme.statusText, rgbSgr(198, 198, 198)),
4037
+ SUBTLE: ansiRgb(theme.statusSubtle, rgbSgr(136, 136, 136)),
4038
+ SUCCESS: ansiRgb(theme.success, rgbSgr(0, 170, 75)),
4039
+ WARNING: ansiRgb(theme.warning, rgbSgr(255, 193, 7)),
4040
+ ERROR: ansiRgb(theme.error, rgbSgr(220, 70, 88))
3933
4041
  };
3934
4042
  }
3935
4043
  function terminalColumns() {
@@ -3977,14 +4085,14 @@ function localContextSegmentFromPct(ctxPct = 0) {
3977
4085
  const barPct = Math.max(0, Math.min(100, pct));
3978
4086
  const fill = pct >= 90 ? ERROR : pct >= 70 ? WARNING : SUCCESS;
3979
4087
  const label = localContextPctDisplayLabel(pct);
3980
- if (!cells) return `${fill}${label}%${RESET2}`;
4088
+ if (!cells) return `${fill}${label}%${RESET3}`;
3981
4089
  let filled = Math.floor(barPct * cells / 100);
3982
4090
  if (barPct >= 1 && filled === 0) filled = 1;
3983
4091
  filled = Math.max(0, Math.min(cells, filled));
3984
4092
  const bar = "\u2593".repeat(filled) + "\u2591".repeat(cells - filled);
3985
4093
  const filledBar = bar.replace(/░/g, "");
3986
4094
  const emptyBar = bar.replace(/▓/g, "");
3987
- return `${fill}${filledBar}${RESET2}${SUBTLE}${emptyBar}${RESET2} ${label}%`;
4095
+ return `${fill}${filledBar}${RESET3}${SUBTLE}${emptyBar}${RESET3} ${label}%`;
3988
4096
  }
3989
4097
  var LOCAL_WORKER_SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
3990
4098
  var LOCAL_L2_SPINNER_FRAME_MS = 120;
@@ -4023,25 +4131,6 @@ function localRunningWorkerCount(agentWorkers = [], agentJobs = []) {
4023
4131
  }
4024
4132
  return seen.size;
4025
4133
  }
4026
- function localRunningWorkerTags(agentWorkers = [], agentJobs = [], limit = 3) {
4027
- const tags = [];
4028
- const seen = /* @__PURE__ */ new Set();
4029
- for (const worker of Array.isArray(agentWorkers) ? agentWorkers : []) {
4030
- const tag = String(worker?.tag || worker?.agent || worker?.name || "").trim();
4031
- if (!tag || isTerminalStatus(worker?.stage || worker?.status) || seen.has(tag)) continue;
4032
- seen.add(tag);
4033
- tags.push(tag);
4034
- }
4035
- for (const job of Array.isArray(agentJobs) ? agentJobs : []) {
4036
- if (!/running/i.test(String(job?.status || job?.stage || ""))) continue;
4037
- const tag = String(job?.tag || job?.agent || job?.type || job?.task_id || job?.taskId || "").trim();
4038
- if (!tag || seen.has(tag)) continue;
4039
- seen.add(tag);
4040
- tags.push(tag);
4041
- }
4042
- if (tags.length <= limit) return tags.join(", ");
4043
- return `${tags.slice(0, limit).join(", ")}, +${tags.length - limit}`;
4044
- }
4045
4134
  function localTimeMs(value) {
4046
4135
  if (typeof value === "number" && Number.isFinite(value) && value > 0) return value;
4047
4136
  const n = Date.parse(String(value || ""));
@@ -4067,29 +4156,27 @@ function localStatusLineL2({
4067
4156
  activeTools = null
4068
4157
  } = {}, now = Date.now()) {
4069
4158
  const { STATUS, SUBTLE, SUCCESS } = statusColors();
4070
- const spin = `${SUCCESS}${localL2SpinnerFrame(now)}${RESET2}`;
4071
- const segSep = ` ${SUBTLE}\u2502${RESET2} `;
4072
- const elapsedSuffix = (label) => label ? ` ${SUBTLE}\xB7${RESET2} ${label}` : "";
4159
+ const spin = `${SUCCESS}${localL2SpinnerFrame(now)}${RESET3}`;
4160
+ const segSep = ` ${SUBTLE}\u2502${RESET3} `;
4161
+ const elapsedSuffix = (label) => label ? ` ${SUBTLE}\xB7${RESET3} ${label}` : "";
4073
4162
  const l2Parts = [];
4074
4163
  const runningCount = localRunningWorkerCount(agentWorkers, agentJobs);
4075
4164
  if (runningCount > 0) {
4076
4165
  const label = `Running ${runningCount} Agent${runningCount === 1 ? "" : "s"}`;
4077
- const tagSummary = localRunningWorkerTags(agentWorkers, agentJobs);
4078
- const tags = tagSummary ? ` ${SUBTLE}(${RESET2}${STATUS}${tagSummary}${RESET2}${SUBTLE})${RESET2}` : "";
4079
4166
  const oldestStart = localOldestWorkerStartMs(agentWorkers, agentJobs);
4080
4167
  const elapsed = oldestStart > 0 ? localFormatElapsed(now - oldestStart) : "";
4081
- l2Parts.push(`${spin} ${STATUS}${label}${RESET2}${tags}${elapsedSuffix(elapsed)}`);
4168
+ l2Parts.push(`${spin} ${STATUS}${label}${RESET3}${elapsedSuffix(elapsed)}`);
4082
4169
  }
4083
4170
  const tools = activeTools && typeof activeTools === "object" ? activeTools : {};
4084
4171
  const exploreInfo = tools.explore || null;
4085
4172
  const searchInfo = tools.search || null;
4086
4173
  if (exploreInfo && localNum(exploreInfo.count) > 0) {
4087
4174
  const elapsed = localNum(exploreInfo.startedAt) > 0 ? localFormatElapsed(now - localNum(exploreInfo.startedAt)) : "";
4088
- l2Parts.push(`${spin} ${STATUS}Exploring${RESET2}${elapsedSuffix(elapsed)}`);
4175
+ l2Parts.push(`${spin} ${STATUS}Exploring${RESET3}${elapsedSuffix(elapsed)}`);
4089
4176
  }
4090
4177
  if (searchInfo && localNum(searchInfo.count) > 0) {
4091
4178
  const elapsed = localNum(searchInfo.startedAt) > 0 ? localFormatElapsed(now - localNum(searchInfo.startedAt)) : "";
4092
- l2Parts.push(`${spin} ${STATUS}Web Searching${RESET2}${elapsedSuffix(elapsed)}`);
4179
+ l2Parts.push(`${spin} ${STATUS}Web Searching${RESET3}${elapsedSuffix(elapsed)}`);
4093
4180
  }
4094
4181
  return l2Parts.length ? l2Parts.join(segSep) : "";
4095
4182
  }
@@ -4111,8 +4198,8 @@ function extractCachedShellSegments(cachedL2 = "", now = Date.now(), capturedAt
4111
4198
  const visible = stripAnsi(cachedL2);
4112
4199
  if (!visible) return [];
4113
4200
  const { STATUS, SUBTLE, SUCCESS } = statusColors();
4114
- const spin = `${SUCCESS}${localL2SpinnerFrame(now)}${RESET2}`;
4115
- const elapsedSuffix = (label) => label ? ` ${SUBTLE}\xB7${RESET2} ${label}` : "";
4201
+ const spin = `${SUCCESS}${localL2SpinnerFrame(now)}${RESET3}`;
4202
+ const elapsedSuffix = (label) => label ? ` ${SUBTLE}\xB7${RESET3} ${label}` : "";
4116
4203
  const out = [];
4117
4204
  for (const seg of visible.split(" \u2502 ")) {
4118
4205
  const m = /^(?:\S+\s+)?Running (\d+) Shells?\b(?:\s·\s(.+?))?\s*$/.exec(seg.trim());
@@ -4124,7 +4211,7 @@ function extractCachedShellSegments(cachedL2 = "", now = Date.now(), capturedAt
4124
4211
  const advancedMs = baseMs > 0 && capturedAt > 0 ? baseMs + Math.max(0, now - capturedAt) : baseMs;
4125
4212
  const elapsed = advancedMs > 0 ? localFormatElapsed(advancedMs) : cachedElapsedText;
4126
4213
  const label = `Running ${n} Shell${n === 1 ? "" : "s"}`;
4127
- out.push(`${spin} ${STATUS}${label}${RESET2}${elapsedSuffix(elapsed)}`);
4214
+ out.push(`${spin} ${STATUS}${label}${RESET3}${elapsedSuffix(elapsed)}`);
4128
4215
  }
4129
4216
  return out;
4130
4217
  }
@@ -4148,7 +4235,7 @@ function localBootStatusLine(args = {}) {
4148
4235
  terminalColumns()
4149
4236
  );
4150
4237
  const flags = [effort ? String(effort).toUpperCase() : "", fast === true ? "FAST" : ""].filter(Boolean);
4151
- const modelBits = [display, ...flags].join(` ${SUBTLE}\xB7${RESET2} `);
4238
+ const modelBits = [display, ...flags].join(` ${SUBTLE}\xB7${RESET3} `);
4152
4239
  const ctxPct = localContextPct({
4153
4240
  provider,
4154
4241
  stats,
@@ -4158,13 +4245,13 @@ function localBootStatusLine(args = {}) {
4158
4245
  compactBoundaryTokens,
4159
4246
  autoCompactTokenLimit
4160
4247
  });
4161
- const l1 = `${STATUS}${modelBits}${RESET2} ${SUBTLE}\u2502${RESET2} ${localContextSegmentFromPct(ctxPct)}`;
4248
+ const l1 = `${STATUS}${modelBits}${RESET3} ${SUBTLE}\u2502${RESET3} ${localContextSegmentFromPct(ctxPct)}`;
4162
4249
  const l2 = localStatusLineL2(args);
4163
4250
  return l2 ? `${l1}
4164
4251
  ${l2}` : l1;
4165
4252
  }
4166
4253
  function normalizeStatusLine(text) {
4167
- return normalizeStatuslineAnsi(text, statusColors(), { reset: RESET2 });
4254
+ return normalizeStatuslineAnsi(text, statusColors(), { reset: RESET3 });
4168
4255
  }
4169
4256
  function workflowModeLabel(workflow = {}, remoteEnabled = false) {
4170
4257
  const name = String(workflow?.name || workflow?.id || "Default").trim() || "Default";
@@ -4282,7 +4369,7 @@ function StatusLineView({ sessionId, clientHostPid, provider, model, effort, fas
4282
4369
  const freshL2 = localStatusLineL2(args, now);
4283
4370
  const shellSegments = extractCachedShellSegments(cachedL2, now, lastRawFullLineAtRef.current);
4284
4371
  const { SUBTLE } = statusColors();
4285
- const localSegSep = ` ${SUBTLE}\u2502${RESET2} `;
4372
+ const localSegSep = ` ${SUBTLE}\u2502${RESET3} `;
4286
4373
  const grafted = [freshL2, ...shellSegments].filter(Boolean).join(localSegSep);
4287
4374
  localNext = grafted ? `${cachedL1}
4288
4375
  ${grafted}` : cachedL1;
@@ -4384,11 +4471,11 @@ function isProblemCodePoint(cp) {
4384
4471
  return cp >= 9312 && cp <= 9471 || cp >= 8596 && cp <= 8703 && cp !== 8635;
4385
4472
  }
4386
4473
  var PROBLEM_RE = /[\u2194-\u21ff\u2460-\u24ff]/;
4387
- function resolveAmbiguousWidePolicy(env = process.env, platform = process.platform) {
4388
- const override = env?.MIXDOG_TUI_AMBIGUOUS_WIDE;
4474
+ function resolveAmbiguousWidePolicy(env2 = process.env, platform2 = process.platform) {
4475
+ const override = env2?.MIXDOG_TUI_AMBIGUOUS_WIDE;
4389
4476
  if (override === "1") return true;
4390
4477
  if (override === "0") return false;
4391
- return platform === "win32" || Boolean(env?.WT_SESSION);
4478
+ return platform2 === "win32" || Boolean(env2?.WT_SESSION);
4392
4479
  }
4393
4480
  var AMBIGUOUS_WIDE = resolveAmbiguousWidePolicy();
4394
4481
  function displayWidthWith(str, wide) {
@@ -7197,8 +7284,8 @@ function execFileBuffer(cmd, args, options = {}) {
7197
7284
  maxBuffer: 16 * 1024 * 1024,
7198
7285
  timeout: 5e3,
7199
7286
  ...options
7200
- }, (error, stdout, stderr) => {
7201
- resolve5({ ok: !error, code: error?.code ?? 0, stdout, stderr, error });
7287
+ }, (error, stdout2, stderr) => {
7288
+ resolve5({ ok: !error, code: error?.code ?? 0, stdout: stdout2, stderr, error });
7202
7289
  });
7203
7290
  });
7204
7291
  }
@@ -7541,7 +7628,7 @@ function runCapture(cmd, args, { timeoutMs = DIALOG_TIMEOUT_MS } = {}) {
7541
7628
  resolve5({ ok: false, code: -1, stdout: "", error });
7542
7629
  return;
7543
7630
  }
7544
- let stdout = "";
7631
+ let stdout2 = "";
7545
7632
  let settled = false;
7546
7633
  const timer2 = setTimeout(() => {
7547
7634
  if (settled) return;
@@ -7554,7 +7641,7 @@ function runCapture(cmd, args, { timeoutMs = DIALOG_TIMEOUT_MS } = {}) {
7554
7641
  }, timeoutMs);
7555
7642
  timer2.unref?.();
7556
7643
  child.stdout.on("data", (chunk) => {
7557
- stdout += chunk.toString("utf8");
7644
+ stdout2 += chunk.toString("utf8");
7558
7645
  });
7559
7646
  child.on("error", (error) => {
7560
7647
  if (settled) return;
@@ -7566,7 +7653,7 @@ function runCapture(cmd, args, { timeoutMs = DIALOG_TIMEOUT_MS } = {}) {
7566
7653
  if (settled) return;
7567
7654
  settled = true;
7568
7655
  clearTimeout(timer2);
7569
- resolve5({ ok: code === 0, code, stdout });
7656
+ resolve5({ ok: code === 0, code, stdout: stdout2 });
7570
7657
  });
7571
7658
  });
7572
7659
  }
@@ -7768,8 +7855,8 @@ namespace Mixdog {
7768
7855
  ].join("\n");
7769
7856
  }
7770
7857
  async function pickFolder({ title = "Select a project folder", initialPath = "" } = {}) {
7771
- const platform = process.platform;
7772
- if (platform === "win32") {
7858
+ const platform2 = process.platform;
7859
+ if (platform2 === "win32") {
7773
7860
  const resolvedInitial = resolveInitialPath(initialPath);
7774
7861
  const result = await runCapture("powershell.exe", [
7775
7862
  "-NoLogo",
@@ -7784,7 +7871,7 @@ async function pickFolder({ title = "Select a project folder", initialPath = ""
7784
7871
  if (!result.ok && !path2) return { available: false, path: null };
7785
7872
  return { available: true, path: path2 || null };
7786
7873
  }
7787
- if (platform === "darwin") {
7874
+ if (platform2 === "darwin") {
7788
7875
  const safeTitle = String(title).replace(/"/g, '\\"');
7789
7876
  const script = `set f to choose folder with prompt "${safeTitle}"
7790
7877
  POSIX path of f`;
@@ -9206,6 +9293,7 @@ function renderTokenAnsiSegments(content, opts = {}) {
9206
9293
  // src/tui/markdown/streaming-markdown.mjs
9207
9294
  import { marked as marked2 } from "marked";
9208
9295
  var stablePrefixByStreamKey = /* @__PURE__ */ new Map();
9296
+ var resolvedPartsByStreamKey = /* @__PURE__ */ new Map();
9209
9297
  var STABLE_PREFIX_LRU_MAX = 32;
9210
9298
  function streamingLayoutText(text) {
9211
9299
  return String(text ?? "").replace(/^\n+|\n+$/g, "");
@@ -9230,6 +9318,23 @@ function getStablePrefixKey(key) {
9230
9318
  stablePrefixByStreamKey.set(key, value);
9231
9319
  return value;
9232
9320
  }
9321
+ function getResolvedPartsKey(key, text) {
9322
+ if (!key) return null;
9323
+ const entry = resolvedPartsByStreamKey.get(key);
9324
+ if (!entry || entry.text !== text) return null;
9325
+ return entry.parts;
9326
+ }
9327
+ function cacheResolvedPartsKey(key, text, parts) {
9328
+ if (!key) return parts;
9329
+ if (resolvedPartsByStreamKey.has(key)) resolvedPartsByStreamKey.delete(key);
9330
+ resolvedPartsByStreamKey.set(key, { text, parts });
9331
+ while (resolvedPartsByStreamKey.size > STABLE_PREFIX_LRU_MAX) {
9332
+ const oldest = resolvedPartsByStreamKey.keys().next().value;
9333
+ if (oldest === void 0) break;
9334
+ resolvedPartsByStreamKey.delete(oldest);
9335
+ }
9336
+ return parts;
9337
+ }
9233
9338
  function hasOpenFence(text) {
9234
9339
  let ticks = 0;
9235
9340
  let tildes = 0;
@@ -9282,31 +9387,36 @@ function balanceStreamingMarkdown(text) {
9282
9387
  }
9283
9388
  function resetStreamingMarkdownStablePrefix(streamKey) {
9284
9389
  if (streamKey == null || streamKey === "") return;
9285
- stablePrefixByStreamKey.delete(String(streamKey));
9390
+ const key = String(streamKey);
9391
+ stablePrefixByStreamKey.delete(key);
9392
+ resolvedPartsByStreamKey.delete(key);
9286
9393
  }
9287
9394
  function resetAllStreamingMarkdownStablePrefixes() {
9288
9395
  stablePrefixByStreamKey.clear();
9396
+ resolvedPartsByStreamKey.clear();
9289
9397
  }
9290
9398
  function resolveStreamingMarkdownParts(text, streamKey) {
9291
9399
  const t = streamingLayoutText(text);
9292
9400
  const key = streamKey == null || streamKey === "" ? null : String(streamKey);
9401
+ const cachedParts = getResolvedPartsKey(key, t);
9402
+ if (cachedParts) return cachedParts;
9293
9403
  if (!t) {
9294
9404
  if (key) stablePrefixByStreamKey.delete(key);
9295
- return {
9405
+ return cacheResolvedPartsKey(key, t, {
9296
9406
  plain: true,
9297
9407
  stablePrefix: "",
9298
9408
  unstableSuffix: "",
9299
9409
  unstableForRender: ""
9300
- };
9410
+ });
9301
9411
  }
9302
9412
  if (!hasMarkdownSyntax(t)) {
9303
9413
  if (key) stablePrefixByStreamKey.delete(key);
9304
- return {
9414
+ return cacheResolvedPartsKey(key, t, {
9305
9415
  plain: true,
9306
9416
  stablePrefix: "",
9307
9417
  unstableSuffix: t,
9308
9418
  unstableForRender: t
9309
- };
9419
+ });
9310
9420
  }
9311
9421
  let stablePrefix = key ? getStablePrefixKey(key) : "";
9312
9422
  if (!t.startsWith(stablePrefix)) {
@@ -9319,13 +9429,13 @@ function resolveStreamingMarkdownParts(text, streamKey) {
9319
9429
  if (key && openPrefix) touchStablePrefixKey(key, openPrefix);
9320
9430
  else if (key) stablePrefixByStreamKey.delete(key);
9321
9431
  const unstableSuffix2 = t.substring(openPrefix.length);
9322
- return {
9432
+ return cacheResolvedPartsKey(key, t, {
9323
9433
  plain: false,
9324
9434
  openFence: true,
9325
9435
  stablePrefix: openPrefix,
9326
9436
  unstableSuffix: unstableSuffix2,
9327
9437
  unstableForRender: unstableSuffix2
9328
- };
9438
+ });
9329
9439
  }
9330
9440
  try {
9331
9441
  configureMarked();
@@ -9354,12 +9464,12 @@ function resolveStreamingMarkdownParts(text, streamKey) {
9354
9464
  }
9355
9465
  if (isWhitespaceOnlyText(stablePrefix)) stablePrefix = "";
9356
9466
  const unstableSuffix = t.substring(stablePrefix.length);
9357
- return {
9467
+ return cacheResolvedPartsKey(key, t, {
9358
9468
  plain: false,
9359
9469
  stablePrefix,
9360
9470
  unstableSuffix,
9361
9471
  unstableForRender: balanceStreamingMarkdown(unstableSuffix)
9362
- };
9472
+ });
9363
9473
  }
9364
9474
 
9365
9475
  // src/tui/markdown/measure-rendered-rows.mjs
@@ -10726,7 +10836,7 @@ function useMouseInput({
10726
10836
  inkInput,
10727
10837
  isRawModeSupported,
10728
10838
  store,
10729
- stdout,
10839
+ stdout: stdout2,
10730
10840
  rows,
10731
10841
  statuslineBandRows,
10732
10842
  dragRef,
@@ -10752,16 +10862,16 @@ function useMouseInput({
10752
10862
  const zoomTimerRef = useRef7(null);
10753
10863
  const edgeAutoscrollRef = useRef7({ dir: 0, timer: null, noMove: 0 });
10754
10864
  const passthroughCtrlWheelZoom = useCallback2(() => {
10755
- if (!stdout?.write) return;
10865
+ if (!stdout2?.write) return;
10756
10866
  try {
10757
- stdout.write(MOUSE_TRACKING_OFF + ALT_SCROLL_OFF);
10867
+ stdout2.write(MOUSE_TRACKING_OFF + ALT_SCROLL_OFF);
10758
10868
  } catch {
10759
10869
  return;
10760
10870
  }
10761
10871
  const restore = (attempt) => {
10762
10872
  zoomTimerRef.current = null;
10763
10873
  try {
10764
- stdout.write(MOUSE_TRACKING_ON + ALT_SCROLL_OFF);
10874
+ stdout2.write(MOUSE_TRACKING_ON + ALT_SCROLL_OFF);
10765
10875
  } catch {
10766
10876
  if (attempt < 5) {
10767
10877
  zoomTimerRef.current = setTimeout(() => restore(attempt + 1), 200);
@@ -10772,7 +10882,7 @@ function useMouseInput({
10772
10882
  if (zoomTimerRef.current) clearTimeout(zoomTimerRef.current);
10773
10883
  zoomTimerRef.current = setTimeout(() => restore(0), 700);
10774
10884
  zoomTimerRef.current.unref?.();
10775
- }, [stdout, zoomTimerRef]);
10885
+ }, [stdout2, zoomTimerRef]);
10776
10886
  useEffect7(() => () => {
10777
10887
  if (zoomTimerRef.current) clearTimeout(zoomTimerRef.current);
10778
10888
  }, [zoomTimerRef]);
@@ -11837,7 +11947,11 @@ function useTranscriptWindow({
11837
11947
  floatingPanelRows: Number(floatingPanelRows) || 0
11838
11948
  };
11839
11949
  if (scrolledUp && !followingRef.current) {
11840
- const growth = streamingTailMountedGrowth(transcriptItems, frameColumns, toolOutputExpanded);
11950
+ const growth = streamingTailMountedGrowth(
11951
+ streamingTailItem ? [streamingTailItem] : transcriptItems,
11952
+ frameColumns,
11953
+ toolOutputExpanded
11954
+ );
11841
11955
  if (growth && growth.delta > 0) {
11842
11956
  const maxOffsetKeepingTailMounted = growth.tailRows + TRANSCRIPT_WINDOW_OVERSCAN_ROWS - 1;
11843
11957
  if (renderScrollOffset <= maxOffsetKeepingTailMounted) {
@@ -12125,9 +12239,9 @@ function useTranscriptWindow({
12125
12239
  import stringWidth8 from "string-width";
12126
12240
  var SEARCH_DEFAULT_ROUTE = Object.freeze({ provider: "default", model: "default" });
12127
12241
  var isSearchDefaultRoute = (route) => String(route?.provider || "").toLowerCase() === "default" && String(route?.model || "").toLowerCase() === "default";
12128
- function terminalSize(stdout) {
12129
- const columns = stdout?.columns;
12130
- const rows = stdout?.rows;
12242
+ function terminalSize(stdout2) {
12243
+ const columns = stdout2?.columns;
12244
+ const rows = stdout2?.rows;
12131
12245
  if (columns && rows) return { columns, rows };
12132
12246
  return {
12133
12247
  columns: columns || 80,
@@ -14685,11 +14799,11 @@ async function _resolveCurrentUserPrincipalAsync() {
14685
14799
  const whoami = join4(systemRoot, "System32", "whoami.exe");
14686
14800
  if (existsSync4(whoami)) {
14687
14801
  try {
14688
- const { stdout } = await _execFileAsync(whoami, ["/user", "/fo", "csv", "/nh"], {
14802
+ const { stdout: stdout2 } = await _execFileAsync(whoami, ["/user", "/fo", "csv", "/nh"], {
14689
14803
  encoding: "utf8",
14690
14804
  windowsHide: true
14691
14805
  });
14692
- const m = String(stdout).match(/S-1-5-[0-9-]+/);
14806
+ const m = String(stdout2).match(/S-1-5-[0-9-]+/);
14693
14807
  if (m) return m[0];
14694
14808
  } catch {
14695
14809
  }
@@ -16130,6 +16244,7 @@ function createProviderSetupPicker({
16130
16244
  setContextPanel(null);
16131
16245
  closeUsagePanel();
16132
16246
  let setup = options.preloadedSetup && typeof options.preloadedSetup === "object" ? options.preloadedSetup : null;
16247
+ options.preloadedSetup = null;
16133
16248
  if (!setup) {
16134
16249
  setPicker({
16135
16250
  title: options.title || "Providers",
@@ -19406,11 +19521,11 @@ function App({ store, initialStatusLine = "", forceOnboarding = false }) {
19406
19521
  const [onboardingActive, setOnboardingActive] = useState8(false);
19407
19522
  const { exit } = useApp();
19408
19523
  const { isRawModeSupported, stdin, internal_eventEmitter: inkInput } = useStdin3();
19409
- const { stdout } = useStdout2();
19524
+ const { stdout: stdout2 } = useStdout2();
19410
19525
  const [exiting, setExiting] = useState8(false);
19411
19526
  const [tuiReady, setTuiReady] = useState8(false);
19412
19527
  const exitRequestedRef = useRef10(false);
19413
- const [resizeState, setResizeState] = useState8(() => ({ ...terminalSize(stdout), epoch: 0 }));
19528
+ const [resizeState, setResizeState] = useState8(() => ({ ...terminalSize(stdout2), epoch: 0 }));
19414
19529
  const [panelTransitionEpoch, setPanelTransitionEpoch] = useState8(0);
19415
19530
  const [panelInkMaskEpoch, setPanelInkMaskEpoch] = useState8(0);
19416
19531
  const windowsLikeTerminal = process.platform === "win32" || Boolean(process.env.WT_SESSION);
@@ -19925,13 +20040,13 @@ function App({ store, initialStatusLine = "", forceOnboarding = false }) {
19925
20040
  return () => clearTimeout(timer2);
19926
20041
  }, []);
19927
20042
  useEffect10(() => {
19928
- if (!stdout) return void 0;
20043
+ if (!stdout2) return void 0;
19929
20044
  let trailing = null;
19930
20045
  const DEBOUNCE_MS = 80;
19931
20046
  let lastRun = 0;
19932
20047
  const update = () => {
19933
20048
  setResizeState((prev) => {
19934
- const next = terminalSize(stdout);
20049
+ const next = terminalSize(stdout2);
19935
20050
  if (next.columns === prev.columns && next.rows === prev.rows) return prev;
19936
20051
  return {
19937
20052
  ...next,
@@ -19952,13 +20067,13 @@ function App({ store, initialStatusLine = "", forceOnboarding = false }) {
19952
20067
  update();
19953
20068
  }, DEBOUNCE_MS);
19954
20069
  };
19955
- stdout.on("resize", onResize);
20070
+ stdout2.on("resize", onResize);
19956
20071
  update();
19957
20072
  return () => {
19958
20073
  if (trailing) clearTimeout(trailing);
19959
- stdout.off("resize", onResize);
20074
+ stdout2.off("resize", onResize);
19960
20075
  };
19961
- }, [stdout]);
20076
+ }, [stdout2]);
19962
20077
  const clearPromptHint = useCallback6(() => {
19963
20078
  if (!promptHintActiveRef.current && !promptHintTimerRef.current) return;
19964
20079
  if (promptHintTimerRef.current) {
@@ -20120,7 +20235,7 @@ function App({ store, initialStatusLine = "", forceOnboarding = false }) {
20120
20235
  inkInput,
20121
20236
  isRawModeSupported,
20122
20237
  store,
20123
- stdout,
20238
+ stdout: stdout2,
20124
20239
  rows: resizeState.rows,
20125
20240
  statuslineBandRows: STATUSLINE_BAND_ROWS,
20126
20241
  dragRef,
@@ -20144,10 +20259,10 @@ function App({ store, initialStatusLine = "", forceOnboarding = false }) {
20144
20259
  clearStitchBuffer
20145
20260
  });
20146
20261
  useEffect10(() => {
20147
- if (!isRawModeSupported || !stdout?.write) return;
20262
+ if (!isRawModeSupported || !stdout2?.write) return;
20148
20263
  if (!supportsExtendedKeys()) return;
20149
20264
  try {
20150
- stdout.write(ENABLE_KITTY_KEYBOARD + ENABLE_MODIFY_OTHER_KEYS);
20265
+ stdout2.write(ENABLE_KITTY_KEYBOARD + ENABLE_MODIFY_OTHER_KEYS);
20151
20266
  } catch {
20152
20267
  }
20153
20268
  }, []);
@@ -24054,6 +24169,7 @@ function createSessionFlow(bag) {
24054
24169
  pendingNotificationKeys,
24055
24170
  displayedExecutionNotificationKeys,
24056
24171
  clearExecutionDedupState,
24172
+ clearToastTimers,
24057
24173
  getState,
24058
24174
  set,
24059
24175
  pushItem,
@@ -24356,7 +24472,14 @@ function createSessionFlow(bag) {
24356
24472
  useCompaction: true
24357
24473
  });
24358
24474
  }
24359
- async function performSessionClear({ verb, doneLabel, skipLabel, surface, useCompaction }) {
24475
+ async function performSessionClear({
24476
+ verb,
24477
+ doneLabel,
24478
+ skipLabel,
24479
+ surface,
24480
+ useCompaction,
24481
+ compactTimeoutMs = AUTO_CLEAR_COMPACT_TIMEOUT_MS
24482
+ }) {
24360
24483
  flags.autoClearRunning = true;
24361
24484
  const startedAt = Date.now();
24362
24485
  set({ commandBusy: true, commandStatus: { active: true, verb, startedAt, mode: "auto-clear" } });
@@ -24367,21 +24490,23 @@ function createSessionFlow(bag) {
24367
24490
  const compaction = runtime.getCompactionSettings();
24368
24491
  compactType = compaction.compactType || compaction.type || null;
24369
24492
  }
24493
+ let clearResult;
24370
24494
  if (compactType) {
24371
24495
  const clearPromise = runtime.clear({ compactType, requireCompactSuccess: true });
24372
24496
  let timer2 = null;
24373
24497
  const timeout = new Promise((_, reject) => {
24374
24498
  timer2 = setTimeout(
24375
- () => reject(new Error(`compaction timed out after ${AUTO_CLEAR_COMPACT_TIMEOUT_MS}ms; auto-clear deferred to next idle`)),
24376
- AUTO_CLEAR_COMPACT_TIMEOUT_MS
24499
+ () => reject(new Error(`compaction timed out after ${compactTimeoutMs}ms; auto-clear deferred to next idle`)),
24500
+ compactTimeoutMs
24377
24501
  );
24378
24502
  });
24379
24503
  try {
24380
- await Promise.race([clearPromise, timeout]);
24504
+ clearResult = await Promise.race([clearPromise, timeout]);
24381
24505
  } catch (raceError) {
24382
24506
  flags.autoClearInFlight = true;
24383
24507
  clearPromise.then(
24384
- () => {
24508
+ (lateResult) => {
24509
+ if (lateResult === false) return;
24385
24510
  if (getState().busy) {
24386
24511
  flags.pendingClearedSessionUi = { doneLabel, surface };
24387
24512
  } else {
@@ -24399,7 +24524,10 @@ function createSessionFlow(bag) {
24399
24524
  if (timer2) clearTimeout(timer2);
24400
24525
  }
24401
24526
  } else {
24402
- await runtime.clear({});
24527
+ clearResult = await runtime.clear({});
24528
+ }
24529
+ if (clearResult === false) {
24530
+ throw new Error("runtime clear returned false");
24403
24531
  }
24404
24532
  applyClearedSessionUi(doneLabel);
24405
24533
  return true;
@@ -24441,6 +24569,8 @@ function createSessionFlow(bag) {
24441
24569
  return getState().stats;
24442
24570
  };
24443
24571
  const clearUiActivityBeforeContextSync = () => {
24572
+ clearToastTimers();
24573
+ resetAllStreamingMarkdownStablePrefixes();
24444
24574
  getState().items = replaceItems([]);
24445
24575
  getState().toasts = [];
24446
24576
  getState().queued = [];
@@ -24546,6 +24676,7 @@ function createRunTurn(bag) {
24546
24676
  set,
24547
24677
  pushItem,
24548
24678
  patchItem,
24679
+ replaceItems,
24549
24680
  updateStreamingTail: updateStreamingTailFromStore,
24550
24681
  settleStreamingTail: settleStreamingTailFromStore,
24551
24682
  clearStreamingTail: clearStreamingTailFromStore,
@@ -24734,7 +24865,11 @@ function createRunTurn(bag) {
24734
24865
  let cancelled = false;
24735
24866
  let askResult = null;
24736
24867
  let turnFinishedNormally = false;
24868
+ let transcriptCompactedThisTurn = false;
24737
24869
  const itemsAtTurnStart = getState().items.length;
24870
+ const submittedIdSet = new Set(submittedIds.filter((id) => id != null));
24871
+ const firstSubmittedIndex = getState().items.findIndex((item) => submittedIdSet.has(item?.id));
24872
+ let currentTurnItemsStart = firstSubmittedIndex >= 0 ? firstSubmittedIndex : itemsAtTurnStart;
24738
24873
  const cardByCallId = /* @__PURE__ */ new Map();
24739
24874
  const toolCards = [];
24740
24875
  const toolGroups = /* @__PURE__ */ new Map();
@@ -25301,6 +25436,13 @@ function createRunTurn(bag) {
25301
25436
  if (!markTurnProgress("compact-event")) return;
25302
25437
  flushStreamBatch();
25303
25438
  clearAggregateContinuation();
25439
+ const compactStatus = String(event?.status || "").toLowerCase();
25440
+ if (!["failed", "skipped", "no_change"].includes(compactStatus)) {
25441
+ const currentTurnItems = getState().items.slice(currentTurnItemsStart);
25442
+ set({ items: replaceItems(currentTurnItems, { preserveStreamingTail: true }) });
25443
+ currentTurnItemsStart = 0;
25444
+ transcriptCompactedThisTurn = true;
25445
+ }
25304
25446
  pushItem({
25305
25447
  kind: "statusdone",
25306
25448
  id: nextId2(),
@@ -25399,6 +25541,13 @@ function createRunTurn(bag) {
25399
25541
  } else {
25400
25542
  askResult = result;
25401
25543
  markPromptCommitted();
25544
+ if (result?.terminationReason === "refusal") {
25545
+ pushNotice(
25546
+ "The model refused to respond (safety refusal) \u2014 retry or rephrase your prompt.",
25547
+ "warn",
25548
+ { transcript: true }
25549
+ );
25550
+ }
25402
25551
  flushToolResults(session?.messages || [], toolCards, cardByCallId, toolGroups, resultsDone, { finalize: true });
25403
25552
  finalizeToolHeaders();
25404
25553
  flushStreamBatch();
@@ -25464,7 +25613,7 @@ function createRunTurn(bag) {
25464
25613
  clearStreamingTail(currentAssistantId);
25465
25614
  }
25466
25615
  }
25467
- const producedTranscriptItem = getState().items.length + closingItems.length > itemsAtTurnStart;
25616
+ const producedTranscriptItem = transcriptCompactedThisTurn || getState().items.length + closingItems.length > itemsAtTurnStart;
25468
25617
  const reclaimed = cancelled && flags.activePromptRestore?.reclaimed === true;
25469
25618
  flags.activePromptRestore = null;
25470
25619
  const elapsedMs = Date.now() - startedAt;
@@ -26667,6 +26816,9 @@ function createEngineApiA(bag) {
26667
26816
  syncContextStats({ allowEstimated: true });
26668
26817
  set({ ...routeState(), stats: { ...getState().stats } });
26669
26818
  if (result) {
26819
+ if (!result.error && result.changed !== false) {
26820
+ set({ items: replaceItems([]) });
26821
+ }
26670
26822
  pushItem({
26671
26823
  kind: "statusdone",
26672
26824
  id: nextId2(),
@@ -27308,7 +27460,6 @@ async function createEngineSession({
27308
27460
  requestToolApproval,
27309
27461
  patchToolCardResult,
27310
27462
  flushToolResults,
27311
- clearExecutionDedupState,
27312
27463
  kickExecutionPendingResume,
27313
27464
  flushDeferredExecutionPendingResumeKick,
27314
27465
  scheduleExecutionPendingResumeKick,
@@ -27694,7 +27845,7 @@ function resolveTuiStderrLogPath() {
27694
27845
  }
27695
27846
  function ansiFg(rgb) {
27696
27847
  const m = /rgb\((\d+),\s*(\d+),\s*(\d+)\)/.exec(String(rgb || ""));
27697
- return m ? `\x1B[38;2;${m[1]};${m[2]};${m[3]}m` : "";
27848
+ return m ? rgbSgr(m[1], m[2], m[3]) : "";
27698
27849
  }
27699
27850
  function paintBootSplash() {
27700
27851
  try {
@@ -27713,12 +27864,12 @@ function paintBootSplash() {
27713
27864
  const textFg = ansiFg(theme.text);
27714
27865
  const logoFg = ansiFg(theme.logo ?? theme.claude) || textFg;
27715
27866
  const subtleFg = ansiFg(theme.inactive);
27716
- const bold = "\x1B[1m";
27867
+ const bold2 = "\x1B[1m";
27717
27868
  const reset = "\x1B[0m";
27718
27869
  let out = "\x1B[4;1H";
27719
27870
  for (let i = 0; i < logo.length; i++) {
27720
27871
  const fg = i < 2 ? textFg : logoFg;
27721
- out += `${bold}${fg}${center(logo[i])}${reset}\r
27872
+ out += `${bold2}${fg}${center(logo[i])}${reset}\r
27722
27873
  `;
27723
27874
  }
27724
27875
  out += "\r\n";