@markusylisiurunen/tau 0.1.33 → 0.1.36
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/README.md +17 -16
- package/dist/app.js +101 -105
- package/dist/app.js.map +1 -1
- package/dist/commands.js +43 -10
- package/dist/commands.js.map +1 -1
- package/dist/terminal.js +13 -0
- package/dist/terminal.js.map +1 -1
- package/dist/tools/bash.js +6 -13
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.js +2 -47
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/grep.js +3 -23
- package/dist/tools/grep.js.map +1 -1
- package/dist/tools/read.js +7 -14
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/registry.js.map +1 -1
- package/dist/tools/write.js +1 -19
- package/dist/tools/write.js.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/ui/app_intro.js +12 -0
- package/dist/ui/app_intro.js.map +1 -0
- package/dist/ui/assistant_message.js +4 -3
- package/dist/ui/assistant_message.js.map +1 -1
- package/dist/ui/bash_execution.js +46 -36
- package/dist/ui/bash_execution.js.map +1 -1
- package/dist/ui/components/one_line_segments.js +69 -0
- package/dist/ui/components/one_line_segments.js.map +1 -1
- package/dist/ui/custom_editor.js +11 -18
- package/dist/ui/custom_editor.js.map +1 -1
- package/dist/ui/file_execution.js +70 -27
- package/dist/ui/file_execution.js.map +1 -1
- package/dist/ui/footer.js +64 -14
- package/dist/ui/footer.js.map +1 -1
- package/dist/ui/inline.js +4 -0
- package/dist/ui/inline.js.map +1 -0
- package/dist/ui/queued_messages.js +9 -8
- package/dist/ui/queued_messages.js.map +1 -1
- package/dist/ui/restricted_execution.js +60 -47
- package/dist/ui/restricted_execution.js.map +1 -1
- package/dist/ui/session_divider.js +4 -3
- package/dist/ui/session_divider.js.map +1 -1
- package/dist/ui/session_summary.js +3 -4
- package/dist/ui/session_summary.js.map +1 -1
- package/dist/ui/slash_autocomplete.js +2 -2
- package/dist/ui/slash_autocomplete.js.map +1 -1
- package/dist/ui/system_message.js +10 -2
- package/dist/ui/system_message.js.map +1 -1
- package/dist/ui/task_execution.js +14 -15
- package/dist/ui/task_execution.js.map +1 -1
- package/dist/ui/theme.js +179 -89
- package/dist/ui/theme.js.map +1 -1
- package/dist/ui/tool_output.js +7 -2
- package/dist/ui/tool_output.js.map +1 -1
- package/dist/ui/tool_truncation.js +21 -0
- package/dist/ui/tool_truncation.js.map +1 -0
- package/dist/ui/user_message.js +1 -2
- package/dist/ui/user_message.js.map +1 -1
- package/dist/version.js +1 -1
- package/package.json +11 -9
package/dist/app.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { homedir } from "node:os";
|
|
2
2
|
import { join, resolve } from "node:path";
|
|
3
3
|
import { streamSimple } from "@mariozechner/pi-ai";
|
|
4
|
-
import { Spacer,
|
|
4
|
+
import { Spacer, TUI } from "@mariozechner/pi-tui";
|
|
5
5
|
import { loadBashCommands } from "./bash_commands.js";
|
|
6
6
|
import { copyTextToClipboard } from "./clipboard.js";
|
|
7
7
|
import { buildHelpText, getRiskLevelDescription, parseCommand } from "./commands.js";
|
|
@@ -20,6 +20,7 @@ import { ToolRegistry } from "./tools/registry.js";
|
|
|
20
20
|
import { createTaskToolDefinition } from "./tools/task.js";
|
|
21
21
|
import { createWriteToolDefinition } from "./tools/write.js";
|
|
22
22
|
import { REASONING_LEVELS, } from "./types.js";
|
|
23
|
+
import { AppIntroComponent } from "./ui/app_intro.js";
|
|
23
24
|
import { AssistantMessageComponent } from "./ui/assistant_message.js";
|
|
24
25
|
import { renderBashAborted, renderBashBlocked, renderBashExecution, renderBashRunning, } from "./ui/bash_execution.js";
|
|
25
26
|
import { ChatContainerComponent } from "./ui/chat_container.js";
|
|
@@ -33,7 +34,7 @@ import { SessionSummaryComponent } from "./ui/session_summary.js";
|
|
|
33
34
|
import { getFileAutocompleteToken, SlashAutocompleteProvider } from "./ui/slash_autocomplete.js";
|
|
34
35
|
import { SystemMessageComponent } from "./ui/system_message.js";
|
|
35
36
|
import { renderTaskBlocked, renderTaskFinished, renderTaskRunning } from "./ui/task_execution.js";
|
|
36
|
-
import {
|
|
37
|
+
import { createUiTheme } from "./ui/theme.js";
|
|
37
38
|
import { UserMessageComponent } from "./ui/user_message.js";
|
|
38
39
|
import { buildBaseSystemPrompt, buildEnvironmentTag, buildProjectContextBlock, buildSkillsIndexBlock, findAgentsFilesFromCwdToHome, formatRiskLevelChangeNotice, } from "./utils/context.js";
|
|
39
40
|
import { formatHistoryForCompression } from "./utils/fork.js";
|
|
@@ -42,13 +43,13 @@ import { getGitRoot } from "./utils/git.js";
|
|
|
42
43
|
import { extractAllFencedCodeBlocks, extractAssistantText } from "./utils/messages.js";
|
|
43
44
|
import { listProjectFiles, listProjectFilesAsync } from "./utils/project_files.js";
|
|
44
45
|
import { APP_VERSION } from "./version.js";
|
|
45
|
-
const { palette } = theme;
|
|
46
46
|
export class ChatApp {
|
|
47
47
|
ui;
|
|
48
48
|
chatContainer;
|
|
49
49
|
footer;
|
|
50
50
|
queuedMessages;
|
|
51
51
|
editor;
|
|
52
|
+
uiTheme;
|
|
52
53
|
personas;
|
|
53
54
|
currentPersona;
|
|
54
55
|
prompts;
|
|
@@ -139,12 +140,13 @@ export class ChatApp {
|
|
|
139
140
|
toolRegistry,
|
|
140
141
|
config: this.config,
|
|
141
142
|
});
|
|
143
|
+
this.uiTheme = createUiTheme("ansi");
|
|
142
144
|
this.ui = new TUI(createAppTerminal());
|
|
143
145
|
this.chatContainer = new ChatContainerComponent();
|
|
144
146
|
this.chatContainer.setCompactToolUi(this.compactToolUi);
|
|
145
|
-
this.footer = new FooterComponent(this.ui);
|
|
146
|
-
this.queuedMessages = new QueuedMessagesComponent(
|
|
147
|
-
this.editor = new CustomEditor(
|
|
147
|
+
this.footer = new FooterComponent(this.uiTheme, this.ui);
|
|
148
|
+
this.queuedMessages = new QueuedMessagesComponent(this.uiTheme, this.queuedUserMessages);
|
|
149
|
+
this.editor = new CustomEditor(this.uiTheme.editorTheme);
|
|
148
150
|
this.setupUI();
|
|
149
151
|
this.setupEditor();
|
|
150
152
|
}
|
|
@@ -154,9 +156,7 @@ export class ChatApp {
|
|
|
154
156
|
this.ui.addChild(this.queuedMessages);
|
|
155
157
|
this.ui.addChild(this.editor);
|
|
156
158
|
this.ui.addChild(this.footer);
|
|
157
|
-
|
|
158
|
-
palette.muted(buildHelpText(this.agentsFiles, this.skills));
|
|
159
|
-
this.chatContainer.addMessage(new Text(headerText, 1, 0));
|
|
159
|
+
this.chatContainer.addMessage(new AppIntroComponent(this.uiTheme, "tau", APP_VERSION, buildHelpText(this.agentsFiles, this.skills)));
|
|
160
160
|
this.ui.setFocus(this.editor);
|
|
161
161
|
this.updateFooter();
|
|
162
162
|
this.updateEditorBorderColor();
|
|
@@ -174,7 +174,7 @@ export class ChatApp {
|
|
|
174
174
|
this.editor.onEscape = () => this.interruptAssistantTurn();
|
|
175
175
|
this.editor.onCtrlF = () => {
|
|
176
176
|
this.expandFileMentions().catch((err) => {
|
|
177
|
-
this.addSystemMessage(`file expansion failed: ${err.message}`,
|
|
177
|
+
this.addSystemMessage(`file expansion failed: ${err.message}`, "error");
|
|
178
178
|
});
|
|
179
179
|
};
|
|
180
180
|
this.editor.onAltUp = () => this.popQueuedUserMessageIntoEditor();
|
|
@@ -238,29 +238,23 @@ export class ChatApp {
|
|
|
238
238
|
}
|
|
239
239
|
// UI Updates ------------------------------------------------------------------------------------
|
|
240
240
|
updateFooter() {
|
|
241
|
-
const reasoningLabel = this.currentPersona.settings.reasoning
|
|
242
|
-
const toolLabel = this.formatRiskLevelLabel();
|
|
241
|
+
const reasoningLabel = this.currentPersona.settings.reasoning ?? "none";
|
|
243
242
|
const contextUsage = this.getContextUsageString();
|
|
244
243
|
const sessionCost = this.getSessionCostString();
|
|
245
244
|
const cwd = formatCwd(process.cwd());
|
|
246
|
-
const left = palette.dim(`${cwd} · ${contextUsage} · ${sessionCost}`);
|
|
247
245
|
const personaName = this.currentPersona.label || this.currentPersona.id;
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
246
|
+
this.footer.setStatus({
|
|
247
|
+
cwd,
|
|
248
|
+
contextUsage,
|
|
249
|
+
sessionCost,
|
|
250
|
+
personaLabel: personaName,
|
|
251
|
+
reasoningLabel,
|
|
252
|
+
riskLevel: this.riskLevel,
|
|
253
|
+
});
|
|
251
254
|
this.ui.requestRender();
|
|
252
255
|
}
|
|
253
|
-
formatRiskLevelLabel() {
|
|
254
|
-
switch (this.riskLevel) {
|
|
255
|
-
case "restricted":
|
|
256
|
-
return palette.riskRestricted("restricted");
|
|
257
|
-
case "read-only":
|
|
258
|
-
return palette.riskReadOnly("read-only");
|
|
259
|
-
case "read-write":
|
|
260
|
-
return palette.riskReadWrite("read-write");
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
256
|
updateEditorBorderColor() {
|
|
257
|
+
const { palette } = this.uiTheme;
|
|
264
258
|
if (this.isBashMode) {
|
|
265
259
|
this.editor.borderColor = (s) => palette.bashRan(s);
|
|
266
260
|
}
|
|
@@ -268,16 +262,16 @@ export class ChatApp {
|
|
|
268
262
|
this.editor.borderColor = (s) => palette.memoryMode(s);
|
|
269
263
|
}
|
|
270
264
|
else {
|
|
271
|
-
this.editor.borderColor = editorBorderForReasoning(this.currentPersona.settings.reasoning);
|
|
265
|
+
this.editor.borderColor = this.uiTheme.editorBorderForReasoning(this.currentPersona.settings.reasoning);
|
|
272
266
|
}
|
|
273
267
|
this.ui.requestRender();
|
|
274
268
|
}
|
|
275
|
-
addSystemMessage(text,
|
|
276
|
-
this.chatContainer.addMessage(new SystemMessageComponent(text,
|
|
269
|
+
addSystemMessage(text, kind) {
|
|
270
|
+
this.chatContainer.addMessage(new SystemMessageComponent(this.uiTheme, text, kind));
|
|
277
271
|
this.ui.requestRender();
|
|
278
272
|
}
|
|
279
273
|
addUserMessage(text, opts) {
|
|
280
|
-
this.chatContainer.addMessage(new UserMessageComponent(text, opts));
|
|
274
|
+
this.chatContainer.addMessage(new UserMessageComponent(this.uiTheme, text, opts));
|
|
281
275
|
this.ui.requestRender();
|
|
282
276
|
}
|
|
283
277
|
addAssistantComponent(component) {
|
|
@@ -388,7 +382,7 @@ export class ChatApp {
|
|
|
388
382
|
}
|
|
389
383
|
}
|
|
390
384
|
const description = getRiskLevelDescription(next);
|
|
391
|
-
this.addSystemMessage(`risk level: ${description} (ctrl+r to cycle)`,
|
|
385
|
+
this.addSystemMessage(`risk level: ${description} (ctrl+r to cycle)`, "success");
|
|
392
386
|
this.ui.requestRender();
|
|
393
387
|
}
|
|
394
388
|
// Personality Management ---------------------------------------------------------------
|
|
@@ -411,10 +405,10 @@ export class ChatApp {
|
|
|
411
405
|
this.updateFooter();
|
|
412
406
|
this.updateEditorBorderColor();
|
|
413
407
|
if (skillsContext.unknown.length > 0) {
|
|
414
|
-
this.addSystemMessage(`warning: unknown skills enabled: ${skillsContext.unknown.join(", ")}`,
|
|
408
|
+
this.addSystemMessage(`warning: unknown skills enabled: ${skillsContext.unknown.join(", ")}`, "warn");
|
|
415
409
|
}
|
|
416
410
|
const label = this.currentPersona.label || this.currentPersona.id;
|
|
417
|
-
this.addSystemMessage(`switched to ${label} (ctrl+p to cycle)`,
|
|
411
|
+
this.addSystemMessage(`switched to ${label} (ctrl+p to cycle)`, "success");
|
|
418
412
|
this.ui.requestRender();
|
|
419
413
|
}
|
|
420
414
|
getSkillsIndexBlockForPersona(persona) {
|
|
@@ -455,7 +449,7 @@ export class ChatApp {
|
|
|
455
449
|
const message = this.showThinking
|
|
456
450
|
? "thoughts visible (ctrl+t to hide)"
|
|
457
451
|
: "thoughts hidden (ctrl+t to show)";
|
|
458
|
-
this.addSystemMessage(message,
|
|
452
|
+
this.addSystemMessage(message, "success");
|
|
459
453
|
this.ui.requestRender();
|
|
460
454
|
}
|
|
461
455
|
toggleCompactToolUi() {
|
|
@@ -464,14 +458,14 @@ export class ChatApp {
|
|
|
464
458
|
const message = this.compactToolUi
|
|
465
459
|
? "compact tool UI enabled (ctrl+o to disable)"
|
|
466
460
|
: "compact tool UI disabled (ctrl+o to enable)";
|
|
467
|
-
this.addSystemMessage(message,
|
|
461
|
+
this.addSystemMessage(message, "success");
|
|
468
462
|
this.ui.requestRender();
|
|
469
463
|
}
|
|
470
464
|
interruptAssistantTurn() {
|
|
471
465
|
if (!this.isStreaming || this.currentTurnAbort?.signal.aborted)
|
|
472
466
|
return;
|
|
473
467
|
this.currentTurnAbort?.abort();
|
|
474
|
-
this.addSystemMessage("interrupted.",
|
|
468
|
+
this.addSystemMessage("interrupted.", "error");
|
|
475
469
|
this.ui.requestRender();
|
|
476
470
|
}
|
|
477
471
|
// Input Handling --------------------------------------------------------------------------------
|
|
@@ -566,7 +560,7 @@ export class ChatApp {
|
|
|
566
560
|
if (trimmed.startsWith("#")) {
|
|
567
561
|
const request = trimmed.slice(1).trim();
|
|
568
562
|
if (!request) {
|
|
569
|
-
this.addSystemMessage("memory mode request was empty.",
|
|
563
|
+
this.addSystemMessage("memory mode request was empty.", "warn");
|
|
570
564
|
return;
|
|
571
565
|
}
|
|
572
566
|
const agentsFilePath = this.getMemoryModeFilePath();
|
|
@@ -635,10 +629,10 @@ export class ChatApp {
|
|
|
635
629
|
case "new":
|
|
636
630
|
this.clearSession();
|
|
637
631
|
break;
|
|
638
|
-
case "
|
|
632
|
+
case "compactOnlySummary":
|
|
639
633
|
await this.forkSessionOnlySummary();
|
|
640
634
|
break;
|
|
641
|
-
case "
|
|
635
|
+
case "compactSummaryAndLastTurn":
|
|
642
636
|
await this.forkSessionSummaryAndLastTurn();
|
|
643
637
|
break;
|
|
644
638
|
case "risk":
|
|
@@ -657,50 +651,50 @@ export class ChatApp {
|
|
|
657
651
|
await this.reloadContent();
|
|
658
652
|
break;
|
|
659
653
|
case "unknown":
|
|
660
|
-
this.addSystemMessage("unknown command. type /help.",
|
|
654
|
+
this.addSystemMessage("unknown command. type /help.", "error");
|
|
661
655
|
break;
|
|
662
656
|
}
|
|
663
657
|
}
|
|
664
658
|
showHelp() {
|
|
665
|
-
this.addSystemMessage(buildHelpText(this.agentsFiles, this.skills),
|
|
659
|
+
this.addSystemMessage(buildHelpText(this.agentsFiles, this.skills), "muted");
|
|
666
660
|
}
|
|
667
661
|
async copyLastAssistantMessage() {
|
|
668
662
|
const lastAssistant = this.getLastAssistantMessage();
|
|
669
663
|
if (!lastAssistant) {
|
|
670
|
-
this.addSystemMessage("no assistant message to copy yet.",
|
|
664
|
+
this.addSystemMessage("no assistant message to copy yet.", "warn");
|
|
671
665
|
return;
|
|
672
666
|
}
|
|
673
667
|
const text = extractAssistantText(lastAssistant);
|
|
674
668
|
if (!text.trim()) {
|
|
675
|
-
this.addSystemMessage("last assistant message was empty.",
|
|
669
|
+
this.addSystemMessage("last assistant message was empty.", "warn");
|
|
676
670
|
return;
|
|
677
671
|
}
|
|
678
672
|
try {
|
|
679
673
|
await copyTextToClipboard(text);
|
|
680
|
-
this.addSystemMessage("copied last assistant message to clipboard.",
|
|
674
|
+
this.addSystemMessage("copied last assistant message to clipboard.", "success");
|
|
681
675
|
}
|
|
682
676
|
catch (err) {
|
|
683
|
-
this.addSystemMessage(`clipboard copy failed: ${err.message}`,
|
|
677
|
+
this.addSystemMessage(`clipboard copy failed: ${err.message}`, "error");
|
|
684
678
|
}
|
|
685
679
|
}
|
|
686
680
|
async copyLastAssistantCodeBlock() {
|
|
687
681
|
const lastAssistant = this.getLastAssistantMessage();
|
|
688
682
|
if (!lastAssistant) {
|
|
689
|
-
this.addSystemMessage("no assistant message to copy yet.",
|
|
683
|
+
this.addSystemMessage("no assistant message to copy yet.", "warn");
|
|
690
684
|
return;
|
|
691
685
|
}
|
|
692
686
|
const text = extractAssistantText(lastAssistant);
|
|
693
687
|
const code = extractAllFencedCodeBlocks(text);
|
|
694
688
|
if (!code) {
|
|
695
|
-
this.addSystemMessage("no code block to copy yet.",
|
|
689
|
+
this.addSystemMessage("no code block to copy yet.", "warn");
|
|
696
690
|
return;
|
|
697
691
|
}
|
|
698
692
|
try {
|
|
699
693
|
await copyTextToClipboard(code);
|
|
700
|
-
this.addSystemMessage("copied all code blocks to clipboard.",
|
|
694
|
+
this.addSystemMessage("copied all code blocks to clipboard.", "success");
|
|
701
695
|
}
|
|
702
696
|
catch (err) {
|
|
703
|
-
this.addSystemMessage(`clipboard copy failed: ${err.message}`,
|
|
697
|
+
this.addSystemMessage(`clipboard copy failed: ${err.message}`, "error");
|
|
704
698
|
}
|
|
705
699
|
}
|
|
706
700
|
clearSession() {
|
|
@@ -711,7 +705,7 @@ export class ChatApp {
|
|
|
711
705
|
this.taskEvents.clear();
|
|
712
706
|
this.subagentCostTotal = 0;
|
|
713
707
|
this.expandedFilesInCurrentPrompt.clear();
|
|
714
|
-
this.chatContainer.addMessage(new SessionDividerComponent("new session"));
|
|
708
|
+
this.chatContainer.addMessage(new SessionDividerComponent(this.uiTheme, "new session"));
|
|
715
709
|
this.isBashMode = false;
|
|
716
710
|
this.isMemoryMode = false;
|
|
717
711
|
this.previousSessionSummary = undefined;
|
|
@@ -847,8 +841,8 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
847
841
|
this.taskEvents.clear();
|
|
848
842
|
this.subagentCostTotal = 0;
|
|
849
843
|
this.expandedFilesInCurrentPrompt.clear();
|
|
850
|
-
this.chatContainer.addMessage(new SessionDividerComponent("new session"));
|
|
851
|
-
this.chatContainer.addMessage(new SessionSummaryComponent(this.previousSessionSummary));
|
|
844
|
+
this.chatContainer.addMessage(new SessionDividerComponent(this.uiTheme, "new session"));
|
|
845
|
+
this.chatContainer.addMessage(new SessionSummaryComponent(this.uiTheme, this.previousSessionSummary));
|
|
852
846
|
this.isBashMode = false;
|
|
853
847
|
this.isMemoryMode = false;
|
|
854
848
|
// Rebuild environment tag and system prompt with the new summary and current risk level
|
|
@@ -859,19 +853,19 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
859
853
|
async forkSessionOnlySummary() {
|
|
860
854
|
const history = this.engine.history;
|
|
861
855
|
if (history.length === 0) {
|
|
862
|
-
this.addSystemMessage("no conversation to fork.",
|
|
856
|
+
this.addSystemMessage("no conversation to fork.", "warn");
|
|
863
857
|
return;
|
|
864
858
|
}
|
|
865
|
-
this.addSystemMessage("summarizing session...",
|
|
859
|
+
this.addSystemMessage("summarizing session...", "success");
|
|
866
860
|
this.isStreaming = true;
|
|
867
861
|
this.footer.startWorkingIcon();
|
|
868
862
|
try {
|
|
869
863
|
const summary = await this.generateSummary(history);
|
|
870
864
|
this.applySessionContext(summary);
|
|
871
|
-
this.addSystemMessage("session forked. previous context has been summarized.",
|
|
865
|
+
this.addSystemMessage("session forked. previous context has been summarized.", "success");
|
|
872
866
|
}
|
|
873
867
|
catch (err) {
|
|
874
|
-
this.addSystemMessage(`fork failed: ${err.message}`,
|
|
868
|
+
this.addSystemMessage(`fork failed: ${err.message}`, "error");
|
|
875
869
|
}
|
|
876
870
|
finally {
|
|
877
871
|
this.footer.stop();
|
|
@@ -883,10 +877,10 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
883
877
|
async forkSessionSummaryAndLastTurn() {
|
|
884
878
|
const history = this.engine.history;
|
|
885
879
|
if (history.length === 0) {
|
|
886
|
-
this.addSystemMessage("no conversation to fork.",
|
|
880
|
+
this.addSystemMessage("no conversation to fork.", "warn");
|
|
887
881
|
return;
|
|
888
882
|
}
|
|
889
|
-
this.addSystemMessage("summarizing session...",
|
|
883
|
+
this.addSystemMessage("summarizing session...", "success");
|
|
890
884
|
this.isStreaming = true;
|
|
891
885
|
this.footer.startWorkingIcon();
|
|
892
886
|
try {
|
|
@@ -907,10 +901,10 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
907
901
|
sessionContext += "\n</last_turn>";
|
|
908
902
|
}
|
|
909
903
|
this.applySessionContext(sessionContext);
|
|
910
|
-
this.addSystemMessage("session forked. previous context and last turn have been included.",
|
|
904
|
+
this.addSystemMessage("session forked. previous context and last turn have been included.", "success");
|
|
911
905
|
}
|
|
912
906
|
catch (err) {
|
|
913
|
-
this.addSystemMessage(`fork failed: ${err.message}`,
|
|
907
|
+
this.addSystemMessage(`fork failed: ${err.message}`, "error");
|
|
914
908
|
}
|
|
915
909
|
finally {
|
|
916
910
|
this.footer.stop();
|
|
@@ -934,12 +928,12 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
934
928
|
}
|
|
935
929
|
}
|
|
936
930
|
const details = getRiskLevelDescription(level);
|
|
937
|
-
this.addSystemMessage(`risk level set to '${level}': ${details}`,
|
|
931
|
+
this.addSystemMessage(`risk level set to '${level}': ${details}`, "success");
|
|
938
932
|
}
|
|
939
933
|
switchPersona(id) {
|
|
940
934
|
const persona = this.personas.find((p) => p.id.toLowerCase() === id.toLowerCase());
|
|
941
935
|
if (!persona) {
|
|
942
|
-
this.addSystemMessage(`unknown persona '${id}'.`,
|
|
936
|
+
this.addSystemMessage(`unknown persona '${id}'.`, "error");
|
|
943
937
|
return;
|
|
944
938
|
}
|
|
945
939
|
this.currentPersona = persona;
|
|
@@ -958,14 +952,14 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
958
952
|
this.updateFooter();
|
|
959
953
|
this.updateEditorBorderColor();
|
|
960
954
|
if (skillsContext.unknown.length > 0) {
|
|
961
|
-
this.addSystemMessage(`warning: unknown skills enabled: ${skillsContext.unknown.join(", ")}`,
|
|
955
|
+
this.addSystemMessage(`warning: unknown skills enabled: ${skillsContext.unknown.join(", ")}`, "warn");
|
|
962
956
|
}
|
|
963
|
-
this.addSystemMessage(`switched to ${persona.label} (${persona.model.id})`,
|
|
957
|
+
this.addSystemMessage(`switched to ${persona.label} (${persona.model.id})`, "success");
|
|
964
958
|
}
|
|
965
959
|
insertPrompt(id) {
|
|
966
960
|
const prompt = this.prompts.find((p) => p.id.toLowerCase() === id.toLowerCase());
|
|
967
961
|
if (!prompt) {
|
|
968
|
-
this.addSystemMessage(`unknown prompt '${id}'.`,
|
|
962
|
+
this.addSystemMessage(`unknown prompt '${id}'.`, "error");
|
|
969
963
|
return;
|
|
970
964
|
}
|
|
971
965
|
this.editor.setText(prompt.template);
|
|
@@ -974,14 +968,14 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
974
968
|
async runSavedBashCommand(id) {
|
|
975
969
|
const saved = this.bashCommands.find((b) => b.id.toLowerCase() === id.toLowerCase());
|
|
976
970
|
if (!saved) {
|
|
977
|
-
this.addSystemMessage(`unknown bash command '${id}'.`,
|
|
971
|
+
this.addSystemMessage(`unknown bash command '${id}'.`, "error");
|
|
978
972
|
return;
|
|
979
973
|
}
|
|
980
974
|
await this.runBashCommand(saved.cmd, { cwd: this.repoRoot });
|
|
981
975
|
}
|
|
982
976
|
async reloadContent() {
|
|
983
977
|
if (this.isStreaming) {
|
|
984
|
-
this.addSystemMessage("cannot reload while streaming. try again after the response.",
|
|
978
|
+
this.addSystemMessage("cannot reload while streaming. try again after the response.", "warn");
|
|
985
979
|
return;
|
|
986
980
|
}
|
|
987
981
|
try {
|
|
@@ -1004,7 +998,7 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1004
998
|
// Persona no longer exists; switch to the first one
|
|
1005
999
|
this.currentPersona = personas[0];
|
|
1006
1000
|
this.clampPersonaReasoning(this.currentPersona);
|
|
1007
|
-
this.addSystemMessage(`previous persona no longer available; switched to ${this.currentPersona.label || this.currentPersona.id}.`,
|
|
1001
|
+
this.addSystemMessage(`previous persona no longer available; switched to ${this.currentPersona.label || this.currentPersona.id}.`, "warn");
|
|
1008
1002
|
}
|
|
1009
1003
|
// Rebuild system prompt and update the engine
|
|
1010
1004
|
const skillsContext = this.getSkillsIndexBlockForPersona(this.currentPersona);
|
|
@@ -1019,7 +1013,7 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1019
1013
|
});
|
|
1020
1014
|
this.engine.setPersona(this.currentPersona, this.baseSystemPrompt);
|
|
1021
1015
|
if (skillsContext.unknown.length > 0) {
|
|
1022
|
-
this.addSystemMessage(`warning: unknown skills enabled: ${skillsContext.unknown.join(", ")}`,
|
|
1016
|
+
this.addSystemMessage(`warning: unknown skills enabled: ${skillsContext.unknown.join(", ")}`, "warn");
|
|
1023
1017
|
}
|
|
1024
1018
|
// Update UI
|
|
1025
1019
|
this.updateFooter();
|
|
@@ -1033,11 +1027,11 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1033
1027
|
const summary = errorCount > 0
|
|
1034
1028
|
? `reloaded: ${personaCount} personas, ${promptCount} prompts, ${skillCount} skills, ${bashCount} bash commands (${errorCount} errors).`
|
|
1035
1029
|
: `reloaded: ${personaCount} personas, ${promptCount} prompts, ${skillCount} skills, ${bashCount} bash commands.`;
|
|
1036
|
-
this.addSystemMessage(summary,
|
|
1030
|
+
this.addSystemMessage(summary, "success");
|
|
1037
1031
|
this.ui.requestRender();
|
|
1038
1032
|
}
|
|
1039
1033
|
catch (err) {
|
|
1040
|
-
this.addSystemMessage(`reload failed: ${err.message}`,
|
|
1034
|
+
this.addSystemMessage(`reload failed: ${err.message}`, "error");
|
|
1041
1035
|
}
|
|
1042
1036
|
}
|
|
1043
1037
|
// Assistant Turn --------------------------------------------------------------------------------
|
|
@@ -1051,7 +1045,7 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1051
1045
|
if (currentAssistant)
|
|
1052
1046
|
return currentAssistant;
|
|
1053
1047
|
currentAssistant = {
|
|
1054
|
-
component: new AssistantMessageComponent(undefined, this.showThinking),
|
|
1048
|
+
component: new AssistantMessageComponent(this.uiTheme, undefined, this.showThinking),
|
|
1055
1049
|
inserted: false,
|
|
1056
1050
|
};
|
|
1057
1051
|
return currentAssistant;
|
|
@@ -1070,7 +1064,7 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1070
1064
|
switch (event.type) {
|
|
1071
1065
|
case "assistant_start":
|
|
1072
1066
|
currentAssistant = {
|
|
1073
|
-
component: new AssistantMessageComponent(undefined, this.showThinking),
|
|
1067
|
+
component: new AssistantMessageComponent(this.uiTheme, undefined, this.showThinking),
|
|
1074
1068
|
inserted: false,
|
|
1075
1069
|
};
|
|
1076
1070
|
break;
|
|
@@ -1106,7 +1100,7 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1106
1100
|
case "tool_ui": {
|
|
1107
1101
|
const uiEvent = event.uiEvent;
|
|
1108
1102
|
if (uiEvent.type === "bash_started") {
|
|
1109
|
-
this.chatContainer.addToolMessage((compact) => renderBashRunning(uiEvent.command, compact), uiEvent.toolCallId);
|
|
1103
|
+
this.chatContainer.addToolMessage((compact) => renderBashRunning(this.uiTheme, uiEvent.command, compact), uiEvent.toolCallId);
|
|
1110
1104
|
this.runningBashComponents.set(uiEvent.toolCallId, {
|
|
1111
1105
|
command: uiEvent.command,
|
|
1112
1106
|
});
|
|
@@ -1114,7 +1108,7 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1114
1108
|
}
|
|
1115
1109
|
else if (uiEvent.type === "bash_execution") {
|
|
1116
1110
|
const running = this.runningBashComponents.get(uiEvent.toolCallId);
|
|
1117
|
-
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderBashExecution(uiEvent.command, uiEvent.exitCode, uiEvent.truncationInfo, compact));
|
|
1111
|
+
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderBashExecution(this.uiTheme, uiEvent.command, uiEvent.exitCode, uiEvent.truncationInfo, compact));
|
|
1118
1112
|
if (running) {
|
|
1119
1113
|
this.runningBashComponents.delete(uiEvent.toolCallId);
|
|
1120
1114
|
}
|
|
@@ -1123,13 +1117,13 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1123
1117
|
else if (uiEvent.type === "bash_blocked") {
|
|
1124
1118
|
if (uiEvent.toolCallId) {
|
|
1125
1119
|
const running = this.runningBashComponents.get(uiEvent.toolCallId);
|
|
1126
|
-
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderBashBlocked(uiEvent.command, uiEvent.reason, compact));
|
|
1120
|
+
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderBashBlocked(this.uiTheme, uiEvent.command, uiEvent.reason, compact));
|
|
1127
1121
|
if (running) {
|
|
1128
1122
|
this.runningBashComponents.delete(uiEvent.toolCallId);
|
|
1129
1123
|
}
|
|
1130
1124
|
}
|
|
1131
1125
|
else {
|
|
1132
|
-
this.chatContainer.addToolMessage((compact) => renderBashBlocked(uiEvent.command, uiEvent.reason, compact));
|
|
1126
|
+
this.chatContainer.addToolMessage((compact) => renderBashBlocked(this.uiTheme, uiEvent.command, uiEvent.reason, compact));
|
|
1133
1127
|
}
|
|
1134
1128
|
this.ui.requestRender();
|
|
1135
1129
|
}
|
|
@@ -1139,7 +1133,10 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1139
1133
|
}
|
|
1140
1134
|
const kind = uiEvent.kind ?? "task";
|
|
1141
1135
|
const subagentName = uiEvent.name.trim() || undefined;
|
|
1142
|
-
this.chatContainer.addToolMessage((compact) => renderTaskRunning(uiEvent.title, [], 0, 0, 0, compact, {
|
|
1136
|
+
this.chatContainer.addToolMessage((compact) => renderTaskRunning(this.uiTheme, uiEvent.title, [], 0, 0, 0, compact, {
|
|
1137
|
+
kind,
|
|
1138
|
+
subagentName,
|
|
1139
|
+
}), uiEvent.toolCallId);
|
|
1143
1140
|
this.runningTaskComponents.set(uiEvent.toolCallId, {
|
|
1144
1141
|
kind,
|
|
1145
1142
|
name: subagentName,
|
|
@@ -1168,14 +1165,14 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1168
1165
|
running.turns = uiEvent.turns;
|
|
1169
1166
|
running.toolCalls = uiEvent.toolCalls;
|
|
1170
1167
|
}
|
|
1171
|
-
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderTaskRunning(uiEvent.title, events, uiEvent.costTotal, uiEvent.turns, uiEvent.toolCalls, compact, { kind, subagentName }));
|
|
1168
|
+
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderTaskRunning(this.uiTheme, uiEvent.title, events, uiEvent.costTotal, uiEvent.turns, uiEvent.toolCalls, compact, { kind, subagentName }));
|
|
1172
1169
|
this.ui.requestRender();
|
|
1173
1170
|
}
|
|
1174
1171
|
else if (uiEvent.type === "task_finished") {
|
|
1175
1172
|
const running = this.runningTaskComponents.get(uiEvent.toolCallId);
|
|
1176
1173
|
const kind = uiEvent.kind ?? running?.kind ?? "task";
|
|
1177
1174
|
const subagentName = uiEvent.name.trim() || undefined;
|
|
1178
|
-
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderTaskFinished(uiEvent.title, uiEvent.costTotal, uiEvent.turns, uiEvent.toolCalls, uiEvent.status, uiEvent.finalOutput, compact, { kind, subagentName }));
|
|
1175
|
+
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderTaskFinished(this.uiTheme, uiEvent.title, uiEvent.costTotal, uiEvent.turns, uiEvent.toolCalls, uiEvent.status, uiEvent.finalOutput, compact, { kind, subagentName }));
|
|
1179
1176
|
this.runningTaskComponents.delete(uiEvent.toolCallId);
|
|
1180
1177
|
this.taskEvents.delete(uiEvent.toolCallId);
|
|
1181
1178
|
this.subagentCostTotal += uiEvent.costTotal;
|
|
@@ -1187,10 +1184,13 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1187
1184
|
const kind = uiEvent.kind ?? running?.kind ?? "task";
|
|
1188
1185
|
const subagentName = uiEvent.name?.trim() || undefined;
|
|
1189
1186
|
if (running) {
|
|
1190
|
-
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderTaskBlocked(uiEvent.title, uiEvent.reason, compact, {
|
|
1187
|
+
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderTaskBlocked(this.uiTheme, uiEvent.title, uiEvent.reason, compact, {
|
|
1188
|
+
kind,
|
|
1189
|
+
subagentName,
|
|
1190
|
+
}));
|
|
1191
1191
|
}
|
|
1192
1192
|
else {
|
|
1193
|
-
this.chatContainer.addToolMessage((compact) => renderTaskBlocked(uiEvent.title, uiEvent.reason, compact, {
|
|
1193
|
+
this.chatContainer.addToolMessage((compact) => renderTaskBlocked(this.uiTheme, uiEvent.title, uiEvent.reason, compact, {
|
|
1194
1194
|
kind,
|
|
1195
1195
|
subagentName,
|
|
1196
1196
|
}), uiEvent.toolCallId);
|
|
@@ -1200,58 +1200,54 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1200
1200
|
this.ui.requestRender();
|
|
1201
1201
|
}
|
|
1202
1202
|
else if (uiEvent.type === "write_success") {
|
|
1203
|
-
this.chatContainer.addToolMessage((compact) => renderWriteSuccess(uiEvent.path, uiEvent.bytes, uiEvent.lines, uiEvent.
|
|
1203
|
+
this.chatContainer.addToolMessage((compact) => renderWriteSuccess(this.uiTheme, uiEvent.path, uiEvent.bytes, uiEvent.lines, uiEvent.content, compact));
|
|
1204
1204
|
this.ui.requestRender();
|
|
1205
1205
|
}
|
|
1206
1206
|
else if (uiEvent.type === "write_blocked") {
|
|
1207
|
-
this.chatContainer.addToolMessage((compact) => renderWriteBlocked(uiEvent.path, uiEvent.reason, compact));
|
|
1207
|
+
this.chatContainer.addToolMessage((compact) => renderWriteBlocked(this.uiTheme, uiEvent.path, uiEvent.reason, compact));
|
|
1208
1208
|
this.ui.requestRender();
|
|
1209
1209
|
}
|
|
1210
1210
|
else if (uiEvent.type === "edit_success") {
|
|
1211
|
-
this.chatContainer.addToolMessage((compact) => renderEditSuccess(uiEvent.path, uiEvent.oldLength, uiEvent.newLength, uiEvent.
|
|
1211
|
+
this.chatContainer.addToolMessage((compact) => renderEditSuccess(this.uiTheme, uiEvent.path, uiEvent.oldLength, uiEvent.newLength, uiEvent.oldText, uiEvent.newText, compact));
|
|
1212
1212
|
this.ui.requestRender();
|
|
1213
1213
|
}
|
|
1214
1214
|
else if (uiEvent.type === "edit_blocked") {
|
|
1215
|
-
this.chatContainer.addToolMessage((compact) => renderEditBlocked(uiEvent.path, uiEvent.reason, compact));
|
|
1215
|
+
this.chatContainer.addToolMessage((compact) => renderEditBlocked(this.uiTheme, uiEvent.path, uiEvent.reason, compact));
|
|
1216
1216
|
this.ui.requestRender();
|
|
1217
1217
|
}
|
|
1218
1218
|
else if (uiEvent.type === "read_success") {
|
|
1219
|
-
this.chatContainer.addToolMessage((compact) => renderReadSuccess(uiEvent.path, uiEvent.startLine, uiEvent.endLine, uiEvent.
|
|
1219
|
+
this.chatContainer.addToolMessage((compact) => renderReadSuccess(this.uiTheme, uiEvent.path, uiEvent.startLine, uiEvent.endLine, uiEvent.content, uiEvent.modelTruncation, compact));
|
|
1220
1220
|
this.ui.requestRender();
|
|
1221
1221
|
}
|
|
1222
1222
|
else if (uiEvent.type === "read_blocked") {
|
|
1223
|
-
this.chatContainer.addToolMessage((compact) => renderReadBlocked(uiEvent.path, uiEvent.reason, compact));
|
|
1223
|
+
this.chatContainer.addToolMessage((compact) => renderReadBlocked(this.uiTheme, uiEvent.path, uiEvent.reason, compact));
|
|
1224
1224
|
this.ui.requestRender();
|
|
1225
1225
|
}
|
|
1226
1226
|
else if (uiEvent.type === "list_success") {
|
|
1227
|
-
this.chatContainer.addToolMessage((compact) => renderListSuccess(uiEvent.path, uiEvent.offset, uiEvent.limit, uiEvent.total, uiEvent.returned, uiEvent.entries, compact));
|
|
1227
|
+
this.chatContainer.addToolMessage((compact) => renderListSuccess(this.uiTheme, uiEvent.path, uiEvent.offset, uiEvent.limit, uiEvent.total, uiEvent.returned, uiEvent.entries, compact));
|
|
1228
1228
|
this.ui.requestRender();
|
|
1229
1229
|
}
|
|
1230
1230
|
else if (uiEvent.type === "list_blocked") {
|
|
1231
|
-
this.chatContainer.addToolMessage((compact) => renderListBlocked(uiEvent.path, uiEvent.reason, compact));
|
|
1231
|
+
this.chatContainer.addToolMessage((compact) => renderListBlocked(this.uiTheme, uiEvent.path, uiEvent.reason, compact));
|
|
1232
1232
|
this.ui.requestRender();
|
|
1233
1233
|
}
|
|
1234
1234
|
else if (uiEvent.type === "grep_started") {
|
|
1235
|
-
this.chatContainer.addToolMessage((compact) => renderGrepRunning(uiEvent.pattern, compact), uiEvent.toolCallId);
|
|
1235
|
+
this.chatContainer.addToolMessage((compact) => renderGrepRunning(this.uiTheme, uiEvent.pattern, compact), uiEvent.toolCallId);
|
|
1236
1236
|
this.ui.requestRender();
|
|
1237
1237
|
}
|
|
1238
1238
|
else if (uiEvent.type === "grep_finished") {
|
|
1239
|
-
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderGrepFinished(uiEvent.pattern, uiEvent.status, uiEvent.exitCode, uiEvent.
|
|
1239
|
+
this.chatContainer.replaceToolMessage(uiEvent.toolCallId, (compact) => renderGrepFinished(this.uiTheme, uiEvent.pattern, uiEvent.status, uiEvent.exitCode, uiEvent.stdout, uiEvent.stderr, uiEvent.captureTruncated, compact));
|
|
1240
1240
|
this.ui.requestRender();
|
|
1241
1241
|
}
|
|
1242
1242
|
else if (uiEvent.type === "grep_blocked") {
|
|
1243
|
-
this.chatContainer.addToolMessage((compact) => renderGrepBlocked(uiEvent.pattern, uiEvent.reason, compact), uiEvent.toolCallId);
|
|
1243
|
+
this.chatContainer.addToolMessage((compact) => renderGrepBlocked(this.uiTheme, uiEvent.pattern, uiEvent.reason, compact), uiEvent.toolCallId);
|
|
1244
1244
|
this.ui.requestRender();
|
|
1245
1245
|
}
|
|
1246
1246
|
break;
|
|
1247
1247
|
}
|
|
1248
1248
|
case "notice": {
|
|
1249
|
-
const
|
|
1250
|
-
|
|
1251
|
-
: event.severity === "warn"
|
|
1252
|
-
? palette.noticeWarn
|
|
1253
|
-
: palette.noticeSuccess;
|
|
1254
|
-
this.addSystemMessage(event.text, style);
|
|
1249
|
+
const kind = event.severity === "error" ? "error" : event.severity === "warn" ? "warn" : "success";
|
|
1250
|
+
this.addSystemMessage(event.text, kind);
|
|
1255
1251
|
break;
|
|
1256
1252
|
}
|
|
1257
1253
|
case "tool_result":
|
|
@@ -1260,17 +1256,17 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1260
1256
|
}
|
|
1261
1257
|
}
|
|
1262
1258
|
catch (err) {
|
|
1263
|
-
this.addSystemMessage(`error: ${err.message}`,
|
|
1259
|
+
this.addSystemMessage(`error: ${err.message}`, "error");
|
|
1264
1260
|
}
|
|
1265
1261
|
finally {
|
|
1266
1262
|
const wasAborted = this.currentTurnAbort?.signal.aborted ?? false;
|
|
1267
1263
|
const reason = wasAborted ? "aborted" : "interrupted";
|
|
1268
1264
|
for (const [id, running] of this.runningBashComponents.entries()) {
|
|
1269
|
-
this.chatContainer.replaceToolMessage(id, (compact) => renderBashAborted(running.command, reason, compact));
|
|
1265
|
+
this.chatContainer.replaceToolMessage(id, (compact) => renderBashAborted(this.uiTheme, running.command, reason, compact));
|
|
1270
1266
|
}
|
|
1271
1267
|
const taskStatus = wasAborted ? "aborted" : "error";
|
|
1272
1268
|
for (const [id, running] of this.runningTaskComponents.entries()) {
|
|
1273
|
-
this.chatContainer.replaceToolMessage(id, (compact) => renderTaskFinished(running.title, running.costTotal, running.turns, running.toolCalls, taskStatus, reason, compact, { kind: running.kind, subagentName: running.name }));
|
|
1269
|
+
this.chatContainer.replaceToolMessage(id, (compact) => renderTaskFinished(this.uiTheme, running.title, running.costTotal, running.turns, running.toolCalls, taskStatus, reason, compact, { kind: running.kind, subagentName: running.name }));
|
|
1274
1270
|
}
|
|
1275
1271
|
this.footer.stop();
|
|
1276
1272
|
this.isStreaming = false;
|
|
@@ -1292,12 +1288,12 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1292
1288
|
stdout: { maxLines: BASH_USER_MAX_STDOUT_LINES, maxTokens: BASH_USER_MAX_STDOUT_TOKENS },
|
|
1293
1289
|
stderr: { maxLines: BASH_USER_MAX_STDERR_LINES, maxTokens: BASH_USER_MAX_STDERR_TOKENS },
|
|
1294
1290
|
});
|
|
1295
|
-
this.chatContainer.addMessage(renderBashExecution(command, exitCode, truncationInfo, false));
|
|
1291
|
+
this.chatContainer.addMessage(renderBashExecution(this.uiTheme, command, exitCode, truncationInfo, false));
|
|
1296
1292
|
this.engine.addUserText(formatBashUserMessageText({ command, truncationInfo }));
|
|
1297
1293
|
this.ui.requestRender();
|
|
1298
1294
|
}
|
|
1299
1295
|
catch (err) {
|
|
1300
|
-
this.addSystemMessage(`bash error: ${err.message}`,
|
|
1296
|
+
this.addSystemMessage(`bash error: ${err.message}`, "error");
|
|
1301
1297
|
}
|
|
1302
1298
|
finally {
|
|
1303
1299
|
this.isStreaming = false;
|
|
@@ -1312,7 +1308,7 @@ Write plain prose, no formatting. Be thorough enough that the reader can resume
|
|
|
1312
1308
|
}
|
|
1313
1309
|
async expandFileMentions() {
|
|
1314
1310
|
if (this.isStreaming) {
|
|
1315
|
-
this.addSystemMessage("cannot expand files while streaming. try again after the response.",
|
|
1311
|
+
this.addSystemMessage("cannot expand files while streaming. try again after the response.", "warn");
|
|
1316
1312
|
return;
|
|
1317
1313
|
}
|
|
1318
1314
|
const editorText = this.editor.getText();
|