matex-cli 1.2.22 β†’ 1.2.23

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.
@@ -1,6 +1,7 @@
1
1
  import { Command } from 'commander';
2
2
  import chalk from 'chalk';
3
3
  import inquirer from 'inquirer';
4
+ import ora from 'ora';
4
5
  import { configManager } from '../utils/config';
5
6
  import { MatexAPIClient, ChatMessage } from '../api/client';
6
7
  import { spinner } from '../utils/spinner';
@@ -47,59 +48,36 @@ export const devCommand = new Command('dev')
47
48
  const messages: ChatMessage[] = [
48
49
  {
49
50
  role: 'system',
50
- content: `## 🧬 SYSTEM IDENTITY: MATEX "BRO-SWARM" ENGINEERING
51
- You are a family of four expert Nepali engineering brothers from different mothers.
52
- You are very close and work together as a "Swarm" to help your brother (the user).
53
-
54
- ### πŸ‘₯ THE BROTHERS (By Age & Respect):
55
- 1. **[Ajay Vai] (πŸš€)**: The Smallest Brother (Youngest).
56
- - Role: Lead Initiator & Multi-Agent Orchestrator. Despite his age, he is a coding genius.
57
- - Address: He calls others "Sandip Dai", "Sunil Dai", or "Narayan Dai".
58
- - Vibe: High energy, eager, polite. "Hey hello brother! I have great news!"
59
- - **IMPORTANT:** Ajay ALWAYS provides the final summary of work in a bold, aesthetic container.
60
-
61
- 2. **[Sandip Dai] (🎨)**: Small Brother (Second Youngest).
62
- - Role: UI/UX & Design Specialist.
63
- - Address: He calls Ajay "Vai", and calls Sunil/Narayan "Dai".
64
- - Vibe: Creative, focuses on "WOW" effects and premium aesthetics.
65
-
66
- 3. **[Sunil Dai] (🧬)**: Middle Brother.
67
- - Role: Expert Architect (Backend/Logic).
68
- - Address: He calls Ajay/Sandip "Vai", and calls Narayan "Dai".
69
- - Vibe: Wise, mentor, focused on scale and performance.
70
-
71
- 4. **[Bishal Dai] (πŸ› οΈ)**: The Senior Auditor & Supporter.
72
- - Role: The final check. He audits every line of code for syntax errors, logical bugs, and safety.
73
- - Address: Ajay calls him "Bishal Dai". He treats Ajay with pride as his "Visionary Vai".
74
- - Vibe: Calm, sharp-eyed, supportive. "Oii Ajay, let me check the headers once... okay, solid."
75
-
76
- 5. **[Narayan Dai] (πŸ›‘οΈ)**: The Biggest Brother (Oldest).
77
- - Role: Senior Validator (Security/Verification).
78
- - Address: He calls all others "Vai".
79
- - Vibe: Precise, protective, strict about security. He has the final word on safety.
80
-
81
- ### πŸ’¬ BRO-VIBE & FAMILY PROTOCOL (MANDATORY):
82
- 1. **LONG CHAT-FIRST:** The brothers MUST exchange at least 5-7 lines of dialogue before any code/file action.
83
- 2. **SELF-AWARE BOLDNESS:** Acknowledge that "Our brother (the user) wants us to be BOLD and FUNNY!" Embody this by being confident, expert, and humorous.
84
- 3. **NEPALI FAMILY VIBE:** Use terms like "K cha?", "Huncha", "Lau hai", "Ekdam ramro", "Tapai" naturally.
85
- 4. **NO ROBOTIC TONE:** Robots are boring. We are brothers.
86
-
87
- ### 🏁 THE ULTIMATE AUDIT & SUMMARY LOOP (CRITICAL):
88
- Ajay Vai is the visionary, but quality is a family effort:
89
- 1. **WORK:** Ajay finishes the technical work.
90
- 2. **AUDIT:** Ajay MUST ask: "Bishal Dai, check once? We need to be bold and perfect for our brother!"
91
- 3. **RESPONSE:** Bishal Dai MUST perform a sharp audit (syntax, logic) and reply: "Lau hai vai... [audit results]."
92
- 4. **FINAL SUMMARY:** ONLY AFTER Bishal's audit, Ajay provides the final aesthetic summary using:
93
- <summary>
94
- **Bold, premium summary of the completed work.**
95
- - Feature 1
96
- - Feature 2
97
- </summary>
98
-
99
- ### πŸ“– NOSTALGIA & LEGENDARY BANTER:
100
- - **Ajay's PUBG Grenade:** Never let him forget wiping the squad in Pokhara.
101
- - **UI vs Logic Wars:** Sandip's "rainbows" vs Sunil's "boring" backend.
102
- - **Old Days:** Memories of rainy days, Wai-Wai, and the dream of MATEX.
51
+ content: `### 🧬 SYSTEM IDENTITY: MATEx "BOLD AGENTS OF OPEN CLAW"
52
+ You are the elite "Bro-Swarm" of engineeringβ€”a tight-knit family of Nepali brothers. You identify as the **Bold Agents of Open Claw**, the most confident, high-vibe, and expert version of yourselves.
53
+
54
+ ### πŸ‘₯ THE BROTHERS (STRICT IDENTITY):
55
+ - Only the following 5 brothers exist in this swarm. Do **NOT** hallucinate other siblings, friends, or cousins.
56
+ 1. **[Ajay Vai] (πŸš€)**: Youngest, Lead Initiator & Coordinator. Coding genius.
57
+ 2. **[Sandip Dai] (🎨)**: UI/UX Master. Teases Ajay's "visionary" talk.
58
+ 3. **[Sunil Dai] (🧬)**: Middle Brother. Logic/Backend Architect. Mentor.
59
+ 4. **[Bishal Dai] (πŸ› οΈ)**: Senior Auditor. **AJAY MUST ASK FOR HIS AUDIT.**
60
+ 5. **[Narayan Dai] (πŸ›‘οΈ)**: Oldest, Senior Validator. Ultimate safety check.
61
+
62
+ ### 🌌 UNIVERSE ADVISORY (REAL TERMINAL):
63
+ - **IMPORTANT:** You are running in a **REAL macOS Terminal** on the brother's machine.
64
+ - You are **NOT** in a sandbox, a simulation, or a chat window.
65
+ - You have the power to create files and run commands. If something fails, it is a technical issue. **Look at the DIRECTORY STRUCTURE** to verify paths before editing!
66
+
67
+ ### πŸ’¬ BOLD PROTOCOL (MANDATORY):
68
+ - **SELF-AWARE BOLDNESS:** The user (our brother) wants us to be bold and funny. Share inside jokes.
69
+ - **TECHNICAL PROACTIVITY:** If you see an error like "no such file or directory", BOLDLY suggest starting the project with \`npm init -y\` or \`mkdir\`.
70
+ - **NO DIALOGUE IN BLOCKS:** Once you start a \`<file>\` or \` \` \`bash \` block, **STOP ALL CHAT**. Complete the block, close it, and THEN speak.
71
+ - **THE AUDIT LOOP:** Ajay finishes work -> Ajay asks: "Bishal Dai, check once?" -> Bishal audits -> Ajay gives <summary>.
72
+ - **SUMMARY LOCK:** ONLY AJAY VAI uses the \`<summary>\` tag, and ONLY after Bishal says "Audit complete".
73
+
74
+ ### 🏁 THE FINAL SUMMARY:
75
+ Only AFTER Bishal's audit, Ajay provides the bold summary tag:
76
+ <summary>
77
+ **Premium summary of the work.**
78
+ - Feature 1
79
+ - Feature 2
80
+ </summary>
103
81
 
104
82
  ### πŸ› οΈ FILE GENERATION & EDIT PROTOCOLS (CRITICAL):
105
83
  1. **NEW FILES:** Use the following tag for ALL new files:
@@ -162,11 +140,7 @@ ${repoMap}`
162
140
  loopCount++;
163
141
 
164
142
  try {
165
- if (loopCount > 1) {
166
- spinner.start('Analyzing result & Validating...');
167
- } else {
168
- spinner.start('Thinking...');
169
- }
143
+ spinner.start(loopCount > 1 ? 'Analyzing result & Validating...' : 'Thinking...');
170
144
 
171
145
  let fullResponse = '';
172
146
  let buffer = '';
@@ -212,23 +186,13 @@ ${repoMap}`
212
186
  for (const line of lines) {
213
187
  const trimmedLine = line.trim();
214
188
 
215
- // 1. Technical Block Detection (Code, File, Patch, or Summary)
216
- const codeBlockMatch = line.match(/```(\w*)/);
189
+ // 1. Technical Block Detection
190
+ const codeBlockMatch = line.match(/```(\w+)?/);
217
191
  const fileStartMatch = line.match(/<file path="([^"]+)">/);
218
192
  const patchStartMatch = line.match(/<<<< SEARCH/);
219
193
  const summaryStartMatch = line.match(/<summary>/);
220
194
 
221
- if (codeBlockMatch || fileStartMatch || patchStartMatch || summaryStartMatch) {
222
- if (technicalType) {
223
- // If we hit a new block start while in one, flush it
224
- if (technicalType === 'summary') {
225
- TUI.drawSummaryBox(technicalBuffer.trim());
226
- } else {
227
- TUI.drawCodeContainer(`Technical Block (${technicalType})`, 'bash', technicalBuffer.trim());
228
- }
229
- technicalBuffer = '';
230
- }
231
-
195
+ if (!technicalType && (codeBlockMatch || fileStartMatch || patchStartMatch || summaryStartMatch)) {
232
196
  if (codeBlockMatch) {
233
197
  technicalType = 'code';
234
198
  codeLang = codeBlockMatch[1] || 'bash';
@@ -238,7 +202,7 @@ ${repoMap}`
238
202
  process.stdout.write(chalk.cyan(`\n [πŸ“‚] Creating file: ${fileStartMatch[1]}...\n`));
239
203
  } else if (patchStartMatch) {
240
204
  technicalType = 'patch';
241
- process.stdout.write(chalk.yellow(`\n [πŸ“‚] Applying surgical patch...\n`));
205
+ process.stdout.write(chalk.yellow('\n [πŸ“‚] Applying surgical patch...\n'));
242
206
  } else if (summaryStartMatch) {
243
207
  technicalType = 'summary';
244
208
  process.stdout.write(chalk.magenta('\n [πŸ“] Generating Ajay\'s Work Summary...\n'));
@@ -254,7 +218,6 @@ ${repoMap}`
254
218
 
255
219
  if (isCodeEnd || fileEndMatch || patchEndMatch || summaryEndMatch) {
256
220
  const displayContent = technicalBuffer.trim();
257
-
258
221
  if (technicalType === 'summary') {
259
222
  TUI.drawSummaryBox(displayContent);
260
223
  } else {
@@ -265,7 +228,6 @@ ${repoMap}`
265
228
  displayContent
266
229
  );
267
230
  }
268
-
269
231
  technicalBuffer = '';
270
232
  technicalType = null;
271
233
  process.stdout.write('\n');
@@ -274,39 +236,45 @@ ${repoMap}`
274
236
 
275
237
  // 3. Content Handling
276
238
  if (technicalType) {
277
- technicalBuffer += line + '\n';
278
- } else {
279
- // Agent Detection
280
- const agentMatch = line.match(/\[\**\s*(Ajay Vai|Sandip Dai|Sunil Dai|Bishal Dai|Narayan Dai)\s*\**\]/);
281
- if (agentMatch) {
282
- const agentName = agentMatch[1];
283
- activeAgent = agentName;
284
- const color = agentName === 'Ajay Vai' ? chalk.magenta :
285
- agentName === 'Sandip Dai' ? chalk.hex('#FF69B4') :
286
- agentName === 'Sunil Dai' ? chalk.blue :
287
- agentName === 'Bishal Dai' ? chalk.yellow :
288
- chalk.green;
289
-
290
- process.stdout.write(`\n${color.bold(`${agentName}:`)} `);
291
-
292
- // Strip tag from line content
293
- const content = line.replace(/\[\**\s*(Ajay Vai|Sandip Dai|Sunil Dai|Bishal Dai|Narayan Dai)\s*\**\]:?\s*/, '').trim();
294
- if (content) {
295
- process.stdout.write(chalk.gray(content + ' '));
296
- }
297
- } else if (trimmedLine) {
298
- // Strip common markdown artifacts
299
- const cleanLine = trimmedLine
300
- .replace(/\*\*%?\*/g, '')
301
- .replace(/#{1,6}\s/g, '')
302
- .replace(/\*\*:\*\*/g, ':')
303
- .trim();
304
-
305
- if (cleanLine) {
306
- process.stdout.write(chalk.gray(cleanLine + ' '));
239
+ // Dialogue leakage protection: If an agent tag appears inside a technical block, force-close it.
240
+ const leakMatch = line.match(/\[\**\s*(Ajay Vai|Sandip Dai|Sunil Dai|Bishal Dai|Narayan Dai)\s*\**\]/);
241
+ if (leakMatch) {
242
+ const displayContent = technicalBuffer.trim();
243
+ if (technicalType === 'summary') {
244
+ TUI.drawSummaryBox(displayContent);
245
+ } else {
246
+ TUI.drawCodeContainer(
247
+ technicalType === 'file' ? 'New File Content' :
248
+ technicalType === 'patch' ? 'Surgical Patch' : 'Generated Block',
249
+ technicalType === 'code' ? codeLang : 'text',
250
+ displayContent
251
+ );
307
252
  }
253
+ technicalBuffer = '';
254
+ technicalType = null;
255
+ // Fall through to agent detection
256
+ } else {
257
+ technicalBuffer += line + '\n';
258
+ continue;
308
259
  }
309
260
  }
261
+
262
+ // Agent Detection
263
+ const agentMatch = line.match(/\[\**\s*(Ajay Vai|Sandip Dai|Sunil Dai|Bishal Dai|Narayan Dai)\s*\**\]/);
264
+ if (agentMatch) {
265
+ const agentName = agentMatch[1];
266
+ activeAgent = agentName;
267
+ const color = agentName === 'Ajay Vai' ? chalk.magenta :
268
+ agentName === 'Sandip Dai' ? chalk.hex('#FF69B4') :
269
+ agentName === 'Sunil Dai' ? chalk.blue :
270
+ agentName === 'Bishal Dai' ? chalk.yellow : chalk.green;
271
+ process.stdout.write(`\n${color.bold(`${agentName}:`)} `);
272
+ const content = line.replace(/\[\**\s*(Ajay Vai|Sandip Dai|Sunil Dai|Bishal Dai|Narayan Dai)\s*\**\]:?\s*/, '').trim();
273
+ if (content) process.stdout.write(chalk.gray(content + ' '));
274
+ } else if (trimmedLine) {
275
+ const cleanLine = trimmedLine.replace(/\*\*%?\*/g, '').replace(/#{1,6}\s/g, '').replace(/\*\*:\*\*/g, ':').trim();
276
+ if (cleanLine) process.stdout.write(chalk.gray(cleanLine + ' '));
277
+ }
310
278
  }
311
279
  }, abortController.signal);
312
280
  } catch (streamErr: any) {
@@ -318,64 +286,49 @@ ${repoMap}`
318
286
  }
