@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.
Files changed (71) hide show
  1. package/dist/app.d.ts +6 -0
  2. package/dist/app.d.ts.map +1 -0
  3. package/dist/app.js +36 -0
  4. package/dist/app.js.map +1 -0
  5. package/dist/cli.js +180674 -0
  6. package/dist/cli.js.map +7 -0
  7. package/dist/config/index.d.ts +20 -0
  8. package/dist/config/index.d.ts.map +1 -0
  9. package/dist/config/index.js +18 -0
  10. package/dist/config/index.js.map +1 -0
  11. package/dist/index.d.ts +2 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +190 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/ui/components/App.d.ts +40 -0
  16. package/dist/ui/components/App.d.ts.map +1 -0
  17. package/dist/ui/components/App.js +196 -0
  18. package/dist/ui/components/App.js.map +1 -0
  19. package/dist/ui/components/AppHeader.d.ts +6 -0
  20. package/dist/ui/components/AppHeader.d.ts.map +1 -0
  21. package/dist/ui/components/AppHeader.js +51 -0
  22. package/dist/ui/components/AppHeader.js.map +1 -0
  23. package/dist/ui/components/ChatInput.d.ts +12 -0
  24. package/dist/ui/components/ChatInput.d.ts.map +1 -0
  25. package/dist/ui/components/ChatInput.js +107 -0
  26. package/dist/ui/components/ChatInput.js.map +1 -0
  27. package/dist/ui/components/MessageList.d.ts +7 -0
  28. package/dist/ui/components/MessageList.d.ts.map +1 -0
  29. package/dist/ui/components/MessageList.js +8 -0
  30. package/dist/ui/components/MessageList.js.map +1 -0
  31. package/dist/ui/components/Permission.d.ts +8 -0
  32. package/dist/ui/components/Permission.d.ts.map +1 -0
  33. package/dist/ui/components/Permission.js +104 -0
  34. package/dist/ui/components/Permission.js.map +1 -0
  35. package/dist/ui/components/SelectOptions.d.ts +12 -0
  36. package/dist/ui/components/SelectOptions.d.ts.map +1 -0
  37. package/dist/ui/components/SelectOptions.js +49 -0
  38. package/dist/ui/components/SelectOptions.js.map +1 -0
  39. package/dist/ui/components/ShellOutput.d.ts +6 -0
  40. package/dist/ui/components/ShellOutput.d.ts.map +1 -0
  41. package/dist/ui/components/ShellOutput.js +13 -0
  42. package/dist/ui/components/ShellOutput.js.map +1 -0
  43. package/dist/ui/components/Spinner.d.ts +6 -0
  44. package/dist/ui/components/Spinner.d.ts.map +1 -0
  45. package/dist/ui/components/Spinner.js +17 -0
  46. package/dist/ui/components/Spinner.js.map +1 -0
  47. package/dist/ui/components/StatusBar.d.ts +8 -0
  48. package/dist/ui/components/StatusBar.d.ts.map +1 -0
  49. package/dist/ui/components/StatusBar.js +8 -0
  50. package/dist/ui/components/StatusBar.js.map +1 -0
  51. package/dist/ui/components/StreamingText.d.ts +6 -0
  52. package/dist/ui/components/StreamingText.d.ts.map +1 -0
  53. package/dist/ui/components/StreamingText.js +46 -0
  54. package/dist/ui/components/StreamingText.js.map +1 -0
  55. package/dist/ui/components/ToolCall.d.ts +9 -0
  56. package/dist/ui/components/ToolCall.d.ts.map +1 -0
  57. package/dist/ui/components/ToolCall.js +29 -0
  58. package/dist/ui/components/ToolCall.js.map +1 -0
  59. package/dist/ui/hooks/use-agent.d.ts +46 -0
  60. package/dist/ui/hooks/use-agent.d.ts.map +1 -0
  61. package/dist/ui/hooks/use-agent.js +277 -0
  62. package/dist/ui/hooks/use-agent.js.map +1 -0
  63. package/dist/ui/render-markdown.d.ts +8 -0
  64. package/dist/ui/render-markdown.d.ts.map +1 -0
  65. package/dist/ui/render-markdown.js +230 -0
  66. package/dist/ui/render-markdown.js.map +1 -0
  67. package/dist/ui/theme.d.ts +13 -0
  68. package/dist/ui/theme.d.ts.map +1 -0
  69. package/dist/ui/theme.js +19 -0
  70. package/dist/ui/theme.js.map +1 -0
  71. 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,6 @@
1
+ interface ShellOutputProps {
2
+ output: string;
3
+ }
4
+ export declare function ShellOutput({ output }: ShellOutputProps): import("react/jsx-runtime").JSX.Element | null;
5
+ export {};
6
+ //# sourceMappingURL=ShellOutput.d.ts.map
@@ -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,6 @@
1
+ interface SpinnerProps {
2
+ label?: string;
3
+ }
4
+ export declare function Spinner({ label }: SpinnerProps): import("react/jsx-runtime").JSX.Element;
5
+ export {};
6
+ //# sourceMappingURL=Spinner.d.ts.map
@@ -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,6 @@
1
+ interface StreamingTextProps {
2
+ text: string;
3
+ }
4
+ export declare function StreamingText({ text }: StreamingTextProps): import("react/jsx-runtime").JSX.Element | null;
5
+ export {};
6
+ //# sourceMappingURL=StreamingText.d.ts.map
@@ -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"}