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.
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +76 -118
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/help.js +1 -1
- package/dist/commands/help.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +107 -159
- package/dist/index.js.map +1 -1
- package/dist/utils/repo-mapper.js +1 -1
- package/dist/utils/repo-mapper.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/dev.ts +83 -130
- package/src/commands/help.ts +1 -1
- package/src/index.ts +94 -146
- package/src/utils/repo-mapper.ts +1 -1
package/src/commands/dev.ts
CHANGED
|
@@ -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:
|
|
51
|
-
You are a family of
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
1. **[Ajay Vai] (π)**:
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
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
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
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();
|
|
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
|
-
|
|
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
|
-
}
|
|
375
|
-
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
376
329
|
} catch (error: any) {
|
|
377
|
-
TUI.exit();
|
|
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
|
});
|
package/src/commands/help.ts
CHANGED
|
@@ -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 ::
|
|
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
|
|
10
|
+
const packageJson = require('../package.json');
|
|
11
|
+
|
|
12
|
+
export const program = new Command();
|
|
19
13
|
|
|
20
14
|
program
|
|
21
15
|
.name('matex')
|
|
22
|
-
.description('
|
|
23
|
-
.version(
|
|
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
|
-
//
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
//
|
|
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',
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
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.
|
|
94
|
-
5. **[Narayan Dai] (π‘οΈ)**:
|
|
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
|
-
### π¬
|
|
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.
|
|
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
|
-
- **
|
|
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
|
-
### π οΈ
|
|
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
|
-
|
|
122
|
-
|
|
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
|
-
|
|
140
|
-
|
|
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
|
-
|
|
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('
|
|
184
|
-
console.error(chalk.red(
|
|
185
|
-
process.exit(1);
|
|
140
|
+
spinner.fail('Request failed');
|
|
141
|
+
console.error(chalk.red(`Error: ${error.message}`));
|
|
186
142
|
}
|
|
187
|
-
})
|
|
188
|
-
|
|
189
|
-
|
|
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);
|
package/src/utils/repo-mapper.ts
CHANGED
|
@@ -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 =
|
|
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';
|