@code-yeongyu/senpi 2026.8.19 → 2026.8.20
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/CHANGELOG.md +117 -0
- package/dist/cli-main.js +4 -0
- package/dist/cli-main.js.map +1 -1
- package/dist/cli.js +31 -3
- package/dist/cli.js.map +1 -1
- package/dist/compile-cache.d.ts +2 -0
- package/dist/compile-cache.d.ts.map +1 -0
- package/dist/compile-cache.js +33 -0
- package/dist/compile-cache.js.map +1 -0
- package/dist/core/agent-session.d.ts +5 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +94 -12
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts +6 -0
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +13 -0
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/cursor-exec-bridge-session.d.ts +2 -1
- package/dist/core/cursor-exec-bridge-session.d.ts.map +1 -1
- package/dist/core/cursor-exec-bridge-session.js +5 -2
- package/dist/core/cursor-exec-bridge-session.js.map +1 -1
- package/dist/core/cursor-exec-bridge.d.ts +9 -1
- package/dist/core/cursor-exec-bridge.d.ts.map +1 -1
- package/dist/core/cursor-exec-bridge.js +26 -2
- package/dist/core/cursor-exec-bridge.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/custom-tools.d.ts +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/custom-tools.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/custom-tools.js +5 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/custom-tools.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/sdk-boundary.d.ts +6 -4
- package/dist/core/extensions/builtin/claude-sdk-oauth/sdk-boundary.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/sdk-boundary.js +24 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/sdk-boundary.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/sdk-boundary.lazy.d.ts +39 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/sdk-boundary.lazy.d.ts.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/sdk-boundary.lazy.js +31 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/sdk-boundary.lazy.js.map +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +2 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +35 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js +1 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-observability.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts +8 -0
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js +4 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-reattach.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js +28 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.d.ts.map +1 -1
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js +5 -2
- package/dist/core/extensions/builtin/claude-sdk-oauth/stream.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/index.js +5 -0
- package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts +1 -1
- package/dist/core/extensions/builtin/compaction/log.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/log.js +1 -0
- package/dist/core/extensions/builtin/compaction/log.js.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.d.ts +1 -0
- package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
- package/dist/core/extensions/builtin/compaction/speculative.js +4 -0
- package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/config-reload/index.js +13 -10
- package/dist/core/extensions/builtin/config-reload/index.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/watch-engine.d.ts +8 -1
- package/dist/core/extensions/builtin/config-reload/watch-engine.d.ts.map +1 -1
- package/dist/core/extensions/builtin/config-reload/watch-engine.js +98 -18
- package/dist/core/extensions/builtin/config-reload/watch-engine.js.map +1 -1
- package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts +1 -1
- package/dist/core/extensions/builtin/config-reload/watch-event-source.d.ts.map +1 -1
- package/dist/core/extensions/builtin/config-reload/watch-event-source.js +7 -2
- package/dist/core/extensions/builtin/config-reload/watch-event-source.js.map +1 -1
- package/dist/core/extensions/builtin/goal/elapsed-ticker.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/elapsed-ticker.js +15 -1
- package/dist/core/extensions/builtin/goal/elapsed-ticker.js.map +1 -1
- package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/index.js +7 -22
- package/dist/core/extensions/builtin/goal/index.js.map +1 -1
- package/dist/core/extensions/builtin/goal/stale-context.d.ts +9 -0
- package/dist/core/extensions/builtin/goal/stale-context.d.ts.map +1 -0
- package/dist/core/extensions/builtin/goal/stale-context.js +11 -0
- package/dist/core/extensions/builtin/goal/stale-context.js.map +1 -0
- package/dist/core/extensions/builtin/goal/wait-ticker.d.ts +8 -0
- package/dist/core/extensions/builtin/goal/wait-ticker.d.ts.map +1 -1
- package/dist/core/extensions/builtin/goal/wait-ticker.js +37 -3
- package/dist/core/extensions/builtin/goal/wait-ticker.js.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/mcp/index.js +12 -1
- package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
- package/dist/core/extensions/builtin/prompt-url-widget.d.ts.map +1 -1
- package/dist/core/extensions/builtin/prompt-url-widget.js +7 -15
- package/dist/core/extensions/builtin/prompt-url-widget.js.map +1 -1
- package/dist/core/extensions/builtin/rules/ui/rules-banner.d.ts.map +1 -1
- package/dist/core/extensions/builtin/rules/ui/rules-banner.js +21 -25
- package/dist/core/extensions/builtin/rules/ui/rules-banner.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/index.d.ts.map +1 -1
- package/dist/core/extensions/builtin/todotools/index.js +20 -0
- package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
- package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts +3 -0
- package/dist/core/extensions/builtin/todotools/native-todo-mirror.d.ts.map +1 -0
- package/dist/core/extensions/builtin/todotools/native-todo-mirror.js +22 -0
- package/dist/core/extensions/builtin/todotools/native-todo-mirror.js.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/content.lazy.d.ts +17 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/content.lazy.d.ts.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/content.lazy.js +22 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/content.lazy.js.map +1 -0
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.js +3 -3
- package/dist/core/extensions/builtin/webfetch/webfetch/tool.js.map +1 -1
- package/dist/core/messages.d.ts +9 -2
- package/dist/core/messages.d.ts.map +1 -1
- package/dist/core/messages.js +13 -18
- package/dist/core/messages.js.map +1 -1
- package/dist/core/retry-fallback/hint-policy.d.ts +3 -2
- package/dist/core/retry-fallback/hint-policy.d.ts.map +1 -1
- package/dist/core/retry-fallback/hint-policy.js +19 -8
- package/dist/core/retry-fallback/hint-policy.js.map +1 -1
- package/dist/core/retry-fallback/settings.js.map +1 -1
- package/dist/core/session-discovery.d.ts +16 -0
- package/dist/core/session-discovery.d.ts.map +1 -0
- package/dist/core/session-discovery.js +101 -0
- package/dist/core/session-discovery.js.map +1 -0
- package/dist/core/session-manager.d.ts +2 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +4 -170
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/session-record.d.ts +14 -0
- package/dist/core/session-record.d.ts.map +1 -0
- package/dist/core/session-record.js +47 -0
- package/dist/core/session-record.js.map +1 -0
- package/dist/core/session-summary-cache.d.ts +40 -0
- package/dist/core/session-summary-cache.d.ts.map +1 -0
- package/dist/core/session-summary-cache.js +79 -0
- package/dist/core/session-summary-cache.js.map +1 -0
- package/dist/core/session-summary-lru.d.ts +54 -0
- package/dist/core/session-summary-lru.d.ts.map +1 -0
- package/dist/core/session-summary-lru.js +72 -0
- package/dist/core/session-summary-lru.js.map +1 -0
- package/dist/core/session-summary.d.ts +29 -0
- package/dist/core/session-summary.d.ts.map +1 -0
- package/dist/core/session-summary.js +90 -0
- package/dist/core/session-summary.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/inspector-policy.d.ts +6 -0
- package/dist/inspector-policy.d.ts.map +1 -1
- package/dist/inspector-policy.js +6 -1
- package/dist/inspector-policy.js.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
- package/dist/modes/interactive/components/earendil-announcement.js +8 -8
- package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
- package/dist/modes/interactive/components/progressive-transcript-container.d.ts +72 -0
- package/dist/modes/interactive/components/progressive-transcript-container.d.ts.map +1 -0
- package/dist/modes/interactive/components/progressive-transcript-container.js +150 -0
- package/dist/modes/interactive/components/progressive-transcript-container.js.map +1 -0
- package/dist/modes/interactive/components/status-indicator.d.ts +1 -1
- package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
- package/dist/modes/interactive/components/status-indicator.js +8 -2
- package/dist/modes/interactive/components/status-indicator.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +4 -0
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +127 -65
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/split-trailing-assistant-text.d.ts +7 -0
- package/dist/modes/interactive/split-trailing-assistant-text.d.ts.map +1 -0
- package/dist/modes/interactive/split-trailing-assistant-text.js +19 -0
- package/dist/modes/interactive/split-trailing-assistant-text.js.map +1 -0
- package/dist/senpi +31 -3
- package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +12 -0
- package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +38 -3
- package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +8 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +25 -1
- package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -1
- package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js +284 -209
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-agent.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts +37 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js +110 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-conversation-rotation.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-task-args.d.ts +3 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-task-args.d.ts.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-task-args.js +17 -0
- package/node_modules/@earendil-works/pi-ai/dist/api/cursor-task-args.js.map +1 -0
- package/node_modules/@earendil-works/pi-ai/dist/cursor/selection-descriptor.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/cursor/selection-descriptor.js +27 -11
- package/node_modules/@earendil-works/pi-ai/dist/cursor/selection-descriptor.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/baseten.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js +2 -0
- package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +30 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +33 -0
- package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
- package/node_modules/@earendil-works/pi-ai/package.json +2 -2
- package/node_modules/@earendil-works/pi-pty/package.json +1 -1
- package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
- package/node_modules/@earendil-works/pi-tui/package.json +1 -1
- package/package.json +7 -7
|
@@ -70,6 +70,7 @@ import { createMermaidMarkdownTransformer } from "./components/mermaid.js";
|
|
|
70
70
|
import { getModelFullId, mergeFavoritePatternsForPersist, } from "./components/model-favorites.js";
|
|
71
71
|
import { ModelSelectorComponent } from "./components/model-selector.js";
|
|
72
72
|
import { formatAuthSelectorProviderType, OAuthSelectorComponent, } from "./components/oauth-selector.js";
|
|
73
|
+
import { DEFAULT_TAIL_BUDGET, DEFAULT_WARM_CHUNK_SIZE, ProgressiveTranscriptContainer, } from "./components/progressive-transcript-container.js";
|
|
73
74
|
import { ScopedModelsSelectorComponent } from "./components/scoped-models-selector.js";
|
|
74
75
|
import { SessionSelectorComponent } from "./components/session-selector.js";
|
|
75
76
|
import { SettingsSelectorComponent } from "./components/settings-selector.js";
|
|
@@ -90,6 +91,7 @@ import { applyKeybindingsFileEdit, seedKeybindingsFile } from "./keybindings-com
|
|
|
90
91
|
import { refreshModelCatalogs } from "./model-catalog-refresh.js";
|
|
91
92
|
import { getModelSearchText } from "./model-search.js";
|
|
92
93
|
import { isRiskyMainModel, RISKY_MAIN_MODEL_WARNING } from "./risky-main-model-warning.js";
|
|
94
|
+
import { splitTrailingAssistantContent } from "./split-trailing-assistant-text.js";
|
|
93
95
|
import { DEFAULT_SMOOTH_FPS, StreamingRevealController } from "./streaming-reveal.js";
|
|
94
96
|
import { getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, onThemeChange, setRegisteredThemes, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
|
|
95
97
|
import { InteractiveThemeController } from "./theme/theme-controller.js";
|
|
@@ -142,6 +144,8 @@ function isCompactionCostNotice(item) {
|
|
|
142
144
|
return "type" in item && item.type === "compaction_cost";
|
|
143
145
|
}
|
|
144
146
|
const DEAD_TERMINAL_ERROR_CODES = new Set(["EIO", "EPIPE", "ENOTCONN"]);
|
|
147
|
+
const DEFAULT_RETRY_STATUS_REFRESH_INTERVAL_MS = 80;
|
|
148
|
+
const LARGE_SESSION_RETRY_STATUS_REFRESH_INTERVAL_MS = 60_000;
|
|
145
149
|
const DEFAULT_WORKING_STATUS_REFRESH_INTERVAL_MS = 600;
|
|
146
150
|
const DEFAULT_WORKING_STATUS_MESSAGE_ANIMATION_INTERVAL_MS = 32;
|
|
147
151
|
const LARGE_SESSION_WORKING_STATUS_REFRESH_INTERVAL_MS = 60_000;
|
|
@@ -464,6 +468,7 @@ export class InteractiveMode {
|
|
|
464
468
|
this.managedToolStatusStarted = false;
|
|
465
469
|
// Streaming message tracking
|
|
466
470
|
this.streamingComponent = undefined;
|
|
471
|
+
this.trailingAssistantComponent = undefined;
|
|
467
472
|
this.streamingMessage = undefined;
|
|
468
473
|
// Tool execution tracking: toolCallId -> component
|
|
469
474
|
this.pendingTools = new Map();
|
|
@@ -560,7 +565,14 @@ export class InteractiveMode {
|
|
|
560
565
|
this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
|
|
561
566
|
this.headerContainer = new Container();
|
|
562
567
|
this.loadedResourcesContainer = new Container();
|
|
563
|
-
|
|
568
|
+
// Resuming a long session paints a bounded, fully-styled tail first and warms
|
|
569
|
+
// the earlier history in background chunks, so /resume is not blocked on
|
|
570
|
+
// Markdown-rendering every persisted message before the first frame.
|
|
571
|
+
this.chatContainer = new ProgressiveTranscriptContainer({
|
|
572
|
+
tailBudget: DEFAULT_TAIL_BUDGET,
|
|
573
|
+
warmChunkSize: DEFAULT_WARM_CHUNK_SIZE,
|
|
574
|
+
requestRender: () => this.ui.requestRender(),
|
|
575
|
+
});
|
|
564
576
|
this.documentContainer = new Container();
|
|
565
577
|
this.documentContainer.addChild(this.headerContainer);
|
|
566
578
|
this.documentContainer.addChild(this.loadedResourcesContainer);
|
|
@@ -796,7 +808,11 @@ export class InteractiveMode {
|
|
|
796
808
|
}
|
|
797
809
|
previousUi.stop({ preserveScreen: true });
|
|
798
810
|
previousUi.setFocus(null);
|
|
799
|
-
|
|
811
|
+
// Detach, not clear: the same live components (spinners, reveals, extension
|
|
812
|
+
// widgets) are remounted on nextUi below. clear() would dispose them,
|
|
813
|
+
// killing every interval they own while they keep rendering static frames
|
|
814
|
+
// forever — the TUI then never self-repaints until an input event forces one.
|
|
815
|
+
previousUi.detachAll();
|
|
800
816
|
if (TuiLayouts.isViewportTUI(previousUi))
|
|
801
817
|
previousUi.setLayoutRoot(undefined);
|
|
802
818
|
const nextUi = createInteractiveTui({
|
|
@@ -1563,25 +1579,32 @@ export class InteractiveMode {
|
|
|
1563
1579
|
const first = collisionList[0]?.collision;
|
|
1564
1580
|
if (!first)
|
|
1565
1581
|
continue;
|
|
1566
|
-
lines.push(
|
|
1567
|
-
lines.push(
|
|
1582
|
+
lines.push({ text: ` "${name}" collision:`, tone: "warning" });
|
|
1583
|
+
lines.push({
|
|
1584
|
+
text: ` ✓ ${this.formatPathWithSource(first.winnerPath, this.findSourceInfoForPath(first.winnerPath, sourceInfos))}`,
|
|
1585
|
+
tone: "warning",
|
|
1586
|
+
});
|
|
1568
1587
|
for (const d of collisionList) {
|
|
1569
1588
|
if (d.collision) {
|
|
1570
|
-
lines.push(
|
|
1589
|
+
lines.push({
|
|
1590
|
+
text: ` ✗ ${this.formatPathWithSource(d.collision.loserPath, this.findSourceInfoForPath(d.collision.loserPath, sourceInfos))} (skipped)`,
|
|
1591
|
+
tone: "warning",
|
|
1592
|
+
});
|
|
1571
1593
|
}
|
|
1572
1594
|
}
|
|
1573
1595
|
}
|
|
1574
1596
|
for (const d of otherDiagnostics) {
|
|
1597
|
+
const tone = d.type === "error" ? "error" : "warning";
|
|
1575
1598
|
if (d.path) {
|
|
1576
1599
|
const formattedPath = this.formatPathWithSource(d.path, this.findSourceInfoForPath(d.path, sourceInfos));
|
|
1577
|
-
lines.push(
|
|
1578
|
-
lines.push(
|
|
1600
|
+
lines.push({ text: ` ${formattedPath}`, tone });
|
|
1601
|
+
lines.push({ text: ` ${d.message}`, tone });
|
|
1579
1602
|
}
|
|
1580
1603
|
else {
|
|
1581
|
-
lines.push(
|
|
1604
|
+
lines.push({ text: ` ${d.message}`, tone });
|
|
1582
1605
|
}
|
|
1583
1606
|
}
|
|
1584
|
-
return lines
|
|
1607
|
+
return lines;
|
|
1585
1608
|
}
|
|
1586
1609
|
showLoadedResources(options) {
|
|
1587
1610
|
// Resource rendering is idempotent; chat clears no longer clear this separate container.
|
|
@@ -1710,17 +1733,22 @@ export class InteractiveMode {
|
|
|
1710
1733
|
}
|
|
1711
1734
|
}
|
|
1712
1735
|
if (showDiagnostics) {
|
|
1736
|
+
const addDiagnosticNotice = (title, diagnostics) => {
|
|
1737
|
+
this.loadedResourcesContainer.addChild(buildNoticeBox({
|
|
1738
|
+
title,
|
|
1739
|
+
tone: "warning",
|
|
1740
|
+
why: "Conflicting or invalid loaded resources were found.",
|
|
1741
|
+
extra: this.formatDiagnostics(diagnostics, sourceInfos),
|
|
1742
|
+
}, { expanded: this.toolOutputExpanded }, theme));
|
|
1743
|
+
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1744
|
+
};
|
|
1713
1745
|
const skillDiagnostics = skillsResult.diagnostics;
|
|
1714
1746
|
if (skillDiagnostics.length > 0) {
|
|
1715
|
-
|
|
1716
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Skill conflicts]")}\n${warningLines}`, 0, 0));
|
|
1717
|
-
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1747
|
+
addDiagnosticNotice("Skill conflicts", skillDiagnostics);
|
|
1718
1748
|
}
|
|
1719
1749
|
const promptDiagnostics = promptsResult.diagnostics;
|
|
1720
1750
|
if (promptDiagnostics.length > 0) {
|
|
1721
|
-
|
|
1722
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Prompt conflicts]")}\n${warningLines}`, 0, 0));
|
|
1723
|
-
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1751
|
+
addDiagnosticNotice("Prompt conflicts", promptDiagnostics);
|
|
1724
1752
|
}
|
|
1725
1753
|
const extensionDiagnostics = [];
|
|
1726
1754
|
const extensionErrors = this.session.resourceLoader.getExtensions().errors;
|
|
@@ -1739,15 +1767,11 @@ export class InteractiveMode {
|
|
|
1739
1767
|
const shortcutDiagnostics = this.session.extensionRunner.getShortcutDiagnostics();
|
|
1740
1768
|
extensionDiagnostics.push(...shortcutDiagnostics);
|
|
1741
1769
|
if (extensionDiagnostics.length > 0) {
|
|
1742
|
-
|
|
1743
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Extension issues]")}\n${warningLines}`, 0, 0));
|
|
1744
|
-
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1770
|
+
addDiagnosticNotice("Extension issues", extensionDiagnostics);
|
|
1745
1771
|
}
|
|
1746
1772
|
const themeDiagnostics = themesResult.diagnostics;
|
|
1747
1773
|
if (themeDiagnostics.length > 0) {
|
|
1748
|
-
|
|
1749
|
-
this.loadedResourcesContainer.addChild(new Text(`${theme.fg("warning", "[Theme conflicts]")}\n${warningLines}`, 0, 0));
|
|
1750
|
-
this.loadedResourcesContainer.addChild(new Spacer(1));
|
|
1774
|
+
addDiagnosticNotice("Theme conflicts", themeDiagnostics);
|
|
1751
1775
|
}
|
|
1752
1776
|
}
|
|
1753
1777
|
}
|
|
@@ -3376,7 +3400,10 @@ export class InteractiveMode {
|
|
|
3376
3400
|
case "message_update":
|
|
3377
3401
|
if (this.streamingComponent && event.message.role === "assistant") {
|
|
3378
3402
|
this.streamingMessage = event.message;
|
|
3379
|
-
|
|
3403
|
+
{
|
|
3404
|
+
const { head } = splitTrailingAssistantContent(event.message.content);
|
|
3405
|
+
this.streamingReveal.setTarget({ ...event.message, content: head });
|
|
3406
|
+
}
|
|
3380
3407
|
for (const content of this.streamingMessage.content) {
|
|
3381
3408
|
if (content.type === "toolCall") {
|
|
3382
3409
|
let component = this.pendingTools.get(content.id);
|
|
@@ -3396,6 +3423,7 @@ export class InteractiveMode {
|
|
|
3396
3423
|
}
|
|
3397
3424
|
}
|
|
3398
3425
|
}
|
|
3426
|
+
this.syncTrailingAssistantText(event.message);
|
|
3399
3427
|
this.ui.requestRender();
|
|
3400
3428
|
}
|
|
3401
3429
|
break;
|
|
@@ -3419,7 +3447,8 @@ export class InteractiveMode {
|
|
|
3419
3447
|
errorMessage = abortedErrorLabel(undefined, this.session.retryAttempt);
|
|
3420
3448
|
this.streamingMessage.errorMessage = errorMessage;
|
|
3421
3449
|
}
|
|
3422
|
-
this.
|
|
3450
|
+
this.syncTrailingAssistantText(this.streamingMessage);
|
|
3451
|
+
this.trailingAssistantComponent = undefined;
|
|
3423
3452
|
this.addContinuityNotice(this.streamingMessage);
|
|
3424
3453
|
if (this.streamingMessage.stopReason === "aborted" || this.streamingMessage.stopReason === "error") {
|
|
3425
3454
|
if (!errorMessage) {
|
|
@@ -3492,13 +3521,17 @@ export class InteractiveMode {
|
|
|
3492
3521
|
case "tool_execution_end": {
|
|
3493
3522
|
this.handleToolExecutionEnd(event);
|
|
3494
3523
|
this.toolArgsReveal.finish(event.toolCallId);
|
|
3495
|
-
|
|
3496
|
-
if (component) {
|
|
3497
|
-
this.
|
|
3498
|
-
component.
|
|
3499
|
-
this.
|
|
3500
|
-
this.
|
|
3524
|
+
let component = this.pendingTools.get(event.toolCallId);
|
|
3525
|
+
if (!component) {
|
|
3526
|
+
component = this.createToolExecutionComponent(event.toolName, event.toolCallId, {});
|
|
3527
|
+
component.setExpanded(this.toolOutputExpanded);
|
|
3528
|
+
this.chatContainer.addChild(component);
|
|
3529
|
+
this.pendingTools.set(event.toolCallId, component);
|
|
3501
3530
|
}
|
|
3531
|
+
this.toolResultReveal.finish(event.toolCallId);
|
|
3532
|
+
component.updateResult({ ...event.result, isError: event.isError });
|
|
3533
|
+
this.pendingTools.delete(event.toolCallId);
|
|
3534
|
+
this.ui.requestRender();
|
|
3502
3535
|
break;
|
|
3503
3536
|
}
|
|
3504
3537
|
case "agent_end":
|
|
@@ -3769,8 +3802,7 @@ export class InteractiveMode {
|
|
|
3769
3802
|
}
|
|
3770
3803
|
case "summarization_retry_scheduled": {
|
|
3771
3804
|
this.showError(event.errorMessage);
|
|
3772
|
-
this.
|
|
3773
|
-
this.ui.requestRender();
|
|
3805
|
+
this.showSummarizationRetryStatusIndicator(event);
|
|
3774
3806
|
break;
|
|
3775
3807
|
}
|
|
3776
3808
|
case "summarization_retry_attempt_start": {
|
|
@@ -3811,7 +3843,15 @@ export class InteractiveMode {
|
|
|
3811
3843
|
}
|
|
3812
3844
|
}
|
|
3813
3845
|
showRetryStatusIndicator(event) {
|
|
3814
|
-
this.
|
|
3846
|
+
this.showRetryStatusIndicatorWithCadence(event);
|
|
3847
|
+
}
|
|
3848
|
+
showSummarizationRetryStatusIndicator(event) {
|
|
3849
|
+
this.showRetryStatusIndicatorWithCadence(event);
|
|
3850
|
+
}
|
|
3851
|
+
showRetryStatusIndicatorWithCadence(event) {
|
|
3852
|
+
const refreshIntervalMs = largeSessionWorkingStatusInterval(this.sessionManager.getEntries().length, DEFAULT_RETRY_STATUS_REFRESH_INTERVAL_MS, LARGE_SESSION_RETRY_STATUS_REFRESH_INTERVAL_MS);
|
|
3853
|
+
const indicator = refreshIntervalMs === DEFAULT_RETRY_STATUS_REFRESH_INTERVAL_MS ? undefined : { intervalMs: refreshIntervalMs };
|
|
3854
|
+
this.showStatusIndicator(new RetryStatusIndicator(this.ui, event.attempt, event.maxAttempts, event.delayMs, indicator));
|
|
3815
3855
|
this.ui.requestRender();
|
|
3816
3856
|
}
|
|
3817
3857
|
/** Extract text content from a user message */
|
|
@@ -3957,6 +3997,29 @@ export class InteractiveMode {
|
|
|
3957
3997
|
}
|
|
3958
3998
|
}
|
|
3959
3999
|
}
|
|
4000
|
+
syncTrailingAssistantText(message) {
|
|
4001
|
+
if (!this.streamingComponent)
|
|
4002
|
+
return;
|
|
4003
|
+
const { head, tail } = splitTrailingAssistantContent(message.content);
|
|
4004
|
+
this.streamingComponent.updateContent({ ...message, content: head }, true);
|
|
4005
|
+
if (tail.length === 0) {
|
|
4006
|
+
if (this.trailingAssistantComponent) {
|
|
4007
|
+
this.chatContainer.detachChild(this.trailingAssistantComponent);
|
|
4008
|
+
this.trailingAssistantComponent = undefined;
|
|
4009
|
+
}
|
|
4010
|
+
return;
|
|
4011
|
+
}
|
|
4012
|
+
const tailMessage = { ...message, content: tail };
|
|
4013
|
+
if (!this.trailingAssistantComponent) {
|
|
4014
|
+
this.trailingAssistantComponent = new AssistantMessageComponent(tailMessage, this.hideThinkingBlock, this.getMarkdownThemeWithSettings(), this.hiddenThinkingLabel, this.outputPad, this.getMarkdownTransformers());
|
|
4015
|
+
this.trailingAssistantComponent.setExpanded(this.toolOutputExpanded);
|
|
4016
|
+
this.chatContainer.addChild(this.trailingAssistantComponent);
|
|
4017
|
+
return;
|
|
4018
|
+
}
|
|
4019
|
+
this.trailingAssistantComponent.updateContent(tailMessage, true);
|
|
4020
|
+
this.chatContainer.detachChild(this.trailingAssistantComponent);
|
|
4021
|
+
this.chatContainer.addChild(this.trailingAssistantComponent);
|
|
4022
|
+
}
|
|
3960
4023
|
createToolExecutionComponent(toolName, toolCallId, args) {
|
|
3961
4024
|
if (this.chrome) {
|
|
3962
4025
|
return new ToolExecutionComponent(toolName, toolCallId, args, {
|
|
@@ -4555,48 +4618,43 @@ export class InteractiveMode {
|
|
|
4555
4618
|
this.ui.requestRender();
|
|
4556
4619
|
}
|
|
4557
4620
|
showNewVersionNotification(newVersion) {
|
|
4558
|
-
const action =
|
|
4559
|
-
const updateInstruction = theme.fg("muted", `New version ${newVersion} is available. Run `) + action;
|
|
4621
|
+
const action = BRAND?.update?.command ?? `${APP_NAME} update`;
|
|
4560
4622
|
const changelogUrl = getReleaseChangelogUrl(newVersion);
|
|
4561
|
-
const changelogLink = getCapabilities().hyperlinks
|
|
4562
|
-
|
|
4563
|
-
:
|
|
4564
|
-
|
|
4565
|
-
|
|
4566
|
-
|
|
4567
|
-
|
|
4568
|
-
this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("warning", text)));
|
|
4569
|
-
this.ui.requestRender();
|
|
4623
|
+
const changelogLink = getCapabilities().hyperlinks ? hyperlink(changelogUrl, changelogUrl) : changelogUrl;
|
|
4624
|
+
this.showNoticeBox({
|
|
4625
|
+
title: "Update Available",
|
|
4626
|
+
tone: "warning",
|
|
4627
|
+
why: `New version ${newVersion} is available. Run ${action}`,
|
|
4628
|
+
extra: [{ text: `Changelog: ${changelogLink}`, tone: "accent" }],
|
|
4629
|
+
});
|
|
4570
4630
|
}
|
|
4571
4631
|
showRiskyMainModelWarning(model) {
|
|
4572
4632
|
if (!model || !isRiskyMainModel(model))
|
|
4573
4633
|
return;
|
|
4574
|
-
this.
|
|
4575
|
-
this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("error", text)));
|
|
4576
|
-
this.chatContainer.addChild(new Text(`${theme.bold(theme.fg("error", "Risky model warning"))}\n${theme.fg("error", RISKY_MAIN_MODEL_WARNING)}`, 1, 0));
|
|
4577
|
-
this.chatContainer.addChild(new DynamicBorder((text) => theme.fg("error", text)));
|
|
4578
|
-
this.ui.requestRender();
|
|
4634
|
+
this.showNoticeBox({ title: "Risky model warning", tone: "error", why: RISKY_MAIN_MODEL_WARNING });
|
|
4579
4635
|
}
|
|
4580
4636
|
showSettingsSourceSelected(event) {
|
|
4581
4637
|
this.showStatus(`Settings: ${path.basename(event.path)} (${event.format.toUpperCase()})`);
|
|
4582
4638
|
}
|
|
4583
4639
|
showHighReasoningWarning(event) {
|
|
4584
4640
|
const { title, body } = buildHighReasoningWarning({ id: event.modelId, provider: event.provider }, event.thinkingLevel);
|
|
4585
|
-
this.
|
|
4586
|
-
|
|
4587
|
-
|
|
4588
|
-
|
|
4589
|
-
|
|
4641
|
+
this.showNoticeBox({
|
|
4642
|
+
title,
|
|
4643
|
+
tone: "error",
|
|
4644
|
+
why: body[0] ?? "High reasoning may affect reliability or cost.",
|
|
4645
|
+
extra: body.slice(1).map((text) => ({ text, tone: "error" })),
|
|
4646
|
+
});
|
|
4590
4647
|
}
|
|
4591
4648
|
showPackageUpdateNotification(packages) {
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4649
|
+
this.showNoticeBox({
|
|
4650
|
+
title: "Package Updates Available",
|
|
4651
|
+
tone: "warning",
|
|
4652
|
+
why: `Package updates are available. Run ${APP_NAME} update --extensions`,
|
|
4653
|
+
extra: [
|
|
4654
|
+
{ text: "Packages:", tone: "dim" },
|
|
4655
|
+
...packages.map((pkg) => ({ text: `- ${pkg}`, tone: "dim" })),
|
|
4656
|
+
],
|
|
4657
|
+
});
|
|
4600
4658
|
}
|
|
4601
4659
|
/**
|
|
4602
4660
|
* Get all queued messages (read-only).
|
|
@@ -6189,7 +6247,6 @@ export class InteractiveMode {
|
|
|
6189
6247
|
this.showWarning(veto.reason ?? "Reload blocked by an extension.");
|
|
6190
6248
|
return;
|
|
6191
6249
|
}
|
|
6192
|
-
this.resetExtensionUI();
|
|
6193
6250
|
const reloadBox = new Container();
|
|
6194
6251
|
const borderColor = (s) => theme.fg("border", s);
|
|
6195
6252
|
reloadBox.addChild(new DynamicBorder(borderColor));
|
|
@@ -6215,6 +6272,13 @@ export class InteractiveMode {
|
|
|
6215
6272
|
if (chatRestoredBeforeSessionStart) {
|
|
6216
6273
|
return;
|
|
6217
6274
|
}
|
|
6275
|
+
// Reset extension UI only once the reload is actually proceeding (this
|
|
6276
|
+
// callback runs after reload()'s internal veto re-check, right before the
|
|
6277
|
+
// new runner's session_start re-registers extension UI). Resetting before
|
|
6278
|
+
// reload() destroyed live extension footers/widgets/tickers on a vetoed
|
|
6279
|
+
// or failed reload with nothing left to restore them, so the TUI stopped
|
|
6280
|
+
// self-repainting until an input event forced a frame.
|
|
6281
|
+
this.resetExtensionUI();
|
|
6218
6282
|
this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
|
|
6219
6283
|
this.outputPad = this.settingsManager.getOutputPad();
|
|
6220
6284
|
this.rebuildChatFromMessages();
|
|
@@ -6718,9 +6782,7 @@ export class InteractiveMode {
|
|
|
6718
6782
|
].join("\n");
|
|
6719
6783
|
fs.mkdirSync(path.dirname(debugLogPath), { recursive: true });
|
|
6720
6784
|
fs.writeFileSync(debugLogPath, debugData);
|
|
6721
|
-
this.
|
|
6722
|
-
this.chatContainer.addChild(new Text(`${theme.fg("accent", "✓ Debug log written")}\n${theme.fg("muted", debugLogPath)}`, 1, 1));
|
|
6723
|
-
this.ui.requestRender();
|
|
6785
|
+
this.showNoticeBox({ title: "✓ Debug log written", tone: "success", why: debugLogPath });
|
|
6724
6786
|
}
|
|
6725
6787
|
handleArminSaysHi() {
|
|
6726
6788
|
this.chatContainer.addChild(new Spacer(1));
|