@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,292 @@
|
|
|
1
|
+
import { getTerminalSize } from "../../terminal/formatting.js";
|
|
2
|
+
import { table } from "../../terminal/index.js";
|
|
3
|
+
import style from "../../terminal/style.js";
|
|
4
|
+
import { Container } from "../tui.js";
|
|
5
|
+
import { visibleWidth } from "../utils.js";
|
|
6
|
+
/**
|
|
7
|
+
* Modal component - displays content in an overlay on top of the main UI
|
|
8
|
+
*/
|
|
9
|
+
export class Modal extends Container {
|
|
10
|
+
title;
|
|
11
|
+
backdrop;
|
|
12
|
+
onClose;
|
|
13
|
+
maxWidth;
|
|
14
|
+
maxHeight;
|
|
15
|
+
scrollPosition = 0;
|
|
16
|
+
constructor(title, content, backdrop = true, onClose, maxWidth, maxHeight) {
|
|
17
|
+
super();
|
|
18
|
+
this.title = title;
|
|
19
|
+
this.backdrop = backdrop;
|
|
20
|
+
this.onClose = onClose;
|
|
21
|
+
const { columns, rows } = getTerminalSize();
|
|
22
|
+
this.maxWidth = maxWidth ?? columns;
|
|
23
|
+
this.maxHeight = maxHeight ?? rows;
|
|
24
|
+
this.addChild(content);
|
|
25
|
+
}
|
|
26
|
+
handleInput(data) {
|
|
27
|
+
// Handle Escape key to close modal
|
|
28
|
+
if (data === "\x1b") {
|
|
29
|
+
this.close();
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
// Handle scrolling
|
|
33
|
+
if (data === "\x1b[A") {
|
|
34
|
+
// Up arrow
|
|
35
|
+
this.scrollPosition = Math.max(0, this.scrollPosition - 1);
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (data === "\x1b[B") {
|
|
39
|
+
// Down arrow
|
|
40
|
+
this.scrollPosition += 1;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
if (data === "\x1b[5~") {
|
|
44
|
+
// Page up
|
|
45
|
+
this.scrollPosition = Math.max(0, this.scrollPosition - 10);
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (data === "\x1b[6~") {
|
|
49
|
+
// Page down
|
|
50
|
+
this.scrollPosition += 10;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (data === "\x1b[H" || data === "g") {
|
|
54
|
+
// Home key or 'g' for top
|
|
55
|
+
this.scrollPosition = 0;
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
if (data === "\x1b[F" || data === "G") {
|
|
59
|
+
// End key or 'G' for bottom
|
|
60
|
+
this.scrollPosition = Number.POSITIVE_INFINITY; // Will be clamped in render
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Pass input to focused child component
|
|
64
|
+
if (this.children.length > 0) {
|
|
65
|
+
const focusedChild = this.children[0];
|
|
66
|
+
if (focusedChild.handleInput) {
|
|
67
|
+
focusedChild.handleInput(data);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
close() {
|
|
72
|
+
if (this.onClose) {
|
|
73
|
+
this.onClose();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
render(width) {
|
|
77
|
+
const lines = [];
|
|
78
|
+
// Calculate modal dimensions - use dynamic sizing
|
|
79
|
+
// Use the provided width directly, ensuring reasonable minimum and maximum
|
|
80
|
+
const modalWidth = Math.max(40, width - 2);
|
|
81
|
+
const contentWidth = modalWidth - 4; // Account for borders and padding
|
|
82
|
+
// Calculate content height
|
|
83
|
+
const contentLines = super.render(contentWidth);
|
|
84
|
+
const contentHeight = contentLines.length;
|
|
85
|
+
// Calculate modal height based on content
|
|
86
|
+
const modalHeight = Math.min(this.maxHeight, Math.max(8, contentHeight + 4));
|
|
87
|
+
// Calculate vertical positioning (centered)
|
|
88
|
+
const { rows } = getTerminalSize();
|
|
89
|
+
const terminalHeight = rows;
|
|
90
|
+
const topOffset = Math.max(0, Math.floor((terminalHeight - modalHeight) / 2));
|
|
91
|
+
// Add top offset for centering
|
|
92
|
+
for (let i = 0; i < topOffset; i++) {
|
|
93
|
+
lines.push(" ".repeat(width));
|
|
94
|
+
}
|
|
95
|
+
// Render modal frame
|
|
96
|
+
const horizontalBorder = style.white("─".repeat(modalWidth - 2));
|
|
97
|
+
const emptyLine = style.white("│") + " ".repeat(modalWidth - 2) + style.white("│");
|
|
98
|
+
// Calculate horizontal offset for centering
|
|
99
|
+
// Use different offsets for left and right to ensure full width coverage
|
|
100
|
+
const leftOffset = Math.floor((width - modalWidth) / 2);
|
|
101
|
+
const rightOffset = width - modalWidth - leftOffset;
|
|
102
|
+
// Top border
|
|
103
|
+
lines.push(" ".repeat(leftOffset) +
|
|
104
|
+
style.white("┌") +
|
|
105
|
+
horizontalBorder +
|
|
106
|
+
style.white("┐") +
|
|
107
|
+
" ".repeat(rightOffset));
|
|
108
|
+
// Render content lines with scrolling support
|
|
109
|
+
const visibleContentHeight = Math.min(contentHeight, modalHeight - 4);
|
|
110
|
+
const maxScroll = Math.max(0, contentHeight - visibleContentHeight);
|
|
111
|
+
// Clamp scroll position
|
|
112
|
+
this.scrollPosition = Math.min(maxScroll, Math.max(0, this.scrollPosition));
|
|
113
|
+
// Add scroll indicator to title if content is scrollable
|
|
114
|
+
let displayTitle = this.title;
|
|
115
|
+
if (contentHeight > visibleContentHeight) {
|
|
116
|
+
const scrollInfo = ` (${this.scrollPosition + 1}-${Math.min(this.scrollPosition + visibleContentHeight, contentHeight)}/${contentHeight})`;
|
|
117
|
+
displayTitle = this.title + scrollInfo;
|
|
118
|
+
}
|
|
119
|
+
displayTitle += " [esc to exit]";
|
|
120
|
+
// Update title line with scroll info
|
|
121
|
+
const titleText = ` ${displayTitle} `;
|
|
122
|
+
const titlePadding = Math.max(0, modalWidth - 2 - visibleWidth(titleText));
|
|
123
|
+
const titleLine = style.white("│") +
|
|
124
|
+
style.bold(titleText) +
|
|
125
|
+
" ".repeat(titlePadding) +
|
|
126
|
+
style.white("│");
|
|
127
|
+
lines.push(" ".repeat(leftOffset) + titleLine + " ".repeat(rightOffset));
|
|
128
|
+
// Separator line
|
|
129
|
+
const separator = style.white("├") + "─".repeat(modalWidth - 2) + style.white("┤");
|
|
130
|
+
lines.push(" ".repeat(leftOffset) + separator + " ".repeat(rightOffset));
|
|
131
|
+
for (let i = 0; i < visibleContentHeight; i++) {
|
|
132
|
+
const contentLineIndex = this.scrollPosition + i;
|
|
133
|
+
const contentLine = contentLines[contentLineIndex] || "";
|
|
134
|
+
const visibleLength = visibleWidth(contentLine);
|
|
135
|
+
const padding = " ".repeat(Math.max(0, contentWidth - visibleLength));
|
|
136
|
+
const line = `${style.white("│")} ${contentLine}${padding} ${style.white("│")}`;
|
|
137
|
+
lines.push(" ".repeat(leftOffset) + line + " ".repeat(rightOffset));
|
|
138
|
+
}
|
|
139
|
+
// Fill remaining content area with empty lines if needed
|
|
140
|
+
const remainingLines = modalHeight - 4 - visibleContentHeight;
|
|
141
|
+
for (let i = 0; i < remainingLines; i++) {
|
|
142
|
+
lines.push(" ".repeat(leftOffset) + emptyLine + " ".repeat(rightOffset));
|
|
143
|
+
}
|
|
144
|
+
// Bottom border
|
|
145
|
+
lines.push(" ".repeat(leftOffset) +
|
|
146
|
+
style.white("└") +
|
|
147
|
+
horizontalBorder +
|
|
148
|
+
style.white("┘") +
|
|
149
|
+
" ".repeat(rightOffset));
|
|
150
|
+
// Fill remaining terminal height with empty lines
|
|
151
|
+
const totalLinesSoFar = lines.length;
|
|
152
|
+
const remainingTerminalLines = Math.max(0, terminalHeight - totalLinesSoFar);
|
|
153
|
+
for (let i = 0; i < remainingTerminalLines; i++) {
|
|
154
|
+
lines.push(" ".repeat(width));
|
|
155
|
+
}
|
|
156
|
+
return lines;
|
|
157
|
+
}
|
|
158
|
+
getCursorPosition() {
|
|
159
|
+
// Modal doesn't have its own cursor, but children might
|
|
160
|
+
if (this.children.length > 0) {
|
|
161
|
+
const childCursor = this.children[0].getCursorPosition?.();
|
|
162
|
+
if (childCursor) {
|
|
163
|
+
// Adjust cursor position for modal frame and centering
|
|
164
|
+
const [childRow, childCol] = childCursor;
|
|
165
|
+
const modalWidth = Math.min(this.maxWidth, 80 - 4);
|
|
166
|
+
const horizontalOffset = Math.floor((80 - modalWidth) / 2);
|
|
167
|
+
// Top padding + title + separator + content offset
|
|
168
|
+
const { columns } = getTerminalSize();
|
|
169
|
+
const terminalHeight = columns;
|
|
170
|
+
const modalHeight = Math.min(this.maxHeight, terminalHeight - 4);
|
|
171
|
+
const topPadding = Math.max(0, Math.floor((terminalHeight - modalHeight) / 2));
|
|
172
|
+
return [
|
|
173
|
+
topPadding + 3 + childRow, // 3 = top border + title + separator
|
|
174
|
+
horizontalOffset + 2 + childCol, // 2 = left border + padding
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* ModalText component - displays text content in a modal with word wrapping
|
|
183
|
+
*/
|
|
184
|
+
export class ModalText extends Container {
|
|
185
|
+
text;
|
|
186
|
+
paddingX;
|
|
187
|
+
paddingY;
|
|
188
|
+
constructor(text, paddingX = 1, paddingY = 0) {
|
|
189
|
+
super();
|
|
190
|
+
this.text = text;
|
|
191
|
+
this.paddingX = paddingX;
|
|
192
|
+
this.paddingY = paddingY;
|
|
193
|
+
}
|
|
194
|
+
render(width) {
|
|
195
|
+
const lines = [];
|
|
196
|
+
const contentWidth = Math.max(1, width - this.paddingX * 2);
|
|
197
|
+
if (!this.text || this.text.trim() === "") {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
// Replace tabs with spaces
|
|
201
|
+
const normalizedText = this.text.replace(/\t/g, " ");
|
|
202
|
+
const textLines = normalizedText.split("\n");
|
|
203
|
+
for (const line of textLines) {
|
|
204
|
+
const visibleLineLength = visibleWidth(line);
|
|
205
|
+
if (visibleLineLength <= contentWidth) {
|
|
206
|
+
lines.push(line);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// Word wrap
|
|
210
|
+
const words = line.split(" ");
|
|
211
|
+
let currentLine = "";
|
|
212
|
+
for (const word of words) {
|
|
213
|
+
const currentVisible = visibleWidth(currentLine);
|
|
214
|
+
const wordVisible = visibleWidth(word);
|
|
215
|
+
let finalWord = word;
|
|
216
|
+
if (wordVisible > contentWidth) {
|
|
217
|
+
// Truncate word to fit
|
|
218
|
+
let truncated = "";
|
|
219
|
+
for (const char of word) {
|
|
220
|
+
if (visibleWidth(truncated + char) > contentWidth) {
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
truncated += char;
|
|
224
|
+
}
|
|
225
|
+
finalWord = truncated;
|
|
226
|
+
}
|
|
227
|
+
if (currentVisible === 0) {
|
|
228
|
+
currentLine = finalWord;
|
|
229
|
+
}
|
|
230
|
+
else if (currentVisible + 1 + visibleWidth(finalWord) <=
|
|
231
|
+
contentWidth) {
|
|
232
|
+
currentLine += ` ${finalWord}`;
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
lines.push(currentLine);
|
|
236
|
+
currentLine = finalWord;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
if (currentLine.length > 0) {
|
|
240
|
+
lines.push(currentLine);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// Add padding
|
|
245
|
+
const leftPad = " ".repeat(this.paddingX);
|
|
246
|
+
const paddedLines = [];
|
|
247
|
+
// Top padding
|
|
248
|
+
for (let i = 0; i < this.paddingY; i++) {
|
|
249
|
+
paddedLines.push("");
|
|
250
|
+
}
|
|
251
|
+
// Content with horizontal padding
|
|
252
|
+
for (const line of lines) {
|
|
253
|
+
const visibleLength = visibleWidth(line);
|
|
254
|
+
const rightPadLength = Math.max(0, width - this.paddingX - visibleLength);
|
|
255
|
+
const rightPad = " ".repeat(rightPadLength);
|
|
256
|
+
paddedLines.push(leftPad + line + rightPad);
|
|
257
|
+
}
|
|
258
|
+
// Bottom padding
|
|
259
|
+
for (let i = 0; i < this.paddingY; i++) {
|
|
260
|
+
paddedLines.push("");
|
|
261
|
+
}
|
|
262
|
+
return paddedLines;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* ModalTable component - displays tabular data in a modal
|
|
267
|
+
* Uses the terminal table function for proper text wrapping and formatting
|
|
268
|
+
*/
|
|
269
|
+
export class ModalTable extends Container {
|
|
270
|
+
data;
|
|
271
|
+
headers;
|
|
272
|
+
colWidths;
|
|
273
|
+
constructor(data, headers, colWidths) {
|
|
274
|
+
super();
|
|
275
|
+
this.data = data;
|
|
276
|
+
this.headers = headers;
|
|
277
|
+
this.colWidths = colWidths;
|
|
278
|
+
}
|
|
279
|
+
render(width) {
|
|
280
|
+
if (this.data.length === 0) {
|
|
281
|
+
return [];
|
|
282
|
+
}
|
|
283
|
+
// Use the terminal table function for proper text wrapping and formatting
|
|
284
|
+
const tableString = table(this.data, {
|
|
285
|
+
header: this.headers,
|
|
286
|
+
colWidths: this.colWidths,
|
|
287
|
+
width: width,
|
|
288
|
+
});
|
|
289
|
+
// Split the table string into lines and return
|
|
290
|
+
return tableString.split("\n");
|
|
291
|
+
}
|
|
292
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ModelManager } from "../../models/manager.ts";
|
|
2
|
+
import type { Component } from "../index.ts";
|
|
3
|
+
type State = {
|
|
4
|
+
projectStatus: string;
|
|
5
|
+
currentContextWindow: number;
|
|
6
|
+
contextWindow: number;
|
|
7
|
+
};
|
|
8
|
+
export declare class PromptStatusComponent implements Component {
|
|
9
|
+
private modelManager;
|
|
10
|
+
private state;
|
|
11
|
+
constructor(modelManager: ModelManager, state: State);
|
|
12
|
+
setState(state: State): void;
|
|
13
|
+
render(width: number): string[];
|
|
14
|
+
}
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=prompt-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-status.d.ts","sourceRoot":"","sources":["../../../source/tui/components/prompt-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAG5D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,KAAK,KAAK,GAAG;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,qBAAa,qBAAsB,YAAW,SAAS;IACrD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,KAAK,CAAQ;gBACT,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,KAAK;IAKpD,QAAQ,CAAC,KAAK,EAAE,KAAK;IAIrB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CAkBhC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { displayProgressBar } from "../../terminal/index.js";
|
|
2
|
+
import style from "../../terminal/style.js";
|
|
3
|
+
export class PromptStatusComponent {
|
|
4
|
+
modelManager;
|
|
5
|
+
state;
|
|
6
|
+
constructor(modelManager, state) {
|
|
7
|
+
this.modelManager = modelManager;
|
|
8
|
+
this.state = state;
|
|
9
|
+
}
|
|
10
|
+
setState(state) {
|
|
11
|
+
this.state = state;
|
|
12
|
+
}
|
|
13
|
+
render(width) {
|
|
14
|
+
const results = [];
|
|
15
|
+
// results.push(style.dim(hr(width)));
|
|
16
|
+
results.push(this.state.projectStatus);
|
|
17
|
+
results.push(style.dim(`${this.modelManager.getModelMetadata("repl").id} [${this.modelManager.getModel("repl").modelId}]`));
|
|
18
|
+
results.push(displayProgressBar(this.state.currentContextWindow, this.state.contextWindow, width));
|
|
19
|
+
return results;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Component } from "../tui.ts";
|
|
2
|
+
export interface SelectItem {
|
|
3
|
+
value: string;
|
|
4
|
+
label: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare class SelectList implements Component {
|
|
8
|
+
private items;
|
|
9
|
+
private filteredItems;
|
|
10
|
+
private selectedIndex;
|
|
11
|
+
private maxVisible;
|
|
12
|
+
onSelect?: (item: SelectItem) => void;
|
|
13
|
+
onCancel?: () => void;
|
|
14
|
+
constructor(items: SelectItem[], maxVisible?: number);
|
|
15
|
+
updateItems(items: SelectItem[]): void;
|
|
16
|
+
setFilter(filter: string): void;
|
|
17
|
+
setSelectedIndex(index: number): void;
|
|
18
|
+
render(width: number): string[];
|
|
19
|
+
handleInput(keyData: string): void;
|
|
20
|
+
getSelectedItem(): SelectItem | null;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=select-list.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-list.d.ts","sourceRoot":"","sources":["../../../source/tui/components/select-list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,UAAW,YAAW,SAAS;IAC1C,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,UAAU,CAAK;IAEhB,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;gBAEjB,KAAK,EAAE,UAAU,EAAE,EAAE,UAAU,SAAI;IAM/C,WAAW,CAAC,KAAK,EAAE,UAAU,EAAE;IAK/B,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAQ/B,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAOrC,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;IA8G/B,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI;IA2BlC,eAAe,IAAI,UAAU,GAAG,IAAI;CAIrC"}
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import style from "../../terminal/style.js";
|
|
2
|
+
export class SelectList {
|
|
3
|
+
items = [];
|
|
4
|
+
filteredItems = [];
|
|
5
|
+
selectedIndex = 0;
|
|
6
|
+
maxVisible = 5;
|
|
7
|
+
onSelect;
|
|
8
|
+
onCancel;
|
|
9
|
+
constructor(items, maxVisible = 5) {
|
|
10
|
+
this.items = items;
|
|
11
|
+
this.filteredItems = items;
|
|
12
|
+
this.maxVisible = maxVisible;
|
|
13
|
+
}
|
|
14
|
+
updateItems(items) {
|
|
15
|
+
this.items = items;
|
|
16
|
+
this.filteredItems = items;
|
|
17
|
+
}
|
|
18
|
+
setFilter(filter) {
|
|
19
|
+
this.filteredItems = this.items.filter((item) => item.value.toLowerCase().startsWith(filter.toLowerCase()));
|
|
20
|
+
// Reset selection when filter changes
|
|
21
|
+
this.selectedIndex = 0;
|
|
22
|
+
}
|
|
23
|
+
setSelectedIndex(index) {
|
|
24
|
+
this.selectedIndex = Math.max(0, Math.min(index, this.filteredItems.length - 1));
|
|
25
|
+
}
|
|
26
|
+
render(width) {
|
|
27
|
+
const lines = [];
|
|
28
|
+
// If no items match filter, show message
|
|
29
|
+
if (this.filteredItems.length === 0) {
|
|
30
|
+
lines.push(style.gray(" No matching commands"));
|
|
31
|
+
return lines;
|
|
32
|
+
}
|
|
33
|
+
// Calculate visible range with scrolling
|
|
34
|
+
const startIndex = Math.max(0, Math.min(this.selectedIndex - Math.floor(this.maxVisible / 2), this.filteredItems.length - this.maxVisible));
|
|
35
|
+
const endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);
|
|
36
|
+
// Render visible items
|
|
37
|
+
for (let i = startIndex; i < endIndex; i++) {
|
|
38
|
+
const item = this.filteredItems[i];
|
|
39
|
+
if (!item)
|
|
40
|
+
continue;
|
|
41
|
+
const isSelected = i === this.selectedIndex;
|
|
42
|
+
let line = "";
|
|
43
|
+
if (isSelected) {
|
|
44
|
+
// Use arrow indicator for selection
|
|
45
|
+
const prefix = style.blue("→ ");
|
|
46
|
+
const prefixWidth = 2; // "→ " is 2 characters visually
|
|
47
|
+
const displayValue = item.label || item.value;
|
|
48
|
+
if (item.description && width > 40) {
|
|
49
|
+
// Calculate how much space we have for value + description
|
|
50
|
+
const maxValueLength = Math.min(displayValue.length, 30);
|
|
51
|
+
const truncatedValue = displayValue.substring(0, maxValueLength);
|
|
52
|
+
const spacing = " ".repeat(Math.max(1, 32 - truncatedValue.length));
|
|
53
|
+
// Calculate remaining space for description using visible widths
|
|
54
|
+
const descriptionStart = prefixWidth + truncatedValue.length + spacing.length;
|
|
55
|
+
const remainingWidth = width - descriptionStart - 2; // -2 for safety
|
|
56
|
+
if (remainingWidth > 10) {
|
|
57
|
+
const truncatedDesc = item.description.substring(0, remainingWidth);
|
|
58
|
+
line =
|
|
59
|
+
prefix +
|
|
60
|
+
style.blue(truncatedValue) +
|
|
61
|
+
style.gray(spacing + truncatedDesc);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// Not enough space for description
|
|
65
|
+
const maxWidth = width - prefixWidth - 2;
|
|
66
|
+
line = prefix + style.blue(displayValue.substring(0, maxWidth));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// No description or not enough width
|
|
71
|
+
const maxWidth = width - prefixWidth - 2;
|
|
72
|
+
line = prefix + style.blue(displayValue.substring(0, maxWidth));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const displayValue = item.label || item.value;
|
|
77
|
+
const prefix = " ";
|
|
78
|
+
if (item.description && width > 40) {
|
|
79
|
+
// Calculate how much space we have for value + description
|
|
80
|
+
const maxValueLength = Math.min(displayValue.length, 30);
|
|
81
|
+
const truncatedValue = displayValue.substring(0, maxValueLength);
|
|
82
|
+
const spacing = " ".repeat(Math.max(1, 32 - truncatedValue.length));
|
|
83
|
+
// Calculate remaining space for description
|
|
84
|
+
const descriptionStart = prefix.length + truncatedValue.length + spacing.length;
|
|
85
|
+
const remainingWidth = width - descriptionStart - 2; // -2 for safety
|
|
86
|
+
if (remainingWidth > 10) {
|
|
87
|
+
const truncatedDesc = item.description.substring(0, remainingWidth);
|
|
88
|
+
line =
|
|
89
|
+
prefix + truncatedValue + style.gray(spacing + truncatedDesc);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// Not enough space for description
|
|
93
|
+
const maxWidth = width - prefix.length - 2;
|
|
94
|
+
line = prefix + displayValue.substring(0, maxWidth);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
// No description or not enough width
|
|
99
|
+
const maxWidth = width - prefix.length - 2;
|
|
100
|
+
line = prefix + displayValue.substring(0, maxWidth);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
lines.push(line);
|
|
104
|
+
}
|
|
105
|
+
// Add scroll indicators if needed
|
|
106
|
+
if (startIndex > 0 || endIndex < this.filteredItems.length) {
|
|
107
|
+
const scrollText = ` (${this.selectedIndex + 1}/${this.filteredItems.length})`;
|
|
108
|
+
// Truncate if too long for terminal
|
|
109
|
+
const maxWidth = width - 2;
|
|
110
|
+
const truncated = scrollText.substring(0, maxWidth);
|
|
111
|
+
const scrollInfo = style.gray(truncated);
|
|
112
|
+
lines.push(scrollInfo);
|
|
113
|
+
}
|
|
114
|
+
return lines;
|
|
115
|
+
}
|
|
116
|
+
handleInput(keyData) {
|
|
117
|
+
// Up arrow
|
|
118
|
+
if (keyData === "\x1b[A") {
|
|
119
|
+
this.selectedIndex = Math.max(0, this.selectedIndex - 1);
|
|
120
|
+
}
|
|
121
|
+
// Down arrow or Tab
|
|
122
|
+
else if (keyData === "\x1b[B" || keyData === "\t") {
|
|
123
|
+
this.selectedIndex = Math.min(this.filteredItems.length - 1, this.selectedIndex + 1);
|
|
124
|
+
}
|
|
125
|
+
// Enter
|
|
126
|
+
else if (keyData === "\r") {
|
|
127
|
+
const selectedItem = this.filteredItems[this.selectedIndex];
|
|
128
|
+
if (selectedItem && this.onSelect) {
|
|
129
|
+
this.onSelect(selectedItem);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Escape or Ctrl+C
|
|
133
|
+
else if (keyData === "\x1b" || keyData === "\x03") {
|
|
134
|
+
if (this.onCancel) {
|
|
135
|
+
this.onCancel();
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
getSelectedItem() {
|
|
140
|
+
const item = this.filteredItems[this.selectedIndex];
|
|
141
|
+
return item || null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { Component } from "../tui.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Spacer component that renders empty lines
|
|
4
|
+
*/
|
|
5
|
+
export declare class Spacer implements Component {
|
|
6
|
+
private lines;
|
|
7
|
+
private customBgRgb?;
|
|
8
|
+
constructor(lines?: number, customBgRgb?: {
|
|
9
|
+
r: number;
|
|
10
|
+
g: number;
|
|
11
|
+
b: number;
|
|
12
|
+
});
|
|
13
|
+
setLines(lines: number): void;
|
|
14
|
+
render(_width: number): string[];
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=spacer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"spacer.d.ts","sourceRoot":"","sources":["../../../source/tui/components/spacer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C;;GAEG;AACH,qBAAa,MAAO,YAAW,SAAS;IACtC,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,WAAW,CAAC,CAAsC;gBAE9C,KAAK,SAAI,EAAE,WAAW,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAKxE,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;IAI7B,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;CAgBjC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import style from "../../terminal/style.js";
|
|
2
|
+
/**
|
|
3
|
+
* Spacer component that renders empty lines
|
|
4
|
+
*/
|
|
5
|
+
export class Spacer {
|
|
6
|
+
lines;
|
|
7
|
+
customBgRgb;
|
|
8
|
+
constructor(lines = 1, customBgRgb) {
|
|
9
|
+
this.lines = lines;
|
|
10
|
+
this.customBgRgb = customBgRgb;
|
|
11
|
+
}
|
|
12
|
+
setLines(lines) {
|
|
13
|
+
this.lines = lines;
|
|
14
|
+
}
|
|
15
|
+
render(_width) {
|
|
16
|
+
const result = [];
|
|
17
|
+
for (let i = 0; i < this.lines; i++) {
|
|
18
|
+
let line = "";
|
|
19
|
+
// Apply background color if specified
|
|
20
|
+
if (this.customBgRgb) {
|
|
21
|
+
line = style.bgRgb(this.customBgRgb.r, this.customBgRgb.g, this.customBgRgb.b)(line);
|
|
22
|
+
}
|
|
23
|
+
result.push(line);
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Component } from "../tui.ts";
|
|
2
|
+
/**
|
|
3
|
+
* Text component - displays multi-line text with word wrapping
|
|
4
|
+
*/
|
|
5
|
+
export declare class Text implements Component {
|
|
6
|
+
private text;
|
|
7
|
+
private paddingX;
|
|
8
|
+
private paddingY;
|
|
9
|
+
private customBgRgb?;
|
|
10
|
+
private cachedText?;
|
|
11
|
+
private cachedWidth?;
|
|
12
|
+
private cachedLines?;
|
|
13
|
+
constructor(text?: string, paddingX?: number, paddingY?: number, customBgRgb?: {
|
|
14
|
+
r: number;
|
|
15
|
+
g: number;
|
|
16
|
+
b: number;
|
|
17
|
+
});
|
|
18
|
+
setText(text: string): void;
|
|
19
|
+
setCustomBgRgb(customBgRgb?: {
|
|
20
|
+
r: number;
|
|
21
|
+
g: number;
|
|
22
|
+
b: number;
|
|
23
|
+
}): void;
|
|
24
|
+
render(width: number): string[];
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=text.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../source/tui/components/text.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAG3C;;GAEG;AACH,qBAAa,IAAK,YAAW,SAAS;IACpC,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAC,CAAsC;IAG1D,OAAO,CAAC,UAAU,CAAC,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAC,CAAS;IAC7B,OAAO,CAAC,WAAW,CAAC,CAAW;gBAG7B,IAAI,SAAK,EACT,QAAQ,SAAI,EACZ,QAAQ,SAAI,EACZ,WAAW,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE;IAQnD,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ3B,cAAc,CAAC,WAAW,CAAC,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAQvE,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE;CA4IhC"}
|