@code-yeongyu/senpi 2026.5.14 → 2026.5.15-2

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 (161) hide show
  1. package/CHANGELOG.md +1107 -1182
  2. package/README.md +1 -2
  3. package/dist/core/agent-session.d.ts +9 -0
  4. package/dist/core/agent-session.d.ts.map +1 -1
  5. package/dist/core/agent-session.js +109 -7
  6. package/dist/core/agent-session.js.map +1 -1
  7. package/dist/core/dynamic-prompt/verification.d.ts +31 -0
  8. package/dist/core/dynamic-prompt/verification.d.ts.map +1 -1
  9. package/dist/core/dynamic-prompt/verification.js +41 -0
  10. package/dist/core/dynamic-prompt/verification.js.map +1 -1
  11. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  12. package/dist/core/extensions/builtin/compaction/index.js +157 -29
  13. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  14. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts +197 -0
  15. package/dist/core/extensions/builtin/compaction/openai-remote.d.ts.map +1 -0
  16. package/dist/core/extensions/builtin/compaction/openai-remote.js +690 -0
  17. package/dist/core/extensions/builtin/compaction/openai-remote.js.map +1 -0
  18. package/dist/core/extensions/builtin/compaction/prompts.d.ts +3 -3
  19. package/dist/core/extensions/builtin/compaction/prompts.d.ts.map +1 -1
  20. package/dist/core/extensions/builtin/compaction/prompts.js +0 -22
  21. package/dist/core/extensions/builtin/compaction/prompts.js.map +1 -1
  22. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts +4 -0
  23. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts.map +1 -0
  24. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js +48 -0
  25. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js.map +1 -0
  26. package/dist/core/extensions/builtin/compaction/speculative.d.ts +3 -1
  27. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  28. package/dist/core/extensions/builtin/compaction/speculative.js +82 -33
  29. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  30. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts +8 -0
  31. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/todo-bridge.js +12 -6
  33. package/dist/core/extensions/builtin/compaction/todo-bridge.js.map +1 -1
  34. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/index.js +0 -2
  36. package/dist/core/extensions/builtin/index.js.map +1 -1
  37. package/dist/core/extensions/builtin/permission-system/prompt.d.ts.map +1 -1
  38. package/dist/core/extensions/builtin/permission-system/prompt.js +0 -5
  39. package/dist/core/extensions/builtin/permission-system/prompt.js.map +1 -1
  40. package/dist/core/extensions/builtin/system-messages.d.ts +7 -7
  41. package/dist/core/extensions/builtin/system-messages.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/system-messages.js +10 -10
  43. package/dist/core/extensions/builtin/system-messages.js.map +1 -1
  44. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts +1 -1
  45. package/dist/core/extensions/builtin/todotools/continuation/prompt.d.ts.map +1 -1
  46. package/dist/core/extensions/builtin/todotools/continuation/prompt.js +1 -1
  47. package/dist/core/extensions/builtin/todotools/continuation/prompt.js.map +1 -1
  48. package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
  49. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/todotools/state.js +1 -1
  51. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  52. package/dist/core/extensions/builtin/todotools/system-messages.d.ts +3 -3
  53. package/dist/core/extensions/builtin/todotools/system-messages.d.ts.map +1 -1
  54. package/dist/core/extensions/builtin/todotools/system-messages.js +6 -6
  55. package/dist/core/extensions/builtin/todotools/system-messages.js.map +1 -1
  56. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts +1 -1
  57. package/dist/core/extensions/builtin/tool-pair-guard/index.d.ts.map +1 -1
  58. package/dist/core/extensions/builtin/tool-pair-guard/index.js +8 -4
  59. package/dist/core/extensions/builtin/tool-pair-guard/index.js.map +1 -1
  60. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts +3 -0
  61. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.d.ts.map +1 -0
  62. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js +89 -0
  63. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-chat-completions-payload.js.map +1 -0
  64. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts +3 -0
  65. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.d.ts.map +1 -0
  66. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js +122 -0
  67. package/dist/core/extensions/builtin/tool-pair-guard/sanitize-openai-responses-payload.js.map +1 -0
  68. package/dist/core/extensions/loader.d.ts.map +1 -1
  69. package/dist/core/extensions/loader.js +2 -0
  70. package/dist/core/extensions/loader.js.map +1 -1
  71. package/dist/core/extensions/runner.d.ts +3 -0
  72. package/dist/core/extensions/runner.d.ts.map +1 -1
  73. package/dist/core/extensions/runner.js +18 -0
  74. package/dist/core/extensions/runner.js.map +1 -1
  75. package/dist/core/extensions/types.d.ts +22 -0
  76. package/dist/core/extensions/types.d.ts.map +1 -1
  77. package/dist/core/extensions/types.js.map +1 -1
  78. package/dist/core/messages.d.ts +3 -3
  79. package/dist/core/messages.d.ts.map +1 -1
  80. package/dist/core/messages.js +5 -10
  81. package/dist/core/messages.js.map +1 -1
  82. package/dist/core/sdk.d.ts +1 -1
  83. package/dist/core/sdk.d.ts.map +1 -1
  84. package/dist/core/sdk.js +7 -22
  85. package/dist/core/sdk.js.map +1 -1
  86. package/dist/core/session-manager.d.ts.map +1 -1
  87. package/dist/core/session-manager.js +1 -1
  88. package/dist/core/session-manager.js.map +1 -1
  89. package/dist/core/settings-manager.d.ts +0 -5
  90. package/dist/core/settings-manager.d.ts.map +1 -1
  91. package/dist/core/settings-manager.js.map +1 -1
  92. package/dist/core/thinking-levels.d.ts +6 -0
  93. package/dist/core/thinking-levels.d.ts.map +1 -0
  94. package/dist/core/thinking-levels.js +36 -0
  95. package/dist/core/thinking-levels.js.map +1 -0
  96. package/dist/core/tools/bash.d.ts.map +1 -1
  97. package/dist/core/tools/bash.js +15 -1
  98. package/dist/core/tools/bash.js.map +1 -1
  99. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  100. package/dist/modes/interactive/components/compaction-summary-message.js +20 -2
  101. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  102. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  103. package/dist/modes/interactive/components/keybinding-hints.js +3 -1
  104. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  105. package/dist/modes/interactive/interactive-mode.d.ts +11 -0
  106. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  107. package/dist/modes/interactive/interactive-mode.js +96 -49
  108. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  109. package/docs/extensions.md +0 -1
  110. package/docs/index.md +0 -1
  111. package/docs/sdk.md +0 -1
  112. package/docs/settings.md +1 -29
  113. package/docs/termux.md +2 -2
  114. package/docs/usage.md +1 -1
  115. package/examples/README.md +1 -1
  116. package/examples/extensions/README.md +0 -1
  117. package/examples/extensions/overlay-qa-tests.ts +1 -1
  118. package/package.json +4 -4
  119. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts +0 -10
  120. package/dist/core/extensions/builtin/background-task/cancel-tool.d.ts.map +0 -1
  121. package/dist/core/extensions/builtin/background-task/cancel-tool.js +0 -109
  122. package/dist/core/extensions/builtin/background-task/cancel-tool.js.map +0 -1
  123. package/dist/core/extensions/builtin/background-task/index.d.ts +0 -3
  124. package/dist/core/extensions/builtin/background-task/index.d.ts.map +0 -1
  125. package/dist/core/extensions/builtin/background-task/index.js +0 -207
  126. package/dist/core/extensions/builtin/background-task/index.js.map +0 -1
  127. package/dist/core/extensions/builtin/background-task/manager.d.ts +0 -17
  128. package/dist/core/extensions/builtin/background-task/manager.d.ts.map +0 -1
  129. package/dist/core/extensions/builtin/background-task/manager.js +0 -114
  130. package/dist/core/extensions/builtin/background-task/manager.js.map +0 -1
  131. package/dist/core/extensions/builtin/background-task/notification.d.ts +0 -22
  132. package/dist/core/extensions/builtin/background-task/notification.d.ts.map +0 -1
  133. package/dist/core/extensions/builtin/background-task/notification.js +0 -105
  134. package/dist/core/extensions/builtin/background-task/notification.js.map +0 -1
  135. package/dist/core/extensions/builtin/background-task/output-tool.d.ts +0 -11
  136. package/dist/core/extensions/builtin/background-task/output-tool.d.ts.map +0 -1
  137. package/dist/core/extensions/builtin/background-task/output-tool.js +0 -127
  138. package/dist/core/extensions/builtin/background-task/output-tool.js.map +0 -1
  139. package/dist/core/extensions/builtin/background-task/spawner.d.ts +0 -8
  140. package/dist/core/extensions/builtin/background-task/spawner.d.ts.map +0 -1
  141. package/dist/core/extensions/builtin/background-task/spawner.js +0 -207
  142. package/dist/core/extensions/builtin/background-task/spawner.js.map +0 -1
  143. package/dist/core/extensions/builtin/background-task/task-tool.d.ts +0 -20
  144. package/dist/core/extensions/builtin/background-task/task-tool.d.ts.map +0 -1
  145. package/dist/core/extensions/builtin/background-task/task-tool.js +0 -302
  146. package/dist/core/extensions/builtin/background-task/task-tool.js.map +0 -1
  147. package/dist/core/extensions/builtin/background-task/types.d.ts +0 -72
  148. package/dist/core/extensions/builtin/background-task/types.d.ts.map +0 -1
  149. package/dist/core/extensions/builtin/background-task/types.js +0 -32
  150. package/dist/core/extensions/builtin/background-task/types.js.map +0 -1
  151. package/docs/agents.md +0 -348
  152. package/examples/extensions/subagent/README.md +0 -172
  153. package/examples/extensions/subagent/agents/planner.md +0 -37
  154. package/examples/extensions/subagent/agents/reviewer.md +0 -35
  155. package/examples/extensions/subagent/agents/scout.md +0 -50
  156. package/examples/extensions/subagent/agents/worker.md +0 -24
  157. package/examples/extensions/subagent/agents.ts +0 -126
  158. package/examples/extensions/subagent/index.ts +0 -987
  159. package/examples/extensions/subagent/prompts/implement-and-review.md +0 -10
  160. package/examples/extensions/subagent/prompts/implement.md +0 -10
  161. package/examples/extensions/subagent/prompts/scout-and-plan.md +0 -9