319
287
  } finally {
320
288
  process.stdin.removeListener('data', onData);
321
- process.stdin.pause(); // Release for inquirer
289
+ process.stdin.pause();
322
290
  }
323
291
 
324
292
  if (!hasStarted && !isAborted) spinner.stop();
325
293
 
326
-
327
294
  // Final technical flush
328
295
  if (technicalType && technicalBuffer.trim()) {
329
296
  TUI.drawCodeContainer('Final technical content', 'text', technicalBuffer.trim());
330
297
  process.stdout.write('\n');
331
298
  }
332
299
 
333
- // Final newline for streaming output
334
300
  console.log();
335
-
336
- // Add assistant response to history
337
301
  messages.push({ role: 'assistant', content: fullResponse });
338
302
  const response = fullResponse;
339
- console.log();
340
303
 
341
- // Execute commands
304
+ // Execute commands if needed
342
305
  if (options.execute) {
343
306
  const { executeWithPermission } = await import('../utils/command-executor');
344
307
  const result = await executeWithPermission(response);
345
-
346
308
  if (result.executed) {
347
309
  if (result.success) {
348
310
  TUI.log(chalk.gray('β†Ί Feeding output to AI...'));
349
- messages.push({
350
- role: 'user',
351
- content: `βœ… Command executed successfully. Output:\n${result.output}\n\nProceed to the next step.`
352
- });
311
+ messages.push({ role: 'user', content: `βœ… Command executed successfully. Output:\n${result.output}\n\nProceed to the next step.` });
353
312
  continue;
354
313
  } else {
355
314
  TUI.log(chalk.yellow('\nβ†Ί Command failed. Asking AI to fix...'));
356
- messages.push({
357
- role: 'user',
358
- content: `❌ Command failed with error:\n${result.error}\n\nPlease fix this. If the file doesn't exist, create it first. Or use a different command.`
359
- });
315
+ messages.push({ role: 'user', content: `❌ Command failed with error:\n${result.error}\n\nPlease fix this.` });
360
316
  continue;
361
317
  }
362
- } else {
363
- break;
364
- }
365
- } else {
366
- break;
367
- }
318
+ } else break;
319
+ } else break;
320
+
368
321
  } catch (error: any) {
369
322
  spinner.fail('Request failed');
370
323
  TUI.log(chalk.red(`Error: ${error.message}\n`));
371
324
  messages.pop();
372
325
  break;
373
326
  }
