casabot 1.1.3 → 1.1.4

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/dist/tui/app.js CHANGED
@@ -22,27 +22,6 @@ function truncateOutput(content, maxLines = 8) {
22
22
  return (lines.slice(0, maxLines).join("\n") +
23
23
  `\n … ${lines.length - maxLines} more lines`);
24
24
  }
25
- function estimateMessageLines(message, width) {
26
- const contentWidth = Math.max(width - 10, 20);
27
- const countLines = (text) => text.split("\n").reduce((sum, line) => sum + Math.max(1, Math.ceil((line.length || 1) / contentWidth)), 0);
28
- if (message.role === "user") {
29
- return 2 + countLines(message.content);
30
- }
31
- if (message.role === "tool") {
32
- return 3 + countLines(truncateOutput(message.content));
33
- }
34
- if (message.role === "assistant" && message.toolCalls?.length) {
35
- let lines = 2;
36
- if (message.content)
37
- lines += countLines(message.content);
38
- lines += 4 + (message.toolCalls?.length ?? 0);
39
- return lines;
40
- }
41
- if (message.role === "assistant") {
42
- return 2 + countLines(message.content);
43
- }
44
- return 2;
45
- }
46
25
  function useMouseWheel(onScrollUp, onScrollDown) {
47
26
  const { stdout } = useStdout();
48
27
  const scrollUpRef = useRef(onScrollUp);
@@ -127,10 +106,6 @@ function WelcomeHint() {
127
106
  function ProcessingIndicator() {
128
107
  return (_jsxs(Box, { paddingX: 2, marginTop: 1, gap: 1, children: [_jsx(Text, { color: "yellow", children: _jsx(Spinner, { type: "dots" }) }), _jsx(Text, { color: "yellow", children: "Thinking…" })] }));
129
108
  }
130
- function ScrollIndicator({ direction, count, }) {
131
- const arrow = direction === "above" ? "▲" : "▼";
132
- return (_jsx(Box, { justifyContent: "center", paddingX: 2, children: _jsx(Text, { dimColor: true, children: `${arrow} ${count} more ${count === 1 ? "message" : "messages"} ${direction}` }) }));
133
- }
134
109
  // border(2) + header(3) + hrules(2) + input(3) + status(1) = 11
135
110
  const CHROME_HEIGHT = 11;
136
111
  function App({ provider, conversation, skills, }) {
@@ -160,26 +135,7 @@ function App({ provider, conversation, skills, }) {
160
135
  setScrollOffset((prev) => (prev === 0 ? 0 : prev + 1));
161
136
  }, [messages.length]);
162
137
  const messagesHeight = Math.max(termSize.rows - CHROME_HEIGHT, 4);
163
- const { visibleMessages, hiddenAbove, hiddenBelow } = useMemo(() => {
164
- if (messages.length === 0) {
165
- return { visibleMessages: [], hiddenAbove: 0, hiddenBelow: 0 };
166
- }
167
- const endIndex = messages.length - scrollOffset;
168
- let usedLines = isProcessing ? 2 : 0;
169
- let startIndex = endIndex;
170
- for (let i = endIndex - 1; i >= 0; i--) {
171
- const lines = estimateMessageLines(messages[i], termSize.columns);
172
- if (usedLines + lines > messagesHeight && startIndex < endIndex)
173
- break;
174
- usedLines += lines;
175
- startIndex = i;
176
- }
177
- return {
178
- visibleMessages: messages.slice(startIndex, endIndex),
179
- hiddenAbove: startIndex,
180
- hiddenBelow: scrollOffset,
181
- };
182
- }, [messages, scrollOffset, messagesHeight, termSize.columns, isProcessing]);
138
+ const visibleMessages = useMemo(() => messages.slice(0, messages.length - scrollOffset), [messages, scrollOffset]);
183
139
  const maxScrollOffset = useMemo(() => {
184
140
  return Math.max(0, messages.length - 1);
185
141
  }, [messages.length]);
@@ -225,7 +181,7 @@ function App({ provider, conversation, skills, }) {
225
181
  }
226
182
  });
227
183
  const userCount = messages.filter((m) => m.role === "user").length;
