@ouro.bot/cli 0.1.0-alpha.174 → 0.1.0-alpha.176
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/changelog.json +9 -0
- package/dist/heart/active-work.js +2 -2
- package/dist/heart/core.js +13 -2
- package/dist/heart/daemon/daemon-cli.js +17 -14
- package/dist/heart/daemon/daemon-entry.js +17 -0
- package/dist/heart/daemon/daemon.js +5 -2
- package/dist/heart/daemon/launchd.js +8 -4
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/prompt.js +119 -60
- package/dist/mind/scrutiny.js +173 -0
- package/dist/nerves/coverage/audit.js +1 -1
- package/dist/repertoire/ado-semantic.js +5 -5
- package/dist/repertoire/coding/tools.js +35 -5
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/tools-base.js +145 -16
- package/dist/repertoire/tools.js +37 -0
- package/dist/senses/cli/adapter.js +307 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +68 -0
- package/dist/senses/cli/message-list.js +84 -0
- package/dist/senses/cli/ouro-tui.js +296 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +64 -0
- package/dist/senses/cli/streaming-markdown.js +486 -0
- package/dist/senses/cli/tool-display.js +77 -0
- package/dist/senses/cli/tool-render.js +89 -0
- package/dist/senses/cli/tui-store.js +198 -0
- package/dist/senses/cli/virtual-list.js +68 -0
- package/dist/senses/cli.js +231 -157
- package/dist/senses/pipeline.js +53 -10
- package/package.json +1 -1
- package/dist/outlook-ui/assets/index-DN6vVYPm.css +0 -1
- package/dist/outlook-ui/assets/index-M1l1tDTX.js +0 -61
- package/dist/outlook-ui/index.html +0 -15
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.InkApp = InkApp;
|
|
37
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
|
+
const react_1 = __importStar(require("react"));
|
|
39
|
+
const ink_1 = require("ink");
|
|
40
|
+
const streaming_markdown_1 = require("./streaming-markdown");
|
|
41
|
+
/**
|
|
42
|
+
* Ouroboros CLI TUI — Ink application shell.
|
|
43
|
+
*
|
|
44
|
+
* Replaces the imperative readline-based CLI with a React/Ink component tree.
|
|
45
|
+
* Provides: message list, input area, spinner, tool result display.
|
|
46
|
+
*
|
|
47
|
+
* Design: Ouroboros-themed (green serpent), NOT Claude/Anthropic design language.
|
|
48
|
+
* Copy-paste integrity: no padding characters. Visual hierarchy via color/bold/dim only.
|
|
49
|
+
*/
|
|
50
|
+
// Ouroboros brand palette
|
|
51
|
+
const OURO_GREEN = "#2ecc40";
|
|
52
|
+
const OURO_TEAL = "#4ec9b0";
|
|
53
|
+
const OURO_DIM = true;
|
|
54
|
+
// Snake-themed spinner frames: serpent eating its own tail
|
|
55
|
+
const SNAKE_FRAMES = [
|
|
56
|
+
"\u{1F40D}\u2003", // snake emoji
|
|
57
|
+
"\u25E0\u2003", // upper half circle
|
|
58
|
+
"\u25D4\u2003", // circle with upper right quadrant
|
|
59
|
+
"\u25D1\u2003", // circle with right half
|
|
60
|
+
"\u25D5\u2003", // circle with all but upper left quadrant
|
|
61
|
+
"\u25E1\u2003", // lower half circle
|
|
62
|
+
"\u{1F40D}\u2003", // snake emoji again
|
|
63
|
+
"\u25CB\u2003", // white circle (tail eaten)
|
|
64
|
+
];
|
|
65
|
+
function UserMessage({ content }) {
|
|
66
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_TEAL, bold: true, children: ") " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { children: content })] }));
|
|
67
|
+
}
|
|
68
|
+
function AssistantMessage({ content }) {
|
|
69
|
+
return ((0, jsx_runtime_1.jsx)(ink_1.Box, { children: (0, jsx_runtime_1.jsx)(streaming_markdown_1.StreamingMarkdown, { text: content }) }));
|
|
70
|
+
}
|
|
71
|
+
function ToolCallDisplay({ toolCall }) {
|
|
72
|
+
let argSummary = "";
|
|
73
|
+
try {
|
|
74
|
+
const args = JSON.parse(toolCall.function.arguments);
|
|
75
|
+
const first = Object.values(args)[0];
|
|
76
|
+
if (typeof first === "string")
|
|
77
|
+
argSummary = first.length > 60 ? first.slice(0, 57) + "..." : first;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
argSummary = toolCall.function.arguments.slice(0, 60);
|
|
81
|
+
}
|
|
82
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_GREEN, bold: true, children: toolCall.function.name }), argSummary ? (0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: true, children: [" ", argSummary] }) : null] }));
|
|
83
|
+
}
|
|
84
|
+
function ToolResultDisplay({ result }) {
|
|
85
|
+
const color = result.success ? OURO_GREEN : "#e74c3c";
|
|
86
|
+
const icon = result.success ? "\u2713" : "\u2717";
|
|
87
|
+
const summary = result.result.length > 120
|
|
88
|
+
? result.result.slice(0, 117) + "..."
|
|
89
|
+
: result.result;
|
|
90
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: color, children: [icon, " ", result.name] }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: true, children: [" ", summary.replace(/\n/g, " ")] })] }));
|
|
91
|
+
}
|
|
92
|
+
function SpinnerComponent({ text, frame }) {
|
|
93
|
+
const char = SNAKE_FRAMES[frame % SNAKE_FRAMES.length];
|
|
94
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_GREEN, children: char }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: OURO_DIM, children: [text, "..."] })] }));
|
|
95
|
+
}
|
|
96
|
+
function InputArea({ onSubmit, }) {
|
|
97
|
+
const [input, setInput] = (0, react_1.useState)("");
|
|
98
|
+
// Ref tracks the latest input value so useInput callback always sees current state
|
|
99
|
+
const inputRef = (0, react_1.useRef)("");
|
|
100
|
+
(0, ink_1.useInput)((inputChar, key) => {
|
|
101
|
+
if (key.return) {
|
|
102
|
+
if (inputRef.current.trim() && onSubmit) {
|
|
103
|
+
onSubmit(inputRef.current);
|
|
104
|
+
}
|
|
105
|
+
inputRef.current = "";
|
|
106
|
+
setInput("");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (key.backspace || key.delete) {
|
|
110
|
+
inputRef.current = inputRef.current.slice(0, -1);
|
|
111
|
+
setInput(inputRef.current);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!key.ctrl && !key.meta && inputChar) {
|
|
115
|
+
inputRef.current += inputChar;
|
|
116
|
+
setInput(inputRef.current);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_TEAL, bold: true, children: ") " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { children: input })] }));
|
|
120
|
+
}
|
|
121
|
+
function MessageList({ messages, toolResults, }) {
|
|
122
|
+
const toolResultMap = new Map();
|
|
123
|
+
if (toolResults) {
|
|
124
|
+
for (const tr of toolResults) {
|
|
125
|
+
toolResultMap.set(tr.toolCallId, tr);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", children: messages.map((msg, i) => {
|
|
129
|
+
if (msg.role === "user" && msg.content) {
|
|
130
|
+
return (0, jsx_runtime_1.jsx)(UserMessage, { content: msg.content }, i);
|
|
131
|
+
}
|
|
132
|
+
if (msg.role === "assistant") {
|
|
133
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [msg.content ? (0, jsx_runtime_1.jsx)(AssistantMessage, { content: msg.content }) : null, msg.tool_calls?.map(tc => {
|
|
134
|
+
const tr = toolResultMap.get(tc.id);
|
|
135
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsx)(ToolCallDisplay, { toolCall: tc }), tr ? (0, jsx_runtime_1.jsx)(ToolResultDisplay, { result: tr }) : null] }, tc.id));
|
|
136
|
+
})] }, i));
|
|
137
|
+
}
|
|
138
|
+
return null;
|
|
139
|
+
}) }));
|
|
140
|
+
}
|
|
141
|
+
function InkApp({ messages, onSubmit, loading, spinnerText, toolResults, }) {
|
|
142
|
+
const [spinnerFrame, setSpinnerFrame] = (0, react_1.useState)(0);
|
|
143
|
+
// Animate spinner
|
|
144
|
+
react_1.default.useEffect(() => {
|
|
145
|
+
if (!loading)
|
|
146
|
+
return;
|
|
147
|
+
const iv = setInterval(() => {
|
|
148
|
+
setSpinnerFrame(f => (f + 1) % SNAKE_FRAMES.length);
|
|
149
|
+
}, 120);
|
|
150
|
+
return () => clearInterval(iv);
|
|
151
|
+
}, [loading]);
|
|
152
|
+
const handleSubmit = (0, react_1.useCallback)((text) => {
|
|
153
|
+
onSubmit?.(text);
|
|
154
|
+
}, [onSubmit]);
|
|
155
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsx)(MessageList, { messages: messages, toolResults: toolResults }), loading && spinnerText ? ((0, jsx_runtime_1.jsx)(SpinnerComponent, { text: spinnerText, frame: spinnerFrame })) : null, (0, jsx_runtime_1.jsx)(InputArea, { onSubmit: handleSubmit })] }));
|
|
156
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.InlineDiff = InlineDiff;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
const react_1 = __importDefault(require("react"));
|
|
9
|
+
const ink_1 = require("ink");
|
|
10
|
+
// Ouroboros brand colors
|
|
11
|
+
const OURO_GREEN = "#2ecc40"; // added lines -- serpent green
|
|
12
|
+
const OURO_RED = "#e74c3c"; // removed lines
|
|
13
|
+
const OURO_HEADER = "#4ec9b0"; // file header -- teal
|
|
14
|
+
const OURO_LINE_NUM = "gray"; // line numbers -- subtle
|
|
15
|
+
/**
|
|
16
|
+
* Simple line-level diff algorithm (Myers-like via LCS).
|
|
17
|
+
* Produces a sequence of add/remove/context lines.
|
|
18
|
+
*/
|
|
19
|
+
function computeDiff(before, after) {
|
|
20
|
+
const oldLines = before ? before.split("\n") : [];
|
|
21
|
+
const newLines = after ? after.split("\n") : [];
|
|
22
|
+
// LCS-based diff
|
|
23
|
+
const m = oldLines.length;
|
|
24
|
+
const n = newLines.length;
|
|
25
|
+
const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
|
|
26
|
+
for (let i = 1; i <= m; i++) {
|
|
27
|
+
for (let j = 1; j <= n; j++) {
|
|
28
|
+
if (oldLines[i - 1] === newLines[j - 1]) {
|
|
29
|
+
dp[i][j] = dp[i - 1][j - 1] + 1;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// Backtrack to build diff
|
|
37
|
+
const result = [];
|
|
38
|
+
let i = m;
|
|
39
|
+
let j = n;
|
|
40
|
+
while (i > 0 || j > 0) {
|
|
41
|
+
if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
|
|
42
|
+
result.unshift({ type: "context", content: oldLines[i - 1], oldNum: i, newNum: j });
|
|
43
|
+
i--;
|
|
44
|
+
j--;
|
|
45
|
+
}
|
|
46
|
+
else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
|
|
47
|
+
result.unshift({ type: "add", content: newLines[j - 1], newNum: j });
|
|
48
|
+
j--;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
result.unshift({ type: "remove", content: oldLines[i - 1], oldNum: i });
|
|
52
|
+
i--;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return result;
|
|
56
|
+
}
|
|
57
|
+
function DiffLineComponent({ line }) {
|
|
58
|
+
const num = line.type === "remove" ? line.oldNum : line.newNum;
|
|
59
|
+
/* v8 ignore next -- defensive fallback; line numbers always present @preserve */
|
|
60
|
+
const lineNum = num !== undefined ? String(num) : "";
|
|
61
|
+
const prefix = line.type === "add" ? "+" : line.type === "remove" ? "-" : " ";
|
|
62
|
+
const color = line.type === "add" ? OURO_GREEN : line.type === "remove" ? OURO_RED : undefined;
|
|
63
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Text, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_LINE_NUM, children: lineNum.padStart(4) }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: color, children: ` ${prefix} ${line.content}` })] }));
|
|
64
|
+
}
|
|
65
|
+
function InlineDiff({ before, after, filePath }) {
|
|
66
|
+
const diffLines = computeDiff(before, after);
|
|
67
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_HEADER, bold: true, children: filePath }), diffLines.map((line, i) => ((0, jsx_runtime_1.jsx)(DiffLineComponent, { line: line }, i)))] }));
|
|
68
|
+
}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.ScrollableMessageList = ScrollableMessageList;
|
|
37
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
|
+
const react_1 = __importStar(require("react"));
|
|
39
|
+
const ink_1 = require("ink");
|
|
40
|
+
const streaming_markdown_1 = require("./streaming-markdown");
|
|
41
|
+
/**
|
|
42
|
+
* Scrollable message list with virtual rendering.
|
|
43
|
+
*
|
|
44
|
+
* Only renders messages within the viewport window. Supports:
|
|
45
|
+
* - Auto-scroll to bottom (pinned mode, default)
|
|
46
|
+
* - Scroll lock at a specific offset
|
|
47
|
+
* - "N below" indicator when scrolled up
|
|
48
|
+
*
|
|
49
|
+
* Ouroboros-themed: green serpent palette, no padding decoration.
|
|
50
|
+
*/
|
|
51
|
+
// Ouroboros brand palette
|
|
52
|
+
const OURO_TEAL = "#4ec9b0";
|
|
53
|
+
const OURO_INDICATOR = "#2ecc40";
|
|
54
|
+
function MessageItem({ message }) {
|
|
55
|
+
if (message.role === "user" && message.content) {
|
|
56
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_TEAL, bold: true, children: ") " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { children: message.content })] }));
|
|
57
|
+
}
|
|
58
|
+
if (message.role === "assistant" && message.content) {
|
|
59
|
+
return (0, jsx_runtime_1.jsx)(streaming_markdown_1.StreamingMarkdown, { text: message.content });
|
|
60
|
+
}
|
|
61
|
+
// system or empty messages render nothing visible
|
|
62
|
+
return (0, jsx_runtime_1.jsx)(ink_1.Text, { children: "" });
|
|
63
|
+
}
|
|
64
|
+
function ScrollableMessageList({ messages, viewportHeight, scrollOffset, }) {
|
|
65
|
+
const { visibleMessages, belowCount } = (0, react_1.useMemo)(() => {
|
|
66
|
+
if (messages.length === 0) {
|
|
67
|
+
return { visibleMessages: [], belowCount: 0 };
|
|
68
|
+
}
|
|
69
|
+
let start;
|
|
70
|
+
if (scrollOffset !== undefined) {
|
|
71
|
+
start = Math.max(0, Math.min(scrollOffset, messages.length - 1));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Auto-scroll: pin to bottom
|
|
75
|
+
start = Math.max(0, messages.length - viewportHeight);
|
|
76
|
+
}
|
|
77
|
+
const end = Math.min(start + viewportHeight, messages.length);
|
|
78
|
+
return {
|
|
79
|
+
visibleMessages: messages.slice(start, end),
|
|
80
|
+
belowCount: messages.length - end,
|
|
81
|
+
};
|
|
82
|
+
}, [messages, viewportHeight, scrollOffset]);
|
|
83
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [visibleMessages.map((msg, i) => ((0, jsx_runtime_1.jsx)(MessageItem, { message: msg }, i))), belowCount > 0 ? ((0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_INDICATOR, dimColor: true, children: `${belowCount} below` })) : null] }));
|
|
84
|
+
}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.OuroTui = OuroTui;
|
|
37
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
38
|
+
/**
|
|
39
|
+
* Ouroboros TUI — full terminal interface using Ink v3 + Static.
|
|
40
|
+
*
|
|
41
|
+
* Architecture:
|
|
42
|
+
* <Static> renders completed messages ONCE — they scroll up naturally.
|
|
43
|
+
* Only the "live" area (current streaming + spinner + input) re-renders.
|
|
44
|
+
* This avoids the screen-clearing problem that broke the previous Ink attempt.
|
|
45
|
+
*
|
|
46
|
+
* Design language: ouroboros brand palette from ouroboros.bot / Outlook UI.
|
|
47
|
+
* ZERO business logic here — pure rendering from CliStore state.
|
|
48
|
+
*/
|
|
49
|
+
const react_1 = __importStar(require("react"));
|
|
50
|
+
const ink_1 = require("ink");
|
|
51
|
+
const streaming_markdown_1 = require("./streaming-markdown");
|
|
52
|
+
// ─── Ouroboros Brand Palette (ANSI RGB) ─────────────────────────────
|
|
53
|
+
// From packages/outlook-ui/src/style.css and ouroboros.bot
|
|
54
|
+
const OURO = {
|
|
55
|
+
scale: "#2f8f4e", // primary green
|
|
56
|
+
teal: "#4ec9b0", // tool/accent teal
|
|
57
|
+
glow: "#74e08f", // bright green (highlights)
|
|
58
|
+
bone: "#eef2ea", // light text
|
|
59
|
+
mist: "#a5b8a8", // dim text
|
|
60
|
+
shadow: "#708373", // very dim
|
|
61
|
+
fang: "#d35f47", // error red
|
|
62
|
+
gold: "#d6b56f", // warning amber
|
|
63
|
+
moss: "#183325", // subtle bg accent
|
|
64
|
+
separator: "#3a5a40", // dim line separator
|
|
65
|
+
};
|
|
66
|
+
// ─── Ring Spinner (growing/shrinking) ───────────────────────────────
|
|
67
|
+
const RING_FRAMES = ["∙", "○", "◎", "●", "◎", "○"];
|
|
68
|
+
function ringColor(elapsedSec) {
|
|
69
|
+
if (elapsedSec >= 45)
|
|
70
|
+
return OURO.fang;
|
|
71
|
+
if (elapsedSec >= 15)
|
|
72
|
+
return OURO.gold;
|
|
73
|
+
return OURO.scale;
|
|
74
|
+
}
|
|
75
|
+
// ─── Header ─────────────────────────────────────────────────────────
|
|
76
|
+
function Header({ agentName, model, contextPercent, cwd }) {
|
|
77
|
+
const showCtx = contextPercent > 0;
|
|
78
|
+
const info = [agentName, model, cwd, showCtx ? `ctx ${contextPercent}%` : ""].filter(Boolean).join(" · ");
|
|
79
|
+
// 3-segment snake: TAIL (fixed) + MIDDLE (stretches) + HEAD (fixed)
|
|
80
|
+
// From the reference art, segments split at the dots:
|
|
81
|
+
//
|
|
82
|
+
// . . ____
|
|
83
|
+
// __.__________________.____/ O \___/
|
|
84
|
+
// <__.__________________._________/ \
|
|
85
|
+
//
|
|
86
|
+
// TAIL: line1="" line2=" __" line3="<__"
|
|
87
|
+
// MIDDLE: line1=" " line2="_" line3="_" (or text)
|
|
88
|
+
// HEAD: line1=" ____" line2="____/ O \\___/" line3="_________/ \\"
|
|
89
|
+
const HEAD1 = " ____";
|
|
90
|
+
const HEAD2 = "____/ O \\___/";
|
|
91
|
+
const HEAD3 = "_________/ \\";
|
|
92
|
+
const TAIL1 = " ";
|
|
93
|
+
const TAIL2 = " __";
|
|
94
|
+
const TAIL3 = "<__";
|
|
95
|
+
const middleLen = Math.max(info.length, 20);
|
|
96
|
+
const textPad = middleLen - info.length;
|
|
97
|
+
const line1 = TAIL1 + " ".repeat(middleLen) + HEAD1;
|
|
98
|
+
const line2 = TAIL2 + "_".repeat(middleLen) + HEAD2;
|
|
99
|
+
const line3text = info + "_".repeat(textPad);
|
|
100
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.scale, children: line1 }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.scale, children: line2 }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { color: OURO.scale, children: [TAIL3, (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.glow, children: line3text }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.scale, children: HEAD3 })] })] }));
|
|
101
|
+
}
|
|
102
|
+
// ─── Message Rendering ──────────────────────────────────────────────
|
|
103
|
+
// Flow control tools are invisible to the user — they are internal agent mechanics
|
|
104
|
+
const FLOW_CONTROL_TOOLS = new Set(["settle", "ponder", "observe", "rest"]);
|
|
105
|
+
function ToolResultLine({ tc }) {
|
|
106
|
+
const icon = tc.success !== false ? "✓" : "✗";
|
|
107
|
+
const iconColor = tc.success !== false ? OURO.scale : OURO.fang;
|
|
108
|
+
const argColor = tc.success === false ? OURO.fang : OURO.shadow;
|
|
109
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Text, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: iconColor, children: icon }), " ", (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.teal, children: tc.name }), " ", (0, jsx_runtime_1.jsx)(ink_1.Text, { color: argColor, children: tc.argSummary })] }));
|
|
110
|
+
}
|
|
111
|
+
function MessageBlock({ msg }) {
|
|
112
|
+
if (msg.role === "tool") {
|
|
113
|
+
const visibleCalls = msg.toolCalls?.filter(tc => !FLOW_CONTROL_TOOLS.has(tc.name));
|
|
114
|
+
if (!visibleCalls || visibleCalls.length === 0)
|
|
115
|
+
return (0, jsx_runtime_1.jsx)(ink_1.Box, { height: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " }) });
|
|
116
|
+
return ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", children: visibleCalls.map((tc, i) => (0, jsx_runtime_1.jsx)(ToolResultLine, { tc: tc }, i)) }));
|
|
117
|
+
}
|
|
118
|
+
if (msg.role === "user") {
|
|
119
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", marginTop: 1, children: [msg.content ? (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.bone, bold: true, children: msg.content }) : null, (0, jsx_runtime_1.jsx)(ink_1.Box, { height: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " }) })] }));
|
|
120
|
+
}
|
|
121
|
+
if (msg.role === "assistant") {
|
|
122
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [msg.content ? (0, jsx_runtime_1.jsx)(streaming_markdown_1.StreamingMarkdown, { text: msg.content }) : null, (0, jsx_runtime_1.jsx)(ink_1.Box, { height: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " }) })] }));
|
|
123
|
+
}
|
|
124
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", marginTop: 1, children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.shadow, children: msg.content }), (0, jsx_runtime_1.jsx)(ink_1.Box, { height: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " }) })] }));
|
|
125
|
+
}
|
|
126
|
+
// ─── Live Area (re-renders) ─────────────────────────────────────────
|
|
127
|
+
function Spinner({ phrasePool, elapsed }) {
|
|
128
|
+
const [frame, setFrame] = (0, react_1.useState)(0);
|
|
129
|
+
const [currentPhrase, setCurrentPhrase] = (0, react_1.useState)(() => phrasePool.length > 0 ? phrasePool[Math.floor(Math.random() * phrasePool.length)] : "");
|
|
130
|
+
// Animate ring frames
|
|
131
|
+
(0, react_1.useEffect)(() => {
|
|
132
|
+
const iv = setInterval(() => setFrame(f => (f + 1) % RING_FRAMES.length), 120);
|
|
133
|
+
return () => clearInterval(iv);
|
|
134
|
+
}, []);
|
|
135
|
+
// Rotate phrases every 3 seconds
|
|
136
|
+
(0, react_1.useEffect)(() => {
|
|
137
|
+
if (phrasePool.length <= 1)
|
|
138
|
+
return;
|
|
139
|
+
const iv = setInterval(() => {
|
|
140
|
+
setCurrentPhrase(phrasePool[Math.floor(Math.random() * phrasePool.length)]);
|
|
141
|
+
}, 3000);
|
|
142
|
+
return () => clearInterval(iv);
|
|
143
|
+
}, [phrasePool]);
|
|
144
|
+
const color = ringColor(elapsed);
|
|
145
|
+
const timeStr = elapsed > 0 ? `${elapsed}s` : "";
|
|
146
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Text, { color: color, children: [RING_FRAMES[frame], " ", timeStr ? (0, jsx_runtime_1.jsxs)(ink_1.Text, { color: OURO.shadow, children: [timeStr, " \u00B7 "] }) : "", currentPhrase] }));
|
|
147
|
+
}
|
|
148
|
+
function formatActiveToolArgs(name, args) {
|
|
149
|
+
switch (name) {
|
|
150
|
+
case "shell":
|
|
151
|
+
return `$ ${args.command ?? "?"}`;
|
|
152
|
+
case "read_file":
|
|
153
|
+
return `path=${args.path ?? "?"}`;
|
|
154
|
+
case "write_file":
|
|
155
|
+
return `path=${args.path ?? "?"}`;
|
|
156
|
+
case "edit_file":
|
|
157
|
+
return args.path ?? "?";
|
|
158
|
+
case "glob":
|
|
159
|
+
return `pattern=${args.pattern ?? "?"}`;
|
|
160
|
+
case "grep":
|
|
161
|
+
return `pattern=${args.pattern ?? "?"} ${args.path ? `path=${args.path}` : ""}`.trim();
|
|
162
|
+
default: {
|
|
163
|
+
// Show first 2 key=value pairs
|
|
164
|
+
const entries = Object.entries(args).slice(0, 2);
|
|
165
|
+
return entries.map(([k, v]) => `${k}=${String(v).slice(0, 50)}`).join(" ");
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
function ActiveToolLine({ tool }) {
|
|
170
|
+
// Hide flow control tools from in-progress display
|
|
171
|
+
if (FLOW_CONTROL_TOOLS.has(tool.name))
|
|
172
|
+
return (0, jsx_runtime_1.jsx)(ink_1.Box, { height: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " }) });
|
|
173
|
+
const argStr = formatActiveToolArgs(tool.name, tool.args);
|
|
174
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Text, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.shadow, children: "∙" }), " ", (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.teal, children: tool.name }), " ", (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.shadow, children: argStr })] }));
|
|
175
|
+
}
|
|
176
|
+
function LiveArea({ live, elapsed }) {
|
|
177
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [live.streamingText ? ((0, jsx_runtime_1.jsx)(streaming_markdown_1.StreamingMarkdown, { text: live.streamingText })) : null, live.activeTool ? ((0, jsx_runtime_1.jsx)(ActiveToolLine, { tool: live.activeTool })) : null, live.loading ? ((0, jsx_runtime_1.jsx)(Spinner, { phrasePool: live.spinnerPhrasePool, elapsed: elapsed })) : null, live.errorMessage ? ((0, jsx_runtime_1.jsxs)(ink_1.Text, { color: OURO.fang, children: ["✗ ", live.errorMessage] })) : null, live.kickMessage ? ((0, jsx_runtime_1.jsxs)(ink_1.Text, { color: OURO.gold, children: ["↻ ", live.kickMessage] })) : null] }));
|
|
178
|
+
}
|
|
179
|
+
// ─── Input ──────────────────────────────────────────────────────────
|
|
180
|
+
function InputArea({ onSubmit, suppressed, onCtrlC, agentName, model, history }) {
|
|
181
|
+
const [input, setInput] = (0, react_1.useState)("");
|
|
182
|
+
const [tooltip, setTooltip] = (0, react_1.useState)("");
|
|
183
|
+
const [cursorVisible, setCursorVisible] = (0, react_1.useState)(true);
|
|
184
|
+
const inputRef = (0, react_1.useRef)("");
|
|
185
|
+
const historyIdx = (0, react_1.useRef)(-1); // -1 = not browsing history
|
|
186
|
+
const savedInput = (0, react_1.useRef)(""); // saves current input when entering history
|
|
187
|
+
// Blinking cursor
|
|
188
|
+
(0, react_1.useEffect)(() => {
|
|
189
|
+
const iv = setInterval(() => setCursorVisible(v => !v), 530);
|
|
190
|
+
return () => clearInterval(iv);
|
|
191
|
+
}, []);
|
|
192
|
+
const handleCtrlC = (0, react_1.useCallback)(() => {
|
|
193
|
+
const action = onCtrlC(inputRef.current.length > 0);
|
|
194
|
+
if (action === "clear") {
|
|
195
|
+
inputRef.current = "";
|
|
196
|
+
setInput("");
|
|
197
|
+
setTooltip("");
|
|
198
|
+
setTooltip("");
|
|
199
|
+
}
|
|
200
|
+
else if (action === "warn") {
|
|
201
|
+
// tooltip handled below
|
|
202
|
+
setTooltip("Ctrl-C again to exit");
|
|
203
|
+
setTimeout(() => setTooltip(""), 3000);
|
|
204
|
+
}
|
|
205
|
+
// "abort" and "exit" are handled by the parent (cli.ts)
|
|
206
|
+
}, [onCtrlC]);
|
|
207
|
+
(0, ink_1.useInput)((inputChar, key) => {
|
|
208
|
+
if (key.ctrl && inputChar === "c") {
|
|
209
|
+
handleCtrlC();
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (suppressed)
|
|
213
|
+
return;
|
|
214
|
+
// Any non-Ctrl-C input clears tooltip
|
|
215
|
+
setTooltip("");
|
|
216
|
+
if (key.escape) {
|
|
217
|
+
if (inputRef.current) {
|
|
218
|
+
inputRef.current = "";
|
|
219
|
+
setInput("");
|
|
220
|
+
historyIdx.current = -1;
|
|
221
|
+
setTooltip("Esc again to clear");
|
|
222
|
+
setTimeout(() => setTooltip(""), 2000);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
setTooltip("");
|
|
226
|
+
}
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (key.return) {
|
|
230
|
+
const text = inputRef.current;
|
|
231
|
+
if (text.trim())
|
|
232
|
+
onSubmit(text);
|
|
233
|
+
inputRef.current = "";
|
|
234
|
+
setInput("");
|
|
235
|
+
historyIdx.current = -1;
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (key.backspace || key.delete) {
|
|
239
|
+
inputRef.current = inputRef.current.slice(0, -1);
|
|
240
|
+
setInput(inputRef.current);
|
|
241
|
+
historyIdx.current = -1;
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
// Up arrow: browse history (newest first)
|
|
245
|
+
if (key.upArrow && history.length > 0) {
|
|
246
|
+
if (historyIdx.current === -1) {
|
|
247
|
+
// Entering history — save current input
|
|
248
|
+
savedInput.current = inputRef.current;
|
|
249
|
+
historyIdx.current = history.length - 1;
|
|
250
|
+
}
|
|
251
|
+
else if (historyIdx.current > 0) {
|
|
252
|
+
historyIdx.current--;
|
|
253
|
+
}
|
|
254
|
+
inputRef.current = history[historyIdx.current];
|
|
255
|
+
setInput(inputRef.current);
|
|
256
|
+
return;
|
|
257
|
+
}
|
|
258
|
+
// Down arrow: browse forward or restore saved input
|
|
259
|
+
if (key.downArrow) {
|
|
260
|
+
if (historyIdx.current >= 0) {
|
|
261
|
+
if (historyIdx.current < history.length - 1) {
|
|
262
|
+
historyIdx.current++;
|
|
263
|
+
inputRef.current = history[historyIdx.current];
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
// Past end of history — restore saved input
|
|
267
|
+
historyIdx.current = -1;
|
|
268
|
+
inputRef.current = savedInput.current;
|
|
269
|
+
}
|
|
270
|
+
setInput(inputRef.current);
|
|
271
|
+
}
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
if (!key.ctrl && !key.meta && inputChar) {
|
|
275
|
+
inputRef.current += inputChar;
|
|
276
|
+
setInput(inputRef.current);
|
|
277
|
+
historyIdx.current = -1; // typing resets history browsing
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
// Get terminal width (capped for sanity)
|
|
281
|
+
const cols = Math.min(process.stdout.columns || 80, 200);
|
|
282
|
+
if (suppressed) {
|
|
283
|
+
// During model generation: show status bar but no input
|
|
284
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "─".repeat(cols) }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: true, children: [agentName, model ? ` · ${model}` : ""] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "─".repeat(cols) })] }));
|
|
285
|
+
}
|
|
286
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "─".repeat(cols) }), (0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.teal, bold: true, children: ") " }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.bone, children: input }), cursorVisible ? (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.scale, children: "█" }) : (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " })] }), (0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: true, children: [agentName, model ? ` · ${model}` : ""] }), (0, jsx_runtime_1.jsx)(ink_1.Box, { flexGrow: 1 }), tooltip ? (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: tooltip }) : null] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { dimColor: true, children: "─".repeat(cols) })] }));
|
|
287
|
+
}
|
|
288
|
+
// ─── Main TUI Component ─────────────────────────────────────────────
|
|
289
|
+
function OuroTui({ agentName, model, completedMessages, inputHistory, live, elapsedSeconds, contextPercent, onSubmit, onCtrlC, cwd, }) {
|
|
290
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsx)(ink_1.Static, { items: [{ id: "__header__" }, ...completedMessages], children: (item, index) => {
|
|
291
|
+
if (index === 0) {
|
|
292
|
+
return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " }), (0, jsx_runtime_1.jsx)(Header, { agentName: agentName, model: model, contextPercent: contextPercent, cwd: cwd }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO.shadow, children: " Press Ctrl-C twice to exit \u00b7 \u2191\u2193 history \u00b7 Esc clear" }), (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " })] }, "header"));
|
|
293
|
+
}
|
|
294
|
+
return (0, jsx_runtime_1.jsx)(MessageBlock, { msg: item }, item.id);
|
|
295
|
+
} }), (live.loading || live.streamingText || live.activeTool) ? (0, jsx_runtime_1.jsx)(ink_1.Box, { height: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " }) }) : null, (0, jsx_runtime_1.jsx)(LiveArea, { live: live, elapsed: elapsedSeconds }), (live.loading || live.streamingText || live.activeTool) ? (0, jsx_runtime_1.jsx)(ink_1.Box, { height: 1, children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: " " }) }) : null, (0, jsx_runtime_1.jsx)(InputArea, { onSubmit: onSubmit, suppressed: live.inputSuppressed, onCtrlC: onCtrlC, agentName: agentName, model: model, history: inputHistory })] }));
|
|
296
|
+
}
|