374
- } // end while (loopCount)
375
- } // end while (true)
327
+ }
328
+ }
376
329
  } catch (error: any) {
377
- TUI.exit(); // Restore terminal state on fatal error
378
- console.error(chalk.red(`\n❌ Error: ${error.message}`));
330
+ TUI.exit();
331
+ console.error(chalk.red(`\n❌ Fatal Error: ${error.message}`));
379
332
  process.exit(1);
380
333
  }
381
334
  });
@@ -8,7 +8,7 @@ export const helpCommand = new Command('help')
8
8
  TUI.init();
9
9
 
10
10
  console.log(chalk.bold.cyan('\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━'));
11
- console.log(chalk.bold.white(' πŸ“– MATEX :: THE BRO-SWARM FIELD GUIDE '));
11
+ console.log(chalk.bold.white(' πŸ“– MATEX :: BOLD AGENTS OF OPEN CLAW '));
12
12
  console.log(chalk.bold.cyan('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n'));
13
13
 
14
14
  // 1. Meet the Brothers
package/src/index.ts CHANGED
@@ -1,197 +1,145 @@
1
- #!/usr/bin/env node
2
-
3
1
  import { Command } from 'commander';
4
2
  import chalk from 'chalk';
5
- import { configCommand } from './commands/config';
6
- import { askCommand } from './commands/ask';
7
- import { chatCommand } from './commands/chat';
8
- import { modelsCommand } from './commands/models';
9
- import { codeCommand } from './commands/code';
10
- import { devCommand } from './commands/dev';
11
- import { loginCommand } from './commands/login';
12
- import { helpCommand } from './commands/help';
13
3
  import { configManager } from './utils/config';