228
- return (_jsxs(Box, { flexDirection: "column", width: termSize.columns, height: termSize.rows, borderStyle: "round", borderColor: "gray", children: [_jsx(Header, {}), _jsx(HRule, { width: termSize.columns }), _jsx(Box, { flexDirection: "column", height: messagesHeight, overflowY: "hidden", justifyContent: "flex-end", children: messages.length === 0 && !isProcessing ? (_jsx(WelcomeHint, {})) : (_jsxs(_Fragment, { children: [hiddenAbove > 0 && (_jsx(ScrollIndicator, { direction: "above", count: hiddenAbove })), visibleMessages.map((msg, i) => (_jsx(MessageView, { message: msg }, hiddenAbove + i))), isProcessing && _jsx(ProcessingIndicator, {}), hiddenBelow > 0 && (_jsx(ScrollIndicator, { direction: "below", count: hiddenBelow }))] })) }), _jsx(HRule, { width: termSize.columns }), _jsx(Box, { paddingX: 1, children: _jsxs(Box, { borderStyle: "round", borderColor: isProcessing ? "gray" : "cyan", paddingX: 1, width: "100%", children: [_jsx(Text, { color: "cyan", bold: true, children: "❯ " }), _jsx(TextInput, { value: input, onChange: setInput, onSubmit: (val) => {
184
+ return (_jsxs(Box, { flexDirection: "column", width: termSize.columns, height: termSize.rows, borderStyle: "round", borderColor: "gray", children: [_jsx(Header, {}), _jsx(HRule, { width: termSize.columns }), _jsx(Box, { flexDirection: "column", height: messagesHeight, overflowY: "hidden", justifyContent: "flex-end", children: messages.length === 0 && !isProcessing ? (_jsx(WelcomeHint, {})) : (_jsxs(_Fragment, { children: [visibleMessages.map((msg, i) => (_jsx(MessageView, { message: msg }, i))), isProcessing && _jsx(ProcessingIndicator, {})] })) }), _jsx(HRule, { width: termSize.columns }), _jsx(Box, { paddingX: 1, children: _jsxs(Box, { borderStyle: "round", borderColor: isProcessing ? "gray" : "cyan", paddingX: 1, width: "100%", children: [_jsx(Text, { color: "cyan", bold: true, children: "❯ " }), _jsx(TextInput, { value: input, onChange: setInput, onSubmit: (val) => {
229
185
  handleSubmit(val).catch(() => { });
230
186
  }, placeholder: "Type your message\u2026", focus: !isProcessing, showCursor: true })] }) }), _jsxs(Box, { paddingX: 2, justifyContent: "space-between", children: [_jsx(Text, { dimColor: true, children: "Ctrl+C exit ↑↓/wheel scroll" }), _jsxs(Text, { dimColor: true, children: [userCount, " ", userCount === 1 ? "message" : "messages"] })] })] }));
231
187
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "casabot",
3
- "version": "1.1.3",
3
+ "version": "1.1.4",
4
4
  "description": "CasAbot — Skill-driven multi-agent orchestrator system",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/tui/app.tsx CHANGED
@@ -30,33 +30,6 @@ function truncateOutput(content: string, maxLines = 8): string {
30
30
  );
31
31
  }
32
32
 
33
- function estimateMessageLines(message: Message, width: number): number {
34
- const contentWidth = Math.max(width - 10, 20);
35
- const countLines = (text: string): number =>
36
- text.split("\n").reduce(
37
- (sum, line) =>
38
- sum + Math.max(1, Math.ceil((line.length || 1) / contentWidth)),
39
- 0,
40
- );
41
-
42
- if (message.role === "user") {
43
- return 2 + countLines(message.content);
44
- }
45
- if (message.role === "tool") {
46
- return 3 + countLines(truncateOutput(message.content));
47
- }
48
- if (message.role === "assistant" && message.toolCalls?.length) {
49
- let lines = 2;
50
- if (message.content) lines += countLines(message.content);
51
- lines += 4 + (message.toolCalls?.length ?? 0);
52
- return lines;
53
- }
54
- if (message.role === "assistant") {
55
- return 2 + countLines(message.content);
56
- }
57
- return 2;
58
- }
59
-
60
33
  function useMouseWheel(
61
34
  onScrollUp: () => void,
62
35
  onScrollDown: () => void,
@@ -258,23 +231,6 @@ function ProcessingIndicator(): React.ReactElement {
258
231
  );
259
232
  }
260
233
 
261
- function ScrollIndicator({
262
- direction,
263
- count,
264
- }: {
265
- direction: "above" | "below";
266
- count: number;
267
- }): React.ReactElement {
268
- const arrow = direction === "above" ? "▲" : "▼";
269
- return (
270
- <Box justifyContent="center" paddingX={2}>
271
- <Text dimColor>
272
- {`${arrow} ${count} more ${count === 1 ? "message" : "messages"} ${direction}`}
273
- </Text>
274
- </Box>
275
- );
276
- }
277
-
278
234
  interface AppProps {
279
235
  provider: ChatProvider;
280
236
  conversation: ConversationHistory;
@@ -320,28 +276,10 @@ function App({
320
276
 
321
277
  const messagesHeight = Math.max(termSize.rows - CHROME_HEIGHT, 4);
322
278
 
323
- const { visibleMessages, hiddenAbove, hiddenBelow } = useMemo(() => {
324
- if (messages.length === 0) {
325
- return { visibleMessages: [] as Message[], hiddenAbove: 0, hiddenBelow: 0 };
326
- }
327
-
328
- const endIndex = messages.length - scrollOffset;
329
- let usedLines = isProcessing ? 2 : 0;
330
- let startIndex = endIndex;
331
-
332
- for (let i = endIndex - 1; i >= 0; i--) {
333
- const lines = estimateMessageLines(messages[i], termSize.columns);
334
- if (usedLines + lines > messagesHeight && startIndex < endIndex) break;
335
- usedLines += lines;
336
- startIndex = i;
337
- }
338
-
339
- return {
340
- visibleMessages: messages.slice(startIndex, endIndex),
341
- hiddenAbove: startIndex,
342
- hiddenBelow: scrollOffset,
343
- };
344
- }, [messages, scrollOffset, messagesHeight, termSize.columns, isProcessing]);
279
+ const visibleMessages = useMemo(
280
+ () => messages.slice(0, messages.length - scrollOffset),
281
+ [messages, scrollOffset],
282
+ );
345
283
 
346
284
  const maxScrollOffset = useMemo(() => {
347
285
  return Math.max(0, messages.length - 1);
@@ -421,16 +359,10 @@ function App({
421
359
  <WelcomeHint />
422
360
  ) : (
423
361
  <>
424
- {hiddenAbove > 0 && (
425
- <ScrollIndicator direction="above" count={hiddenAbove} />
426
- )}
427
362
  {visibleMessages.map((msg, i) => (
428
- <MessageView key={hiddenAbove + i} message={msg} />
363
+ <MessageView key={i} message={msg} />
429
364
  ))}
430
365
  {isProcessing && <ProcessingIndicator />}
431
- {hiddenBelow > 0 && (
432
- <ScrollIndicator direction="below" count={hiddenBelow} />
433
- )}
434
366
  </>
435
367
  )}
436
368
  </Box>