@nils.del/supergrok 1.0.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/.env +45 -0
- package/.grok/settings.json +13 -0
- package/dist/agent/index.d.ts +35 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +244 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +242 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/client.d.ts +33 -0
- package/dist/mcp/client.d.ts.map +1 -0
- package/dist/mcp/client.js +134 -0
- package/dist/mcp/client.js.map +1 -0
- package/dist/mcp/config.d.ts +15 -0
- package/dist/mcp/config.d.ts.map +1 -0
- package/dist/mcp/config.js +123 -0
- package/dist/mcp/config.js.map +1 -0
- package/dist/mcp/transports.d.ts +24 -0
- package/dist/mcp/transports.d.ts.map +1 -0
- package/dist/mcp/transports.js +91 -0
- package/dist/mcp/transports.js.map +1 -0
- package/dist/tools/bash.d.ts +28 -0
- package/dist/tools/bash.d.ts.map +1 -0
- package/dist/tools/bash.js +70 -0
- package/dist/tools/bash.js.map +1 -0
- package/dist/tools/index.d.ts +77 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +80 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/text-editor.d.ts +69 -0
- package/dist/tools/text-editor.d.ts.map +1 -0
- package/dist/tools/text-editor.js +178 -0
- package/dist/tools/text-editor.js.map +1 -0
- package/dist/tools/types.d.ts +14 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/ui/readline-ui.d.ts +32 -0
- package/dist/ui/readline-ui.d.ts.map +1 -0
- package/dist/ui/readline-ui.js +256 -0
- package/dist/ui/readline-ui.js.map +1 -0
- package/dist/utils/settings.d.ts +20 -0
- package/dist/utils/settings.d.ts.map +1 -0
- package/dist/utils/settings.js +101 -0
- package/dist/utils/settings.js.map +1 -0
- package/package.json +51 -0
- package/src/agent/index.ts +302 -0
- package/src/index.ts +275 -0
- package/src/mcp/client.ts +178 -0
- package/src/mcp/config.ts +149 -0
- package/src/mcp/transports.ts +142 -0
- package/src/tools/bash.ts +84 -0
- package/src/tools/index.ts +91 -0
- package/src/tools/text-editor.ts +222 -0
- package/src/tools/types.ts +14 -0
- package/src/ui/readline-ui.ts +294 -0
- package/src/utils/settings.ts +129 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { executeBashCommand, bashToolDefinition } from './bash.js';
|
|
2
|
+
import { viewFile, createFile, strReplace, insertText, textEditorToolDefinition } from './text-editor.js';
|
|
3
|
+
import { getMCPManager } from '../mcp/client.js';
|
|
4
|
+
export function getBuiltInTools() {
|
|
5
|
+
return [bashToolDefinition, textEditorToolDefinition];
|
|
6
|
+
}
|
|
7
|
+
export async function getAllTools() {
|
|
8
|
+
const builtInTools = getBuiltInTools();
|
|
9
|
+
const mcpManager = getMCPManager();
|
|
10
|
+
// Ensure MCP servers are initialized
|
|
11
|
+
await mcpManager.ensureServersInitialized();
|
|
12
|
+
const mcpTools = mcpManager.getTools().map(tool => ({
|
|
13
|
+
type: "function",
|
|
14
|
+
function: {
|
|
15
|
+
name: tool.name,
|
|
16
|
+
description: tool.description,
|
|
17
|
+
parameters: tool.inputSchema
|
|
18
|
+
}
|
|
19
|
+
}));
|
|
20
|
+
return [...builtInTools, ...mcpTools];
|
|
21
|
+
}
|
|
22
|
+
export async function executeToolCall(toolCall) {
|
|
23
|
+
const { function: fn } = toolCall;
|
|
24
|
+
const args = JSON.parse(fn.arguments || '{}');
|
|
25
|
+
// Handle MCP tools
|
|
26
|
+
if (fn.name.startsWith('mcp__')) {
|
|
27
|
+
try {
|
|
28
|
+
const mcpManager = getMCPManager();
|
|
29
|
+
const result = await mcpManager.callTool(fn.name, args);
|
|
30
|
+
// Convert MCP result to our format
|
|
31
|
+
const content = result.content
|
|
32
|
+
.map((c) => {
|
|
33
|
+
if (c.type === 'text')
|
|
34
|
+
return c.text;
|
|
35
|
+
if (c.type === 'image')
|
|
36
|
+
return `[Image: ${c.mimeType}]`;
|
|
37
|
+
return JSON.stringify(c);
|
|
38
|
+
})
|
|
39
|
+
.join('\n');
|
|
40
|
+
return {
|
|
41
|
+
success: !result.isError,
|
|
42
|
+
output: result.isError ? undefined : content,
|
|
43
|
+
error: result.isError ? content : undefined
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
return {
|
|
48
|
+
success: false,
|
|
49
|
+
error: `MCP tool error: ${error.message}`
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Handle built-in tools
|
|
54
|
+
switch (fn.name) {
|
|
55
|
+
case 'bash':
|
|
56
|
+
return await executeBashCommand(args);
|
|
57
|
+
case 'str_replace_editor':
|
|
58
|
+
switch (args.command) {
|
|
59
|
+
case 'view':
|
|
60
|
+
return await viewFile({ path: args.path, view_range: args.view_range });
|
|
61
|
+
case 'create':
|
|
62
|
+
return await createFile({ path: args.path, file_text: args.file_text });
|
|
63
|
+
case 'str_replace':
|
|
64
|
+
return await strReplace({ path: args.path, old_str: args.old_str, new_str: args.new_str });
|
|
65
|
+
case 'insert':
|
|
66
|
+
return await insertText({ path: args.path, insert_line: args.insert_line, new_str: args.new_str });
|
|
67
|
+
default:
|
|
68
|
+
return {
|
|
69
|
+
success: false,
|
|
70
|
+
error: `Unknown editor command: ${args.command}`
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
default:
|
|
74
|
+
return {
|
|
75
|
+
success: false,
|
|
76
|
+
error: `Unknown tool: ${fn.name}`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { ToolResult } from './types.js';
|
|
2
|
+
export interface ViewArgs {
|
|
3
|
+
path: string;
|
|
4
|
+
view_range?: [number, number];
|
|
5
|
+
}
|
|
6
|
+
export interface CreateArgs {
|
|
7
|
+
path: string;
|
|
8
|
+
file_text: string;
|
|
9
|
+
}
|
|
10
|
+
export interface StrReplaceArgs {
|
|
11
|
+
path: string;
|
|
12
|
+
old_str: string;
|
|
13
|
+
new_str: string;
|
|
14
|
+
}
|
|
15
|
+
export interface InsertArgs {
|
|
16
|
+
path: string;
|
|
17
|
+
insert_line: number;
|
|
18
|
+
new_str: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function viewFile(args: ViewArgs): Promise<ToolResult>;
|
|
21
|
+
export declare function createFile(args: CreateArgs): Promise<ToolResult>;
|
|
22
|
+
export declare function strReplace(args: StrReplaceArgs): Promise<ToolResult>;
|
|
23
|
+
export declare function insertText(args: InsertArgs): Promise<ToolResult>;
|
|
24
|
+
export declare const textEditorToolDefinition: {
|
|
25
|
+
type: "function";
|
|
26
|
+
function: {
|
|
27
|
+
name: string;
|
|
28
|
+
description: string;
|
|
29
|
+
parameters: {
|
|
30
|
+
type: string;
|
|
31
|
+
properties: {
|
|
32
|
+
command: {
|
|
33
|
+
type: string;
|
|
34
|
+
enum: string[];
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
path: {
|
|
38
|
+
type: string;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
file_text: {
|
|
42
|
+
type: string;
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
old_str: {
|
|
46
|
+
type: string;
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
49
|
+
new_str: {
|
|
50
|
+
type: string;
|
|
51
|
+
description: string;
|
|
52
|
+
};
|
|
53
|
+
insert_line: {
|
|
54
|
+
type: string;
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
view_range: {
|
|
58
|
+
type: string;
|
|
59
|
+
items: {
|
|
60
|
+
type: string;
|
|
61
|
+
};
|
|
62
|
+
description: string;
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
required: string[];
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
//# sourceMappingURL=text-editor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-editor.d.ts","sourceRoot":"","sources":["../../src/tools/text-editor.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC,CA4ClE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAqBtE;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,CAyC1E;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAmCtE;AAED,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CpC,CAAC"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export async function viewFile(args) {
|
|
4
|
+
try {
|
|
5
|
+
const filePath = path.resolve(process.cwd(), args.path);
|
|
6
|
+
if (!fs.existsSync(filePath)) {
|
|
7
|
+
return {
|
|
8
|
+
success: false,
|
|
9
|
+
error: `File not found: ${args.path}`
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
13
|
+
const lines = content.split('\n');
|
|
14
|
+
if (args.view_range) {
|
|
15
|
+
const [start, end] = args.view_range;
|
|
16
|
+
const startIdx = Math.max(0, start - 1);
|
|
17
|
+
const endIdx = Math.min(lines.length, end);
|
|
18
|
+
const numberedLines = lines
|
|
19
|
+
.slice(startIdx, endIdx)
|
|
20
|
+
.map((line, i) => `${startIdx + i + 1}: ${line}`)
|
|
21
|
+
.join('\n');
|
|
22
|
+
return {
|
|
23
|
+
success: true,
|
|
24
|
+
output: `File: ${args.path} (lines ${start}-${end})\n\n${numberedLines}`
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
const numberedLines = lines
|
|
28
|
+
.map((line, i) => `${i + 1}: ${line}`)
|
|
29
|
+
.join('\n');
|
|
30
|
+
return {
|
|
31
|
+
success: true,
|
|
32
|
+
output: `File: ${args.path} (${lines.length} lines)\n\n${numberedLines}`
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
return {
|
|
37
|
+
success: false,
|
|
38
|
+
error: `Failed to read file: ${error.message}`
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export async function createFile(args) {
|
|
43
|
+
try {
|
|
44
|
+
const filePath = path.resolve(process.cwd(), args.path);
|
|
45
|
+
const dir = path.dirname(filePath);
|
|
46
|
+
if (!fs.existsSync(dir)) {
|
|
47
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
fs.writeFileSync(filePath, args.file_text);
|
|
50
|
+
return {
|
|
51
|
+
success: true,
|
|
52
|
+
output: `File created successfully: ${args.path}`
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
return {
|
|
57
|
+
success: false,
|
|
58
|
+
error: `Failed to create file: ${error.message}`
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
export async function strReplace(args) {
|
|
63
|
+
try {
|
|
64
|
+
const filePath = path.resolve(process.cwd(), args.path);
|
|
65
|
+
if (!fs.existsSync(filePath)) {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
error: `File not found: ${args.path}`
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
72
|
+
if (!content.includes(args.old_str)) {
|
|
73
|
+
return {
|
|
74
|
+
success: false,
|
|
75
|
+
error: `String not found in file: "${args.old_str.substring(0, 50)}..."`
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const occurrences = content.split(args.old_str).length - 1;
|
|
79
|
+
if (occurrences > 1) {
|
|
80
|
+
return {
|
|
81
|
+
success: false,
|
|
82
|
+
error: `Found ${occurrences} occurrences of the string. Please provide a more specific string to replace.`
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const newContent = content.replace(args.old_str, args.new_str);
|
|
86
|
+
fs.writeFileSync(filePath, newContent);
|
|
87
|
+
return {
|
|
88
|
+
success: true,
|
|
89
|
+
output: `Successfully replaced text in ${args.path}`
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
return {
|
|
94
|
+
success: false,
|
|
95
|
+
error: `Failed to replace text: ${error.message}`
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
export async function insertText(args) {
|
|
100
|
+
try {
|
|
101
|
+
const filePath = path.resolve(process.cwd(), args.path);
|
|
102
|
+
if (!fs.existsSync(filePath)) {
|
|
103
|
+
return {
|
|
104
|
+
success: false,
|
|
105
|
+
error: `File not found: ${args.path}`
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
109
|
+
const lines = content.split('\n');
|
|
110
|
+
if (args.insert_line < 0 || args.insert_line > lines.length) {
|
|
111
|
+
return {
|
|
112
|
+
success: false,
|
|
113
|
+
error: `Invalid line number: ${args.insert_line}. File has ${lines.length} lines.`
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
lines.splice(args.insert_line, 0, args.new_str);
|
|
117
|
+
const newContent = lines.join('\n');
|
|
118
|
+
fs.writeFileSync(filePath, newContent);
|
|
119
|
+
return {
|
|
120
|
+
success: true,
|
|
121
|
+
output: `Successfully inserted text at line ${args.insert_line} in ${args.path}`
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
error: `Failed to insert text: ${error.message}`
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
export const textEditorToolDefinition = {
|
|
132
|
+
type: "function",
|
|
133
|
+
function: {
|
|
134
|
+
name: "str_replace_editor",
|
|
135
|
+
description: `A powerful text editor tool for viewing and modifying files. Commands:
|
|
136
|
+
- view: View file contents with line numbers
|
|
137
|
+
- create: Create a new file with specified content
|
|
138
|
+
- str_replace: Replace a specific string in a file (must be unique)
|
|
139
|
+
- insert: Insert text at a specific line number`,
|
|
140
|
+
parameters: {
|
|
141
|
+
type: "object",
|
|
142
|
+
properties: {
|
|
143
|
+
command: {
|
|
144
|
+
type: "string",
|
|
145
|
+
enum: ["view", "create", "str_replace", "insert"],
|
|
146
|
+
description: "The editing command to execute"
|
|
147
|
+
},
|
|
148
|
+
path: {
|
|
149
|
+
type: "string",
|
|
150
|
+
description: "The file path to operate on"
|
|
151
|
+
},
|
|
152
|
+
file_text: {
|
|
153
|
+
type: "string",
|
|
154
|
+
description: "For create command: the content of the new file"
|
|
155
|
+
},
|
|
156
|
+
old_str: {
|
|
157
|
+
type: "string",
|
|
158
|
+
description: "For str_replace command: the exact string to replace"
|
|
159
|
+
},
|
|
160
|
+
new_str: {
|
|
161
|
+
type: "string",
|
|
162
|
+
description: "For str_replace/insert commands: the new string to insert"
|
|
163
|
+
},
|
|
164
|
+
insert_line: {
|
|
165
|
+
type: "number",
|
|
166
|
+
description: "For insert command: the line number to insert at (0-indexed)"
|
|
167
|
+
},
|
|
168
|
+
view_range: {
|
|
169
|
+
type: "array",
|
|
170
|
+
items: { type: "number" },
|
|
171
|
+
description: "For view command: optional [start, end] line range"
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
required: ["command", "path"]
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
//# sourceMappingURL=text-editor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text-editor.js","sourceRoot":"","sources":["../../src/tools/text-editor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ToolResult {
|
|
2
|
+
success: boolean;
|
|
3
|
+
output?: string;
|
|
4
|
+
error?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ToolCall {
|
|
7
|
+
id: string;
|
|
8
|
+
type: string;
|
|
9
|
+
function: {
|
|
10
|
+
name: string;
|
|
11
|
+
arguments: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { GrokAgent } from '../agent/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* A readline-based UI that doesn't have the Ink flickering issues.
|
|
4
|
+
*
|
|
5
|
+
* Key differences from Ink-based UI:
|
|
6
|
+
* 1. Uses Node.js readline which has proper terminal handling on Linux
|
|
7
|
+
* 2. Line-based output instead of full-screen rendering
|
|
8
|
+
* 3. Input is captured properly even during MCP operations
|
|
9
|
+
* 4. No React rendering overhead
|
|
10
|
+
*/
|
|
11
|
+
export declare class ReadlineUI {
|
|
12
|
+
private agent;
|
|
13
|
+
private rl;
|
|
14
|
+
private isProcessing;
|
|
15
|
+
private currentSpinner;
|
|
16
|
+
private spinnerFrames;
|
|
17
|
+
private spinnerIndex;
|
|
18
|
+
constructor(agent: GrokAgent);
|
|
19
|
+
private cleanup;
|
|
20
|
+
private startSpinner;
|
|
21
|
+
private stopSpinner;
|
|
22
|
+
private prompt;
|
|
23
|
+
private printHeader;
|
|
24
|
+
private showMCPStatus;
|
|
25
|
+
private printToolCall;
|
|
26
|
+
private printToolResult;
|
|
27
|
+
private handleCommand;
|
|
28
|
+
private processMessage;
|
|
29
|
+
start(initialMessage?: string): Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export declare function runReadlineUI(agent: GrokAgent, initialMessage?: string): Promise<void>;
|
|
32
|
+
//# sourceMappingURL=readline-ui.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"readline-ui.d.ts","sourceRoot":"","sources":["../../src/ui/readline-ui.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAA0B,MAAM,mBAAmB,CAAC;AAGtE;;;;;;;;GAQG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAY;IACzB,OAAO,CAAC,EAAE,CAAqB;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,aAAa,CAAsD;IAC3E,OAAO,CAAC,YAAY,CAAK;gBAEb,KAAK,EAAE,SAAS;IAkC5B,OAAO,CAAC,OAAO;IAKf,OAAO,CAAC,YAAY;IAUpB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,WAAW;YAaL,aAAa;IAiB3B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,aAAa;YAuDP,cAAc;IA+DtB,KAAK,CAAC,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAwCpD;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,SAAS,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG5F"}
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import * as readline from 'readline';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { getMCPManager } from '../mcp/client.js';
|
|
4
|
+
/**
|
|
5
|
+
* A readline-based UI that doesn't have the Ink flickering issues.
|
|
6
|
+
*
|
|
7
|
+
* Key differences from Ink-based UI:
|
|
8
|
+
* 1. Uses Node.js readline which has proper terminal handling on Linux
|
|
9
|
+
* 2. Line-based output instead of full-screen rendering
|
|
10
|
+
* 3. Input is captured properly even during MCP operations
|
|
11
|
+
* 4. No React rendering overhead
|
|
12
|
+
*/
|
|
13
|
+
export class ReadlineUI {
|
|
14
|
+
agent;
|
|
15
|
+
rl;
|
|
16
|
+
isProcessing = false;
|
|
17
|
+
currentSpinner = null;
|
|
18
|
+
spinnerFrames = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
|
|
19
|
+
spinnerIndex = 0;
|
|
20
|
+
constructor(agent) {
|
|
21
|
+
this.agent = agent;
|
|
22
|
+
// Create readline interface with proper configuration for raw mode
|
|
23
|
+
this.rl = readline.createInterface({
|
|
24
|
+
input: process.stdin,
|
|
25
|
+
output: process.stdout,
|
|
26
|
+
terminal: true,
|
|
27
|
+
historySize: 100,
|
|
28
|
+
prompt: chalk.cyan('❯ ')
|
|
29
|
+
});
|
|
30
|
+
// Handle Ctrl+C gracefully
|
|
31
|
+
this.rl.on('close', () => {
|
|
32
|
+
this.cleanup();
|
|
33
|
+
process.exit(0);
|
|
34
|
+
});
|
|
35
|
+
// Handle SIGINT (Ctrl+C)
|
|
36
|
+
process.on('SIGINT', () => {
|
|
37
|
+
if (this.isProcessing) {
|
|
38
|
+
this.agent.abortCurrentOperation();
|
|
39
|
+
this.stopSpinner();
|
|
40
|
+
console.log(chalk.yellow('\n[Aborted]'));
|
|
41
|
+
this.isProcessing = false;
|
|
42
|
+
this.prompt();
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
console.log(chalk.gray('\nGoodbye!'));
|
|
46
|
+
this.cleanup();
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
cleanup() {
|
|
52
|
+
this.stopSpinner();
|
|
53
|
+
this.rl.close();
|
|
54
|
+
}
|
|
55
|
+
startSpinner(message) {
|
|
56
|
+
this.spinnerIndex = 0;
|
|
57
|
+
process.stdout.write(`\r${chalk.yellow(this.spinnerFrames[0])} ${message}`);
|
|
58
|
+
this.currentSpinner = setInterval(() => {
|
|
59
|
+
this.spinnerIndex = (this.spinnerIndex + 1) % this.spinnerFrames.length;
|
|
60
|
+
process.stdout.write(`\r${chalk.yellow(this.spinnerFrames[this.spinnerIndex])} ${message}`);
|
|
61
|
+
}, 80);
|
|
62
|
+
}
|
|
63
|
+
stopSpinner() {
|
|
64
|
+
if (this.currentSpinner) {
|
|
65
|
+
clearInterval(this.currentSpinner);
|
|
66
|
+
this.currentSpinner = null;
|
|
67
|
+
process.stdout.write('\r\x1b[K'); // Clear the line
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
prompt() {
|
|
71
|
+
this.rl.prompt();
|
|
72
|
+
}
|
|
73
|
+
printHeader() {
|
|
74
|
+
console.log();
|
|
75
|
+
console.log(chalk.magenta.bold(' ╔═══════════════════════════════════════════╗'));
|
|
76
|
+
console.log(chalk.magenta.bold(' ║') + chalk.cyan.bold(' GROK CLI (Fixed Edition) ') + chalk.magenta.bold('║'));
|
|
77
|
+
console.log(chalk.magenta.bold(' ║') + chalk.gray(' No Ink flickering • Works with MCP ') + chalk.magenta.bold('║'));
|
|
78
|
+
console.log(chalk.magenta.bold(' ╚═══════════════════════════════════════════╝'));
|
|
79
|
+
console.log();
|
|
80
|
+
console.log(chalk.gray(' Type your message and press Enter. Commands:'));
|
|
81
|
+
console.log(chalk.gray(' /help - Show help /clear - Clear history /exit - Quit'));
|
|
82
|
+
console.log(chalk.gray(' Ctrl+C - Cancel operation or exit'));
|
|
83
|
+
console.log();
|
|
84
|
+
}
|
|
85
|
+
async showMCPStatus() {
|
|
86
|
+
const mcpManager = getMCPManager();
|
|
87
|
+
await mcpManager.ensureServersInitialized();
|
|
88
|
+
const servers = mcpManager.getServers();
|
|
89
|
+
const tools = mcpManager.getTools();
|
|
90
|
+
if (servers.length > 0) {
|
|
91
|
+
console.log(chalk.green(` ✓ MCP: ${servers.length} server(s), ${tools.length} tool(s)`));
|
|
92
|
+
servers.forEach(server => {
|
|
93
|
+
const serverTools = tools.filter(t => t.serverName === server);
|
|
94
|
+
console.log(chalk.gray(` • ${server}: ${serverTools.length} tools`));
|
|
95
|
+
});
|
|
96
|
+
console.log();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
printToolCall(name, args) {
|
|
100
|
+
const shortArgs = args.length > 100 ? args.substring(0, 100) + '...' : args;
|
|
101
|
+
console.log(chalk.blue(` ⚡ ${name}`));
|
|
102
|
+
console.log(chalk.gray(` ${shortArgs}`));
|
|
103
|
+
}
|
|
104
|
+
printToolResult(result) {
|
|
105
|
+
if (result.success) {
|
|
106
|
+
const output = result.output || 'Success';
|
|
107
|
+
const lines = output.split('\n');
|
|
108
|
+
const displayLines = lines.length > 10 ? [...lines.slice(0, 10), `... (${lines.length - 10} more lines)`] : lines;
|
|
109
|
+
console.log(chalk.green(' ✓ ') + chalk.gray(displayLines.join('\n ')));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.log(chalk.red(' ✗ ') + chalk.red(result.error || 'Error'));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
handleCommand(input) {
|
|
116
|
+
const command = input.trim().toLowerCase();
|
|
117
|
+
switch (command) {
|
|
118
|
+
case '/help':
|
|
119
|
+
console.log();
|
|
120
|
+
console.log(chalk.cyan('Available Commands:'));
|
|
121
|
+
console.log(chalk.gray(' /help - Show this help message'));
|
|
122
|
+
console.log(chalk.gray(' /clear - Clear conversation history'));
|
|
123
|
+
console.log(chalk.gray(' /model - Show current model'));
|
|
124
|
+
console.log(chalk.gray(' /mcp - Show MCP server status'));
|
|
125
|
+
console.log(chalk.gray(' /exit - Exit the application'));
|
|
126
|
+
console.log();
|
|
127
|
+
console.log(chalk.cyan('Keyboard Shortcuts:'));
|
|
128
|
+
console.log(chalk.gray(' Ctrl+C - Cancel current operation or exit'));
|
|
129
|
+
console.log(chalk.gray(' Up/Down - Navigate command history'));
|
|
130
|
+
console.log();
|
|
131
|
+
return true;
|
|
132
|
+
case '/clear':
|
|
133
|
+
this.agent.clearHistory();
|
|
134
|
+
console.clear();
|
|
135
|
+
this.printHeader();
|
|
136
|
+
console.log(chalk.green(' ✓ Conversation cleared'));
|
|
137
|
+
console.log();
|
|
138
|
+
return true;
|
|
139
|
+
case '/model':
|
|
140
|
+
console.log(chalk.cyan(` Current model: ${this.agent.getCurrentModel()}`));
|
|
141
|
+
console.log();
|
|
142
|
+
return true;
|
|
143
|
+
case '/mcp':
|
|
144
|
+
this.showMCPStatus();
|
|
145
|
+
return true;
|
|
146
|
+
case '/exit':
|
|
147
|
+
case 'exit':
|
|
148
|
+
case 'quit':
|
|
149
|
+
console.log(chalk.gray('Goodbye!'));
|
|
150
|
+
this.cleanup();
|
|
151
|
+
process.exit(0);
|
|
152
|
+
return true;
|
|
153
|
+
default:
|
|
154
|
+
if (input.startsWith('/')) {
|
|
155
|
+
console.log(chalk.red(` Unknown command: ${input}`));
|
|
156
|
+
console.log(chalk.gray(' Type /help for available commands'));
|
|
157
|
+
console.log();
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async processMessage(input) {
|
|
164
|
+
this.isProcessing = true;
|
|
165
|
+
console.log();
|
|
166
|
+
try {
|
|
167
|
+
let lastContent = '';
|
|
168
|
+
let isFirstContent = true;
|
|
169
|
+
let toolCount = 0;
|
|
170
|
+
for await (const chunk of this.agent.processUserMessageStream(input)) {
|
|
171
|
+
switch (chunk.type) {
|
|
172
|
+
case 'content':
|
|
173
|
+
if (chunk.content) {
|
|
174
|
+
if (isFirstContent) {
|
|
175
|
+
process.stdout.write(chalk.white(' '));
|
|
176
|
+
isFirstContent = false;
|
|
177
|
+
}
|
|
178
|
+
process.stdout.write(chunk.content);
|
|
179
|
+
lastContent += chunk.content;
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
case 'tool_calls':
|
|
183
|
+
if (lastContent) {
|
|
184
|
+
console.log();
|
|
185
|
+
lastContent = '';
|
|
186
|
+
}
|
|
187
|
+
console.log();
|
|
188
|
+
if (chunk.toolCalls) {
|
|
189
|
+
for (const tc of chunk.toolCalls) {
|
|
190
|
+
toolCount++;
|
|
191
|
+
this.printToolCall(tc.function.name, tc.function.arguments);
|
|
192
|
+
this.startSpinner(`Executing tool ${toolCount}...`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
isFirstContent = true;
|
|
196
|
+
break;
|
|
197
|
+
case 'tool_result':
|
|
198
|
+
this.stopSpinner();
|
|
199
|
+
if (chunk.toolResult) {
|
|
200
|
+
this.printToolResult(chunk.toolResult);
|
|
201
|
+
}
|
|
202
|
+
console.log();
|
|
203
|
+
break;
|
|
204
|
+
case 'done':
|
|
205
|
+
if (lastContent && !lastContent.endsWith('\n')) {
|
|
206
|
+
console.log();
|
|
207
|
+
}
|
|
208
|
+
break;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
catch (error) {
|
|
213
|
+
this.stopSpinner();
|
|
214
|
+
console.log(chalk.red(`\n Error: ${error.message}`));
|
|
215
|
+
}
|
|
216
|
+
console.log();
|
|
217
|
+
this.isProcessing = false;
|
|
218
|
+
}
|
|
219
|
+
async start(initialMessage) {
|
|
220
|
+
// Clear screen and print header
|
|
221
|
+
console.clear();
|
|
222
|
+
this.printHeader();
|
|
223
|
+
// Show MCP status
|
|
224
|
+
await this.showMCPStatus();
|
|
225
|
+
// Show current model
|
|
226
|
+
console.log(chalk.yellow(` Model: ${this.agent.getCurrentModel()}`));
|
|
227
|
+
console.log();
|
|
228
|
+
// Process initial message if provided
|
|
229
|
+
if (initialMessage) {
|
|
230
|
+
console.log(chalk.cyan('❯ ') + initialMessage);
|
|
231
|
+
await this.processMessage(initialMessage);
|
|
232
|
+
}
|
|
233
|
+
// Main input loop
|
|
234
|
+
this.rl.on('line', async (input) => {
|
|
235
|
+
const trimmed = input.trim();
|
|
236
|
+
if (!trimmed) {
|
|
237
|
+
this.prompt();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
// Check for commands
|
|
241
|
+
if (this.handleCommand(trimmed)) {
|
|
242
|
+
this.prompt();
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
// Process as a message to the AI
|
|
246
|
+
await this.processMessage(trimmed);
|
|
247
|
+
this.prompt();
|
|
248
|
+
});
|
|
249
|
+
this.prompt();
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
export async function runReadlineUI(agent, initialMessage) {
|
|
253
|
+
const ui = new ReadlineUI(agent);
|
|
254
|
+
await ui.start(initialMessage);
|
|
255
|
+
}
|
|
256
|
+
//# sourceMappingURL=readline-ui.js.map
|