@x-code-cli/cli 0.1.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/app.d.ts +6 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/app.js +36 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.js +180674 -0
- package/dist/cli.js.map +7 -0
- package/dist/config/index.d.ts +20 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +18 -0
- package/dist/config/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +190 -0
- package/dist/index.js.map +1 -0
- package/dist/ui/components/App.d.ts +40 -0
- package/dist/ui/components/App.d.ts.map +1 -0
- package/dist/ui/components/App.js +196 -0
- package/dist/ui/components/App.js.map +1 -0
- package/dist/ui/components/AppHeader.d.ts +6 -0
- package/dist/ui/components/AppHeader.d.ts.map +1 -0
- package/dist/ui/components/AppHeader.js +51 -0
- package/dist/ui/components/AppHeader.js.map +1 -0
- package/dist/ui/components/ChatInput.d.ts +12 -0
- package/dist/ui/components/ChatInput.d.ts.map +1 -0
- package/dist/ui/components/ChatInput.js +107 -0
- package/dist/ui/components/ChatInput.js.map +1 -0
- package/dist/ui/components/MessageList.d.ts +7 -0
- package/dist/ui/components/MessageList.d.ts.map +1 -0
- package/dist/ui/components/MessageList.js +8 -0
- package/dist/ui/components/MessageList.js.map +1 -0
- package/dist/ui/components/Permission.d.ts +8 -0
- package/dist/ui/components/Permission.d.ts.map +1 -0
- package/dist/ui/components/Permission.js +104 -0
- package/dist/ui/components/Permission.js.map +1 -0
- package/dist/ui/components/SelectOptions.d.ts +12 -0
- package/dist/ui/components/SelectOptions.d.ts.map +1 -0
- package/dist/ui/components/SelectOptions.js +49 -0
- package/dist/ui/components/SelectOptions.js.map +1 -0
- package/dist/ui/components/ShellOutput.d.ts +6 -0
- package/dist/ui/components/ShellOutput.d.ts.map +1 -0
- package/dist/ui/components/ShellOutput.js +13 -0
- package/dist/ui/components/ShellOutput.js.map +1 -0
- package/dist/ui/components/Spinner.d.ts +6 -0
- package/dist/ui/components/Spinner.d.ts.map +1 -0
- package/dist/ui/components/Spinner.js +17 -0
- package/dist/ui/components/Spinner.js.map +1 -0
- package/dist/ui/components/StatusBar.d.ts +8 -0
- package/dist/ui/components/StatusBar.d.ts.map +1 -0
- package/dist/ui/components/StatusBar.js +8 -0
- package/dist/ui/components/StatusBar.js.map +1 -0
- package/dist/ui/components/StreamingText.d.ts +6 -0
- package/dist/ui/components/StreamingText.d.ts.map +1 -0
- package/dist/ui/components/StreamingText.js +46 -0
- package/dist/ui/components/StreamingText.js.map +1 -0
- package/dist/ui/components/ToolCall.d.ts +9 -0
- package/dist/ui/components/ToolCall.d.ts.map +1 -0
- package/dist/ui/components/ToolCall.js +29 -0
- package/dist/ui/components/ToolCall.js.map +1 -0
- package/dist/ui/hooks/use-agent.d.ts +46 -0
- package/dist/ui/hooks/use-agent.d.ts.map +1 -0
- package/dist/ui/hooks/use-agent.js +277 -0
- package/dist/ui/hooks/use-agent.js.map +1 -0
- package/dist/ui/render-markdown.d.ts +8 -0
- package/dist/ui/render-markdown.d.ts.map +1 -0
- package/dist/ui/render-markdown.js +230 -0
- package/dist/ui/render-markdown.js.map +1 -0
- package/dist/ui/theme.d.ts +13 -0
- package/dist/ui/theme.d.ts.map +1 -0
- package/dist/ui/theme.js +19 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +28 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// @x-code/cli — User text input component with slash command completion
|
|
3
|
+
//
|
|
4
|
+
// Inspired by Claude Code: completion list appears BELOW the input line,
|
|
5
|
+
// with a soft colour scheme — selected item uses the accent blue, unselected
|
|
6
|
+
// items are dimmed grey. The input line only ever shows what the user has
|
|
7
|
+
// actually typed — no ghost hints that confuse backspace behaviour.
|
|
8
|
+
import { useMemo, useState } from 'react';
|
|
9
|
+
import { Box, Text, useInput } from 'ink';
|
|
10
|
+
import { ACCENT } from '../theme.js';
|
|
11
|
+
const PASTE_PREVIEW_THRESHOLD = 500;
|
|
12
|
+
const PASTE_PREVIEW_LINES = 3;
|
|
13
|
+
export function ChatInput({ onSubmit, disabled, commands = [] }) {
|
|
14
|
+
const [text, setText] = useState('');
|
|
15
|
+
const [isPasteTruncated, setIsPasteTruncated] = useState(false);
|
|
16
|
+
// Index for cycling through multiple completion matches
|
|
17
|
+
const [completionIndex, setCompletionIndex] = useState(0);
|
|
18
|
+
// ── Fuzzy matching: filter commands whose name contains the typed chars in order ──
|
|
19
|
+
const matches = useMemo(() => {
|
|
20
|
+
if (!text.startsWith('/') || text.includes(' '))
|
|
21
|
+
return [];
|
|
22
|
+
const query = text.slice(1).toLowerCase(); // strip leading "/"
|
|
23
|
+
if (!query) {
|
|
24
|
+
// Just "/" typed — show all commands
|
|
25
|
+
return [...commands];
|
|
26
|
+
}
|
|
27
|
+
return commands.filter((c) => {
|
|
28
|
+
const name = c.name.slice(1).toLowerCase(); // strip "/" from command name
|
|
29
|
+
// fuzzy: every character of query appears in order inside name
|
|
30
|
+
let qi = 0;
|
|
31
|
+
for (let ni = 0; ni < name.length && qi < query.length; ni++) {
|
|
32
|
+
if (name[ni] === query[qi])
|
|
33
|
+
qi++;
|
|
34
|
+
}
|
|
35
|
+
return qi === query.length;
|
|
36
|
+
});
|
|
37
|
+
}, [text, commands]);
|
|
38
|
+
// The currently highlighted completion (if any)
|
|
39
|
+
const safeIndex = matches.length > 0 ? completionIndex % matches.length : 0;
|
|
40
|
+
const currentMatch = matches.length > 0 ? matches[safeIndex] : null;
|
|
41
|
+
useInput((input, key) => {
|
|
42
|
+
if (disabled)
|
|
43
|
+
return;
|
|
44
|
+
// Tab — accept the current completion, append a space so the
|
|
45
|
+
// dropdown closes and the user can continue typing arguments
|
|
46
|
+
if (key.tab) {
|
|
47
|
+
if (currentMatch) {
|
|
48
|
+
setText(currentMatch.name);
|
|
49
|
+
setCompletionIndex(0);
|
|
50
|
+
}
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
// Enter — submit
|
|
54
|
+
if (key.return) {
|
|
55
|
+
if (text.trim()) {
|
|
56
|
+
onSubmit(text);
|
|
57
|
+
setText('');
|
|
58
|
+
setIsPasteTruncated(false);
|
|
59
|
+
setCompletionIndex(0);
|
|
60
|
+
}
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
// Backspace / Delete — always removes exactly one character
|
|
64
|
+
if (key.backspace || key.delete) {
|
|
65
|
+
setText((prev) => prev.slice(0, -1));
|
|
66
|
+
setCompletionIndex(0);
|
|
67
|
+
if (text.length <= PASTE_PREVIEW_THRESHOLD) {
|
|
68
|
+
setIsPasteTruncated(false);
|
|
69
|
+
}
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
// Arrow up/down — cycle through completions
|
|
73
|
+
if (key.upArrow && matches.length > 0) {
|
|
74
|
+
setCompletionIndex((prev) => (prev - 1 + matches.length) % matches.length);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (key.downArrow && matches.length > 0) {
|
|
78
|
+
setCompletionIndex((prev) => (prev + 1) % matches.length);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
// Regular character input
|
|
82
|
+
if (input && !key.ctrl && !key.meta) {
|
|
83
|
+
const newText = text + input;
|
|
84
|
+
setText(newText);
|
|
85
|
+
setCompletionIndex(0);
|
|
86
|
+
if (input.length > PASTE_PREVIEW_THRESHOLD) {
|
|
87
|
+
setIsPasteTruncated(true);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
if (disabled)
|
|
92
|
+
return null;
|
|
93
|
+
// Display text (truncated if paste)
|
|
94
|
+
let displayText = text;
|
|
95
|
+
if (isPasteTruncated && text.length > PASTE_PREVIEW_THRESHOLD) {
|
|
96
|
+
const lines = text.split('\n');
|
|
97
|
+
const previewLines = lines.slice(0, PASTE_PREVIEW_LINES);
|
|
98
|
+
displayText = previewLines.join('\n') + `\n... (${text.length} characters)`;
|
|
99
|
+
}
|
|
100
|
+
// Pad command names so descriptions line up nicely
|
|
101
|
+
const maxNameLen = matches.reduce((max, c) => Math.max(max, c.name.length), 0);
|
|
102
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsxs(Box, { children: [_jsx(Text, { color: ACCENT, bold: true, children: '> ' }), _jsx(Text, { children: displayText }), _jsx(Text, { dimColor: true, children: "\u2588" })] }), matches.length > 0 && (_jsx(Box, { flexDirection: "column", marginTop: 0, marginLeft: 2, children: matches.map((cmd, i) => {
|
|
103
|
+
const isSelected = i === safeIndex;
|
|
104
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? ACCENT : 'gray', bold: isSelected, children: cmd.name.padEnd(maxNameLen + 2) }), _jsx(Text, { color: isSelected ? undefined : 'gray', dimColor: !isSelected, children: cmd.description })] }, cmd.name));
|
|
105
|
+
}) }))] }));
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=ChatInput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatInput.js","sourceRoot":"","sources":["../../../src/ui/components/ChatInput.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DisplayMessage } from '@x-code/core';
|
|
2
|
+
interface MessageListProps {
|
|
3
|
+
messages: DisplayMessage[];
|
|
4
|
+
}
|
|
5
|
+
export declare function MessageList({ messages }: MessageListProps): import("react/jsx-runtime").JSX.Element;
|
|
6
|
+
export {};
|
|
7
|
+
//# sourceMappingURL=MessageList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageList.d.ts","sourceRoot":"","sources":["../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAKlD,UAAU,gBAAgB;IACxB,QAAQ,EAAE,cAAc,EAAE,CAAA;CAC3B;AAED,wBAAgB,WAAW,CAAC,EAAE,QAAQ,EAAE,EAAE,gBAAgB,2CA2BzD"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Static, Text } from 'ink';
|
|
3
|
+
import { renderMarkdown } from '../render-markdown.js';
|
|
4
|
+
import { ACCENT, WARNING } from '../theme.js';
|
|
5
|
+
export function MessageList({ messages }) {
|
|
6
|
+
return (_jsx(Static, { items: messages, children: (msg) => (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [msg.role === 'user' ? (_jsxs(Text, { children: [_jsx(Text, { color: ACCENT, bold: true, children: '> ' }), msg.content] })) : (_jsx(Text, { children: renderMarkdown(msg.content) })), msg.toolCalls?.map((tc) => (_jsx(Box, { marginLeft: 2, children: _jsxs(Text, { color: WARNING, dimColor: true, children: ["[", tc.status, "] ", tc.toolName, tc.output ? `: ${tc.output.slice(0, 100)}${tc.output.length > 100 ? '...' : ''}` : ''] }) }, tc.id)))] }, msg.id)) }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=MessageList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MessageList.js","sourceRoot":"","sources":["../../../src/ui/components/MessageList.tsx"],"names":[],"mappings":";AAYA,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAIvC,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAM7C,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAoB;IACxD,OAAO,CACL,KAAC,MAAM,IAAC,KAAK,EAAE,QAAQ,YACpB,CAAC,GAAG,EAAE,EAAE,CAAC,CACR,MAAC,GAAG,IAAc,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC,aACrD,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CACrB,MAAC,IAAI,eACH,KAAC,IAAI,IAAC,KAAK,EAAE,MAAM,EAAE,IAAI,kBACtB,IAAI,GACA,EACN,GAAG,CAAC,OAAO,IACP,CACR,CAAC,CAAC,CAAC,CACF,KAAC,IAAI,cAAE,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,GAAQ,CAC3C,EACA,GAAG,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAC1B,KAAC,GAAG,IAAa,UAAU,EAAE,CAAC,YAC5B,MAAC,IAAI,IAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,wBAC1B,EAAE,CAAC,MAAM,QAAI,EAAE,CAAC,QAAQ,EACzB,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IACjF,IAJC,EAAE,CAAC,EAAE,CAKT,CACP,CAAC,KAlBM,GAAG,CAAC,EAAE,CAmBV,CACP,GACM,CACV,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
interface PermissionProps {
|
|
2
|
+
toolName: string;
|
|
3
|
+
input: Record<string, unknown>;
|
|
4
|
+
onResolve: (approved: boolean) => void;
|
|
5
|
+
}
|
|
6
|
+
export declare function Permission({ toolName, input, onResolve }: PermissionProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=Permission.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Permission.d.ts","sourceRoot":"","sources":["../../../src/ui/components/Permission.tsx"],"names":[],"mappings":"AAaA,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,SAAS,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;CACvC;AAsBD,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,eAAe,2CAoDzE"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @x-code/cli — Permission confirmation component (Y/N + diff preview)
|
|
3
|
+
import { diffLines } from 'diff';
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
import { Box, Text, useInput } from 'ink';
|
|
7
|
+
import { getPermissionLevel } from '@x-code/core';
|
|
8
|
+
import { ACCENT, ERROR, SUCCESS, WARNING } from '../theme.js';
|
|
9
|
+
const PERMISSION_LABELS = {
|
|
10
|
+
'always-allow': { label: 'read-only', color: SUCCESS },
|
|
11
|
+
ask: { label: 'write', color: WARNING },
|
|
12
|
+
deny: { label: 'dangerous', color: ERROR },
|
|
13
|
+
};
|
|
14
|
+
/** Build a human-readable title for the permission request */
|
|
15
|
+
function getPermissionTitle(toolName) {
|
|
16
|
+
switch (toolName) {
|
|
17
|
+
case 'shell':
|
|
18
|
+
return 'X-Code wants to run a shell command';
|
|
19
|
+
case 'writeFile':
|
|
20
|
+
return 'X-Code wants to write a file';
|
|
21
|
+
case 'edit':
|
|
22
|
+
return 'X-Code wants to edit a file';
|
|
23
|
+
default:
|
|
24
|
+
return `X-Code wants to use ${toolName}`;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
export function Permission({ toolName, input, onResolve }) {
|
|
28
|
+
useInput((inputKey) => {
|
|
29
|
+
if (inputKey.toLowerCase() === 'y')
|
|
30
|
+
onResolve(true);
|
|
31
|
+
else if (inputKey.toLowerCase() === 'n')
|
|
32
|
+
onResolve(false);
|
|
33
|
+
});
|
|
34
|
+
// Tool-specific preview
|
|
35
|
+
let preview = null;
|
|
36
|
+
if (toolName === 'shell') {
|
|
37
|
+
const level = getPermissionLevel('shell', input);
|
|
38
|
+
const info = PERMISSION_LABELS[level] ?? PERMISSION_LABELS.ask;
|
|
39
|
+
preview = (_jsx(Box, { flexDirection: "column", marginLeft: 2, children: _jsxs(Box, { gap: 1, children: [_jsxs(Text, { color: ACCENT, children: ["$ ", input.command] }), _jsxs(Text, { color: info.color, children: ["[", info.label, "]"] })] }) }));
|
|
40
|
+
}
|
|
41
|
+
else if (toolName === 'writeFile') {
|
|
42
|
+
preview = _jsx(WriteFilePreview, { filePath: input.filePath, content: input.content });
|
|
43
|
+
}
|
|
44
|
+
else if (toolName === 'edit') {
|
|
45
|
+
const filePath = input.filePath;
|
|
46
|
+
const oldStr = input.oldString;
|
|
47
|
+
const newStr = input.newString;
|
|
48
|
+
preview = (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsx(Text, { color: ACCENT, children: filePath }), _jsx(DiffView, { oldText: oldStr, newText: newStr })] }));
|
|
49
|
+
}
|
|
50
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: WARNING, paddingX: 1, children: [_jsx(Text, { color: WARNING, bold: true, children: getPermissionTitle(toolName) }), preview, _jsxs(Box, { marginTop: 0, gap: 1, children: [_jsx(Text, { dimColor: true, children: "Allow?" }), _jsx(Text, { color: SUCCESS, bold: true, children: "(y)es" }), _jsx(Text, { dimColor: true, children: "/" }), _jsx(Text, { color: ERROR, bold: true, children: "(n)o" })] })] }));
|
|
51
|
+
}
|
|
52
|
+
/** writeFile preview — shows diff if file already exists, else shows content summary */
|
|
53
|
+
function WriteFilePreview({ filePath, content }) {
|
|
54
|
+
const [existingContent, setExistingContent] = useState(null);
|
|
55
|
+
const [loaded, setLoaded] = useState(false);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
fs.readFile(filePath, 'utf-8')
|
|
58
|
+
.then((data) => {
|
|
59
|
+
setExistingContent(data);
|
|
60
|
+
setLoaded(true);
|
|
61
|
+
})
|
|
62
|
+
.catch(() => {
|
|
63
|
+
setExistingContent(null);
|
|
64
|
+
setLoaded(true);
|
|
65
|
+
});
|
|
66
|
+
}, [filePath]);
|
|
67
|
+
if (!loaded) {
|
|
68
|
+
return (_jsx(Box, { marginLeft: 2, children: _jsx(Text, { dimColor: true, children: "Loading..." }) }));
|
|
69
|
+
}
|
|
70
|
+
// Existing file — show diff
|
|
71
|
+
if (existingContent !== null) {
|
|
72
|
+
return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Text, { color: ACCENT, children: [filePath, " (overwrite)"] }), _jsx(DiffView, { oldText: existingContent, newText: content })] }));
|
|
73
|
+
}
|
|
74
|
+
// New file — show content summary
|
|
75
|
+
return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, children: [_jsxs(Text, { color: ACCENT, children: [filePath, " (new file)"] }), _jsxs(Text, { dimColor: true, children: [content.slice(0, 300), content.length > 300 ? '\n...' : ''] })] }));
|
|
76
|
+
}
|
|
77
|
+
/** Render a unified diff with red/green coloring */
|
|
78
|
+
function DiffView({ oldText, newText }) {
|
|
79
|
+
const changes = diffLines(oldText, newText);
|
|
80
|
+
const maxLines = 20;
|
|
81
|
+
let lineCount = 0;
|
|
82
|
+
const elements = [];
|
|
83
|
+
for (const change of changes) {
|
|
84
|
+
const lines = change.value.split('\n').filter((l) => l !== '' || change.value === '\n');
|
|
85
|
+
for (const line of lines) {
|
|
86
|
+
if (lineCount >= maxLines) {
|
|
87
|
+
elements.push(_jsx(Text, { dimColor: true, children: "... (diff truncated)" }, "truncated"));
|
|
88
|
+
return _jsx(Box, { flexDirection: "column", children: elements });
|
|
89
|
+
}
|
|
90
|
+
if (change.added) {
|
|
91
|
+
elements.push(_jsxs(Text, { color: SUCCESS, children: ["+ ", line] }, `+${lineCount}`));
|
|
92
|
+
}
|
|
93
|
+
else if (change.removed) {
|
|
94
|
+
elements.push(_jsxs(Text, { color: ERROR, children: ["- ", line] }, `-${lineCount}`));
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
elements.push(_jsxs(Text, { dimColor: true, children: [' ', line] }, ` ${lineCount}`));
|
|
98
|
+
}
|
|
99
|
+
lineCount++;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return _jsx(Box, { flexDirection: "column", children: elements });
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=Permission.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Permission.js","sourceRoot":"","sources":["../../../src/ui/components/Permission.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Option {
|
|
2
|
+
label: string;
|
|
3
|
+
description: string;
|
|
4
|
+
}
|
|
5
|
+
interface SelectOptionsProps {
|
|
6
|
+
question: string;
|
|
7
|
+
options: Option[];
|
|
8
|
+
onSelect: (answer: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function SelectOptions({ question, options, onSelect }: SelectOptionsProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=SelectOptions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectOptions.d.ts","sourceRoot":"","sources":["../../../src/ui/components/SelectOptions.tsx"],"names":[],"mappings":"AAOA,UAAU,MAAM;IACd,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CACnC;AAED,wBAAgB,aAAa,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,kBAAkB,2CAkEhF"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @x-code/cli — askUser multi-select interaction component
|
|
3
|
+
import { useState } from 'react';
|
|
4
|
+
import { Box, Text, useInput } from 'ink';
|
|
5
|
+
import { ACCENT } from '../theme.js';
|
|
6
|
+
export function SelectOptions({ question, options, onSelect }) {
|
|
7
|
+
// Append "Other" option
|
|
8
|
+
const allOptions = [...options, { label: 'Other', description: 'Custom input' }];
|
|
9
|
+
const [selected, setSelected] = useState(0);
|
|
10
|
+
const [customInput, setCustomInput] = useState('');
|
|
11
|
+
const [isCustomMode, setIsCustomMode] = useState(false);
|
|
12
|
+
useInput((input, key) => {
|
|
13
|
+
if (isCustomMode) {
|
|
14
|
+
if (key.return) {
|
|
15
|
+
onSelect(customInput || 'Other');
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
if (key.backspace || key.delete) {
|
|
19
|
+
setCustomInput((prev) => prev.slice(0, -1));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (key.escape) {
|
|
23
|
+
setIsCustomMode(false);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
if (input && !key.ctrl && !key.meta) {
|
|
27
|
+
setCustomInput((prev) => prev + input);
|
|
28
|
+
}
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
if (key.upArrow) {
|
|
32
|
+
setSelected((prev) => (prev > 0 ? prev - 1 : allOptions.length - 1));
|
|
33
|
+
}
|
|
34
|
+
else if (key.downArrow) {
|
|
35
|
+
setSelected((prev) => (prev < allOptions.length - 1 ? prev + 1 : 0));
|
|
36
|
+
}
|
|
37
|
+
else if (key.return) {
|
|
38
|
+
if (selected === allOptions.length - 1) {
|
|
39
|
+
// "Other" selected
|
|
40
|
+
setIsCustomMode(true);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
onSelect(allOptions[selected].label);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", borderColor: ACCENT, paddingX: 1, children: [_jsxs(Text, { color: ACCENT, bold: true, children: ["? ", question] }), !isCustomMode ? (allOptions.map((opt, i) => (_jsxs(Box, { children: [_jsxs(Text, { color: i === selected ? ACCENT : undefined, children: [i === selected ? '> ' : ' ', opt.label] }), _jsxs(Text, { dimColor: true, children: [" \u2014 ", opt.description] })] }, i)))) : (_jsxs(Box, { children: [_jsx(Text, { color: ACCENT, children: '> ' }), _jsx(Text, { children: customInput }), _jsx(Text, { dimColor: true, children: "\u2588" })] })), _jsx(Text, { dimColor: true, children: isCustomMode ? 'Enter to confirm, Esc to go back' : '↑↓ Navigate Enter Confirm' })] }));
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=SelectOptions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectOptions.js","sourceRoot":"","sources":["../../../src/ui/components/SelectOptions.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShellOutput.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ShellOutput.tsx"],"names":[],"mappings":"AAOA,UAAU,gBAAgB;IACxB,MAAM,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,WAAW,CAAC,EAAE,MAAM,EAAE,EAAE,gBAAgB,kDAsBvD"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { DIM, WARNING } from '../theme.js';
|
|
4
|
+
export function ShellOutput({ output }) {
|
|
5
|
+
if (!output)
|
|
6
|
+
return null;
|
|
7
|
+
// Show last N lines to avoid overwhelming the terminal
|
|
8
|
+
const lines = output.split('\n');
|
|
9
|
+
const maxLines = 20;
|
|
10
|
+
const displayLines = lines.length > maxLines ? lines.slice(-maxLines) : lines;
|
|
11
|
+
return (_jsxs(Box, { flexDirection: "column", marginLeft: 2, borderStyle: "single", borderColor: DIM, paddingX: 1, children: [displayLines.map((line, i) => (_jsx(Text, { dimColor: true, children: line }, i))), lines.length > maxLines && (_jsxs(Text, { dimColor: true, color: WARNING, children: ["... (", lines.length - maxLines, " lines above)"] }))] }));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=ShellOutput.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ShellOutput.js","sourceRoot":"","sources":["../../../src/ui/components/ShellOutput.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE/B,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAM1C,MAAM,UAAU,WAAW,CAAC,EAAE,MAAM,EAAoB;IACtD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAA;IAExB,uDAAuD;IACvD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAChC,MAAM,QAAQ,GAAG,EAAE,CAAA;IACnB,MAAM,YAAY,GAAG,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAE7E,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,UAAU,EAAE,CAAC,EAAE,WAAW,EAAC,QAAQ,EAAC,WAAW,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC,aAC1F,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAC7B,KAAC,IAAI,IAAS,QAAQ,kBACnB,IAAI,IADI,CAAC,CAEL,CACR,CAAC,EACD,KAAK,CAAC,MAAM,GAAG,QAAQ,IAAI,CAC1B,MAAC,IAAI,IAAC,QAAQ,QAAC,KAAK,EAAE,OAAO,sBACrB,KAAK,CAAC,MAAM,GAAG,QAAQ,qBACxB,CACR,IACG,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.d.ts","sourceRoot":"","sources":["../../../src/ui/components/Spinner.tsx"],"names":[],"mappings":"AASA,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,wBAAgB,OAAO,CAAC,EAAE,KAAqB,EAAE,EAAE,YAAY,2CAe9D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
// @x-code/cli — Loading spinner component
|
|
3
|
+
import { useEffect, useState } from 'react';
|
|
4
|
+
import { Text } from 'ink';
|
|
5
|
+
import { ACCENT } from '../theme.js';
|
|
6
|
+
const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
7
|
+
export function Spinner({ label = 'Thinking...' }) {
|
|
8
|
+
const [frame, setFrame] = useState(0);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
const timer = setInterval(() => {
|
|
11
|
+
setFrame((prev) => (prev + 1) % FRAMES.length);
|
|
12
|
+
}, 80);
|
|
13
|
+
return () => clearInterval(timer);
|
|
14
|
+
}, []);
|
|
15
|
+
return (_jsxs(Text, { color: ACCENT, children: [FRAMES[frame], " ", label] }));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=Spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../../src/ui/components/Spinner.tsx"],"names":[],"mappings":";AAAA,0CAA0C;AAC1C,OAAc,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAElD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE1B,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEpC,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAMjE,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,GAAG,aAAa,EAAgB;IAC7D,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;IAErC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC7B,QAAQ,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAA;QAChD,CAAC,EAAE,EAAE,CAAC,CAAA;QACN,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAA;IACnC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,OAAO,CACL,MAAC,IAAI,IAAC,KAAK,EAAE,MAAM,aAChB,MAAM,CAAC,KAAK,CAAC,OAAG,KAAK,IACjB,CACR,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TokenUsage } from '@x-code/core';
|
|
2
|
+
interface StatusBarProps {
|
|
3
|
+
modelId: string;
|
|
4
|
+
usage: TokenUsage;
|
|
5
|
+
}
|
|
6
|
+
export declare function StatusBar({ modelId, usage }: StatusBarProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=StatusBar.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAE9C,UAAU,cAAc;IACtB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE,UAAU,CAAA;CAClB;AAED,wBAAgB,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,cAAc,2CAU3D"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
export function StatusBar({ modelId, usage }) {
|
|
4
|
+
const symbol = usage.costCurrency === 'CNY' ? '¥' : '$';
|
|
5
|
+
const costStr = usage.estimatedCost > 0 ? ` ${symbol}${usage.estimatedCost.toFixed(4)}` : '';
|
|
6
|
+
return (_jsx(Box, { children: _jsxs(Text, { dimColor: true, children: [modelId, " | ", usage.totalTokens.toLocaleString(), " tokens", costStr] }) }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=StatusBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/ui/components/StatusBar.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAS/B,MAAM,UAAU,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAkB;IAC1D,MAAM,MAAM,GAAG,KAAK,CAAC,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;IACvD,MAAM,OAAO,GAAG,KAAK,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,MAAM,GAAG,KAAK,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAA;IAC5F,OAAO,CACL,KAAC,GAAG,cACF,MAAC,IAAI,IAAC,QAAQ,mBACX,OAAO,SAAK,KAAK,CAAC,WAAW,CAAC,cAAc,EAAE,aAAS,OAAO,IAC1D,GACH,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingText.d.ts","sourceRoot":"","sources":["../../../src/ui/components/StreamingText.tsx"],"names":[],"mappings":"AA2BA,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAA;CACb;AAED,wBAAgB,aAAa,CAAC,EAAE,IAAI,EAAE,EAAE,kBAAkB,kDA0BzD"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// @x-code/cli — Streaming text output component
|
|
3
|
+
//
|
|
4
|
+
// IMPORTANT: This component renders OUTSIDE of Ink's <Static> region, which
|
|
5
|
+
// means Ink clears and redraws it on every state change. If the rendered
|
|
6
|
+
// output exceeds the terminal's visible height, Ink cannot erase the overflow
|
|
7
|
+
// that has already scrolled off-screen — causing the same content to appear
|
|
8
|
+
// multiple times (the "duplicate rendering" bug).
|
|
9
|
+
//
|
|
10
|
+
// The fix follows the same approach used by Gemini CLI:
|
|
11
|
+
// Only display the TAIL of the streaming text, capped to
|
|
12
|
+
// (terminal rows − reserved rows for ChatInput / padding).
|
|
13
|
+
//
|
|
14
|
+
// The full text is still accumulated in state.streamingText; once streaming
|
|
15
|
+
// finishes it is moved into the <Static> message history where Ink writes
|
|
16
|
+
// it permanently without further redraws.
|
|
17
|
+
//
|
|
18
|
+
// Markdown rendering is applied to the visible tail so headings, bold,
|
|
19
|
+
// code blocks, etc. display with proper terminal formatting.
|
|
20
|
+
import { useMemo } from 'react';
|
|
21
|
+
import { Box, Text, useStdout } from 'ink';
|
|
22
|
+
import { renderMarkdown } from '../render-markdown.js';
|
|
23
|
+
/** Rows reserved for other non-Static UI: ChatInput + padding + 1 buffer */
|
|
24
|
+
const RESERVED_ROWS = 6;
|
|
25
|
+
export function StreamingText({ text }) {
|
|
26
|
+
const { stdout } = useStdout();
|
|
27
|
+
const terminalRows = stdout?.rows ?? 24;
|
|
28
|
+
// Maximum lines the streaming area may occupy
|
|
29
|
+
const maxLines = Math.max(1, terminalRows - RESERVED_ROWS);
|
|
30
|
+
// Only show the last `maxLines` lines so the non-Static area never
|
|
31
|
+
// exceeds the terminal viewport.
|
|
32
|
+
const visibleText = useMemo(() => {
|
|
33
|
+
if (!text)
|
|
34
|
+
return '';
|
|
35
|
+
const lines = text.split('\n');
|
|
36
|
+
if (lines.length <= maxLines)
|
|
37
|
+
return text;
|
|
38
|
+
return lines.slice(-maxLines).join('\n');
|
|
39
|
+
}, [text, maxLines]);
|
|
40
|
+
// Render markdown to ANSI
|
|
41
|
+
const rendered = useMemo(() => renderMarkdown(visibleText), [visibleText]);
|
|
42
|
+
if (!rendered)
|
|
43
|
+
return null;
|
|
44
|
+
return (_jsx(Box, { flexDirection: "column", overflow: "hidden", children: _jsx(Text, { children: rendered }) }));
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=StreamingText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingText.js","sourceRoot":"","sources":["../../../src/ui/components/StreamingText.tsx"],"names":[],"mappings":";AAAA,gDAAgD;AAChD,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,8EAA8E;AAC9E,4EAA4E;AAC5E,kDAAkD;AAClD,EAAE;AACF,wDAAwD;AACxD,2DAA2D;AAC3D,6DAA6D;AAC7D,EAAE;AACF,4EAA4E;AAC5E,0EAA0E;AAC1E,0CAA0C;AAC1C,EAAE;AACF,uEAAuE;AACvE,6DAA6D;AAC7D,OAAc,EAAE,OAAO,EAAE,MAAM,OAAO,CAAA;AAEtC,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,KAAK,CAAA;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAEtD,4EAA4E;AAC5E,MAAM,aAAa,GAAG,CAAC,CAAA;AAMvB,MAAM,UAAU,aAAa,CAAC,EAAE,IAAI,EAAsB;IACxD,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAA;IAC9B,MAAM,YAAY,GAAG,MAAM,EAAE,IAAI,IAAI,EAAE,CAAA;IAEvC,8CAA8C;IAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,YAAY,GAAG,aAAa,CAAC,CAAA;IAE1D,mEAAmE;IACnE,iCAAiC;IACjC,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE;QAC/B,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAA;QACpB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC9B,IAAI,KAAK,CAAC,MAAM,IAAI,QAAQ;YAAE,OAAO,IAAI,CAAA;QACzC,OAAO,KAAK,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAA;IAEpB,0BAA0B;IAC1B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,cAAc,CAAC,WAAW,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAE1E,IAAI,CAAC,QAAQ;QAAE,OAAO,IAAI,CAAA;IAE1B,OAAO,CACL,KAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAC,QAAQ,YAC3C,KAAC,IAAI,cAAE,QAAQ,GAAQ,GACnB,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
interface ToolCallProps {
|
|
2
|
+
toolName: string;
|
|
3
|
+
input: Record<string, unknown>;
|
|
4
|
+
status: 'pending' | 'running' | 'completed' | 'denied';
|
|
5
|
+
output?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function ToolCall({ toolName, input, status, output }: ToolCallProps): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=ToolCall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolCall.d.ts","sourceRoot":"","sources":["../../../src/ui/components/ToolCall.tsx"],"names":[],"mappings":"AAOA,UAAU,aAAa;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,QAAQ,CAAA;IACtD,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,aAAa,2CA8C1E"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { ACCENT, ERROR, SUCCESS, WARNING } from '../theme.js';
|
|
4
|
+
export function ToolCall({ toolName, input, status, output }) {
|
|
5
|
+
const statusColors = {
|
|
6
|
+
pending: WARNING,
|
|
7
|
+
running: ACCENT,
|
|
8
|
+
completed: SUCCESS,
|
|
9
|
+
denied: ERROR,
|
|
10
|
+
};
|
|
11
|
+
const statusIcons = {
|
|
12
|
+
pending: '○',
|
|
13
|
+
running: '◑',
|
|
14
|
+
completed: '●',
|
|
15
|
+
denied: '✕',
|
|
16
|
+
};
|
|
17
|
+
// Show relevant input preview
|
|
18
|
+
const inputPreview = toolName === 'shell'
|
|
19
|
+
? input.command
|
|
20
|
+
: toolName === 'readFile' || toolName === 'writeFile' || toolName === 'edit'
|
|
21
|
+
? input.filePath
|
|
22
|
+
: toolName === 'glob'
|
|
23
|
+
? input.pattern
|
|
24
|
+
: toolName === 'grep'
|
|
25
|
+
? input.pattern
|
|
26
|
+
: JSON.stringify(input).slice(0, 80);
|
|
27
|
+
return (_jsxs(Box, { flexDirection: "column", marginLeft: 1, children: [_jsxs(Text, { children: [_jsxs(Text, { color: statusColors[status], children: [statusIcons[status], " "] }), _jsx(Text, { bold: true, color: ACCENT, children: toolName }), _jsxs(Text, { dimColor: true, children: [" ", inputPreview] })] }), output && status === 'completed' && (_jsx(Box, { marginLeft: 3, children: _jsxs(Text, { dimColor: true, children: [output.slice(0, 200), output.length > 200 ? '...' : ''] }) }))] }));
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=ToolCall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ToolCall.js","sourceRoot":"","sources":["../../../src/ui/components/ToolCall.tsx"],"names":[],"mappings":";AAGA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAA;AAE/B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAS7D,MAAM,UAAU,QAAQ,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAiB;IACzE,MAAM,YAAY,GAA2B;QAC3C,OAAO,EAAE,OAAO;QAChB,OAAO,EAAE,MAAM;QACf,SAAS,EAAE,OAAO;QAClB,MAAM,EAAE,KAAK;KACd,CAAA;IAED,MAAM,WAAW,GAA2B;QAC1C,OAAO,EAAE,GAAG;QACZ,OAAO,EAAE,GAAG;QACZ,SAAS,EAAE,GAAG;QACd,MAAM,EAAE,GAAG;KACZ,CAAA;IAED,8BAA8B;IAC9B,MAAM,YAAY,GAChB,QAAQ,KAAK,OAAO;QAClB,CAAC,CAAE,KAAK,CAAC,OAAkB;QAC3B,CAAC,CAAC,QAAQ,KAAK,UAAU,IAAI,QAAQ,KAAK,WAAW,IAAI,QAAQ,KAAK,MAAM;YAC1E,CAAC,CAAE,KAAK,CAAC,QAAmB;YAC5B,CAAC,CAAC,QAAQ,KAAK,MAAM;gBACnB,CAAC,CAAE,KAAK,CAAC,OAAkB;gBAC3B,CAAC,CAAC,QAAQ,KAAK,MAAM;oBACnB,CAAC,CAAE,KAAK,CAAC,OAAkB;oBAC3B,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAE9C,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,UAAU,EAAE,CAAC,aACvC,MAAC,IAAI,eACH,MAAC,IAAI,IAAC,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,aAAG,WAAW,CAAC,MAAM,CAAC,SAAS,EAChE,KAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,MAAM,YACrB,QAAQ,GACJ,EACP,MAAC,IAAI,IAAC,QAAQ,wBAAG,YAAY,IAAQ,IAChC,EACN,MAAM,IAAI,MAAM,KAAK,WAAW,IAAI,CACnC,KAAC,GAAG,IAAC,UAAU,EAAE,CAAC,YAChB,MAAC,IAAI,IAAC,QAAQ,mBACX,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EACpB,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAC5B,GACH,CACP,IACG,CACP,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { AgentOptions, DisplayMessage, LanguageModel, SessionSummary, TokenUsage } from '@x-code/core';
|
|
2
|
+
interface PendingPermission {
|
|
3
|
+
toolName: string;
|
|
4
|
+
input: Record<string, unknown>;
|
|
5
|
+
resolve: (approved: boolean) => void;
|
|
6
|
+
}
|
|
7
|
+
interface PendingQuestion {
|
|
8
|
+
question: string;
|
|
9
|
+
options: {
|
|
10
|
+
label: string;
|
|
11
|
+
description: string;
|
|
12
|
+
}[];
|
|
13
|
+
resolve: (answer: string) => void;
|
|
14
|
+
}
|
|
15
|
+
export interface AgentState {
|
|
16
|
+
messages: DisplayMessage[];
|
|
17
|
+
streamingText: string;
|
|
18
|
+
isLoading: boolean;
|
|
19
|
+
currentToolCall: {
|
|
20
|
+
toolName: string;
|
|
21
|
+
input: Record<string, unknown>;
|
|
22
|
+
} | null;
|
|
23
|
+
shellOutput: string;
|
|
24
|
+
pendingPermission: PendingPermission | null;
|
|
25
|
+
pendingQuestion: PendingQuestion | null;
|
|
26
|
+
usage: TokenUsage;
|
|
27
|
+
error: string | null;
|
|
28
|
+
latestSession: SessionSummary | null;
|
|
29
|
+
}
|
|
30
|
+
export declare function useAgent(initialModel: LanguageModel, options: AgentOptions): {
|
|
31
|
+
state: AgentState;
|
|
32
|
+
submit: (text: string) => Promise<void>;
|
|
33
|
+
resolvePermission: (approved: boolean) => void;
|
|
34
|
+
resolveQuestion: (answer: string) => void;
|
|
35
|
+
abort: () => void;
|
|
36
|
+
cleanup: () => Promise<void>;
|
|
37
|
+
clear: () => void;
|
|
38
|
+
compact: () => Promise<void>;
|
|
39
|
+
switchModel: (newModelId: string, newModel: LanguageModel) => void;
|
|
40
|
+
saveCurrentSession: () => Promise<boolean>;
|
|
41
|
+
dismissSession: () => void;
|
|
42
|
+
addInfoMessage: (content: string) => void;
|
|
43
|
+
addUserMessage: (content: string) => void;
|
|
44
|
+
};
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=use-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-agent.d.ts","sourceRoot":"","sources":["../../../src/ui/hooks/use-agent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAEV,YAAY,EACZ,cAAc,EACd,aAAa,EAEb,cAAc,EACd,UAAU,EACX,MAAM,cAAc,CAAA;AAErB,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B,OAAO,EAAE,CAAC,QAAQ,EAAE,OAAO,KAAK,IAAI,CAAA;CACrC;AAED,UAAU,eAAe;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IACjD,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CAClC;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,EAAE,CAAA;IAC1B,aAAa,EAAE,MAAM,CAAA;IACrB,SAAS,EAAE,OAAO,CAAA;IAClB,eAAe,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,IAAI,CAAA;IAC5E,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,iBAAiB,GAAG,IAAI,CAAA;IAC3C,eAAe,EAAE,eAAe,GAAG,IAAI,CAAA;IACvC,KAAK,EAAE,UAAU,CAAA;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;IACpB,aAAa,EAAE,cAAc,GAAG,IAAI,CAAA;CACrC;AAED,wBAAgB,QAAQ,CAAC,YAAY,EAAE,aAAa,EAAE,OAAO,EAAE,YAAY;;mBAyE1D,MAAM;kCA0G4B,OAAO;8BAYX,MAAM;;;;;8BAuDN,MAAM,YAAY,aAAa;;;8BAW/B,MAAM;8BAgBN,MAAM;EA8BpD"}
|