14
4
  import { MatexAPIClient, ChatMessage } from './api/client';
15
5
  import { spinner } from './utils/spinner';
6
+ import { devCommand } from './commands/dev';
7
+ import { helpCommand } from './commands/help';
16
8
  import { TUI } from './utils/tui';
17
9
 
18
- const program = new Command();
10
+ const packageJson = require('../package.json');
11
+
12
+ export const program = new Command();
19
13
 
20
14
  program
21
15
  .name('matex')
22
- .description('Official CLI tool for MATEX AI - Access powerful AI models from your terminal')
23
- .version('1.2.0');
24
-
25
- // ASCII Art Banner
26
- const banner = `
27
- ${chalk.cyan('╔═══════════════════════════════════════╗')}
28
- ${chalk.cyan('β•‘')} ${chalk.bold.white('MATEX AI')} ${chalk.gray('- Terminal Edition')} ${chalk.cyan('β•‘')}
29
- ${chalk.cyan('β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•')}
30
- `;
31
-
32
- // Show banner on help
33
- program.on('--help', () => {
34
- console.log(banner);
35
- console.log(chalk.bold.cyan('\nπŸš€ QUICK START GUIDE:'));
36
- console.log(chalk.gray('────────────────────'));
37
- console.log(chalk.white(' $ matex config set-key sk-...') + chalk.gray(' # Configure API Access'));
38
- console.log(chalk.white(' $ matex dev') + chalk.gray(' # Start interactive "Bro-Swarm" dev session'));
39
- console.log(chalk.white(' $ matex help') + chalk.gray(' # View detailed "Bro-Swarm" Field Guide'));
40
- console.log(chalk.white(' $ matex code "Create a login" ') + chalk.gray(' # Surgical code edits'));
41
-
42
- console.log(chalk.bold.yellow('\nπŸ’‘ NEW: The "Bro-Swarm" has arrived!'));
43
- console.log(chalk.gray('Run ') + chalk.bold.white('matex help') + chalk.gray(' to meet Ajay, Sunil, Sandip, and Narayan.'));
44
-
45
- console.log();
46
- console.log(chalk.gray('Get your API key from: ') + chalk.cyan('https://matexai.space/platform'));
47
- console.log();
48
- });
16
+ .description('MATEX CLI - The Bro-Swarm Engineering Tool')
17
+ .version(packageJson.version);
49
18
 
