genesis-ai-cli 14.2.0 → 14.3.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/src/cli/agentic.d.ts +78 -0
- package/dist/src/cli/agentic.js +748 -0
- package/dist/src/index.js +23 -0
- package/package.json +1 -1
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Genesis v14.2 - Agentic CLI Interface
|
|
3
|
+
*
|
|
4
|
+
* Provides Claude Code-like capabilities:
|
|
5
|
+
* - File operations (read, write, edit, glob, grep)
|
|
6
|
+
* - Bash command execution
|
|
7
|
+
* - MCP server integration
|
|
8
|
+
* - Web search/fetch
|
|
9
|
+
* - Memory and context
|
|
10
|
+
* - Agent orchestration
|
|
11
|
+
*
|
|
12
|
+
* Usage: genesis agentic [--model <model>] [--cwd <dir>]
|
|
13
|
+
*/
|
|
14
|
+
export interface AgenticConfig {
|
|
15
|
+
model?: string;
|
|
16
|
+
cwd?: string;
|
|
17
|
+
verbose?: boolean;
|
|
18
|
+
maxTokens?: number;
|
|
19
|
+
temperature?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface ToolDefinition {
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
parameters: {
|
|
25
|
+
type: 'object';
|
|
26
|
+
properties: Record<string, {
|
|
27
|
+
type: string;
|
|
28
|
+
description: string;
|
|
29
|
+
enum?: string[];
|
|
30
|
+
}>;
|
|
31
|
+
required?: string[];
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export interface ToolCall {
|
|
35
|
+
id: string;
|
|
36
|
+
name: string;
|
|
37
|
+
arguments: Record<string, unknown>;
|
|
38
|
+
}
|
|
39
|
+
export interface Message {
|
|
40
|
+
role: 'user' | 'assistant' | 'system' | 'tool';
|
|
41
|
+
content: string;
|
|
42
|
+
tool_calls?: ToolCall[];
|
|
43
|
+
tool_call_id?: string;
|
|
44
|
+
name?: string;
|
|
45
|
+
}
|
|
46
|
+
export declare class AgenticToolExecutor {
|
|
47
|
+
private cwd;
|
|
48
|
+
private mcp;
|
|
49
|
+
private memory;
|
|
50
|
+
constructor(cwd?: string);
|
|
51
|
+
execute(tool: ToolCall): Promise<string>;
|
|
52
|
+
private readFile;
|
|
53
|
+
private writeFile;
|
|
54
|
+
private editFile;
|
|
55
|
+
private globFiles;
|
|
56
|
+
private grepFiles;
|
|
57
|
+
private executeBash;
|
|
58
|
+
private webSearch;
|
|
59
|
+
private webFetch;
|
|
60
|
+
private launchTask;
|
|
61
|
+
private handleMemory;
|
|
62
|
+
}
|
|
63
|
+
export declare class AgenticChat {
|
|
64
|
+
private config;
|
|
65
|
+
private llm;
|
|
66
|
+
private executor;
|
|
67
|
+
private conversationHistory;
|
|
68
|
+
private rl;
|
|
69
|
+
constructor(config?: AgenticConfig);
|
|
70
|
+
start(): Promise<void>;
|
|
71
|
+
private showWelcome;
|
|
72
|
+
private buildSystemPrompt;
|
|
73
|
+
private chatLoop;
|
|
74
|
+
private handleCommand;
|
|
75
|
+
private processUserMessage;
|
|
76
|
+
private formatResponse;
|
|
77
|
+
}
|
|
78
|
+
export declare function runAgenticChat(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,748 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Genesis v14.2 - Agentic CLI Interface
|
|
4
|
+
*
|
|
5
|
+
* Provides Claude Code-like capabilities:
|
|
6
|
+
* - File operations (read, write, edit, glob, grep)
|
|
7
|
+
* - Bash command execution
|
|
8
|
+
* - MCP server integration
|
|
9
|
+
* - Web search/fetch
|
|
10
|
+
* - Memory and context
|
|
11
|
+
* - Agent orchestration
|
|
12
|
+
*
|
|
13
|
+
* Usage: genesis agentic [--model <model>] [--cwd <dir>]
|
|
14
|
+
*/
|
|
15
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
18
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
19
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
20
|
+
}
|
|
21
|
+
Object.defineProperty(o, k2, desc);
|
|
22
|
+
}) : (function(o, m, k, k2) {
|
|
23
|
+
if (k2 === undefined) k2 = k;
|
|
24
|
+
o[k2] = m[k];
|
|
25
|
+
}));
|
|
26
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
27
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
28
|
+
}) : function(o, v) {
|
|
29
|
+
o["default"] = v;
|
|
30
|
+
});
|
|
31
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
32
|
+
var ownKeys = function(o) {
|
|
33
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
34
|
+
var ar = [];
|
|
35
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
36
|
+
return ar;
|
|
37
|
+
};
|
|
38
|
+
return ownKeys(o);
|
|
39
|
+
};
|
|
40
|
+
return function (mod) {
|
|
41
|
+
if (mod && mod.__esModule) return mod;
|
|
42
|
+
var result = {};
|
|
43
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
44
|
+
__setModuleDefault(result, mod);
|
|
45
|
+
return result;
|
|
46
|
+
};
|
|
47
|
+
})();
|
|
48
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.AgenticChat = exports.AgenticToolExecutor = void 0;
|
|
50
|
+
exports.runAgenticChat = runAgenticChat;
|
|
51
|
+
const readline = __importStar(require("readline"));
|
|
52
|
+
const fs = __importStar(require("fs"));
|
|
53
|
+
const path = __importStar(require("path"));
|
|
54
|
+
const child_process_1 = require("child_process");
|
|
55
|
+
const index_js_1 = require("../llm/index.js");
|
|
56
|
+
const index_js_2 = require("../mcp/index.js");
|
|
57
|
+
const index_js_3 = require("../memory/index.js");
|
|
58
|
+
const index_js_4 = require("../agents/index.js");
|
|
59
|
+
const ui_js_1 = require("./ui.js");
|
|
60
|
+
// ============================================================================
|
|
61
|
+
// Colors (local to avoid conflict with ui.js)
|
|
62
|
+
// ============================================================================
|
|
63
|
+
const AGENTIC_COLORS = {
|
|
64
|
+
cyan: '\x1b[36m',
|
|
65
|
+
green: '\x1b[32m',
|
|
66
|
+
yellow: '\x1b[33m',
|
|
67
|
+
red: '\x1b[31m',
|
|
68
|
+
reset: '\x1b[0m',
|
|
69
|
+
};
|
|
70
|
+
function colorize(text, color) {
|
|
71
|
+
return `${AGENTIC_COLORS[color]}${text}${AGENTIC_COLORS.reset}`;
|
|
72
|
+
}
|
|
73
|
+
// ============================================================================
|
|
74
|
+
// Tool Definitions (Claude Code-like)
|
|
75
|
+
// ============================================================================
|
|
76
|
+
const AGENTIC_TOOLS = [
|
|
77
|
+
{
|
|
78
|
+
name: 'Read',
|
|
79
|
+
description: 'Read a file from the filesystem. Returns file contents with line numbers.',
|
|
80
|
+
parameters: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
file_path: { type: 'string', description: 'Absolute path to the file to read' },
|
|
84
|
+
offset: { type: 'number', description: 'Line number to start reading from (1-based)' },
|
|
85
|
+
limit: { type: 'number', description: 'Maximum number of lines to read' },
|
|
86
|
+
},
|
|
87
|
+
required: ['file_path'],
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
name: 'Write',
|
|
92
|
+
description: 'Write content to a file, creating it if it does not exist.',
|
|
93
|
+
parameters: {
|
|
94
|
+
type: 'object',
|
|
95
|
+
properties: {
|
|
96
|
+
file_path: { type: 'string', description: 'Absolute path to the file to write' },
|
|
97
|
+
content: { type: 'string', description: 'Content to write to the file' },
|
|
98
|
+
},
|
|
99
|
+
required: ['file_path', 'content'],
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: 'Edit',
|
|
104
|
+
description: 'Edit a file by replacing a specific string with another.',
|
|
105
|
+
parameters: {
|
|
106
|
+
type: 'object',
|
|
107
|
+
properties: {
|
|
108
|
+
file_path: { type: 'string', description: 'Absolute path to the file to edit' },
|
|
109
|
+
old_string: { type: 'string', description: 'Exact string to find and replace' },
|
|
110
|
+
new_string: { type: 'string', description: 'Replacement string' },
|
|
111
|
+
replace_all: { type: 'boolean', description: 'Replace all occurrences (default: false)' },
|
|
112
|
+
},
|
|
113
|
+
required: ['file_path', 'old_string', 'new_string'],
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: 'Glob',
|
|
118
|
+
description: 'Find files matching a glob pattern (e.g., "**/*.ts").',
|
|
119
|
+
parameters: {
|
|
120
|
+
type: 'object',
|
|
121
|
+
properties: {
|
|
122
|
+
pattern: { type: 'string', description: 'Glob pattern to match files' },
|
|
123
|
+
path: { type: 'string', description: 'Directory to search in (default: cwd)' },
|
|
124
|
+
},
|
|
125
|
+
required: ['pattern'],
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
name: 'Grep',
|
|
130
|
+
description: 'Search for a regex pattern in files. Returns matching lines.',
|
|
131
|
+
parameters: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
properties: {
|
|
134
|
+
pattern: { type: 'string', description: 'Regex pattern to search for' },
|
|
135
|
+
path: { type: 'string', description: 'File or directory to search in' },
|
|
136
|
+
glob_pattern: { type: 'string', description: 'Only search files matching this glob (e.g., "*.ts")' },
|
|
137
|
+
context: { type: 'number', description: 'Lines of context before/after match' },
|
|
138
|
+
},
|
|
139
|
+
required: ['pattern'],
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
name: 'Bash',
|
|
144
|
+
description: 'Execute a bash command. Use for git, npm, docker, etc.',
|
|
145
|
+
parameters: {
|
|
146
|
+
type: 'object',
|
|
147
|
+
properties: {
|
|
148
|
+
command: { type: 'string', description: 'The bash command to execute' },
|
|
149
|
+
cwd: { type: 'string', description: 'Working directory for the command' },
|
|
150
|
+
timeout: { type: 'number', description: 'Timeout in milliseconds (default: 120000)' },
|
|
151
|
+
},
|
|
152
|
+
required: ['command'],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'WebSearch',
|
|
157
|
+
description: 'Search the web using configured search providers (Brave, Google, etc.).',
|
|
158
|
+
parameters: {
|
|
159
|
+
type: 'object',
|
|
160
|
+
properties: {
|
|
161
|
+
query: { type: 'string', description: 'Search query' },
|
|
162
|
+
num_results: { type: 'number', description: 'Number of results to return (default: 5)' },
|
|
163
|
+
},
|
|
164
|
+
required: ['query'],
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
name: 'WebFetch',
|
|
169
|
+
description: 'Fetch content from a URL and extract text.',
|
|
170
|
+
parameters: {
|
|
171
|
+
type: 'object',
|
|
172
|
+
properties: {
|
|
173
|
+
url: { type: 'string', description: 'URL to fetch' },
|
|
174
|
+
prompt: { type: 'string', description: 'What to extract from the page' },
|
|
175
|
+
},
|
|
176
|
+
required: ['url', 'prompt'],
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'Task',
|
|
181
|
+
description: 'Launch a sub-agent to handle complex tasks autonomously.',
|
|
182
|
+
parameters: {
|
|
183
|
+
type: 'object',
|
|
184
|
+
properties: {
|
|
185
|
+
prompt: { type: 'string', description: 'Task description for the agent' },
|
|
186
|
+
agent_type: {
|
|
187
|
+
type: 'string',
|
|
188
|
+
description: 'Type of agent to use',
|
|
189
|
+
enum: ['explorer', 'builder', 'critic', 'planner', 'researcher'],
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
required: ['prompt', 'agent_type'],
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
name: 'Memory',
|
|
197
|
+
description: 'Store or retrieve information from long-term memory.',
|
|
198
|
+
parameters: {
|
|
199
|
+
type: 'object',
|
|
200
|
+
properties: {
|
|
201
|
+
action: {
|
|
202
|
+
type: 'string',
|
|
203
|
+
description: 'Action to perform',
|
|
204
|
+
enum: ['store', 'search', 'list'],
|
|
205
|
+
},
|
|
206
|
+
content: { type: 'string', description: 'Content to store (for store action)' },
|
|
207
|
+
query: { type: 'string', description: 'Query to search (for search action)' },
|
|
208
|
+
tags: { type: 'string', description: 'Comma-separated tags' },
|
|
209
|
+
},
|
|
210
|
+
required: ['action'],
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
];
|
|
214
|
+
// ============================================================================
|
|
215
|
+
// Simple Glob Implementation (no external dependency)
|
|
216
|
+
// ============================================================================
|
|
217
|
+
function simpleGlob(pattern, cwd) {
|
|
218
|
+
const results = [];
|
|
219
|
+
function walk(dir, prefix = '') {
|
|
220
|
+
try {
|
|
221
|
+
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
222
|
+
for (const entry of entries) {
|
|
223
|
+
const fullPath = path.join(dir, entry.name);
|
|
224
|
+
const relativePath = path.join(prefix, entry.name);
|
|
225
|
+
// Skip node_modules, .git, dist
|
|
226
|
+
if (entry.isDirectory() && ['node_modules', '.git', 'dist'].includes(entry.name)) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (entry.isDirectory()) {
|
|
230
|
+
walk(fullPath, relativePath);
|
|
231
|
+
}
|
|
232
|
+
else {
|
|
233
|
+
// Simple pattern matching
|
|
234
|
+
if (matchesPattern(relativePath, pattern)) {
|
|
235
|
+
results.push(relativePath);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
catch {
|
|
241
|
+
// Ignore permission errors
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
function matchesPattern(filePath, pat) {
|
|
245
|
+
// Convert glob to regex
|
|
246
|
+
const regexPat = pat
|
|
247
|
+
.replace(/\*\*/g, '<<<DOUBLESTAR>>>')
|
|
248
|
+
.replace(/\*/g, '[^/]*')
|
|
249
|
+
.replace(/<<<DOUBLESTAR>>>/g, '.*')
|
|
250
|
+
.replace(/\?/g, '.')
|
|
251
|
+
.replace(/\./g, '\\.');
|
|
252
|
+
return new RegExp(`^${regexPat}$`).test(filePath);
|
|
253
|
+
}
|
|
254
|
+
walk(cwd);
|
|
255
|
+
return results.sort();
|
|
256
|
+
}
|
|
257
|
+
// ============================================================================
|
|
258
|
+
// Tool Executor
|
|
259
|
+
// ============================================================================
|
|
260
|
+
class AgenticToolExecutor {
|
|
261
|
+
cwd;
|
|
262
|
+
mcp = (0, index_js_2.getMCPClient)();
|
|
263
|
+
memory = (0, index_js_3.getMemorySystem)();
|
|
264
|
+
constructor(cwd = process.cwd()) {
|
|
265
|
+
this.cwd = cwd;
|
|
266
|
+
}
|
|
267
|
+
async execute(tool) {
|
|
268
|
+
const { name, arguments: args } = tool;
|
|
269
|
+
try {
|
|
270
|
+
switch (name) {
|
|
271
|
+
case 'Read':
|
|
272
|
+
return await this.readFile(args);
|
|
273
|
+
case 'Write':
|
|
274
|
+
return await this.writeFile(args);
|
|
275
|
+
case 'Edit':
|
|
276
|
+
return await this.editFile(args);
|
|
277
|
+
case 'Glob':
|
|
278
|
+
return await this.globFiles(args);
|
|
279
|
+
case 'Grep':
|
|
280
|
+
return await this.grepFiles(args);
|
|
281
|
+
case 'Bash':
|
|
282
|
+
return await this.executeBash(args);
|
|
283
|
+
case 'WebSearch':
|
|
284
|
+
return await this.webSearch(args);
|
|
285
|
+
case 'WebFetch':
|
|
286
|
+
return await this.webFetch(args);
|
|
287
|
+
case 'Task':
|
|
288
|
+
return await this.launchTask(args);
|
|
289
|
+
case 'Memory':
|
|
290
|
+
return await this.handleMemory(args);
|
|
291
|
+
default:
|
|
292
|
+
return `Unknown tool: ${name}`;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
catch (err) {
|
|
296
|
+
return `Error executing ${name}: ${err instanceof Error ? err.message : String(err)}`;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
// Read file with line numbers
|
|
300
|
+
async readFile(args) {
|
|
301
|
+
const filePath = path.isAbsolute(args.file_path) ? args.file_path : path.join(this.cwd, args.file_path);
|
|
302
|
+
if (!fs.existsSync(filePath)) {
|
|
303
|
+
return `File not found: ${filePath}`;
|
|
304
|
+
}
|
|
305
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
306
|
+
const lines = content.split('\n');
|
|
307
|
+
const offset = args.offset || 1;
|
|
308
|
+
const limit = args.limit || lines.length;
|
|
309
|
+
const startIdx = Math.max(0, offset - 1);
|
|
310
|
+
const endIdx = Math.min(lines.length, startIdx + limit);
|
|
311
|
+
const result = lines.slice(startIdx, endIdx).map((line, i) => {
|
|
312
|
+
const lineNum = startIdx + i + 1;
|
|
313
|
+
const padding = String(endIdx).length;
|
|
314
|
+
return `${String(lineNum).padStart(padding)}→${line}`;
|
|
315
|
+
}).join('\n');
|
|
316
|
+
return result || '(empty file)';
|
|
317
|
+
}
|
|
318
|
+
// Write file
|
|
319
|
+
async writeFile(args) {
|
|
320
|
+
const filePath = path.isAbsolute(args.file_path) ? args.file_path : path.join(this.cwd, args.file_path);
|
|
321
|
+
// Ensure directory exists
|
|
322
|
+
const dir = path.dirname(filePath);
|
|
323
|
+
if (!fs.existsSync(dir)) {
|
|
324
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
325
|
+
}
|
|
326
|
+
fs.writeFileSync(filePath, args.content, 'utf-8');
|
|
327
|
+
return `Successfully wrote ${args.content.length} bytes to ${filePath}`;
|
|
328
|
+
}
|
|
329
|
+
// Edit file with string replacement
|
|
330
|
+
async editFile(args) {
|
|
331
|
+
const filePath = path.isAbsolute(args.file_path) ? args.file_path : path.join(this.cwd, args.file_path);
|
|
332
|
+
if (!fs.existsSync(filePath)) {
|
|
333
|
+
return `File not found: ${filePath}`;
|
|
334
|
+
}
|
|
335
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
336
|
+
if (!content.includes(args.old_string)) {
|
|
337
|
+
return `String not found in file: "${args.old_string.slice(0, 50)}..."`;
|
|
338
|
+
}
|
|
339
|
+
const count = (content.match(new RegExp(args.old_string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g')) || []).length;
|
|
340
|
+
let newContent;
|
|
341
|
+
if (args.replace_all) {
|
|
342
|
+
newContent = content.split(args.old_string).join(args.new_string);
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
newContent = content.replace(args.old_string, args.new_string);
|
|
346
|
+
}
|
|
347
|
+
fs.writeFileSync(filePath, newContent, 'utf-8');
|
|
348
|
+
return args.replace_all
|
|
349
|
+
? `Replaced ${count} occurrences in ${filePath}`
|
|
350
|
+
: `Replaced 1 occurrence in ${filePath}`;
|
|
351
|
+
}
|
|
352
|
+
// Glob file matching
|
|
353
|
+
async globFiles(args) {
|
|
354
|
+
const searchPath = args.path ? (path.isAbsolute(args.path) ? args.path : path.join(this.cwd, args.path)) : this.cwd;
|
|
355
|
+
const files = simpleGlob(args.pattern, searchPath);
|
|
356
|
+
if (files.length === 0) {
|
|
357
|
+
return 'No files found matching pattern';
|
|
358
|
+
}
|
|
359
|
+
return files.slice(0, 100).join('\n') + (files.length > 100 ? `\n... and ${files.length - 100} more` : '');
|
|
360
|
+
}
|
|
361
|
+
// Grep search
|
|
362
|
+
async grepFiles(args) {
|
|
363
|
+
const searchPath = args.path || this.cwd;
|
|
364
|
+
const context = args.context || 0;
|
|
365
|
+
// Use ripgrep if available, fallback to grep
|
|
366
|
+
const cmd = args.glob_pattern
|
|
367
|
+
? `rg -n ${context > 0 ? `-C ${context}` : ''} --glob "${args.glob_pattern}" "${args.pattern}" "${searchPath}" 2>/dev/null || grep -rn ${context > 0 ? `-C ${context}` : ''} --include="${args.glob_pattern}" "${args.pattern}" "${searchPath}" 2>/dev/null`
|
|
368
|
+
: `rg -n ${context > 0 ? `-C ${context}` : ''} "${args.pattern}" "${searchPath}" 2>/dev/null || grep -rn ${context > 0 ? `-C ${context}` : ''} "${args.pattern}" "${searchPath}" 2>/dev/null`;
|
|
369
|
+
try {
|
|
370
|
+
const result = (0, child_process_1.execSync)(cmd, { encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 }).trim();
|
|
371
|
+
const lines = result.split('\n');
|
|
372
|
+
return lines.slice(0, 200).join('\n') + (lines.length > 200 ? `\n... and ${lines.length - 200} more matches` : '');
|
|
373
|
+
}
|
|
374
|
+
catch {
|
|
375
|
+
return 'No matches found';
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
// Bash command execution
|
|
379
|
+
async executeBash(args) {
|
|
380
|
+
const cwd = args.cwd || this.cwd;
|
|
381
|
+
const timeout = args.timeout || 120000;
|
|
382
|
+
return new Promise((resolve) => {
|
|
383
|
+
const proc = (0, child_process_1.spawn)('bash', ['-c', args.command], {
|
|
384
|
+
cwd,
|
|
385
|
+
timeout,
|
|
386
|
+
env: { ...process.env },
|
|
387
|
+
});
|
|
388
|
+
let stdout = '';
|
|
389
|
+
let stderr = '';
|
|
390
|
+
proc.stdout.on('data', (data) => { stdout += data.toString(); });
|
|
391
|
+
proc.stderr.on('data', (data) => { stderr += data.toString(); });
|
|
392
|
+
proc.on('close', (code) => {
|
|
393
|
+
if (code === 0) {
|
|
394
|
+
resolve(stdout.trim() || '(no output)');
|
|
395
|
+
}
|
|
396
|
+
else {
|
|
397
|
+
resolve(`Exit code ${code}\n${stderr || stdout}`);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
proc.on('error', (err) => {
|
|
401
|
+
resolve(`Error: ${err.message}`);
|
|
402
|
+
});
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
// Web search via MCP
|
|
406
|
+
async webSearch(args) {
|
|
407
|
+
try {
|
|
408
|
+
// Try Brave search first, then Gemini, then Exa
|
|
409
|
+
const providers = ['brave-search.brave_web_search', 'gemini.web_search', 'exa.web_search_exa'];
|
|
410
|
+
for (const provider of providers) {
|
|
411
|
+
const [server, tool] = provider.split('.');
|
|
412
|
+
try {
|
|
413
|
+
const result = await this.mcp.call(server, tool, {
|
|
414
|
+
query: args.query,
|
|
415
|
+
count: args.num_results || 5,
|
|
416
|
+
});
|
|
417
|
+
if (result.success && result.data) {
|
|
418
|
+
return typeof result.data === 'string' ? result.data : JSON.stringify(result.data, null, 2);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
catch {
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
return 'Web search not available - no search MCP servers configured';
|
|
426
|
+
}
|
|
427
|
+
catch (err) {
|
|
428
|
+
return `Web search error: ${err instanceof Error ? err.message : String(err)}`;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
// Web fetch via MCP (firecrawl)
|
|
432
|
+
async webFetch(args) {
|
|
433
|
+
try {
|
|
434
|
+
const result = await this.mcp.call('firecrawl', 'firecrawl_scrape', {
|
|
435
|
+
url: args.url,
|
|
436
|
+
formats: ['markdown'],
|
|
437
|
+
});
|
|
438
|
+
if (result.success && result.data) {
|
|
439
|
+
const content = typeof result.data === 'string' ? result.data : JSON.stringify(result.data);
|
|
440
|
+
return content.slice(0, 10000) + (content.length > 10000 ? '\n... (truncated)' : '');
|
|
441
|
+
}
|
|
442
|
+
return 'Failed to fetch URL';
|
|
443
|
+
}
|
|
444
|
+
catch (err) {
|
|
445
|
+
return `Fetch error: ${err instanceof Error ? err.message : String(err)}`;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// Launch sub-agent task
|
|
449
|
+
async launchTask(args) {
|
|
450
|
+
const coordinator = (0, index_js_4.getCoordinator)();
|
|
451
|
+
try {
|
|
452
|
+
const task = await coordinator.coordinate({
|
|
453
|
+
query: args.prompt,
|
|
454
|
+
agents: [args.agent_type],
|
|
455
|
+
pattern: 'sequential',
|
|
456
|
+
});
|
|
457
|
+
if (task.finalResult) {
|
|
458
|
+
return typeof task.finalResult === 'string' ? task.finalResult : JSON.stringify(task.finalResult, null, 2);
|
|
459
|
+
}
|
|
460
|
+
return `Task completed with status: ${task.status}`;
|
|
461
|
+
}
|
|
462
|
+
catch (err) {
|
|
463
|
+
return `Task error: ${err instanceof Error ? err.message : String(err)}`;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
// Memory operations
|
|
467
|
+
async handleMemory(args) {
|
|
468
|
+
const memory = this.memory;
|
|
469
|
+
switch (args.action) {
|
|
470
|
+
case 'store':
|
|
471
|
+
if (!args.content)
|
|
472
|
+
return 'Missing content to store';
|
|
473
|
+
// Use remember for simple episodic storage
|
|
474
|
+
memory.remember({
|
|
475
|
+
what: args.content,
|
|
476
|
+
tags: args.tags?.split(',').map(t => t.trim()) || [],
|
|
477
|
+
});
|
|
478
|
+
return 'Stored in memory';
|
|
479
|
+
case 'search':
|
|
480
|
+
if (!args.query)
|
|
481
|
+
return 'Missing search query';
|
|
482
|
+
const results = await memory.recall(args.query, { limit: 5 });
|
|
483
|
+
if (!results || results.length === 0) {
|
|
484
|
+
return 'No memories found';
|
|
485
|
+
}
|
|
486
|
+
return results.map((r, i) => {
|
|
487
|
+
const text = typeof r === 'string' ? r : (r.content || r.text || JSON.stringify(r));
|
|
488
|
+
return `${i + 1}. ${text.slice(0, 200)}...`;
|
|
489
|
+
}).join('\n\n');
|
|
490
|
+
case 'list':
|
|
491
|
+
const stats = memory.getStats();
|
|
492
|
+
return `Memory stats: ${JSON.stringify(stats, null, 2)}`;
|
|
493
|
+
default:
|
|
494
|
+
return `Unknown memory action: ${args.action}`;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
exports.AgenticToolExecutor = AgenticToolExecutor;
|
|
499
|
+
// ============================================================================
|
|
500
|
+
// Agentic Chat Loop
|
|
501
|
+
// ============================================================================
|
|
502
|
+
class AgenticChat {
|
|
503
|
+
config;
|
|
504
|
+
llm;
|
|
505
|
+
executor;
|
|
506
|
+
conversationHistory = [];
|
|
507
|
+
rl = null;
|
|
508
|
+
constructor(config = {}) {
|
|
509
|
+
this.config = {
|
|
510
|
+
cwd: process.cwd(),
|
|
511
|
+
model: 'claude-sonnet-4-20250514',
|
|
512
|
+
maxTokens: 8192,
|
|
513
|
+
temperature: 0.7,
|
|
514
|
+
...config,
|
|
515
|
+
};
|
|
516
|
+
this.llm = (0, index_js_1.getLLMBridge)();
|
|
517
|
+
this.executor = new AgenticToolExecutor(this.config.cwd);
|
|
518
|
+
}
|
|
519
|
+
async start() {
|
|
520
|
+
this.showWelcome();
|
|
521
|
+
this.rl = readline.createInterface({
|
|
522
|
+
input: process.stdin,
|
|
523
|
+
output: process.stdout,
|
|
524
|
+
});
|
|
525
|
+
console.log((0, ui_js_1.muted)(`Working directory: ${this.config.cwd}`));
|
|
526
|
+
console.log((0, ui_js_1.muted)(`Model: ${this.config.model}`));
|
|
527
|
+
console.log((0, ui_js_1.muted)('Type /help for commands, /quit to exit\n'));
|
|
528
|
+
await this.chatLoop();
|
|
529
|
+
}
|
|
530
|
+
showWelcome() {
|
|
531
|
+
console.log('\n' + (0, ui_js_1.box)(`${colorize('Genesis Agentic Interface', 'cyan')}
|
|
532
|
+
|
|
533
|
+
${(0, ui_js_1.muted)('Claude Code-like capabilities:')}
|
|
534
|
+
${colorize('•', 'green')} Read/Write/Edit files
|
|
535
|
+
${colorize('•', 'green')} Bash command execution
|
|
536
|
+
${colorize('•', 'green')} Web search and fetch
|
|
537
|
+
${colorize('•', 'green')} Agent task delegation
|
|
538
|
+
${colorize('•', 'green')} Persistent memory`, { padding: 1 }));
|
|
539
|
+
}
|
|
540
|
+
buildSystemPrompt() {
|
|
541
|
+
return `You are Genesis, an autonomous AI agent with full agentic capabilities.
|
|
542
|
+
|
|
543
|
+
You have access to these tools:
|
|
544
|
+
${AGENTIC_TOOLS.map(t => `- ${t.name}: ${t.description}`).join('\n')}
|
|
545
|
+
|
|
546
|
+
Current working directory: ${this.config.cwd}
|
|
547
|
+
Current date: ${new Date().toISOString().split('T')[0]}
|
|
548
|
+
|
|
549
|
+
Guidelines:
|
|
550
|
+
1. Use tools proactively to accomplish tasks
|
|
551
|
+
2. Read files before editing them
|
|
552
|
+
3. Use Glob/Grep to explore codebases
|
|
553
|
+
4. Execute bash commands for git, npm, etc.
|
|
554
|
+
5. Break complex tasks into steps
|
|
555
|
+
6. Store important information in memory
|
|
556
|
+
|
|
557
|
+
When you need to use a tool, respond with a JSON tool call in this format:
|
|
558
|
+
\`\`\`tool
|
|
559
|
+
{"name": "ToolName", "arguments": {...}}
|
|
560
|
+
\`\`\`
|
|
561
|
+
|
|
562
|
+
You can make multiple tool calls in sequence. After each tool result, continue your work.`;
|
|
563
|
+
}
|
|
564
|
+
async chatLoop() {
|
|
565
|
+
return new Promise((resolve) => {
|
|
566
|
+
const askQuestion = () => {
|
|
567
|
+
if (!this.rl) {
|
|
568
|
+
resolve();
|
|
569
|
+
return;
|
|
570
|
+
}
|
|
571
|
+
this.rl.question(colorize('\n❯ ', 'cyan'), async (input) => {
|
|
572
|
+
if (!input.trim()) {
|
|
573
|
+
askQuestion();
|
|
574
|
+
return;
|
|
575
|
+
}
|
|
576
|
+
// Handle commands
|
|
577
|
+
if (input.startsWith('/')) {
|
|
578
|
+
const handled = await this.handleCommand(input);
|
|
579
|
+
if (handled === 'quit') {
|
|
580
|
+
resolve();
|
|
581
|
+
return;
|
|
582
|
+
}
|
|
583
|
+
askQuestion();
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
// Process user message
|
|
587
|
+
await this.processUserMessage(input);
|
|
588
|
+
askQuestion();
|
|
589
|
+
});
|
|
590
|
+
};
|
|
591
|
+
// Handle readline close event (e.g., Ctrl+D)
|
|
592
|
+
this.rl.on('close', () => {
|
|
593
|
+
console.log((0, ui_js_1.muted)('\nGoodbye!'));
|
|
594
|
+
resolve();
|
|
595
|
+
});
|
|
596
|
+
askQuestion();
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
async handleCommand(input) {
|
|
600
|
+
const [cmd, ...args] = input.slice(1).split(' ');
|
|
601
|
+
switch (cmd) {
|
|
602
|
+
case 'quit':
|
|
603
|
+
case 'exit':
|
|
604
|
+
case 'q':
|
|
605
|
+
console.log((0, ui_js_1.muted)('\nGoodbye!'));
|
|
606
|
+
this.rl?.close();
|
|
607
|
+
return 'quit';
|
|
608
|
+
case 'help':
|
|
609
|
+
console.log(`
|
|
610
|
+
${colorize('Commands:', 'cyan')}
|
|
611
|
+
/help - Show this help
|
|
612
|
+
/clear - Clear conversation
|
|
613
|
+
/tools - List available tools
|
|
614
|
+
/memory - Show memory stats
|
|
615
|
+
/cwd - Change working directory
|
|
616
|
+
/quit - Exit
|
|
617
|
+
`);
|
|
618
|
+
break;
|
|
619
|
+
case 'clear':
|
|
620
|
+
this.conversationHistory = [];
|
|
621
|
+
console.log((0, ui_js_1.success)('Conversation cleared'));
|
|
622
|
+
break;
|
|
623
|
+
case 'tools':
|
|
624
|
+
console.log(`\n${colorize('Available Tools:', 'cyan')}\n`);
|
|
625
|
+
AGENTIC_TOOLS.forEach(t => {
|
|
626
|
+
console.log(` ${colorize(t.name, 'green')}: ${(0, ui_js_1.muted)(t.description)}`);
|
|
627
|
+
});
|
|
628
|
+
break;
|
|
629
|
+
case 'memory':
|
|
630
|
+
const result = await this.executor.execute({
|
|
631
|
+
id: 'cmd',
|
|
632
|
+
name: 'Memory',
|
|
633
|
+
arguments: { action: 'list' },
|
|
634
|
+
});
|
|
635
|
+
console.log(result);
|
|
636
|
+
break;
|
|
637
|
+
case 'cwd':
|
|
638
|
+
if (args[0]) {
|
|
639
|
+
const newCwd = path.resolve(this.config.cwd, args[0]);
|
|
640
|
+
if (fs.existsSync(newCwd)) {
|
|
641
|
+
this.config.cwd = newCwd;
|
|
642
|
+
this.executor = new AgenticToolExecutor(newCwd);
|
|
643
|
+
console.log((0, ui_js_1.success)(`Working directory: ${newCwd}`));
|
|
644
|
+
}
|
|
645
|
+
else {
|
|
646
|
+
console.log((0, ui_js_1.error)(`Directory not found: ${newCwd}`));
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
console.log((0, ui_js_1.info)(`Current: ${this.config.cwd}`));
|
|
651
|
+
}
|
|
652
|
+
break;
|
|
653
|
+
default:
|
|
654
|
+
console.log((0, ui_js_1.warning)(`Unknown command: ${cmd}`));
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
async processUserMessage(input) {
|
|
658
|
+
// Build full context
|
|
659
|
+
const systemPrompt = this.buildSystemPrompt();
|
|
660
|
+
const contextMessages = this.conversationHistory.join('\n\n');
|
|
661
|
+
const fullPrompt = contextMessages ? `${contextMessages}\n\nUser: ${input}` : input;
|
|
662
|
+
this.conversationHistory.push(`User: ${input}`);
|
|
663
|
+
const spinner = new ui_js_1.Spinner('Thinking...');
|
|
664
|
+
spinner.start();
|
|
665
|
+
try {
|
|
666
|
+
let continueLoop = true;
|
|
667
|
+
let iterations = 0;
|
|
668
|
+
const maxIterations = 20;
|
|
669
|
+
let currentPrompt = fullPrompt;
|
|
670
|
+
while (continueLoop && iterations < maxIterations) {
|
|
671
|
+
iterations++;
|
|
672
|
+
// Call LLM using chat method
|
|
673
|
+
const response = await this.llm.chat(currentPrompt, systemPrompt);
|
|
674
|
+
spinner.stop();
|
|
675
|
+
const content = response.content || '';
|
|
676
|
+
// Check for tool calls
|
|
677
|
+
const toolMatch = content.match(/```tool\s*\n([\s\S]*?)\n```/);
|
|
678
|
+
if (toolMatch) {
|
|
679
|
+
try {
|
|
680
|
+
const toolCall = JSON.parse(toolMatch[1]);
|
|
681
|
+
console.log((0, ui_js_1.muted)(`\n ⚙ ${toolCall.name}...`));
|
|
682
|
+
const result = await this.executor.execute({
|
|
683
|
+
id: `tool-${Date.now()}`,
|
|
684
|
+
name: toolCall.name,
|
|
685
|
+
arguments: toolCall.arguments,
|
|
686
|
+
});
|
|
687
|
+
// Show tool result
|
|
688
|
+
const resultPreview = result.length > 500 ? result.slice(0, 500) + '...' : result;
|
|
689
|
+
console.log((0, ui_js_1.muted)(` ✓ ${resultPreview.split('\n')[0]}`));
|
|
690
|
+
// Add to conversation history
|
|
691
|
+
this.conversationHistory.push(`Assistant: ${content}`);
|
|
692
|
+
this.conversationHistory.push(`Tool (${toolCall.name}): ${result}`);
|
|
693
|
+
// Continue with tool result
|
|
694
|
+
currentPrompt = `Tool result for ${toolCall.name}:\n\`\`\`\n${result}\n\`\`\`\n\nContinue with your task.`;
|
|
695
|
+
spinner.start();
|
|
696
|
+
}
|
|
697
|
+
catch {
|
|
698
|
+
// Not a valid tool call, treat as regular response
|
|
699
|
+
this.conversationHistory.push(`Assistant: ${content}`);
|
|
700
|
+
console.log('\n' + this.formatResponse(content));
|
|
701
|
+
continueLoop = false;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
else {
|
|
705
|
+
// Regular response without tool call
|
|
706
|
+
this.conversationHistory.push(`Assistant: ${content}`);
|
|
707
|
+
console.log('\n' + this.formatResponse(content));
|
|
708
|
+
continueLoop = false;
|
|
709
|
+
}
|
|
710
|
+
}
|
|
711
|
+
if (iterations >= maxIterations) {
|
|
712
|
+
console.log((0, ui_js_1.warning)('\n(Reached maximum iterations)'));
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
catch (err) {
|
|
716
|
+
spinner.stop();
|
|
717
|
+
console.log((0, ui_js_1.error)(`\nError: ${err instanceof Error ? err.message : String(err)}`));
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
formatResponse(content) {
|
|
721
|
+
// Remove tool blocks from display
|
|
722
|
+
return content.replace(/```tool\s*\n[\s\S]*?\n```/g, '').trim();
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
exports.AgenticChat = AgenticChat;
|
|
726
|
+
// ============================================================================
|
|
727
|
+
// CLI Entry Point
|
|
728
|
+
// ============================================================================
|
|
729
|
+
async function runAgenticChat(args) {
|
|
730
|
+
const config = {
|
|
731
|
+
cwd: process.cwd(),
|
|
732
|
+
model: 'claude-sonnet-4-20250514',
|
|
733
|
+
};
|
|
734
|
+
// Parse args
|
|
735
|
+
for (let i = 0; i < args.length; i++) {
|
|
736
|
+
if (args[i] === '--model' && args[i + 1]) {
|
|
737
|
+
config.model = args[++i];
|
|
738
|
+
}
|
|
739
|
+
else if (args[i] === '--cwd' && args[i + 1]) {
|
|
740
|
+
config.cwd = path.resolve(args[++i]);
|
|
741
|
+
}
|
|
742
|
+
else if (args[i] === '--verbose') {
|
|
743
|
+
config.verbose = true;
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
const chat = new AgenticChat(config);
|
|
747
|
+
await chat.start();
|
|
748
|
+
}
|
package/dist/src/index.js
CHANGED
|
@@ -72,6 +72,7 @@ for (const file of envFiles) {
|
|
|
72
72
|
}
|
|
73
73
|
const orchestrator_js_1 = require("./orchestrator.js");
|
|
74
74
|
const chat_js_1 = require("./cli/chat.js");
|
|
75
|
+
const agentic_js_1 = require("./cli/agentic.js");
|
|
75
76
|
const index_js_1 = require("./llm/index.js");
|
|
76
77
|
const index_js_2 = require("./mcp/index.js");
|
|
77
78
|
const process_js_1 = require("./daemon/process.js");
|
|
@@ -1783,6 +1784,23 @@ async function cmdAgents(subcommand, options) {
|
|
|
1783
1784
|
console.log(c('Unknown agents subcommand. Use: status, parallel, coordinate, pipeline', 'red'));
|
|
1784
1785
|
}
|
|
1785
1786
|
// ============================================================================
|
|
1787
|
+
// Agentic Command (v14.2: Claude Code-like Interface)
|
|
1788
|
+
// ============================================================================
|
|
1789
|
+
async function cmdAgentic(subcommand, options) {
|
|
1790
|
+
const args = [];
|
|
1791
|
+
// Pass through options
|
|
1792
|
+
if (options.model) {
|
|
1793
|
+
args.push('--model', options.model);
|
|
1794
|
+
}
|
|
1795
|
+
if (options.cwd) {
|
|
1796
|
+
args.push('--cwd', options.cwd);
|
|
1797
|
+
}
|
|
1798
|
+
if (options.verbose) {
|
|
1799
|
+
args.push('--verbose');
|
|
1800
|
+
}
|
|
1801
|
+
await (0, agentic_js_1.runAgenticChat)(args);
|
|
1802
|
+
}
|
|
1803
|
+
// ============================================================================
|
|
1786
1804
|
// Install Command (v10.1: Self-Installation)
|
|
1787
1805
|
// ============================================================================
|
|
1788
1806
|
async function cmdInstall(options) {
|
|
@@ -1993,6 +2011,11 @@ async function main() {
|
|
|
1993
2011
|
case 'agents':
|
|
1994
2012
|
await cmdAgents(positional, options);
|
|
1995
2013
|
break;
|
|
2014
|
+
case 'agentic':
|
|
2015
|
+
case 'agent':
|
|
2016
|
+
// v14.2: Agentic chat interface with Claude Code-like capabilities
|
|
2017
|
+
await cmdAgentic(positional, options);
|
|
2018
|
+
break;
|
|
1996
2019
|
default:
|
|
1997
2020
|
console.error(c(`Unknown command: ${command}`, 'red'));
|
|
1998
2021
|
console.log('Use "genesis help" for usage information');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "genesis-ai-cli",
|
|
3
|
-
"version": "14.
|
|
3
|
+
"version": "14.3.0",
|
|
4
4
|
"description": "Fully Autonomous AI System with RSI (Recursive Self-Improvement) - Self-funding, Self-deploying, Production Memory, A2A Protocol & Governance",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|