@travisennis/acai 0.0.5 → 0.0.6
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 +4 -2
- package/dist/agent/index.d.ts +119 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +406 -0
- package/dist/agent/manual-loop.d.ts +41 -0
- package/dist/agent/manual-loop.d.ts.map +1 -0
- package/dist/agent/manual-loop.js +278 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +27 -33
- package/dist/commands/add-directory-command.d.ts +3 -0
- package/dist/commands/add-directory-command.d.ts.map +1 -0
- package/dist/commands/add-directory-command.js +85 -0
- package/dist/commands/application-log-command.d.ts.map +1 -1
- package/dist/commands/application-log-command.js +34 -0
- package/dist/commands/clear-command.d.ts.map +1 -1
- package/dist/commands/clear-command.js +8 -0
- package/dist/commands/compact-command.d.ts.map +1 -1
- package/dist/commands/compact-command.js +15 -2
- package/dist/commands/context-command.d.ts +3 -0
- package/dist/commands/context-command.d.ts.map +1 -0
- package/dist/commands/context-command.js +183 -0
- package/dist/commands/copy-command.d.ts.map +1 -1
- package/dist/commands/copy-command.js +28 -0
- package/dist/commands/edit-command.d.ts.map +1 -1
- package/dist/commands/edit-command.js +33 -0
- package/dist/commands/edit-prompt-command.d.ts.map +1 -1
- package/dist/commands/edit-prompt-command.js +28 -0
- package/dist/commands/exit-command.d.ts.map +1 -1
- package/dist/commands/exit-command.js +20 -0
- package/dist/commands/files-command.d.ts.map +1 -1
- package/dist/commands/files-command.js +57 -0
- package/dist/commands/generate-rules-command.d.ts.map +1 -1
- package/dist/commands/generate-rules-command.js +311 -1
- package/dist/commands/handoff-command.d.ts +3 -0
- package/dist/commands/handoff-command.d.ts.map +1 -0
- package/dist/commands/handoff-command.js +202 -0
- package/dist/commands/health-command.d.ts.map +1 -1
- package/dist/commands/health-command.js +119 -2
- package/dist/commands/help-command.d.ts.map +1 -1
- package/dist/commands/help-command.js +28 -0
- package/dist/commands/history-command.d.ts +3 -0
- package/dist/commands/history-command.d.ts.map +1 -0
- package/dist/commands/history-command.js +534 -0
- package/dist/commands/init-command.d.ts +1 -1
- package/dist/commands/init-command.d.ts.map +1 -1
- package/dist/commands/init-command.js +55 -18
- package/dist/commands/last-log-command.d.ts.map +1 -1
- package/dist/commands/last-log-command.js +27 -0
- package/dist/commands/list-directories-command.d.ts +3 -0
- package/dist/commands/list-directories-command.d.ts.map +1 -0
- package/dist/commands/list-directories-command.js +48 -0
- package/dist/commands/list-tools-command.d.ts.map +1 -1
- package/dist/commands/list-tools-command.js +66 -3
- package/dist/commands/manager.d.ts +15 -3
- package/dist/commands/manager.d.ts.map +1 -1
- package/dist/commands/manager.js +86 -26
- package/dist/commands/model-command.d.ts +22 -0
- package/dist/commands/model-command.d.ts.map +1 -1
- package/dist/commands/model-command.js +256 -0
- package/dist/commands/paste-command.d.ts.map +1 -1
- package/dist/commands/paste-command.js +92 -0
- package/dist/commands/pickup-command.d.ts +3 -0
- package/dist/commands/pickup-command.d.ts.map +1 -0
- package/dist/commands/pickup-command.js +161 -0
- package/dist/commands/prompt-command.d.ts +1 -1
- package/dist/commands/prompt-command.d.ts.map +1 -1
- package/dist/commands/prompt-command.js +117 -2
- package/dist/commands/remove-directory-command.d.ts +3 -0
- package/dist/commands/remove-directory-command.d.ts.map +1 -0
- package/dist/commands/remove-directory-command.js +87 -0
- package/dist/commands/reset-command.d.ts +1 -1
- package/dist/commands/reset-command.d.ts.map +1 -1
- package/dist/commands/reset-command.js +13 -2
- package/dist/commands/rules-command.d.ts.map +1 -1
- package/dist/commands/rules-command.js +65 -0
- package/dist/commands/save-command.d.ts.map +1 -1
- package/dist/commands/save-command.js +12 -0
- package/dist/commands/shell-command.d.ts.map +1 -1
- package/dist/commands/shell-command.js +68 -0
- package/dist/commands/types.d.ts +9 -4
- package/dist/commands/types.d.ts.map +1 -1
- package/dist/commands/usage-command.d.ts.map +1 -1
- package/dist/commands/usage-command.js +22 -0
- package/dist/config.d.ts +6 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +23 -29
- package/dist/formatting.d.ts +108 -0
- package/dist/formatting.d.ts.map +1 -1
- package/dist/formatting.js +147 -0
- package/dist/index.d.ts +7 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +140 -38
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +47 -18
- package/dist/mentions.d.ts +2 -1
- package/dist/mentions.d.ts.map +1 -1
- package/dist/mentions.js +16 -1
- package/dist/messages.d.ts +8 -0
- package/dist/messages.d.ts.map +1 -1
- package/dist/messages.js +56 -19
- package/dist/middleware/cache.d.ts +3 -0
- package/dist/middleware/cache.d.ts.map +1 -0
- package/dist/middleware/cache.js +53 -0
- package/dist/middleware/index.d.ts +1 -0
- package/dist/middleware/index.d.ts.map +1 -1
- package/dist/middleware/index.js +1 -0
- package/dist/models/ai-config.d.ts +4 -2
- package/dist/models/ai-config.d.ts.map +1 -1
- package/dist/models/ai-config.js +12 -2
- package/dist/models/anthropic-provider.d.ts.map +1 -1
- package/dist/models/anthropic-provider.js +3 -60
- package/dist/models/manager.d.ts +2 -1
- package/dist/models/manager.d.ts.map +1 -1
- package/dist/models/manager.js +26 -2
- package/dist/models/openrouter-provider.d.ts +7 -14
- package/dist/models/openrouter-provider.d.ts.map +1 -1
- package/dist/models/openrouter-provider.js +114 -169
- package/dist/models/providers.d.ts +1 -1
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/prompts.d.ts +1 -0
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +53 -4
- package/dist/repl/display-tool-messages.d.ts +1 -1
- package/dist/repl/display-tool-messages.d.ts.map +1 -1
- package/dist/repl/display-tool-messages.js +47 -44
- package/dist/repl/get-prompt-header.d.ts.map +1 -1
- package/dist/repl/get-prompt-header.js +1 -30
- package/dist/repl/project-status-line.d.ts +2 -0
- package/dist/repl/project-status-line.d.ts.map +1 -0
- package/dist/repl/project-status-line.js +31 -0
- package/dist/repl/prompt.d.ts +21 -0
- package/dist/repl/prompt.d.ts.map +1 -0
- package/dist/{repl-prompt.js → repl/prompt.js} +119 -22
- package/dist/repl/tool-call-repair.d.ts.map +1 -1
- package/dist/repl/tool-call-repair.js +8 -4
- package/dist/repl-new.d.ts +53 -0
- package/dist/repl-new.d.ts.map +1 -0
- package/dist/repl-new.js +374 -0
- package/dist/repl.d.ts +3 -5
- package/dist/repl.d.ts.map +1 -1
- package/dist/repl.js +74 -166
- package/dist/terminal/checkbox-prompt.d.ts.map +1 -1
- package/dist/terminal/checkbox-prompt.js +10 -4
- package/dist/terminal/index.d.ts +7 -0
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +94 -0
- package/dist/terminal/input-prompt.d.ts +2 -1
- package/dist/terminal/input-prompt.d.ts.map +1 -1
- package/dist/terminal/markdown.js +3 -0
- package/dist/terminal/search-prompt.d.ts.map +1 -1
- package/dist/terminal/search-prompt.js +11 -10
- package/dist/terminal/select-prompt.d.ts +2 -2
- package/dist/terminal/select-prompt.d.ts.map +1 -1
- package/dist/terminal/select-prompt.js +47 -39
- package/dist/tokens/threshold.d.ts +35 -0
- package/dist/tokens/threshold.d.ts.map +1 -0
- package/dist/tokens/threshold.js +85 -0
- package/dist/tools/advanced-edit-file.d.ts +69 -0
- package/dist/tools/advanced-edit-file.d.ts.map +1 -0
- package/dist/tools/advanced-edit-file.js +281 -0
- package/dist/tools/agent.d.ts +16 -5
- package/dist/tools/agent.d.ts.map +1 -1
- package/dist/tools/agent.js +71 -58
- package/dist/tools/bash-utils.d.ts +1 -1
- package/dist/tools/bash-utils.d.ts.map +1 -1
- package/dist/tools/bash-utils.js +14 -6
- package/dist/tools/bash.d.ts +21 -12
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +88 -135
- package/dist/tools/code-interpreter.d.ts +21 -9
- package/dist/tools/code-interpreter.d.ts.map +1 -1
- package/dist/tools/code-interpreter.js +138 -137
- package/dist/tools/delete-file.d.ts +17 -10
- package/dist/tools/delete-file.d.ts.map +1 -1
- package/dist/tools/delete-file.js +51 -95
- package/dist/tools/directory-tree.d.ts +17 -6
- package/dist/tools/directory-tree.d.ts.map +1 -1
- package/dist/tools/directory-tree.js +47 -49
- package/dist/tools/dynamic-tool-loader.d.ts +18 -8
- package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-loader.js +121 -129
- package/dist/tools/dynamic-tool-parser.d.ts +1 -0
- package/dist/tools/dynamic-tool-parser.d.ts.map +1 -1
- package/dist/tools/dynamic-tool-parser.js +1 -0
- package/dist/tools/edit-file.d.ts +35 -15
- package/dist/tools/edit-file.d.ts.map +1 -1
- package/dist/tools/edit-file.js +112 -112
- package/dist/tools/filesystem-utils.d.ts +2 -1
- package/dist/tools/filesystem-utils.d.ts.map +1 -1
- package/dist/tools/filesystem-utils.js +31 -17
- package/dist/tools/glob.d.ts +36 -0
- package/dist/tools/glob.d.ts.map +1 -0
- package/dist/tools/glob.js +143 -0
- package/dist/tools/grep.d.ts +73 -12
- package/dist/tools/grep.d.ts.map +1 -1
- package/dist/tools/grep.js +413 -168
- package/dist/tools/index.d.ts +204 -124
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +242 -135
- package/dist/tools/llm-edit-fixer.d.ts +25 -0
- package/dist/tools/llm-edit-fixer.d.ts.map +1 -0
- package/dist/tools/llm-edit-fixer.js +150 -0
- package/dist/tools/move-file.d.ts +19 -7
- package/dist/tools/move-file.d.ts.map +1 -1
- package/dist/tools/move-file.js +40 -33
- package/dist/tools/read-file.d.ts +47 -9
- package/dist/tools/read-file.d.ts.map +1 -1
- package/dist/tools/read-file.js +74 -69
- package/dist/tools/read-multiple-files.d.ts +17 -6
- package/dist/tools/read-multiple-files.d.ts.map +1 -1
- package/dist/tools/read-multiple-files.js +76 -73
- package/dist/tools/save-file.d.ts +45 -12
- package/dist/tools/save-file.d.ts.map +1 -1
- package/dist/tools/save-file.js +58 -101
- package/dist/tools/think.d.ts +15 -7
- package/dist/tools/think.d.ts.map +1 -1
- package/dist/tools/think.js +30 -22
- package/dist/tools/types.d.ts +4 -10
- package/dist/tools/types.d.ts.map +1 -1
- package/dist/tools/types.js +9 -0
- package/dist/tools/utils.d.ts +14 -0
- package/dist/tools/utils.d.ts.map +1 -0
- package/dist/tools/utils.js +16 -0
- package/dist/tools/web-fetch.d.ts +11 -4
- package/dist/tools/web-fetch.d.ts.map +1 -1
- package/dist/tools/web-fetch.js +39 -38
- package/dist/tools/web-search.d.ts +15 -6
- package/dist/tools/web-search.d.ts.map +1 -1
- package/dist/tools/web-search.js +50 -32
- package/dist/tui/autocomplete.d.ts +44 -0
- package/dist/tui/autocomplete.d.ts.map +1 -0
- package/dist/tui/autocomplete.js +466 -0
- package/dist/tui/components/assistant-message.d.ts +18 -0
- package/dist/tui/components/assistant-message.d.ts.map +1 -0
- package/dist/tui/components/assistant-message.js +29 -0
- package/dist/tui/components/editor.d.ts +51 -0
- package/dist/tui/components/editor.d.ts.map +1 -0
- package/dist/tui/components/editor.js +758 -0
- package/dist/tui/components/footer.d.ts +24 -0
- package/dist/tui/components/footer.d.ts.map +1 -0
- package/dist/tui/components/footer.js +197 -0
- package/dist/tui/components/input.d.ts +14 -0
- package/dist/tui/components/input.d.ts.map +1 -0
- package/dist/tui/components/input.js +122 -0
- package/dist/tui/components/loader.d.ts +19 -0
- package/dist/tui/components/loader.d.ts.map +1 -0
- package/dist/tui/components/loader.js +45 -0
- package/dist/tui/components/markdown.d.ts +103 -0
- package/dist/tui/components/markdown.d.ts.map +1 -0
- package/dist/tui/components/markdown.js +533 -0
- package/dist/tui/components/modal.d.ts +40 -0
- package/dist/tui/components/modal.d.ts.map +1 -0
- package/dist/tui/components/modal.js +292 -0
- package/dist/tui/components/prompt-status.d.ts +16 -0
- package/dist/tui/components/prompt-status.d.ts.map +1 -0
- package/dist/tui/components/prompt-status.js +21 -0
- package/dist/tui/components/select-list.d.ts +22 -0
- package/dist/tui/components/select-list.d.ts.map +1 -0
- package/dist/tui/components/select-list.js +143 -0
- package/dist/tui/components/spacer.d.ts +16 -0
- package/dist/tui/components/spacer.d.ts.map +1 -0
- package/dist/tui/components/spacer.js +27 -0
- package/dist/tui/components/text.d.ts +26 -0
- package/dist/tui/components/text.d.ts.map +1 -0
- package/dist/tui/components/text.js +143 -0
- package/dist/tui/components/thinking-block.d.ts +14 -0
- package/dist/tui/components/thinking-block.d.ts.map +1 -0
- package/dist/tui/components/thinking-block.js +30 -0
- package/dist/tui/components/tool-execution.d.ts +17 -0
- package/dist/tui/components/tool-execution.d.ts.map +1 -0
- package/dist/tui/components/tool-execution.js +153 -0
- package/dist/tui/components/user-message.d.ts +9 -0
- package/dist/tui/components/user-message.d.ts.map +1 -0
- package/dist/tui/components/user-message.js +21 -0
- package/dist/tui/components/welcome.d.ts +6 -0
- package/dist/tui/components/welcome.d.ts.map +1 -0
- package/dist/tui/components/welcome.js +30 -0
- package/dist/tui/index.d.ts +14 -0
- package/dist/tui/index.d.ts.map +1 -0
- package/dist/tui/index.js +18 -0
- package/dist/tui/terminal.d.ts +37 -0
- package/dist/tui/terminal.d.ts.map +1 -0
- package/dist/tui/terminal.js +104 -0
- package/dist/tui/tui.d.ts +67 -0
- package/dist/tui/tui.d.ts.map +1 -0
- package/dist/tui/tui.js +184 -0
- package/dist/tui/utils.d.ts +19 -0
- package/dist/tui/utils.d.ts.map +1 -0
- package/dist/tui/utils.js +31 -0
- package/dist/utils/generators.d.ts +3 -0
- package/dist/utils/generators.d.ts.map +1 -0
- package/dist/utils/generators.js +25 -0
- package/dist/utils/iterables.d.ts +2 -0
- package/dist/utils/iterables.d.ts.map +1 -0
- package/dist/utils/iterables.js +6 -0
- package/package.json +16 -16
- package/dist/conversation-analyzer.d.ts +0 -11
- package/dist/conversation-analyzer.d.ts.map +0 -1
- package/dist/conversation-analyzer.js +0 -88
- package/dist/repl-prompt.d.ts +0 -15
- package/dist/repl-prompt.d.ts.map +0 -1
- package/dist/tokens/manage-output.d.ts +0 -34
- package/dist/tokens/manage-output.d.ts.map +0 -1
- package/dist/tokens/manage-output.js +0 -44
- package/dist/tool-executor.d.ts +0 -28
- package/dist/tool-executor.d.ts.map +0 -1
- package/dist/tool-executor.js +0 -74
- package/dist/tools/file-editing-utils.d.ts +0 -2
- package/dist/tools/file-editing-utils.d.ts.map +0 -1
- package/dist/tools/file-editing-utils.js +0 -135
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import style from "../../terminal/style.js";
|
|
2
|
+
import { visibleWidth } from "../utils.js";
|
|
3
|
+
/**
|
|
4
|
+
* Text component - displays multi-line text with word wrapping
|
|
5
|
+
*/
|
|
6
|
+
export class Text {
|
|
7
|
+
text;
|
|
8
|
+
paddingX; // Left/right padding
|
|
9
|
+
paddingY; // Top/bottom padding
|
|
10
|
+
customBgRgb;
|
|
11
|
+
// Cache for rendered output
|
|
12
|
+
cachedText;
|
|
13
|
+
cachedWidth;
|
|
14
|
+
cachedLines;
|
|
15
|
+
constructor(text = "", paddingX = 1, paddingY = 1, customBgRgb) {
|
|
16
|
+
this.text = text;
|
|
17
|
+
this.paddingX = paddingX;
|
|
18
|
+
this.paddingY = paddingY;
|
|
19
|
+
this.customBgRgb = customBgRgb;
|
|
20
|
+
}
|
|
21
|
+
setText(text) {
|
|
22
|
+
this.text = text;
|
|
23
|
+
// Invalidate cache when text changes
|
|
24
|
+
this.cachedText = undefined;
|
|
25
|
+
this.cachedWidth = undefined;
|
|
26
|
+
this.cachedLines = undefined;
|
|
27
|
+
}
|
|
28
|
+
setCustomBgRgb(customBgRgb) {
|
|
29
|
+
this.customBgRgb = customBgRgb;
|
|
30
|
+
// Invalidate cache when color changes
|
|
31
|
+
this.cachedText = undefined;
|
|
32
|
+
this.cachedWidth = undefined;
|
|
33
|
+
this.cachedLines = undefined;
|
|
34
|
+
}
|
|
35
|
+
render(width) {
|
|
36
|
+
// Check cache
|
|
37
|
+
if (this.cachedLines &&
|
|
38
|
+
this.cachedText === this.text &&
|
|
39
|
+
this.cachedWidth === width) {
|
|
40
|
+
return this.cachedLines;
|
|
41
|
+
}
|
|
42
|
+
// Calculate available width for content (subtract horizontal padding)
|
|
43
|
+
const contentWidth = Math.max(1, width - this.paddingX * 2);
|
|
44
|
+
// Don't render anything if there's no actual text
|
|
45
|
+
if (!this.text || this.text.trim() === "") {
|
|
46
|
+
const result = [];
|
|
47
|
+
// Update cache
|
|
48
|
+
this.cachedText = this.text;
|
|
49
|
+
this.cachedWidth = width;
|
|
50
|
+
this.cachedLines = result;
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
// Replace tabs with 3 spaces for consistent rendering
|
|
54
|
+
const normalizedText = this.text.replace(/\t/g, " ");
|
|
55
|
+
const lines = [];
|
|
56
|
+
const textLines = normalizedText.split("\n");
|
|
57
|
+
for (const line of textLines) {
|
|
58
|
+
// Measure visible length (strip ANSI codes)
|
|
59
|
+
const visibleLineLength = visibleWidth(line);
|
|
60
|
+
if (visibleLineLength <= contentWidth) {
|
|
61
|
+
lines.push(line);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Word wrap
|
|
65
|
+
const words = line.split(" ");
|
|
66
|
+
let currentLine = "";
|
|
67
|
+
for (const word of words) {
|
|
68
|
+
const currentVisible = visibleWidth(currentLine);
|
|
69
|
+
const wordVisible = visibleWidth(word);
|
|
70
|
+
// If word is too long, truncate it
|
|
71
|
+
let finalWord = word;
|
|
72
|
+
if (wordVisible > contentWidth) {
|
|
73
|
+
// Truncate word to fit
|
|
74
|
+
let truncated = "";
|
|
75
|
+
for (const char of word) {
|
|
76
|
+
if (visibleWidth(truncated + char) > contentWidth) {
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
truncated += char;
|
|
80
|
+
}
|
|
81
|
+
finalWord = truncated;
|
|
82
|
+
}
|
|
83
|
+
if (currentVisible === 0) {
|
|
84
|
+
currentLine = finalWord;
|
|
85
|
+
}
|
|
86
|
+
else if (currentVisible + 1 + visibleWidth(finalWord) <=
|
|
87
|
+
contentWidth) {
|
|
88
|
+
currentLine += ` ${finalWord}`;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
lines.push(currentLine);
|
|
92
|
+
currentLine = finalWord;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (currentLine.length > 0) {
|
|
96
|
+
lines.push(currentLine);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
// Add padding to each line
|
|
101
|
+
const leftPad = " ".repeat(this.paddingX);
|
|
102
|
+
const paddedLines = [];
|
|
103
|
+
for (const line of lines) {
|
|
104
|
+
// Calculate visible length (strip ANSI codes)
|
|
105
|
+
const visibleLength = visibleWidth(line);
|
|
106
|
+
// Right padding to fill to width (accounting for left padding and content)
|
|
107
|
+
const rightPadLength = Math.max(0, width - this.paddingX - visibleLength);
|
|
108
|
+
const rightPad = " ".repeat(rightPadLength);
|
|
109
|
+
let paddedLine = leftPad + line + rightPad;
|
|
110
|
+
// Apply background color if specified
|
|
111
|
+
if (this.customBgRgb) {
|
|
112
|
+
paddedLine = style.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(paddedLine);
|
|
113
|
+
}
|
|
114
|
+
paddedLines.push(paddedLine);
|
|
115
|
+
}
|
|
116
|
+
// Add top padding (empty lines)
|
|
117
|
+
const emptyLine = " ".repeat(width);
|
|
118
|
+
const topPadding = [];
|
|
119
|
+
for (let i = 0; i < this.paddingY; i++) {
|
|
120
|
+
let emptyPaddedLine = emptyLine;
|
|
121
|
+
if (this.customBgRgb) {
|
|
122
|
+
emptyPaddedLine = style.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(emptyPaddedLine);
|
|
123
|
+
}
|
|
124
|
+
topPadding.push(emptyPaddedLine);
|
|
125
|
+
}
|
|
126
|
+
// Add bottom padding (empty lines)
|
|
127
|
+
const bottomPadding = [];
|
|
128
|
+
for (let i = 0; i < this.paddingY; i++) {
|
|
129
|
+
let emptyPaddedLine = emptyLine;
|
|
130
|
+
if (this.customBgRgb) {
|
|
131
|
+
emptyPaddedLine = style.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(emptyPaddedLine);
|
|
132
|
+
}
|
|
133
|
+
bottomPadding.push(emptyPaddedLine);
|
|
134
|
+
}
|
|
135
|
+
// Combine top padding, content, and bottom padding
|
|
136
|
+
const result = [...topPadding, ...paddedLines, ...bottomPadding];
|
|
137
|
+
// Update cache
|
|
138
|
+
this.cachedText = this.text;
|
|
139
|
+
this.cachedWidth = width;
|
|
140
|
+
this.cachedLines = result;
|
|
141
|
+
return result.length > 0 ? result : [""];
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Container } from "../tui.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Component that renders a thinking block
|
|
4
|
+
*/
|
|
5
|
+
export declare class ThinkingBlockComponent extends Container {
|
|
6
|
+
private contentContainer;
|
|
7
|
+
constructor(message?: {
|
|
8
|
+
content: string;
|
|
9
|
+
});
|
|
10
|
+
updateContent(message: {
|
|
11
|
+
content: string;
|
|
12
|
+
}): void;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=thinking-block.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thinking-block.d.ts","sourceRoot":"","sources":["../../../source/tui/components/thinking-block.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC;;GAEG;AACH,qBAAa,sBAAuB,SAAQ,SAAS;IACnD,OAAO,CAAC,gBAAgB,CAAY;gBAExB,OAAO,CAAC,EAAE;QACpB,OAAO,EAAE,MAAM,CAAC;KACjB;IAYD,aAAa,CAAC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;CAsBlD"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import style from "../../terminal/style.js";
|
|
2
|
+
import { Container } from "../tui.js";
|
|
3
|
+
import { Markdown } from "./markdown.js";
|
|
4
|
+
import { Spacer } from "./spacer.js";
|
|
5
|
+
/**
|
|
6
|
+
* Component that renders a thinking block
|
|
7
|
+
*/
|
|
8
|
+
export class ThinkingBlockComponent extends Container {
|
|
9
|
+
contentContainer;
|
|
10
|
+
constructor(message) {
|
|
11
|
+
super();
|
|
12
|
+
// Container for text/thinking content
|
|
13
|
+
this.contentContainer = new Container();
|
|
14
|
+
this.addChild(this.contentContainer);
|
|
15
|
+
if (message) {
|
|
16
|
+
this.updateContent(message);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
updateContent(message) {
|
|
20
|
+
// Clear content container
|
|
21
|
+
this.contentContainer.clear();
|
|
22
|
+
if (message.content.length > 0) {
|
|
23
|
+
this.contentContainer.addChild(new Spacer(1));
|
|
24
|
+
}
|
|
25
|
+
const content = message.content;
|
|
26
|
+
// Assistant text messages with no background - trim the text
|
|
27
|
+
// Set paddingY=0 to avoid extra spacing before tool executions
|
|
28
|
+
this.contentContainer.addChild(new Markdown(style.dim(content.trim()), undefined, undefined, undefined, 1, 0));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ToolEvent } from "../../agent/index.ts";
|
|
2
|
+
import { Container } from "../index.ts";
|
|
3
|
+
export declare class ToolExecutionComponent extends Container {
|
|
4
|
+
private contentContainer;
|
|
5
|
+
private toolName;
|
|
6
|
+
private events;
|
|
7
|
+
constructor(event: ToolEvent);
|
|
8
|
+
update(event: ToolEvent): void;
|
|
9
|
+
private renderDisplay;
|
|
10
|
+
private getIndicator;
|
|
11
|
+
private handleToolInitMessage;
|
|
12
|
+
private handleToolUpdateMessage;
|
|
13
|
+
private handleToolCompletionMessage;
|
|
14
|
+
private handleToolErrorMessage;
|
|
15
|
+
private processEventsInOrder;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=tool-execution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-execution.d.ts","sourceRoot":"","sources":["../../../source/tui/components/tool-execution.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAGtD,OAAO,EAAE,SAAS,EAAgB,MAAM,aAAa,CAAC;AAItD,qBAAa,sBAAuB,SAAQ,SAAS;IACnD,OAAO,CAAC,gBAAgB,CAAY;IACpC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAc;gBAEhB,KAAK,EAAE,SAAS;IAY5B,MAAM,CAAC,KAAK,EAAE,SAAS;IAKvB,OAAO,CAAC,aAAa;IAwDrB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,uBAAuB;IAkB/B,OAAO,CAAC,2BAA2B;IAcnC,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,oBAAoB;CA+C7B"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { capitalize } from "../../formatting.js";
|
|
2
|
+
import style from "../../terminal/style.js";
|
|
3
|
+
import { Container, Spacer, Text } from "../index.js";
|
|
4
|
+
export class ToolExecutionComponent extends Container {
|
|
5
|
+
contentContainer;
|
|
6
|
+
toolName;
|
|
7
|
+
events;
|
|
8
|
+
constructor(event) {
|
|
9
|
+
super();
|
|
10
|
+
this.toolName = event.name;
|
|
11
|
+
this.events = [event];
|
|
12
|
+
// Container for text/thinking content
|
|
13
|
+
this.contentContainer = new Container();
|
|
14
|
+
this.addChild(this.contentContainer);
|
|
15
|
+
this.renderDisplay();
|
|
16
|
+
}
|
|
17
|
+
update(event) {
|
|
18
|
+
this.events.push(event);
|
|
19
|
+
this.renderDisplay();
|
|
20
|
+
}
|
|
21
|
+
renderDisplay() {
|
|
22
|
+
// Clear content container
|
|
23
|
+
this.contentContainer.clear();
|
|
24
|
+
const lines = [];
|
|
25
|
+
// Build display from complete event history with proper ordering
|
|
26
|
+
const processedEvents = this.processEventsInOrder();
|
|
27
|
+
for (let i = 0; i < processedEvents.length; i++) {
|
|
28
|
+
const event = processedEvents[i];
|
|
29
|
+
const eventType = event.type;
|
|
30
|
+
switch (eventType) {
|
|
31
|
+
case "tool-call-start":
|
|
32
|
+
lines.push(`${this.handleToolInitMessage(event)}`);
|
|
33
|
+
break;
|
|
34
|
+
case "tool-call-update":
|
|
35
|
+
lines.push(`├── ${this.handleToolUpdateMessage(event.msg)}`);
|
|
36
|
+
break;
|
|
37
|
+
case "tool-call-end":
|
|
38
|
+
lines.push(`└── ${this.handleToolCompletionMessage(event.msg)}`);
|
|
39
|
+
break;
|
|
40
|
+
case "tool-call-error":
|
|
41
|
+
lines.push(`└── ${this.handleToolErrorMessage(event.msg)}`);
|
|
42
|
+
break;
|
|
43
|
+
default: {
|
|
44
|
+
eventType;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Render all lines with proper indicators
|
|
49
|
+
const currentStatus = this.events[this.events.length - 1].type;
|
|
50
|
+
const indicator = this.getIndicator(currentStatus);
|
|
51
|
+
const displayLines = [];
|
|
52
|
+
for (let i = 0; i < lines.length; i++) {
|
|
53
|
+
let line = lines[i];
|
|
54
|
+
if (i === 0) {
|
|
55
|
+
line = `${indicator} ${line}`;
|
|
56
|
+
}
|
|
57
|
+
displayLines.push(line);
|
|
58
|
+
}
|
|
59
|
+
this.contentContainer.addChild(new Spacer(1));
|
|
60
|
+
this.contentContainer.addChild(new Text(displayLines.join("\n"), 1, 1, {
|
|
61
|
+
r: 52,
|
|
62
|
+
g: 53,
|
|
63
|
+
b: 65,
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
getIndicator(status) {
|
|
67
|
+
switch (status) {
|
|
68
|
+
case "tool-call-start":
|
|
69
|
+
return style.blue.bold("●");
|
|
70
|
+
case "tool-call-update":
|
|
71
|
+
return style.yellow.bold("●");
|
|
72
|
+
case "tool-call-end":
|
|
73
|
+
return style.green.bold("●");
|
|
74
|
+
case "tool-call-error":
|
|
75
|
+
return style.red.bold("●");
|
|
76
|
+
default:
|
|
77
|
+
status;
|
|
78
|
+
}
|
|
79
|
+
return style.blue.bold("●");
|
|
80
|
+
}
|
|
81
|
+
handleToolInitMessage(event) {
|
|
82
|
+
const message = event.msg;
|
|
83
|
+
let result = `${style.bold(capitalize(this.toolName))} `;
|
|
84
|
+
result += message.trim() ? `${style.bold(message)} ` : "";
|
|
85
|
+
result += style.dim(JSON.stringify(event.args).slice(0, 50));
|
|
86
|
+
return result;
|
|
87
|
+
}
|
|
88
|
+
handleToolUpdateMessage(message) {
|
|
89
|
+
const newlineIndex = message.indexOf("\n");
|
|
90
|
+
let result = "";
|
|
91
|
+
if (newlineIndex === -1) {
|
|
92
|
+
result += style.bold(message);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
const firstLine = message.slice(0, newlineIndex);
|
|
96
|
+
// const remainingLines = message.slice(newlineIndex + 1);
|
|
97
|
+
result += style.bold(firstLine);
|
|
98
|
+
// if (remainingLines.trim()) {
|
|
99
|
+
// terminal.display(remainingLines);
|
|
100
|
+
// }
|
|
101
|
+
}
|
|
102
|
+
return result;
|
|
103
|
+
}
|
|
104
|
+
handleToolCompletionMessage(message) {
|
|
105
|
+
const newlineIndex = message.indexOf("\n");
|
|
106
|
+
let result = "";
|
|
107
|
+
if (newlineIndex === -1) {
|
|
108
|
+
result += style.bold(message);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const firstLine = message.slice(0, newlineIndex);
|
|
112
|
+
result += style.bold(firstLine);
|
|
113
|
+
}
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
handleToolErrorMessage(message) {
|
|
117
|
+
return style.bold.red(message);
|
|
118
|
+
}
|
|
119
|
+
processEventsInOrder() {
|
|
120
|
+
const events = [...this.events];
|
|
121
|
+
const processed = [];
|
|
122
|
+
// Ensure we have a tool-call-start event
|
|
123
|
+
const hasStartEvent = events.some((event) => event.type === "tool-call-start");
|
|
124
|
+
if (!hasStartEvent && events.length > 0) {
|
|
125
|
+
// Create synthetic start event using the first event's name
|
|
126
|
+
const firstEvent = events[0];
|
|
127
|
+
processed.push({
|
|
128
|
+
type: "tool-call-start",
|
|
129
|
+
name: firstEvent.name,
|
|
130
|
+
toolCallId: firstEvent.toolCallId,
|
|
131
|
+
msg: "",
|
|
132
|
+
args: firstEvent.args,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
// Process events in the correct order: start → update → end/error
|
|
136
|
+
const startEvents = events.filter((event) => event.type === "tool-call-start");
|
|
137
|
+
const updateEvents = events.filter((event) => event.type === "tool-call-update");
|
|
138
|
+
const endEvents = events.filter((event) => event.type === "tool-call-end");
|
|
139
|
+
const errorEvents = events.filter((event) => event.type === "tool-call-error");
|
|
140
|
+
// Add start events first
|
|
141
|
+
processed.push(...startEvents);
|
|
142
|
+
// Add update events
|
|
143
|
+
processed.push(...updateEvents);
|
|
144
|
+
// Add end or error events (only one should be present)
|
|
145
|
+
if (endEvents.length > 0) {
|
|
146
|
+
processed.push(...endEvents);
|
|
147
|
+
}
|
|
148
|
+
else if (errorEvents.length > 0) {
|
|
149
|
+
processed.push(...errorEvents);
|
|
150
|
+
}
|
|
151
|
+
return processed;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-message.d.ts","sourceRoot":"","sources":["../../../source/tui/components/user-message.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAItC;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;IACjD,OAAO,CAAC,QAAQ,CAAW;gBAEf,IAAI,EAAE,MAAM;CAezB"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Container } from "../tui.js";
|
|
2
|
+
import { Markdown } from "./markdown.js";
|
|
3
|
+
import { Spacer } from "./spacer.js";
|
|
4
|
+
/**
|
|
5
|
+
* Component that renders a user message
|
|
6
|
+
*/
|
|
7
|
+
export class UserMessageComponent extends Container {
|
|
8
|
+
markdown;
|
|
9
|
+
constructor(text) {
|
|
10
|
+
super();
|
|
11
|
+
this.addChild(new Spacer(1));
|
|
12
|
+
// User messages with dark gray background
|
|
13
|
+
this.markdown = new Markdown(text, undefined, undefined, {
|
|
14
|
+
r: 52,
|
|
15
|
+
g: 53,
|
|
16
|
+
b: 65,
|
|
17
|
+
});
|
|
18
|
+
this.addChild(this.markdown);
|
|
19
|
+
this.addChild(new Spacer(1));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"welcome.d.ts","sourceRoot":"","sources":["../../../source/tui/components/welcome.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,qBAAa,OAAQ,YAAW,SAAS;IACvC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAiChC,OAAO,CAAC,OAAO;CAUhB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import style from "../../terminal/style.js";
|
|
2
|
+
import { getPackageVersion } from "../../version.js";
|
|
3
|
+
export class Welcome {
|
|
4
|
+
render(_width) {
|
|
5
|
+
const version = getPackageVersion();
|
|
6
|
+
const result = [];
|
|
7
|
+
result.push(style.magenta(this.getLogo()));
|
|
8
|
+
result.push("");
|
|
9
|
+
result.push(style.magenta("Greetings! I am acai."));
|
|
10
|
+
result.push(style.gray(` Version ${version}`));
|
|
11
|
+
result.push("");
|
|
12
|
+
result.push(style.white(` Type ${style.cyan("/help")} to see available commands.`));
|
|
13
|
+
result.push(style.white(" You can ask acai to explain code, fix issues, or perform tasks."));
|
|
14
|
+
result.push(style.white(` Example: "${style.italic("Please analyze this codebase and explain its structure.")}"`));
|
|
15
|
+
result.push(style.dim(" Use Ctrl+C to interrupt acai and exit."));
|
|
16
|
+
result.push("");
|
|
17
|
+
result.push(style.yellow(`The current working directory is ${process.cwd()}`));
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
getLogo() {
|
|
21
|
+
return `
|
|
22
|
+
█████╗ ██████╗ █████╗ ██╗
|
|
23
|
+
██╔══██╗██╔════╝██╔══██╗██║
|
|
24
|
+
███████║██║ ███████║██║
|
|
25
|
+
██╔══██║██║ ██╔══██║██║
|
|
26
|
+
██║ ██║╚██████╗██║ ██║██║
|
|
27
|
+
╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝
|
|
28
|
+
`;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { type AutocompleteItem, type AutocompleteProvider, CombinedAutocompleteProvider, type SlashCommand, } from "./autocomplete.ts";
|
|
2
|
+
export { Editor, type TextEditorConfig } from "./components/editor.ts";
|
|
3
|
+
export { Input } from "./components/input.ts";
|
|
4
|
+
export { Loader } from "./components/loader.ts";
|
|
5
|
+
export { Markdown } from "./components/markdown.ts";
|
|
6
|
+
export { Modal, ModalTable, ModalText } from "./components/modal.ts";
|
|
7
|
+
export { type SelectItem, SelectList } from "./components/select-list.ts";
|
|
8
|
+
export { Spacer } from "./components/spacer.ts";
|
|
9
|
+
export { Text } from "./components/text.ts";
|
|
10
|
+
export { UserMessageComponent } from "./components/user-message.ts";
|
|
11
|
+
export { ProcessTerminal, type Terminal } from "./terminal.ts";
|
|
12
|
+
export { type Component, Container, TUI } from "./tui.ts";
|
|
13
|
+
export { visibleWidth } from "./utils.ts";
|
|
14
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../source/tui/index.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EACzB,4BAA4B,EAC5B,KAAK,YAAY,GAClB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,MAAM,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACrE,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC;AAC5C,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AAEpE,OAAO,EAAE,eAAe,EAAE,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,EAAE,KAAK,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Core TUI interfaces and classes
|
|
2
|
+
// Autocomplete support
|
|
3
|
+
export { CombinedAutocompleteProvider, } from "./autocomplete.js";
|
|
4
|
+
// Components
|
|
5
|
+
export { Editor } from "./components/editor.js";
|
|
6
|
+
export { Input } from "./components/input.js";
|
|
7
|
+
export { Loader } from "./components/loader.js";
|
|
8
|
+
export { Markdown } from "./components/markdown.js";
|
|
9
|
+
export { Modal, ModalTable, ModalText } from "./components/modal.js";
|
|
10
|
+
export { SelectList } from "./components/select-list.js";
|
|
11
|
+
export { Spacer } from "./components/spacer.js";
|
|
12
|
+
export { Text } from "./components/text.js";
|
|
13
|
+
export { UserMessageComponent } from "./components/user-message.js";
|
|
14
|
+
// Terminal interface and implementations
|
|
15
|
+
export { ProcessTerminal } from "./terminal.js";
|
|
16
|
+
export { Container, TUI } from "./tui.js";
|
|
17
|
+
// Utilities
|
|
18
|
+
export { visibleWidth } from "./utils.js";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal terminal interface for TUI
|
|
3
|
+
*/
|
|
4
|
+
export interface Terminal {
|
|
5
|
+
start(onInput: (data: string) => void, onResize: () => void): void;
|
|
6
|
+
stop(): void;
|
|
7
|
+
write(data: string): void;
|
|
8
|
+
get columns(): number;
|
|
9
|
+
get rows(): number;
|
|
10
|
+
moveBy(lines: number): void;
|
|
11
|
+
hideCursor(): void;
|
|
12
|
+
showCursor(): void;
|
|
13
|
+
clearLine(): void;
|
|
14
|
+
clearFromCursor(): void;
|
|
15
|
+
clearScreen(): void;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Real terminal using process.stdin/stdout
|
|
19
|
+
*/
|
|
20
|
+
export declare class ProcessTerminal implements Terminal {
|
|
21
|
+
private wasRaw;
|
|
22
|
+
private inputHandler?;
|
|
23
|
+
private resizeHandler?;
|
|
24
|
+
private rl?;
|
|
25
|
+
start(onInput: (data: string) => void, onResize: () => void): void;
|
|
26
|
+
stop(): void;
|
|
27
|
+
write(data: string): void;
|
|
28
|
+
get columns(): number;
|
|
29
|
+
get rows(): number;
|
|
30
|
+
moveBy(lines: number): void;
|
|
31
|
+
hideCursor(): void;
|
|
32
|
+
showCursor(): void;
|
|
33
|
+
clearLine(): void;
|
|
34
|
+
clearFromCursor(): void;
|
|
35
|
+
clearScreen(): void;
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../source/tui/terminal.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,QAAQ;IAEvB,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI,CAAC;IAGnE,IAAI,IAAI,IAAI,CAAC;IAGb,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAG1B,IAAI,OAAO,IAAI,MAAM,CAAC;IACtB,IAAI,IAAI,IAAI,MAAM,CAAC;IAGnB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAG5B,UAAU,IAAI,IAAI,CAAC;IACnB,UAAU,IAAI,IAAI,CAAC;IAGnB,SAAS,IAAI,IAAI,CAAC;IAClB,eAAe,IAAI,IAAI,CAAC;IACxB,WAAW,IAAI,IAAI,CAAC;CACrB;AAID;;GAEG;AACH,qBAAa,eAAgB,YAAW,QAAQ;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAC,CAAyB;IAC9C,OAAO,CAAC,aAAa,CAAC,CAAa;IACnC,OAAO,CAAC,EAAE,CAAC,CAAqB;IAEhC,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM,IAAI,GAAG,IAAI;IA2ClE,IAAI,IAAI,IAAI;IA0BZ,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAIzB,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAW3B,UAAU,IAAI,IAAI;IAIlB,UAAU,IAAI,IAAI;IAIlB,SAAS,IAAI,IAAI;IAIjB,eAAe,IAAI,IAAI;IAIvB,WAAW,IAAI,IAAI;CAGpB"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import readline from "node:readline";
|
|
2
|
+
/**
|
|
3
|
+
* Real terminal using process.stdin/stdout
|
|
4
|
+
*/
|
|
5
|
+
export class ProcessTerminal {
|
|
6
|
+
wasRaw = false;
|
|
7
|
+
inputHandler;
|
|
8
|
+
resizeHandler;
|
|
9
|
+
rl;
|
|
10
|
+
start(onInput, onResize) {
|
|
11
|
+
this.inputHandler = onInput;
|
|
12
|
+
this.resizeHandler = onResize;
|
|
13
|
+
// Save previous state
|
|
14
|
+
this.wasRaw = process.stdin.isRaw || false;
|
|
15
|
+
// Check if we're in a TTY environment
|
|
16
|
+
const isTty = process.stdin.isTTY && process.stdout.isTTY;
|
|
17
|
+
if (isTty) {
|
|
18
|
+
// Create readline interface for reliable input handling
|
|
19
|
+
this.rl = readline.createInterface({
|
|
20
|
+
input: process.stdin,
|
|
21
|
+
output: process.stdout,
|
|
22
|
+
terminal: true,
|
|
23
|
+
});
|
|
24
|
+
// Enable raw mode for character-by-character input
|
|
25
|
+
if (process.stdin.setRawMode) {
|
|
26
|
+
process.stdin.setRawMode(true);
|
|
27
|
+
}
|
|
28
|
+
process.stdin.setEncoding("utf8");
|
|
29
|
+
process.stdin.resume();
|
|
30
|
+
// Enable bracketed paste mode - terminal will wrap pastes in \x1b[200~ ... \x1b[201~
|
|
31
|
+
process.stdout.write("\x1b[?2004h");
|
|
32
|
+
// Set up input handler
|
|
33
|
+
process.stdin.on("data", this.inputHandler);
|
|
34
|
+
process.stdout.on("resize", this.resizeHandler);
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
console.warn("Not running in a TTY environment - input will not work");
|
|
38
|
+
// In non-TTY environments, we can't use raw mode
|
|
39
|
+
// But we can still set up basic input handling if needed
|
|
40
|
+
process.stdin.setEncoding("utf8");
|
|
41
|
+
if (process.stdin.isPaused()) {
|
|
42
|
+
process.stdin.resume();
|
|
43
|
+
}
|
|
44
|
+
process.stdin.on("data", this.inputHandler);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
stop() {
|
|
48
|
+
// Disable bracketed paste mode
|
|
49
|
+
process.stdout.write("\x1b[?2004l");
|
|
50
|
+
// Remove event handlers
|
|
51
|
+
if (this.inputHandler) {
|
|
52
|
+
process.stdin.removeListener("data", this.inputHandler);
|
|
53
|
+
this.inputHandler = undefined;
|
|
54
|
+
}
|
|
55
|
+
if (this.resizeHandler) {
|
|
56
|
+
process.stdout.removeListener("resize", this.resizeHandler);
|
|
57
|
+
this.resizeHandler = undefined;
|
|
58
|
+
}
|
|
59
|
+
// Close readline interface
|
|
60
|
+
if (this.rl) {
|
|
61
|
+
this.rl.close();
|
|
62
|
+
this.rl = undefined;
|
|
63
|
+
}
|
|
64
|
+
// Restore raw mode state
|
|
65
|
+
if (process.stdin.setRawMode) {
|
|
66
|
+
process.stdin.setRawMode(this.wasRaw);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
write(data) {
|
|
70
|
+
process.stdout.write(data);
|
|
71
|
+
}
|
|
72
|
+
get columns() {
|
|
73
|
+
return process.stdout.columns || 80;
|
|
74
|
+
}
|
|
75
|
+
get rows() {
|
|
76
|
+
return process.stdout.rows || 24;
|
|
77
|
+
}
|
|
78
|
+
moveBy(lines) {
|
|
79
|
+
if (lines > 0) {
|
|
80
|
+
// Move down
|
|
81
|
+
process.stdout.write(`\x1b[${lines}B`);
|
|
82
|
+
}
|
|
83
|
+
else if (lines < 0) {
|
|
84
|
+
// Move up
|
|
85
|
+
process.stdout.write(`\x1b[${-lines}A`);
|
|
86
|
+
}
|
|
87
|
+
// lines === 0: no movement
|
|
88
|
+
}
|
|
89
|
+
hideCursor() {
|
|
90
|
+
process.stdout.write("\x1b[?25l");
|
|
91
|
+
}
|
|
92
|
+
showCursor() {
|
|
93
|
+
process.stdout.write("\x1b[?25h");
|
|
94
|
+
}
|
|
95
|
+
clearLine() {
|
|
96
|
+
process.stdout.write("\x1b[K");
|
|
97
|
+
}
|
|
98
|
+
clearFromCursor() {
|
|
99
|
+
process.stdout.write("\x1b[J");
|
|
100
|
+
}
|
|
101
|
+
clearScreen() {
|
|
102
|
+
process.stdout.write("\x1b[2J\x1b[H"); // Clear screen and move to home (1,1)
|
|
103
|
+
}
|
|
104
|
+
}
|