openpaean 0.1.0 → 0.2.0
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/ui/App.d.ts +1 -1
- package/dist/ui/App.d.ts.map +1 -1
- package/dist/ui/App.js +15 -9
- package/dist/ui/App.js.map +1 -1
- package/dist/ui/FullscreenApp.d.ts +1 -0
- package/dist/ui/FullscreenApp.d.ts.map +1 -1
- package/dist/ui/FullscreenApp.js +8 -5
- package/dist/ui/FullscreenApp.js.map +1 -1
- package/dist/ui/components/MarkdownText.d.ts +23 -0
- package/dist/ui/components/MarkdownText.d.ts.map +1 -0
- package/dist/ui/components/MarkdownText.js +84 -0
- package/dist/ui/components/MarkdownText.js.map +1 -0
- package/dist/ui/components/ScrollableBox.d.ts +21 -0
- package/dist/ui/components/ScrollableBox.d.ts.map +1 -0
- package/dist/ui/components/ScrollableBox.js +101 -0
- package/dist/ui/components/ScrollableBox.js.map +1 -0
- package/dist/ui/components/StreamingText.d.ts +1 -1
- package/dist/ui/components/StreamingText.d.ts.map +1 -1
- package/dist/ui/components/StreamingText.js +6 -5
- package/dist/ui/components/StreamingText.js.map +1 -1
- package/dist/ui/components/index.d.ts +2 -0
- package/dist/ui/components/index.d.ts.map +1 -1
- package/dist/ui/components/index.js +2 -0
- package/dist/ui/components/index.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/App.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* App Component
|
|
3
3
|
* Main Ink application for the CLI chat interface
|
|
4
|
-
* Supports both inline and fullscreen modes
|
|
4
|
+
* Supports both inline and fullscreen modes with keyboard scrolling
|
|
5
5
|
*/
|
|
6
6
|
import React from 'react';
|
|
7
7
|
import type { McpState, McpToolResult } from '../agent/types.js';
|
package/dist/ui/App.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAyC,MAAM,OAAO,CAAC;AAI9D,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEjE,MAAM,WAAW,QAAQ;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,aAAa,CAAC,EAAE,CACZ,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,eAAO,MAAM,GAAG,EAAE,KAAK,CAAC,EAAE,CAAC,QAAQ,CAsLlC,CAAC"}
|
package/dist/ui/App.js
CHANGED
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
3
|
* App Component
|
|
4
4
|
* Main Ink application for the CLI chat interface
|
|
5
|
-
* Supports both inline and fullscreen modes
|
|
5
|
+
* Supports both inline and fullscreen modes with keyboard scrolling
|
|
6
6
|
*/
|
|
7
|
-
import { useState, useCallback } from 'react';
|
|
8
|
-
import { Box, Text, useApp, useInput } from 'ink';
|
|
9
|
-
import { Header, InputArea, Spinner, StreamingText, ToolCallIndicator } from './components/index.js';
|
|
7
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
8
|
+
import { Box, Text, useApp, useInput, useStdout } from 'ink';
|
|
9
|
+
import { Header, InputArea, Spinner, StreamingText, ToolCallIndicator, ScrollableBox, MarkdownText } from './components/index.js';
|
|
10
10
|
import { useAgentStream, useCommands } from './hooks/index.js';
|
|
11
11
|
export const App = ({ mcpState, onMcpToolCall, debug: _debug = false, fullscreen = false }) => {
|
|
12
12
|
const { exit } = useApp();
|
|
13
|
+
const { stdout } = useStdout();
|
|
13
14
|
const [commandOutput, setCommandOutput] = useState(null);
|
|
14
15
|
const [commandSuggestions, setCommandSuggestions] = useState([]);
|
|
16
|
+
// Terminal dimensions
|
|
17
|
+
const terminalHeight = stdout?.rows || 24;
|
|
18
|
+
const terminalWidth = stdout?.columns || 80;
|
|
19
|
+
// Calculate content area height for fullscreen mode
|
|
20
|
+
// Reserve space for: header (3) + input area (3) + footer (1) = 7 lines
|
|
21
|
+
const contentHeight = fullscreen ? Math.max(terminalHeight - 7, 10) : 20;
|
|
15
22
|
// Calculate MCP tool count
|
|
16
23
|
const mcpToolCount = mcpState?.mcpServers?.reduce((sum, server) => sum + (server.tools?.length || 0), 0);
|
|
17
24
|
// Initialize hooks
|
|
@@ -55,10 +62,8 @@ export const App = ({ mcpState, onMcpToolCall, debug: _debug = false, fullscreen
|
|
|
55
62
|
}, [getCompletions]);
|
|
56
63
|
// Handle user input submission
|
|
57
64
|
const handleSubmit = useCallback((input) => {
|
|
58
|
-
// Clear previous command output and suggestions
|
|
59
65
|
setCommandOutput(null);
|
|
60
66
|
setCommandSuggestions([]);
|
|
61
|
-
// Check if it's a command
|
|
62
67
|
if (input.startsWith('/')) {
|
|
63
68
|
const result = handleCommand(input);
|
|
64
69
|
if (result.handled) {
|
|
@@ -72,9 +77,10 @@ export const App = ({ mcpState, onMcpToolCall, debug: _debug = false, fullscreen
|
|
|
72
77
|
return;
|
|
73
78
|
}
|
|
74
79
|
}
|
|
75
|
-
// Send message to agent
|
|
76
80
|
sendMessage(input);
|
|
77
81
|
}, [handleCommand, sendMessage, exit]);
|
|
78
|
-
|
|
82
|
+
// Memoize message content (expensive renders)
|
|
83
|
+
const messageContent = useMemo(() => (_jsxs(_Fragment, { children: [messages.map((msg) => (_jsx(Box, { flexDirection: "column", marginBottom: 1, children: msg.role === 'user' ? (_jsxs(Box, { children: [_jsx(Text, { color: "cyan", bold: true, children: "You: " }), _jsx(Text, { children: msg.content })] })) : (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: "magenta", bold: true, children: "OpenPaean: " }), _jsx(MarkdownText, { width: terminalWidth - 4, children: msg.content })] })) }, msg.id))), commandOutput && (_jsx(Box, { marginBottom: 1, children: _jsx(Text, { dimColor: true, children: commandOutput }) })), currentToolCall && (_jsx(Box, { marginBottom: 1, children: _jsx(ToolCallIndicator, { name: currentToolCall.name, type: currentToolCall.type, serverName: currentToolCall.serverName, status: "pending" }) })), isProcessing && streamingText && (_jsx(Box, { marginBottom: 1, children: _jsx(StreamingText, { text: streamingText, isComplete: false, rawMode: rawMode }) })), isProcessing && !streamingText && !currentToolCall && (_jsx(Box, { marginBottom: 1, children: _jsx(Spinner, { label: "Thinking...", type: "thinking" }) }))] })), [messages, commandOutput, currentToolCall, isProcessing, streamingText, rawMode, terminalWidth]);
|
|
84
|
+
return (_jsxs(Box, { flexDirection: "column", flexGrow: 1, padding: fullscreen ? 0 : 1, children: [!fullscreen && _jsx(Header, { mcpToolCount: mcpToolCount }), fullscreen ? (_jsx(ScrollableBox, { height: contentHeight, autoScroll: true, enableKeyboard: !isProcessing, showIndicator: true, children: messageContent })) : (_jsx(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: messageContent })), _jsx(InputArea, { onSubmit: handleSubmit, onInputChange: handleInputChange, onTabComplete: handleTabComplete, suggestions: commandSuggestions, disabled: isProcessing })] }));
|
|
79
85
|
};
|
|
80
86
|
//# sourceMappingURL=App.js.map
|
package/dist/ui/App.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AAEH,OAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"App.js","sourceRoot":"","sources":["../../src/ui/App.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullscreenApp.d.ts","sourceRoot":"","sources":["../../src/ui/FullscreenApp.tsx"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"FullscreenApp.d.ts","sourceRoot":"","sources":["../../src/ui/FullscreenApp.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAO,KAAK,QAAQ,EAAE,MAAM,UAAU,CAAC;AAE9C,UAAU,kBAAmB,SAAQ,QAAQ;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AA+BD;;;GAGG;AACH,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAmEtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
package/dist/ui/FullscreenApp.js
CHANGED
|
@@ -2,20 +2,21 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
/**
|
|
3
3
|
* Fullscreen App Wrapper
|
|
4
4
|
* Provides fullscreen terminal experience using alternate screen buffer
|
|
5
|
+
* With scroll position indicator and keyboard navigation hints
|
|
5
6
|
*/
|
|
6
|
-
import
|
|
7
|
+
import React from 'react';
|
|
7
8
|
import { Box, Text, useStdout } from 'ink';
|
|
8
9
|
import { App } from './App.js';
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Hook to get terminal dimensions with resize handling
|
|
11
12
|
*/
|
|
12
13
|
function useTerminalSize() {
|
|
13
14
|
const { stdout } = useStdout();
|
|
14
|
-
const [size, setSize] = useState({
|
|
15
|
+
const [size, setSize] = React.useState({
|
|
15
16
|
width: stdout?.columns || 80,
|
|
16
17
|
height: stdout?.rows || 24,
|
|
17
18
|
});
|
|
18
|
-
useEffect(() => {
|
|
19
|
+
React.useEffect(() => {
|
|
19
20
|
if (!stdout)
|
|
20
21
|
return;
|
|
21
22
|
const handleResize = () => {
|
|
@@ -42,7 +43,9 @@ export const FullscreenApp = (props) => {
|
|
|
42
43
|
const headerHeight = 3;
|
|
43
44
|
const footerHeight = 1;
|
|
44
45
|
const contentHeight = Math.max(height - headerHeight - footerHeight, 10);
|
|
45
|
-
|
|
46
|
+
// MCP tool count
|
|
47
|
+
const mcpToolCount = props.mcpState?.mcpServers?.reduce((sum, s) => sum + (s.tools?.length || 0), 0) || 0;
|
|
48
|
+
return (_jsxs(Box, { flexDirection: "column", width: width, height: height, children: [_jsxs(Box, { height: headerHeight, borderStyle: "single", borderColor: "magenta", paddingX: 1, justifyContent: "space-between", alignItems: "center", children: [_jsx(Text, { bold: true, color: "magenta", children: title }), _jsx(Box, { children: mcpToolCount > 0 && (_jsxs(Text, { dimColor: true, children: ["\uD83D\uDD17 MCP: ", mcpToolCount, " tools"] })) })] }), _jsx(Box, { flexDirection: "column", height: contentHeight, children: _jsx(App, { ...props, fullscreen: true }) }), _jsxs(Box, { height: footerHeight, paddingX: 1, justifyContent: "space-between", children: [_jsxs(Text, { dimColor: true, children: [_jsx(Text, { color: "gray", children: "Ctrl+C" }), " Exit", _jsx(Text, { color: "gray", children: " \u2502 " }), _jsx(Text, { color: "gray", children: "\u2191\u2193" }), " Scroll", _jsx(Text, { color: "gray", children: " \u2502 " }), _jsx(Text, { color: "gray", children: "PgUp/Dn" }), " Page"] }), _jsx(Text, { dimColor: true, children: "/help: Commands" })] })] }));
|
|
46
49
|
};
|
|
47
50
|
export default FullscreenApp;
|
|
48
51
|
//# sourceMappingURL=FullscreenApp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FullscreenApp.js","sourceRoot":"","sources":["../../src/ui/FullscreenApp.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"FullscreenApp.js","sourceRoot":"","sources":["../../src/ui/FullscreenApp.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MarkdownText Component
|
|
3
|
+
* Renders markdown text with terminal-friendly formatting
|
|
4
|
+
* Uses marked + marked-terminal for rich rendering
|
|
5
|
+
*/
|
|
6
|
+
import React from 'react';
|
|
7
|
+
interface MarkdownTextProps {
|
|
8
|
+
children: string;
|
|
9
|
+
/** Whether to show as streaming (with cursor) */
|
|
10
|
+
streaming?: boolean;
|
|
11
|
+
/** Terminal width for text wrapping */
|
|
12
|
+
width?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare const MarkdownText: React.FC<MarkdownTextProps>;
|
|
15
|
+
/**
|
|
16
|
+
* Simple text component for when markdown is disabled
|
|
17
|
+
*/
|
|
18
|
+
export declare const PlainText: React.FC<{
|
|
19
|
+
children: string;
|
|
20
|
+
streaming?: boolean;
|
|
21
|
+
}>;
|
|
22
|
+
export default MarkdownText;
|
|
23
|
+
//# sourceMappingURL=MarkdownText.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownText.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MarkdownText.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAkB,MAAM,OAAO,CAAC;AAMvC,UAAU,iBAAiB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,uCAAuC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;CAClB;AA6CD,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAwCpD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAYzE,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* MarkdownText Component
|
|
4
|
+
* Renders markdown text with terminal-friendly formatting
|
|
5
|
+
* Uses marked + marked-terminal for rich rendering
|
|
6
|
+
*/
|
|
7
|
+
import { useMemo } from 'react';
|
|
8
|
+
import { Box, Text, Transform } from 'ink';
|
|
9
|
+
import { Marked } from 'marked';
|
|
10
|
+
import { markedTerminal } from 'marked-terminal';
|
|
11
|
+
import chalk from 'chalk';
|
|
12
|
+
// Create a configured marked instance
|
|
13
|
+
function createMarkedInstance(width) {
|
|
14
|
+
const marked = new Marked();
|
|
15
|
+
marked.use(markedTerminal({
|
|
16
|
+
// Code blocks - prominent background
|
|
17
|
+
code: (code) => {
|
|
18
|
+
const lines = code.split('\n');
|
|
19
|
+
const maxLen = Math.max(...lines.map(l => l.length));
|
|
20
|
+
const paddedLines = lines.map(l => ` ${l.padEnd(maxLen)} `);
|
|
21
|
+
return chalk.bgGray.white('\n' + paddedLines.join('\n') + '\n');
|
|
22
|
+
},
|
|
23
|
+
// Inline code
|
|
24
|
+
codespan: chalk.bgGray.yellow,
|
|
25
|
+
// Blockquote - gray with left border
|
|
26
|
+
blockquote: chalk.gray.italic,
|
|
27
|
+
// Headers - colored and bold
|
|
28
|
+
heading: chalk.bold.cyan,
|
|
29
|
+
firstHeading: chalk.bold.magenta.underline,
|
|
30
|
+
// Text styles
|
|
31
|
+
strong: chalk.bold,
|
|
32
|
+
em: chalk.italic,
|
|
33
|
+
del: chalk.strikethrough.dim,
|
|
34
|
+
// Links
|
|
35
|
+
link: chalk.blue.underline,
|
|
36
|
+
href: chalk.dim.blue,
|
|
37
|
+
// Lists
|
|
38
|
+
listitem: chalk.reset,
|
|
39
|
+
list: chalk.reset,
|
|
40
|
+
// Table
|
|
41
|
+
table: chalk.reset,
|
|
42
|
+
// Misc
|
|
43
|
+
unescape: true,
|
|
44
|
+
emoji: true,
|
|
45
|
+
width: width,
|
|
46
|
+
showSectionPrefix: false,
|
|
47
|
+
reflowText: true,
|
|
48
|
+
tab: 2,
|
|
49
|
+
}));
|
|
50
|
+
return marked;
|
|
51
|
+
}
|
|
52
|
+
export const MarkdownText = ({ children, streaming = false, width = 80, }) => {
|
|
53
|
+
// Memoize the rendered markdown
|
|
54
|
+
const renderedText = useMemo(() => {
|
|
55
|
+
if (!children || children.trim() === '') {
|
|
56
|
+
return '';
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const marked = createMarkedInstance(width);
|
|
60
|
+
const result = marked.parse(children);
|
|
61
|
+
// Handle sync result
|
|
62
|
+
if (typeof result === 'string') {
|
|
63
|
+
// Trim trailing newlines but preserve internal structure
|
|
64
|
+
return result.replace(/\n+$/, '');
|
|
65
|
+
}
|
|
66
|
+
// Fallback for async (shouldn't happen with our config)
|
|
67
|
+
return children;
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
// Fallback to plain text on error
|
|
71
|
+
console.error('Markdown render error:', error);
|
|
72
|
+
return children;
|
|
73
|
+
}
|
|
74
|
+
}, [children, width]);
|
|
75
|
+
return (_jsx(Box, { flexDirection: "column", children: _jsx(Transform, { transform: (output) => output, children: _jsxs(Text, { wrap: "wrap", children: [renderedText, streaming && _jsx(Text, { dimColor: true, children: "\u258C" })] }) }) }));
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Simple text component for when markdown is disabled
|
|
79
|
+
*/
|
|
80
|
+
export const PlainText = ({ children, streaming = false, }) => {
|
|
81
|
+
return (_jsx(Box, { flexDirection: "column", children: _jsxs(Text, { wrap: "wrap", children: [children, streaming && _jsx(Text, { dimColor: true, children: "\u258C" })] }) }));
|
|
82
|
+
};
|
|
83
|
+
export default MarkdownText;
|
|
84
|
+
//# sourceMappingURL=MarkdownText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MarkdownText.js","sourceRoot":"","sources":["../../../src/ui/components/MarkdownText.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ScrollableBox Component
|
|
3
|
+
* A scrollable container with keyboard navigation support
|
|
4
|
+
* Inspired by Claude Code and OpenCode TUI patterns
|
|
5
|
+
*/
|
|
6
|
+
import React, { type ReactNode } from 'react';
|
|
7
|
+
export interface ScrollableBoxProps {
|
|
8
|
+
children: ReactNode;
|
|
9
|
+
height: number;
|
|
10
|
+
/** Called when scroll position changes */
|
|
11
|
+
onScrollChange?: (scrollTop: number, maxScroll: number) => void;
|
|
12
|
+
/** Whether to auto-scroll to bottom on new content */
|
|
13
|
+
autoScroll?: boolean;
|
|
14
|
+
/** Enable keyboard navigation */
|
|
15
|
+
enableKeyboard?: boolean;
|
|
16
|
+
/** Show scroll indicator */
|
|
17
|
+
showIndicator?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare const ScrollableBox: React.FC<ScrollableBoxProps>;
|
|
20
|
+
export default ScrollableBox;
|
|
21
|
+
//# sourceMappingURL=ScrollableBox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollableBox.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ScrollableBox.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,EAA4C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGxF,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,SAAS,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,cAAc,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,sDAAsD;IACtD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iCAAiC;IACjC,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,4BAA4B;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;CAC3B;AASD,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAgJtD,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* ScrollableBox Component
|
|
4
|
+
* A scrollable container with keyboard navigation support
|
|
5
|
+
* Inspired by Claude Code and OpenCode TUI patterns
|
|
6
|
+
*/
|
|
7
|
+
import { useState, useEffect, useCallback, useRef } from 'react';
|
|
8
|
+
import { Box, Text, useInput } from 'ink';
|
|
9
|
+
export const ScrollableBox = ({ children, height, onScrollChange, autoScroll = true, enableKeyboard = true, showIndicator = true, }) => {
|
|
10
|
+
const [scrollState, setScrollState] = useState({
|
|
11
|
+
scrollTop: 0,
|
|
12
|
+
contentHeight: 0,
|
|
13
|
+
isAtBottom: true,
|
|
14
|
+
userScrolled: false,
|
|
15
|
+
});
|
|
16
|
+
// Track content changes for auto-scroll
|
|
17
|
+
const childrenRef = useRef(children);
|
|
18
|
+
const contentChanged = childrenRef.current !== children;
|
|
19
|
+
childrenRef.current = children;
|
|
20
|
+
// Calculate max scroll
|
|
21
|
+
const maxScroll = Math.max(0, scrollState.contentHeight - height);
|
|
22
|
+
const canScroll = scrollState.contentHeight > height;
|
|
23
|
+
const scrollBy = useCallback((delta) => {
|
|
24
|
+
setScrollState(prev => {
|
|
25
|
+
const newScrollTop = Math.max(0, Math.min(prev.scrollTop + delta, maxScroll));
|
|
26
|
+
const isAtBottom = newScrollTop >= maxScroll - 1;
|
|
27
|
+
return {
|
|
28
|
+
...prev,
|
|
29
|
+
scrollTop: newScrollTop,
|
|
30
|
+
isAtBottom,
|
|
31
|
+
userScrolled: delta < 0 ? true : prev.userScrolled,
|
|
32
|
+
};
|
|
33
|
+
});
|
|
34
|
+
}, [maxScroll]);
|
|
35
|
+
const scrollToBottom = useCallback(() => {
|
|
36
|
+
setScrollState(prev => ({
|
|
37
|
+
...prev,
|
|
38
|
+
scrollTop: maxScroll,
|
|
39
|
+
isAtBottom: true,
|
|
40
|
+
userScrolled: false,
|
|
41
|
+
}));
|
|
42
|
+
}, [maxScroll]);
|
|
43
|
+
const scrollToTop = useCallback(() => {
|
|
44
|
+
setScrollState(prev => ({
|
|
45
|
+
...prev,
|
|
46
|
+
scrollTop: 0,
|
|
47
|
+
isAtBottom: false,
|
|
48
|
+
userScrolled: true,
|
|
49
|
+
}));
|
|
50
|
+
}, []);
|
|
51
|
+
// Auto-scroll on content change
|
|
52
|
+
useEffect(() => {
|
|
53
|
+
if (autoScroll && contentChanged && !scrollState.userScrolled) {
|
|
54
|
+
scrollToBottom();
|
|
55
|
+
}
|
|
56
|
+
}, [autoScroll, contentChanged, scrollState.userScrolled, scrollToBottom]);
|
|
57
|
+
// Notify parent of scroll changes
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
onScrollChange?.(scrollState.scrollTop, maxScroll);
|
|
60
|
+
}, [scrollState.scrollTop, maxScroll, onScrollChange]);
|
|
61
|
+
// Keyboard navigation
|
|
62
|
+
useInput((input, key) => {
|
|
63
|
+
if (!enableKeyboard || !canScroll)
|
|
64
|
+
return;
|
|
65
|
+
// Arrow keys: single line scroll
|
|
66
|
+
if (key.upArrow) {
|
|
67
|
+
scrollBy(-1);
|
|
68
|
+
}
|
|
69
|
+
else if (key.downArrow) {
|
|
70
|
+
scrollBy(1);
|
|
71
|
+
}
|
|
72
|
+
// Page Up/Down: page scroll
|
|
73
|
+
if (key.pageUp) {
|
|
74
|
+
scrollBy(-Math.max(1, height - 2));
|
|
75
|
+
}
|
|
76
|
+
else if (key.pageDown) {
|
|
77
|
+
scrollBy(Math.max(1, height - 2));
|
|
78
|
+
}
|
|
79
|
+
// Home/End: jump to top/bottom
|
|
80
|
+
if (input === 'g' && key.ctrl) {
|
|
81
|
+
scrollToTop();
|
|
82
|
+
}
|
|
83
|
+
else if (input === 'G') {
|
|
84
|
+
scrollToBottom();
|
|
85
|
+
}
|
|
86
|
+
// Ctrl+Home / Ctrl+End alternatives
|
|
87
|
+
if (key.ctrl && key.upArrow) {
|
|
88
|
+
scrollToTop();
|
|
89
|
+
}
|
|
90
|
+
else if (key.ctrl && key.downArrow) {
|
|
91
|
+
scrollToBottom();
|
|
92
|
+
}
|
|
93
|
+
}, { isActive: enableKeyboard });
|
|
94
|
+
// Calculate scroll indicator position
|
|
95
|
+
const indicatorPosition = maxScroll > 0
|
|
96
|
+
? Math.round((scrollState.scrollTop / maxScroll) * (height - 1))
|
|
97
|
+
: 0;
|
|
98
|
+
return (_jsxs(Box, { flexDirection: "row", height: height, children: [_jsx(Box, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: _jsx(Box, { flexDirection: "column", marginTop: -scrollState.scrollTop, children: children }) }), showIndicator && canScroll && (_jsx(Box, { flexDirection: "column", width: 1, marginLeft: 1, children: Array.from({ length: height }).map((_, i) => (_jsx(Text, { color: i === indicatorPosition ? 'magenta' : 'gray', dimColor: i !== indicatorPosition, children: i === indicatorPosition ? '█' : '│' }, i))) })), showIndicator && scrollState.userScrolled && !scrollState.isAtBottom && (_jsx(Box, { position: "absolute", marginTop: height - 1, children: _jsx(Text, { color: "yellow", bold: true, children: "\u2193 New messages (press End)" }) }))] }));
|
|
99
|
+
};
|
|
100
|
+
export default ScrollableBox;
|
|
101
|
+
//# sourceMappingURL=ScrollableBox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollableBox.js","sourceRoot":"","sources":["../../../src/ui/components/ScrollableBox.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StreamingText.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StreamingText.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"StreamingText.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StreamingText.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,UAAU,kBAAkB;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,eAAO,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAwBtD,CAAC"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Box, Text } from 'ink';
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
import { Box, Text, useStdout } from 'ink';
|
|
3
|
+
import { MarkdownText, PlainText } from './MarkdownText.js';
|
|
4
|
+
export const StreamingText = ({ text, isComplete = false, rawMode = false }) => {
|
|
5
|
+
const { stdout } = useStdout();
|
|
6
|
+
const width = stdout?.columns || 80;
|
|
7
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { children: _jsx(Text, { color: "magenta", bold: true, children: "OpenPaean: " }) }), _jsx(Box, { marginLeft: 0, flexDirection: "column", children: rawMode ? (_jsx(PlainText, { streaming: !isComplete, children: text })) : (_jsx(MarkdownText, { streaming: !isComplete, width: width - 4, children: text })) })] }));
|
|
7
8
|
};
|
|
8
9
|
//# sourceMappingURL=StreamingText.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StreamingText.js","sourceRoot":"","sources":["../../../src/ui/components/StreamingText.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"StreamingText.js","sourceRoot":"","sources":["../../../src/ui/components/StreamingText.tsx"],"names":[],"mappings":";AAMA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,KAAK,CAAC;AAC3C,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAQ5D,MAAM,CAAC,MAAM,aAAa,GAAiC,CAAC,EACxD,IAAI,EACJ,UAAU,GAAG,KAAK,EAClB,OAAO,GAAG,KAAK,EAClB,EAAE,EAAE;IACD,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;IAEpC,OAAO,CACH,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACvB,KAAC,GAAG,cACA,KAAC,IAAI,IAAC,KAAK,EAAC,SAAS,EAAC,IAAI,kCAAmB,GAC3C,EACN,KAAC,GAAG,IAAC,UAAU,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ,YACrC,OAAO,CAAC,CAAC,CAAC,CACP,KAAC,SAAS,IAAC,SAAS,EAAE,CAAC,UAAU,YAAG,IAAI,GAAa,CACxD,CAAC,CAAC,CAAC,CACA,KAAC,YAAY,IAAC,SAAS,EAAE,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,YACjD,IAAI,GACM,CAClB,GACC,IACJ,CACT,CAAC;AACN,CAAC,CAAC"}
|
|
@@ -6,4 +6,6 @@ export { InputArea } from './InputArea.js';
|
|
|
6
6
|
export { Spinner } from './Spinner.js';
|
|
7
7
|
export { StreamingText } from './StreamingText.js';
|
|
8
8
|
export { ToolCallIndicator } from './ToolCallIndicator.js';
|
|
9
|
+
export { ScrollableBox } from './ScrollableBox.js';
|
|
10
|
+
export { MarkdownText, PlainText } from './MarkdownText.js';
|
|
9
11
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -6,4 +6,6 @@ export { InputArea } from './InputArea.js';
|
|
|
6
6
|
export { Spinner } from './Spinner.js';
|
|
7
7
|
export { StreamingText } from './StreamingText.js';
|
|
8
8
|
export { ToolCallIndicator } from './ToolCallIndicator.js';
|
|
9
|
+
export { ScrollableBox } from './ScrollableBox.js';
|
|
10
|
+
export { MarkdownText, PlainText } from './MarkdownText.js';
|
|
9
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/components/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC"}
|