@@ -76,6 +76,7 @@ class ExpandableText extends Text {
76
76
  }
77
77
  }
78
78
  const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
79
+ const DEFAULT_WORKING_STATUS_REFRESH_INTERVAL_MS = 600;
79
80
  function isDeadTerminalError(error) {
80
81
  if (!error || typeof error !== "object" || !("code" in error)) {
81
82
  return false;
@@ -83,6 +84,23 @@ function isDeadTerminalError(error) {
83
84
  const code = error.code;
84
85
  return code !== undefined && DEAD_TERMINAL_ERROR_CODES.has(code);
85
86
  }
87
+ export function formatWorkingElapsedSeconds(elapsedSeconds) {
88
+ const totalSeconds = Math.max(0, Math.floor(elapsedSeconds));
89
+ const seconds = totalSeconds % 60;
90
+ const totalMinutes = Math.floor(totalSeconds / 60);
91
+ if (totalSeconds < 60) {
92
+ return `${totalSeconds}s`;
93
+ }
94
+ if (totalSeconds < 3600) {
95
+ return `${totalMinutes}m ${seconds.toString().padStart(2, "0")}s`;
96
+ }
97
+ const hours = Math.floor(totalMinutes / 60);
98
+ const minutes = totalMinutes % 60;
99
+ return `${hours}h ${minutes.toString().padStart(2, "0")}m ${seconds.toString().padStart(2, "0")}s`;
100
+ }
101
+ export function formatWorkingStatusMessage(message, elapsedSeconds, interruptKey) {
102
+ return `${message} (${formatWorkingElapsedSeconds(elapsedSeconds)} • ${interruptKey} to interrupt)`;
103
+ }
86
104
  const ANTHROPIC_SUBSCRIPTION_AUTH_WARNING = "Anthropic subscription auth is active. Third-party harness usage draws from extra usage and is billed per token, not your Claude plan limits. Manage extra usage at https://claude.ai/settings/usage.";
87
105
  function isAnthropicSubscriptionAuthKey(apiKey) {
88
106
  return typeof apiKey === "string" && apiKey.startsWith("sk-ant-oat");
@@ -129,7 +147,9 @@ export class InteractiveMode {
129
147
  workingMessage = undefined;
130
148
  workingVisible = true;
131
149
  workingIndicatorOptions = undefined;
132
- defaultWorkingMessage = "Working...";
150
+ workingStartedAt = undefined;
151
+ workingElapsedIntervalId = undefined;
152
+ defaultWorkingMessage = "Working";
133
153
  defaultHiddenThinkingLabel = "Thinking...";
134
154
  hiddenThinkingLabel = this.defaultHiddenThinkingLabel;
135
155
  lastSigintTime = 0;
@@ -166,6 +186,7 @@ export class InteractiveMode {
166
186
  // Auto-compaction state
167
187
  autoCompactionLoader = undefined;
168
188
  autoCompactionEscapeHandler;
189
+ autoCompactionProgressText = "";
169
190
  // Auto-retry state
170
191
  retryLoader = undefined;
171
192
  retryCountdown = undefined;
@@ -1097,11 +1118,7 @@ export class InteractiveMode {
1097
1118
  commandContextActions: {
1098
1119
  waitForIdle: () => this.session.agent.waitForIdle(),
1099
1120
  newSession: async (options) => {
1100
- if (this.loadingAnimation) {
1101
- this.loadingAnimation.stop();
1102
- this.loadingAnimation = undefined;
1103
- }
1104
- this.statusContainer.clear();
1121
+ this.stopWorkingLoader();
1105
1122
  try {
1106
1123
  const result = await this.runtimeHost.newSession(options);
1107
1124
  if (!result.cancelled) {
@@ -1285,10 +1302,43 @@ export class InteractiveMode {
1285
1302
  getWorkingLoaderMessage() {
1286
1303
  return this.workingMessage ?? this.defaultWorkingMessage;
1287
1304
  }
1305
+ getWorkingElapsedSeconds() {
1306
+ if (this.workingStartedAt === undefined) {
1307
+ return 0;
1308
+ }
1309
+ return Math.max(0, Math.floor((Date.now() - this.workingStartedAt) / 1000));
1310
+ }
1311
+ getWorkingStatusMessage() {
1312
+ return formatWorkingStatusMessage(this.getWorkingLoaderMessage(), this.getWorkingElapsedSeconds(), keyText("app.interrupt"));
1313
+ }
1314
+ refreshWorkingLoaderMessage() {
1315
+ this.loadingAnimation?.setMessage(this.getWorkingStatusMessage());
1316
+ }
1317
+ startWorkingElapsedTimer() {
1318
+ this.stopWorkingElapsedTimer();
1319
+ this.workingStartedAt = Date.now();
1320
+ this.workingElapsedIntervalId = setInterval(() => {
1321
+ this.refreshWorkingLoaderMessage();
1322
+ }, DEFAULT_WORKING_STATUS_REFRESH_INTERVAL_MS);
1323
+ }
1324
+ stopWorkingElapsedTimer() {
1325
+ if (this.workingElapsedIntervalId) {
1326
+ clearInterval(this.workingElapsedIntervalId);
1327
+ this.workingElapsedIntervalId = undefined;
1328
+ }
1329
+ }
1330
+ getWorkingIndicatorOptions() {
1331
+ return (this.workingIndicatorOptions ?? {
1332
+ frames: [theme.fg("accent", "•"), theme.fg("muted", "◦")],
1333
+ intervalMs: DEFAULT_WORKING_STATUS_REFRESH_INTERVAL_MS,
1334
+ });
1335
+ }
1288
1336
  createWorkingLoader() {
1289
- return new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), this.getWorkingLoaderMessage(), this.workingIndicatorOptions);
1337
+ return new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), this.getWorkingStatusMessage(), this.getWorkingIndicatorOptions());
1290
1338
  }
1291
1339
  stopWorkingLoader() {
1340
+ this.stopWorkingElapsedTimer();
1341
+ this.workingStartedAt = undefined;
1292
1342
  if (this.loadingAnimation) {
1293
1343
  this.loadingAnimation.stop();
1294
1344
  this.loadingAnimation = undefined;
@@ -1304,6 +1354,7 @@ export class InteractiveMode {
1304
1354
  }
1305
1355
  if (this.session.isStreaming && !this.loadingAnimation) {
1306
1356
  this.statusContainer.clear();
1357
+ this.startWorkingElapsedTimer();
1307
1358
  this.loadingAnimation = this.createWorkingLoader();
1308
1359
  this.statusContainer.addChild(this.loadingAnimation);
1309
1360
  }
@@ -1311,7 +1362,7 @@ export class InteractiveMode {
1311
1362
  }
1312
1363
  setWorkingIndicator(options) {
1313
1364
  this.workingIndicatorOptions = options;
1314
- this.loadingAnimation?.setIndicator(options);
1365
+ this.loadingAnimation?.setIndicator(this.getWorkingIndicatorOptions());
1315
1366
  this.ui.requestRender();
1316
1367
  }
1317
1368
  setHiddenThinkingLabel(label) {
@@ -1399,9 +1450,7 @@ export class InteractiveMode {
1399
1450
  this.workingMessage = undefined;
1400
1451
  this.workingVisible = true;
1401
1452
  this.setWorkingIndicator();
1402
- if (this.loadingAnimation) {
1403
- this.loadingAnimation.setMessage(`${this.defaultWorkingMessage} (${keyText("app.interrupt")} to interrupt)`);
1404
- }
1453
+ this.refreshWorkingLoaderMessage();
1405
1454
  this.setHiddenThinkingLabel();
1406
1455
  }
1407
1456
  // Maximum total widget lines to prevent viewport overflow
@@ -1526,9 +1575,7 @@ export class InteractiveMode {
1526
1575
  setStatus: (key, text) => this.setExtensionStatus(key, text),
1527
1576
  setWorkingMessage: (message) => {
1528
1577
  this.workingMessage = message;
1529
- if (this.loadingAnimation) {
1530
- this.loadingAnimation.setMessage(message ?? this.defaultWorkingMessage);
1531
- }
1578
+ this.refreshWorkingLoaderMessage();
1532
1579
  },
1533
1580
  setWorkingVisible: (visible) => this.setWorkingVisible(visible),
1534
1581
  setWorkingIndicator: (options) => this.setWorkingIndicator(options),
@@ -2149,6 +2196,7 @@ export class InteractiveMode {
2149
2196
  }
2150
2197
  this.stopWorkingLoader();
2151
2198
  if (this.workingVisible) {
2199
+ this.startWorkingElapsedTimer();
2152
2200
  this.loadingAnimation = this.createWorkingLoader();
2153
2201
  this.statusContainer.addChild(this.loadingAnimation);
2154
2202
  }
@@ -2290,11 +2338,7 @@ export class InteractiveMode {
2290
2338
  if (this.settingsManager.getShowTerminalProgress()) {
2291
2339
  this.ui.terminal.setProgress(false);
2292
2340
  }
2293
- if (this.loadingAnimation) {
2294
- this.loadingAnimation.stop();
2295
- this.loadingAnimation = undefined;
2296
- this.statusContainer.clear();
2297
- }
2341
+ this.stopWorkingLoader();
2298
2342
  if (this.streamingComponent) {
2299
2343
  this.chatContainer.removeChild(this.streamingComponent);
2300
2344
  this.streamingComponent = undefined;
@@ -2315,11 +2359,31 @@ export class InteractiveMode {
2315
2359
  };
2316
2360
  this.statusContainer.clear();
2317
2361
  const cancelHint = `(${keyText("app.interrupt")} to cancel)`;
2318
- const label = event.reason === "manual"
2319
- ? `Compacting context... ${cancelHint}`
2320
- : `${event.reason === "overflow" ? "Context overflow detected, " : ""}Auto-compacting... ${cancelHint}`;
2362
+ const label = event.reason === "threshold"
2363
+ ? `Auto-compacting... ${cancelHint}`
2364
+ : event.reason === "overflow"
2365
+ ? `Context overflow detected, compacting... ${cancelHint}`
2366
+ : event.reason === "pre_prompt"
2367
+ ? `Compacting before next prompt... ${cancelHint}`
2368
+ : `Compacting context... ${cancelHint}`;
2321
2369
  this.autoCompactionLoader = new Loader(this.ui, (spinner) => theme.fg("accent", spinner), (text) => theme.fg("muted", text), label);
2322
2370
  this.statusContainer.addChild(this.autoCompactionLoader);
2371
+ this.autoCompactionProgressText = "";
2372
+ this.ui.requestRender();
2373
+ break;
2374
+ }
2375
+ case "compaction_progress": {
2376
+ if (!this.autoCompactionLoader)
2377
+ break;
2378
+ const nextText = event.text !== undefined ? event.text : `${this.autoCompactionProgressText}${event.delta ?? ""}`;
2379
+ if (!nextText)
2380
+ break;
2381
+ this.autoCompactionProgressText = nextText;
2382
+ const preview = nextText.length > 4_000 ? `...${nextText.slice(nextText.length - 4_000)}` : nextText;
2383
+ this.statusContainer.clear();
2384
+ this.statusContainer.addChild(this.autoCompactionLoader);
2385
+ this.statusContainer.addChild(new Spacer(1));
2386
+ this.statusContainer.addChild(new Text(theme.fg("muted", preview), 1, 0));
2323
2387
  this.ui.requestRender();
2324
2388
  break;
2325
2389
  }
@@ -2334,6 +2398,7 @@ export class InteractiveMode {
2334
2398
  if (this.autoCompactionLoader) {
2335
2399
  this.autoCompactionLoader.stop();
2336
2400
  this.autoCompactionLoader = undefined;
2401
+ this.autoCompactionProgressText = "";
2337
2402
  this.statusContainer.clear();
2338
2403
  }
2339
2404
  if (event.aborted) {
@@ -2347,7 +2412,7 @@ export class InteractiveMode {
2347
2412
  else if (event.result) {
2348
2413
  this.chatContainer.clear();
2349
2414
  this.rebuildChatFromMessages();
2350
- this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString()));
2415
+ this.addMessageToChat(createCompactionSummaryMessage(event.result.summary, event.result.tokensBefore, new Date().toISOString(), event.result.details));
2351
2416
  this.footer.invalidate();
2352
2417
  }
2353
2418
  else if (event.errorMessage) {
@@ -2932,6 +2997,7 @@ export class InteractiveMode {
2932
2997
  showError(errorMessage) {
2933
2998
  this.chatContainer.addChild(new Spacer(1));
2934
2999
  this.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage}`), 1, 0));
3000
+ this.chatContainer.addChild(new Spacer(1));
2935
3001
  this.ui.requestRender();
2936
3002
  }
2937
3003
  showWarning(warningMessage) {
@@ -3021,7 +3087,7 @@ export class InteractiveMode {
3021
3087
  if (allQueued.length === 0) {
3022
3088
  this.updatePendingMessagesDisplay();
3023
3089
  if (options?.abort) {
3024
- this.agent.abort();
3090
+ void this.session.abort();
3025
3091
  }
3026
3092
  return 0;
3027
3093
  }
@@ -3031,7 +3097,7 @@ export class InteractiveMode {
3031
3097
  this.editor.setText(combinedText);
3032
3098
  this.updatePendingMessagesDisplay();
3033
3099
  if (options?.abort) {
3034
- this.agent.abort();
3100
+ void this.session.abort();
3035
3101
  }
3036
3102
  return allQueued.length;
3037
3103
  }
@@ -3651,11 +3717,7 @@ export class InteractiveMode {
3651
3717
  });
3652
3718
  }
3653
3719
  async handleResumeSession(sessionPath, options) {
3654
- if (this.loadingAnimation) {
3655
- this.loadingAnimation.stop();
3656
- this.loadingAnimation = undefined;
3657
- }
3658
- this.statusContainer.clear();
3720
+ this.stopWorkingLoader();
3659
3721
  try {
3660
3722
  const result = await this.runtimeHost.switchSession(sessionPath, {
3661
3723
  withSession: options?.withSession,
@@ -4140,11 +4202,7 @@ export class InteractiveMode {
4140
4202
  return;
4141
4203
  }
4142
4204
  try {
4143
- if (this.loadingAnimation) {
4144
- this.loadingAnimation.stop();
4145
- this.loadingAnimation = undefined;
4146
- }
4147
- this.statusContainer.clear();
4205
+ this.stopWorkingLoader();
4148
4206
  const result = await this.runtimeHost.importFromJsonl(inputPath);
4149
4207
  if (result.cancelled) {
4150
4208
  this.showStatus("Import cancelled");
@@ -4468,11 +4526,7 @@ export class InteractiveMode {
4468
4526
  this.ui.requestRender();
4469
4527
  }
4470
4528
  async handleClearCommand() {
4471
- if (this.loadingAnimation) {
4472
- this.loadingAnimation.stop();
4473
- this.loadingAnimation = undefined;
4474
- }
4475
- this.statusContainer.clear();
4529
+ this.stopWorkingLoader();
4476
4530
  try {
4477
4531
  const result = await this.runtimeHost.newSession();
4478
4532
  if (result.cancelled) {
@@ -4606,11 +4660,7 @@ export class InteractiveMode {
4606
4660
  this.showWarning("Nothing to compact (no messages yet)");
4607
4661
  return;
4608
4662
  }
4609
- if (this.loadingAnimation) {
4610
- this.loadingAnimation.stop();
4611
- this.loadingAnimation = undefined;
4612
- }
4613
- this.statusContainer.clear();
4663
+ this.stopWorkingLoader();
4614
4664
  try {
4615
4665
  await this.session.compact(customInstructions);
4616
4666
  }
@@ -4623,10 +4673,7 @@ export class InteractiveMode {
4623
4673
  if (this.settingsManager.getShowTerminalProgress()) {
4624
4674
  this.ui.terminal.setProgress(false);
4625
4675
  }
4626
- if (this.loadingAnimation) {
4627
- this.loadingAnimation.stop();
4628
- this.loadingAnimation = undefined;
4629
- }
4676
+ this.stopWorkingLoader();
4630
4677
  this.clearExtensionTerminalInputListeners();
4631
4678
  this.footer.dispose();
4632
4679
  this.footerDataProvider.dispose();