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.
@@ -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.2.0",
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",