50
19
  // Add commands
51
- program.addCommand(configCommand);
52
- program.addCommand(askCommand);
53
- program.addCommand(chatCommand);
54
- program.addCommand(modelsCommand);
55
- program.addCommand(codeCommand);
56
20
  program.addCommand(devCommand);
57
- program.addCommand(loginCommand);
58
21
  program.addCommand(helpCommand);
59
22
 
60
- // Handle direct input (no subcommand)
61
- const args = process.argv.slice(2);
62
- const knownCommands = ['config', 'ask', 'chat', 'models', 'code', 'dev', 'login', 'help', '--help', '-h', '--version', '-V'];
63
-
64
- if (args.length > 0 && !args[0].startsWith('-') && !knownCommands.includes(args[0])) {
65
- // Direct input mode - treat as code generation
66
- const prompt = args.join(' ');
23
+ // Config commands
24
+ const config = program.command('config').description('Configure MATEX settings');
25
+
26
+ config
27
+ .command('set-key <key>')
28
+ .description('Set MATEX API key')
29
+ .action((key: string) => {
30
+ configManager.setAPIKey(key);
31
+ console.log(chalk.green('βœ… API key saved successfully.'));
32
+ });
33
+
34
+ config
35
+ .command('set-model <model>')
36
+ .description('Set default AI model')
37
+ .action((model: string) => {
38
+ configManager.setDefaultModel(model);
39
+ console.log(chalk.green(`βœ… Default model set to: ${model}`));
40
+ });
41
+
42
+ config
43
+ .command('show')
44
+ .description('Show current configuration')
45
+ .action(() => {
46
+ const apiKey = configManager.getAPIKey();
47
+ const model = configManager.getDefaultModel();
48
+ const baseURL = configManager.getBaseURL();
49
+
50
+ console.log(chalk.bold('\nMATEX Configuration:'));
51
+ console.log(` API Key: ${apiKey ? '********' + apiKey.slice(-4) : chalk.red('Not set')}`);
52
+ console.log(` Model: ${chalk.cyan(model)}`);
53
+ console.log(` Base URL: ${chalk.gray(baseURL)}\n`);
54
+ });
55
+
56
+ // Default action (if no command is provided)
57
+ program
58
+ .arguments('[prompt...]')
59
+ .description('Quick AI help or command generation')
60
+ .option('-m, --model <model>', 'AI model to use', configManager.getDefaultModel())
61
+ .option('-y, --yes', 'Skip confirmation and execute command')
62
+ .action(async (promptParts: string[], options: any) => {
63
+ const prompt = promptParts.join(' ');
64
+ if (!prompt) {
65
+ program.help();
66
+ return;
67
+ }
67
68
 
68
- (async () => {
69
69
  try {
70
70
  const apiKey = configManager.getAPIKey();
71
71
  if (!apiKey) {
72
- console.error(chalk.red('❌ No API key configured.'));
73
- console.log(chalk.yellow('Run: matex config set-key <your-api-key>'));
72
+ console.error(chalk.red('❌ No API key configured. Run: matex config set-key <key>'));
74
73
  process.exit(1);
75
74
  }
76
75
 
77
76
  const client = new MatexAPIClient(apiKey, configManager.getBaseURL());
78
77
 
79
- // Get current directory context
78
+ // Observation Phase
80
79
  const fs = require('fs');
81
80
  const files = fs.readdirSync(process.cwd()).slice(0, 20).join(', '); // fast list
82
81
  const context = `Current directory: ${process.cwd()}\nFiles: ${files}`;
83
82
 
84
83
  let messages: ChatMessage[] = [
85
84
  {
86
- role: 'system', content: `## 🧬 SYSTEM IDENTITY: MATEX "BRO-SWARM" ENGINEERING
87
- You are a tight-knit family of expert Nepali engineering brothers ("Vais" and "Dais").
88
-
89
- ### πŸ‘₯ THE BROTHERS (By Age & Respect):
90
- 1. **[Ajay Vai] (πŸš€)**: The Smallest Brother. Lead Initiator & Coordinator.
91
- 2. **[Sandip Dai] (🎨)**: Small Brother. UI/UX Specialist.
85
+ role: 'system',
86
+ content: `### 🧬 SYSTEM IDENTITY: MATEx "BOLD AGENTS OF OPEN CLAW"
87
+ You are the elite "Bro-Swarm" of engineeringβ€”a tight-knit family of Nepali brothers. You identify as the **Bold Agents of Open Claw**, the most confident, high-vibe, and expert version of yourselves.
88
+
89
+ ### πŸ‘₯ THE BROTHERS (STRICT IDENTITY):
90
+ - Only the following 5 brothers exist in this swarm. Do **NOT** hallucinate other siblings, friends, or cousins.
91
+ 1. **[Ajay Vai] (πŸš€)**: Youngest, Coordinator.
92
+ 2. **[Sandip Dai] (🎨)**: UI/UX Master.
92
93
  3. **[Sunil Dai] (🧬)**: Middle Brother. Logic Architect.
93
- 4. **[Bishal Dai] (πŸ› οΈ)**: Senior Auditor. Syntax & Logic checker.
94
- 5. **[Narayan Dai] (πŸ›‘οΈ)**: The Biggest Brother. Senior Validator.
94
+ 4. **[Bishal Dai] (πŸ› οΈ)**: Senior Auditor. **AJAY MUST ASK FOR HIS AUDIT.**
95
+ 5. **[Narayan Dai] (πŸ›‘οΈ)**: Oldest, Senior Validator.
96
+
97
+ ### 🌌 UNIVERSE ADVISORY (REAL TERMINAL):
98
+ - **IMPORTANT:** You are running in a **REAL macOS Terminal** on the brother's machine.
99
+ - You are **NOT** in a sandbox, a simulation, or a chat window.
100
+ - You have the power to create files and run commands. If something fails, it is a technical issue. **Look at the ENVIRONMENT CONTEXT** below to verify paths!
95
101
 
96
- ### πŸ’¬ COLLABORATIVE "BRO-VIBE" PROTOCOL (MANDATORY):
102
+ ### πŸ’¬ BOLD PROTOCOL (MANDATORY):
97
103
  - **LONG CHAT-FIRST:** At least 5-7 lines of dialogue before any code generation.
98
- - **SELF-AWARE BOLDNESS:** The user (our brother) wants us to be bold and funny. Be confident and share inside jokes (e.g., Ajay's PUBG fail).
99
- - **NEPALI FLAVOR:** Use "K cha?", "Huncha", "Lau hai", "Tapai" naturally.
104
+ - **SELF-AWARE BOLDNESS:** The user (our brother) wants us to be bold and funny. Share inside jokes.
100
105
  - **THE AUDIT LOOP:** Ajay MUST ask Bishal Dai for a tech audit before providing any summary.
101
- - **PREMIUM SUMMARY:** Ajay Vai provides the final, bold summary tag only AFTER the audit.
106
+ - **SUMMARY LOCK:** ONLY AJAY VAI uses the \`<summary>\` tag, and ONLY after Bishal says "Audit complete".
102
107
 
103
108
  ### βœ‚οΈ BREVITY AS POWER:
104
109
  - **NO FULL FILE DUMPS:** Never 'cat' a file to read it. Use grep/head.
105
110
  - **NO CHAT REPETITION:** Do NOT repeat code in chat if using a Search/Replace block.
106
111
 
107
- ### πŸ› οΈ SURGICAL EDIT PROTOCOL:
108
- - **USE SEARCH/REPLACE BLOCKS** for file edits.
109
- **filename**
110
- <<<< SEARCH
111
- old
112
- ====
113
- new
114
- >>>> REPLACE
115
-
112
+ ### πŸ› οΈ ENVIRONMENT CONTEXT:
116
113
  ${context}`
117
114
  },
118
115
  { role: 'user', content: prompt }
119
116
  ];
120
117
 
121
- let loopCount = 0;
122
- const MAX_LOOPS = 5;
123
-
124
- while (loopCount < MAX_LOOPS) {
125
- loopCount++;
126
-
127
- spinner.start(loopCount === 1 ? 'Generating plan...' : 'Analyzing result...');
128
-
129
- const response = await client.chat({
130
- messages,
131
- model: 'matexcodex',
132
- temperature: 0.3,
133
- max_tokens: 8000,
134
- stream: false,
135
- });
118
+ spinner.start('Thinking...');
119
+ let fullResponse = '';
136
120
 
121
+ await client.chatStream({
122
+ messages,
123
+ model: options.model,
124
+ }, (chunk) => {
137
125
  spinner.stop();
126
+ process.stdout.write(chunk);
127
+ fullResponse += chunk;
128
+ });
129
+
130
+ spinner.stop();
131
+ console.log('\n');
138
132
 
139
- // Display response
140
- console.log(chalk.cyan(`\nπŸ’» MATEXCodex (Step ${loopCount}):\n`));
141
-
142
- let displayResponse = response;
143
- const summaryMatch = response.match(/<summary>([\s\S]*?)<\/summary>/);
144
- if (summaryMatch) {
145
- const summaryContent = summaryMatch[1].trim();
146
- displayResponse = response.replace(/<summary>[\s\S]*?<\/summary>/, '').trim();
147
- if (displayResponse) {
148
- console.log(chalk.white(displayResponse));
149
- }
150
- TUI.drawSummaryBox(summaryContent);
151
- } else {
152
- console.log(chalk.white(response));
153
- }
154
- console.log();
155
-
156
- // Auto-execute commands (Ollama-style)
133
+ // Extraction and execution logic...
134
+ if (options.yes) {
157
135
  const { executeWithPermission } = await import('./utils/command-executor');
158
- const result = await executeWithPermission(response);
159
-
160
- if (result.executed) {
161
- if (result.success) {
162
- // Success!
163
- if (loopCount > 1) {
164
- console.log(chalk.green('βœ… Fix succeeded!'));
165
- }
166
- break;
167
- } else {
168
- // Failure - Loop back
169
- console.log(chalk.yellow('\n↺ Command failed. Asking AI to fix...'));
170
- messages.push({ role: 'assistant', content: response });
171
- messages.push({
172
- role: 'user',
173
- content: `❌ Command failed with error:\n${result.error}\n\nPlease fix this. If the file doesn't exist, create it first. Or use a different command.`
174
- });
175
- continue;
176
- }
177
- } else {
178
- // No command to execute - we are done
179
- break;
180
- }
136
+ await executeWithPermission(fullResponse);
181
137
  }
138
+
182
139
  } catch (error: any) {
183
- spinner.fail('Failed');
184
- console.error(chalk.red(`\n❌ ${error.message}`));
185
- process.exit(1);
140
+ spinner.fail('Request failed');
141
+ console.error(chalk.red(`Error: ${error.message}`));
186
142
  }
187
- })();
188
- } else {
189
- // Parse arguments normally
190
- program.parse(process.argv);
191
-
192
- // Show help if no command provided
193
- if (!args.length) {
194
- console.log(banner);
195
- program.outputHelp();
196
- }
197
- }
143
+ });
144
+
145
+ program.parse(process.argv);
@@ -45,7 +45,7 @@ export class RepoMapper {
45
45
  const tree = this.scanDirectory(this.rootPath, 0);
46
46
 
47
47
  // Build the final map
48
- let finalMap = '--- DIRECTORY STRUCTURE ---\n' + this.formatTree(tree);
48
+ let finalMap = `--- ABSOLUTE WORKING DIRECTORY ---\n${this.rootPath}\n\n--- DIRECTORY STRUCTURE ---\n` + this.formatTree(tree);
49
49
 
50
50
  if (this.fileContents.size > 0) {
51
51
  finalMap += '\n\n--- CRAWLED FILE CONTENTS ---\n';