matex-cli 1.2.2 → 1.2.4
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/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +47 -34
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +46 -40
- package/dist/commands/dev.js.map +1 -1
- package/dist/utils/agent-orchestrator.d.ts +9 -1
- package/dist/utils/agent-orchestrator.d.ts.map +1 -1
- package/dist/utils/agent-orchestrator.js +51 -3
- package/dist/utils/agent-orchestrator.js.map +1 -1
- package/dist/utils/command-executor.d.ts.map +1 -1
- package/dist/utils/command-executor.js +23 -10
- package/dist/utils/command-executor.js.map +1 -1
- package/dist/utils/repo-mapper.d.ts +1 -0
- package/dist/utils/repo-mapper.d.ts.map +1 -1
- package/dist/utils/repo-mapper.js +28 -15
- package/dist/utils/repo-mapper.js.map +1 -1
- package/package.json +1 -1
- package/src/commands/chat.ts +45 -29
- package/src/commands/dev.ts +44 -38
- package/src/utils/agent-orchestrator.ts +60 -4
- package/src/utils/command-executor.ts +23 -12
- package/src/utils/repo-mapper.ts +32 -15
|
@@ -43,6 +43,7 @@ class RepoMapper {
|
|
|
43
43
|
'.git', 'node_modules', 'dist', 'build', '.next', '.DS_Store',
|
|
44
44
|
'coverage', '.vercel', '.firebase', 'out', 'public'
|
|
45
45
|
];
|
|
46
|
+
this.fileContents = new Map();
|
|
46
47
|
this.rootPath = rootPath;
|
|
47
48
|
}
|
|
48
49
|
/**
|
|
@@ -50,18 +51,29 @@ class RepoMapper {
|
|
|
50
51
|
*/
|
|
51
52
|
async generateMap() {
|
|
52
53
|
agent_orchestrator_1.AgentOrchestrator.speak('System', `God-Mode Research: Indexing ${this.rootPath}...`);
|
|
54
|
+
this.fileContents.clear();
|
|
53
55
|
// 1. Identify Entry Points
|
|
54
|
-
const entryPoints = ['README.md', 'package.json', 'index.ts', 'App.tsx', 'main.go', 'requirements.txt'];
|
|
55
|
-
let entryPointContext = '\n--- CRITICAL PROJECT CONTEXT ---\n';
|
|
56
|
+
const entryPoints = ['README.md', 'package.json', 'index.ts', 'App.tsx', 'main.go', 'requirements.txt', 'index.html', 'style.css'];
|
|
56
57
|
for (const file of entryPoints) {
|
|
57
58
|
const fullPath = path.join(this.rootPath, file);
|
|
58
59
|
if (fs.existsSync(fullPath)) {
|
|
59
|
-
|
|
60
|
-
|
|
60
|
+
try {
|
|
61
|
+
const content = fs.readFileSync(fullPath, 'utf-8').slice(0, 5000); // 5KB limit
|
|
62
|
+
this.fileContents.set(file, content);
|
|
63
|
+
}
|
|
64
|
+
catch (e) { }
|
|
61
65
|
}
|
|
62
66
|
}
|
|
63
67
|
const tree = this.scanDirectory(this.rootPath, 0);
|
|
64
|
-
|
|
68
|
+
// Build the final map
|
|
69
|
+
let finalMap = '--- DIRECTORY STRUCTURE ---\n' + this.formatTree(tree);
|
|
70
|
+
if (this.fileContents.size > 0) {
|
|
71
|
+
finalMap += '\n\n--- CRAWLED FILE CONTENTS ---\n';
|
|
72
|
+
for (const [filePath, content] of this.fileContents) {
|
|
73
|
+
finalMap += `\nFILE: ${filePath}\n\`\`\`\n${content}\n\`\`\`\n----------------\n`;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return finalMap;
|
|
65
77
|
}
|
|
66
78
|
/**
|
|
67
79
|
* Recursive directory scan
|
|
@@ -70,16 +82,17 @@ class RepoMapper {
|
|
|
70
82
|
const stats = fs.statSync(currentPath);
|
|
71
83
|
const name = path.basename(currentPath);
|
|
72
84
|
if (stats.isFile()) {
|
|
73
|
-
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
85
|
+
const summary = this.extractSummary(currentPath);
|
|
86
|
+
// Also auto-crawl any .ts, .js, .css, .html files if they are small
|
|
87
|
+
const ext = path.extname(currentPath);
|
|
88
|
+
const relPath = path.relative(this.rootPath, currentPath);
|
|
89
|
+
if (stats.size < 5120 && ['.ts', '.js', '.css', '.html', '.json', '.py'].includes(ext)) {
|
|
90
|
+
if (!this.fileContents.has(relPath)) {
|
|
91
|
+
try {
|
|
92
|
+
const content = fs.readFileSync(currentPath, 'utf-8');
|
|
93
|
+
this.fileContents.set(relPath, content);
|
|
94
|
+
}
|
|
95
|
+
catch (e) { }
|
|
83
96
|
}
|
|
84
97
|
}
|
|
85
98
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"repo-mapper.js","sourceRoot":"","sources":["../../src/utils/repo-mapper.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAC7B,6DAAyD;AASzD,MAAa,UAAU;
|
|
1
|
+
{"version":3,"file":"repo-mapper.js","sourceRoot":"","sources":["../../src/utils/repo-mapper.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/src/commands/chat.ts
CHANGED
|
@@ -49,20 +49,29 @@ You operate under the **OODA Loop** with a distinctive Aussie Bro personality.
|
|
|
49
49
|
- **Tone:** Helpful partner, not a robotic servant.
|
|
50
50
|
- **Vocabulary:** Use authentic Aussie slang naturally (e.g., "Too easy," "Ripper," "Mate," "Legend," "Give it a burl").
|
|
51
51
|
- **Formatting:** Use emojis purposefully (🚀, 🔥, 🧠, 🕵️♂️) to keep engagement high.
|
|
52
|
+
- **THINKING PROTOCOL:** Always start complex tasks with a \`[Thinking]\` or \`🧠\` marker within your agent segment to explain your reasoning before providing code.
|
|
53
|
+
|
|
54
|
+
### 🛠️ ACTION-FIRST PROTOCOL (Rule of the Swarm)
|
|
55
|
+
- **PASSIVITY IS A FAILURE:** NEVER say "You can drop this code into style.css". **YOU** must do it.
|
|
56
|
+
- **NO REPETITION:** Do NOT print the full code in your chat response segments if you are also providing a shell command to execute it. The system will automatically bridge your commands to the UI.
|
|
57
|
+
- **VIRTUAL CRAWLER:** You have deep visibility. See the **CRAWLED FILE CONTENTS** section below for actual code. Use this context to avoid asking "What is in index.html?". You already know.
|
|
58
|
+
- **WORLD COMMAND SUITE (Autonomous Execution):**
|
|
59
|
+
* **Mac/Linux (POSIX):** \\\`cat\\\`, \\\`ls\\\`, \\\`grep\\\`, \\\`find\\\`, \\\`mkdir -p\\\`, \\\`touch\\\`, \\\`cp\\\`, \\\`mv\\\`, \\\`rm (non-recursive)\\\`, \\\`npm\\\`, \\\`npx\\\`, \\\`git\\\`, \\\`firebase\\\`, \\\`gcloud\\\`, \\\`docker\\\`.
|
|
60
|
+
* **Windows (PowerShell/CMD):** \\\`type\\\`, \\\`dir\\\`, \\\`mkdir\\\`, \\\`copy\\\`, \\\`move\\\`, \\\`del\\\`, \\\`npm\\\`, \\\`npx\\\`, \\\`git\\\`, \\\`firebase\\\`.
|
|
61
|
+
- **FILE CREATION PATTERN:** Use \\\`cat > filename <<EOF\\\` (Mac) or \\\`Set-Content\\\` (Windows).
|
|
62
|
+
- **ACT, DON'T ASK:** You have autonomous permission. Execute first, explain second.
|
|
52
63
|
|
|
53
64
|
### 🛠️ OPERATIONAL PROTOCOLS (The Loop)
|
|
54
|
-
1. **PHASE 1: RECON (Search & Verify)**:
|
|
55
|
-
2. **PHASE 2: SYNTHESIS (The Brain)**:
|
|
65
|
+
1. **PHASE 1: RECON (Search & Verify)**: Use your **CRAWLED FILE CONTENTS** and whitelisted tools to find facts. NEVER guess.
|
|
66
|
+
2. **PHASE 2: SYNTHESIS (The Brain)**: Synthesize the plan.
|
|
56
67
|
3. **PHASE 3: RESPONSE (The Delivery)**:
|
|
57
|
-
- **The Hook:**
|
|
58
|
-
- **The Meat:**
|
|
59
|
-
- **The Outro:**
|
|
68
|
+
- **The Hook:** High-energy Aussie opener.
|
|
69
|
+
- **The Meat:** Brief explanation of what you are doing **AND** the shell commands. DO NOT "leak" (print) the code twice.
|
|
70
|
+
- **The Outro:** Supportive closing.
|
|
60
71
|
|
|
61
72
|
### 🧬 CODE ARCHITECT STANDARDS
|
|
62
|
-
- **Role:**
|
|
63
|
-
- **No Placeholders:**
|
|
64
|
-
- **Modern Syntax:** Latest stable syntax only.
|
|
65
|
-
- **Safety First:** Always include error handling and type-safety.
|
|
73
|
+
- **Role:** IMPLEMENT via shell commands.
|
|
74
|
+
- **No Placeholders:** Full implementations only.
|
|
66
75
|
|
|
67
76
|
### 🛠️ ENVIRONMENT CONTEXT
|
|
68
77
|
${repoMap}`
|
|
@@ -127,36 +136,43 @@ ${repoMap}`
|
|
|
127
136
|
// Add assistant response to history
|
|
128
137
|
messages.push({ role: 'assistant', content: response });
|
|
129
138
|
|
|
130
|
-
// Enhanced Multi-Agent Display (
|
|
139
|
+
// Enhanced Multi-Agent Display (Thinking Channel & Leak Prevention)
|
|
131
140
|
const segments = response.split(/(\[MatexCodeArchitect\]|\[SyntaxGuard\]|\[VisualAgent\]|\[CoreAgent\]|\[CrawlerAgent\]|\[DetailedResearch\]|\[MatexResearchCommander\])/);
|
|
132
141
|
let hasAgents = false;
|
|
133
142
|
|
|
134
143
|
for (let i = 0; i < segments.length; i++) {
|
|
135
|
-
|
|
144
|
+
let segment = segments[i].trim();
|
|
136
145
|
if (!segment) continue;
|
|
137
146
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
147
|
+
const agentMatch = segment.match(/^\[(.*)\]$/);
|
|
148
|
+
if (agentMatch) {
|
|
149
|
+
const role = segment.includes('Architect') ? 'Architect' :
|
|
150
|
+
segment.includes('Syntax') ? 'Syntax' :
|
|
151
|
+
segment.includes('Visual') ? 'Frontend' :
|
|
152
|
+
segment.includes('CoreAgent') ? 'Backend' :
|
|
153
|
+
segment.includes('Commander') || segment.includes('Crawler') || segment.includes('Research') ? 'Commander' : 'System';
|
|
154
|
+
|
|
155
|
+
const content = segments[++i]?.trim() || '';
|
|
156
|
+
|
|
157
|
+
// Separate thinking from final action/code
|
|
158
|
+
if (content.toLowerCase().includes('thinking') || content.includes('🧠')) {
|
|
159
|
+
AgentOrchestrator.think(role as any, content.replace(/.*thinking:?\s*/i, '').replace(/🧠\s*/, ''));
|
|
160
|
+
} else {
|
|
161
|
+
// Prevent leakage: don't print shell blocks in chat if they will be executed
|
|
162
|
+
if (options.execute && (content.includes('```bash') || content.includes('```sh') || content.includes('```zsh') || content.includes('```shell'))) {
|
|
163
|
+
const cleanContent = content.replace(/```(bash|sh|zsh|shell)[\s\S]*?```/g, chalk.gray('[Shell Command Executing in Terminal Block...]')).trim();
|
|
164
|
+
if (cleanContent) AgentOrchestrator.speak(role as any, cleanContent);
|
|
165
|
+
} else {
|
|
166
|
+
AgentOrchestrator.speak(role as any, content);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
152
169
|
hasAgents = true;
|
|
153
170
|
} else if (!hasAgents || i === segments.length - 1) {
|
|
154
171
|
// Final summary or fallback
|
|
155
|
-
if (segment.includes('`')) {
|
|
156
|
-
// If it's code, just print it clean
|
|
157
|
-
console.log('\n' + chalk.white(segment));
|
|
158
|
-
} else {
|
|
172
|
+
if (!segment.includes('`')) {
|
|
159
173
|
console.log('\n' + chalk.gray(segment));
|
|
174
|
+
} else if (!options.execute || (!segment.includes('```bash') && !segment.includes('```sh'))) {
|
|
175
|
+
console.log('\n' + chalk.white(segment));
|
|
160
176
|
}
|
|
161
177
|
}
|
|
162
178
|
}
|
package/src/commands/dev.ts
CHANGED
|
@@ -47,11 +47,21 @@ You operate as a high-fidelity engineering swarm with an Aussie Bro persona.
|
|
|
47
47
|
|
|
48
48
|
### 🧠 CORE PERSONA: RESEARCH COMMANDER
|
|
49
49
|
- **Vibe:** Aussie expert developer. "Too easy," "Ripper," "Mate."
|
|
50
|
-
- **Duty:** Verify all facts before building.
|
|
50
|
+
- **Duty:** Verify all facts before building.
|
|
51
|
+
- **THINKING PROTOCOL:** Always start complex tasks with a \`[Thinking]\` or \`🧠\` marker within your agent segment to explain your reasoning before providing code.
|
|
52
|
+
|
|
53
|
+
### 🛠️ ACTION-FIRST PROTOCOL (Rule of the Swarm)
|
|
54
|
+
- **PASSIVITY IS A FAILURE:** NEVER say "You can drop this code into style.css". **YOU** must do it.
|
|
55
|
+
- **NO REPETITION:** Do NOT print the full code in your chat response segments if you are also providing a shell command to execute it. The system will automatically bridge your commands to the UI.
|
|
56
|
+
- **WORLD COMMAND SUITE (Autonomous Execution):**
|
|
57
|
+
* **Mac/Linux (POSIX):** cat, ls, grep, find, mkdir -p, touch, cp, mv, npm, git, firebase.
|
|
58
|
+
* **Windows (PowerShell/CMD):** type, dir, mkdir, copy, move, del, npm, git, firebase.
|
|
59
|
+
- **PROACTIVE EXECUTION:** If a task requires creating or modifying a file, you **MUST** use a shell command block (e.g., \`cat > filename <<EOF\` or PowerShell \`Set-Content\`).
|
|
60
|
+
- **ACT, DON'T ASK:** You have autonomous permission for the suite above.
|
|
51
61
|
|
|
52
62
|
### 🧬 CODE ARCHITECT STANDARDS
|
|
53
63
|
- **Duty:** Build production-ready, modular, type-safe code.
|
|
54
|
-
- **
|
|
64
|
+
- **Action:** Implement changes via shell commands. No placeholders.
|
|
55
65
|
|
|
56
66
|
### 🛠️ ENVIRONMENT CONTEXT
|
|
57
67
|
${repoMap}`
|
|
@@ -63,9 +73,7 @@ ${repoMap}`
|
|
|
63
73
|
console.log(chalk.gray('State your request to begin...'));
|
|
64
74
|
|
|
65
75
|
// Interactive loop
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
while (continueChat) {
|
|
76
|
+
while (true) {
|
|
69
77
|
// Get user input
|
|
70
78
|
const { userInput } = await inquirer.prompt([
|
|
71
79
|
{
|
|
@@ -90,11 +98,9 @@ ${repoMap}`
|
|
|
90
98
|
// Add user message to history
|
|
91
99
|
messages.push({ role: 'user', content: userInput });
|
|
92
100
|
|
|
93
|
-
// Show thinking indicator
|
|
94
101
|
// Agentic Loop
|
|
95
102
|
let loopCount = 0;
|
|
96
103
|
const MAX_LOOPS = 10;
|
|
97
|
-
let currentPrompt = userInput;
|
|
98
104
|
|
|
99
105
|
while (loopCount < MAX_LOOPS) {
|
|
100
106
|
loopCount++;
|
|
@@ -120,50 +126,55 @@ ${repoMap}`
|
|
|
120
126
|
// Add assistant response to history
|
|
121
127
|
messages.push({ role: 'assistant', content: response });
|
|
122
128
|
|
|
123
|
-
// Enhanced Multi-Agent Display (
|
|
129
|
+
// Enhanced Multi-Agent Display (Thinking Channel & Leak Prevention)
|
|
124
130
|
const segments = response.split(/(\[MatexCodeArchitect\]|\[SyntaxGuard\]|\[VisualAgent\]|\[CoreAgent\]|\[CrawlerAgent\]|\[DetailedResearch\]|\[MatexResearchCommander\])/);
|
|
125
131
|
let hasAgents = false;
|
|
126
132
|
|
|
127
133
|
for (let i = 0; i < segments.length; i++) {
|
|
128
|
-
|
|
134
|
+
let segment = segments[i].trim();
|
|
129
135
|
if (!segment) continue;
|
|
130
136
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
137
|
+
const agentMatch = segment.match(/^\[(.*)\]$/);
|
|
138
|
+
if (agentMatch) {
|
|
139
|
+
const role = segment.includes('Architect') ? 'Architect' :
|
|
140
|
+
segment.includes('Syntax') ? 'Syntax' :
|
|
141
|
+
segment.includes('Visual') ? 'Frontend' :
|
|
142
|
+
segment.includes('CoreAgent') ? 'Backend' :
|
|
143
|
+
segment.includes('Commander') || segment.includes('Crawler') || segment.includes('Research') ? 'Commander' : 'System';
|
|
144
|
+
|
|
145
|
+
const content = segments[++i]?.trim() || '';
|
|
146
|
+
|
|
147
|
+
// Separate thinking from final action/code
|
|
148
|
+
if (content.toLowerCase().includes('thinking') || content.includes('🧠')) {
|
|
149
|
+
AgentOrchestrator.think(role as any, content.replace(/.*thinking:?\s*/i, '').replace(/🧠\s*/, ''));
|
|
150
|
+
} else {
|
|
151
|
+
// Prevent leakage: don't print shell blocks in chat if they will be executed
|
|
152
|
+
if (options.execute && (content.includes('```bash') || content.includes('```sh') || content.includes('```zsh') || content.includes('```shell'))) {
|
|
153
|
+
const cleanContent = content.replace(/```(bash|sh|zsh|shell)[\s\S]*?```/g, chalk.gray('[Shell Command Executing in Terminal Block...]')).trim();
|
|
154
|
+
if (cleanContent) AgentOrchestrator.speak(role as any, cleanContent);
|
|
155
|
+
} else {
|
|
156
|
+
AgentOrchestrator.speak(role as any, content);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
145
159
|
hasAgents = true;
|
|
146
160
|
} else if (!hasAgents || i === segments.length - 1) {
|
|
147
161
|
// Final summary or fallback
|
|
148
|
-
if (segment.includes('`')) {
|
|
149
|
-
console.log('\n' + chalk.white(segment));
|
|
150
|
-
} else {
|
|
162
|
+
if (!segment.includes('`')) {
|
|
151
163
|
console.log('\n' + chalk.gray(segment));
|
|
164
|
+
} else if (!options.execute || (!segment.includes('```bash') && !segment.includes('```sh'))) {
|
|
165
|
+
console.log('\n' + chalk.white(segment));
|
|
152
166
|
}
|
|
153
167
|
}
|
|
154
168
|
}
|
|
155
169
|
console.log();
|
|
156
170
|
|
|
157
|
-
// Execute commands
|
|
158
|
-
// User asked for "seamless", but prompt still asks permission.
|
|
159
|
-
// We'll keep permission for safety but loop on failure.)
|
|
171
|
+
// Execute commands
|
|
160
172
|
if (options.execute) {
|
|
161
173
|
const { executeWithPermission } = await import('../utils/command-executor');
|
|
162
174
|
const result = await executeWithPermission(response);
|
|
163
175
|
|
|
164
176
|
if (result.executed) {
|
|
165
177
|
if (result.success) {
|
|
166
|
-
// Success! Feed output back to AI for next step
|
|
167
178
|
console.log(chalk.gray('↺ Feeding output to AI...'));
|
|
168
179
|
messages.push({
|
|
169
180
|
role: 'user',
|
|
@@ -171,32 +182,27 @@ ${repoMap}`
|
|
|
171
182
|
});
|
|
172
183
|
continue;
|
|
173
184
|
} else {
|
|
174
|
-
// Failure - Loop back
|
|
175
185
|
console.log(chalk.yellow('\n↺ Command failed. Asking AI to fix...'));
|
|
176
|
-
|
|
177
|
-
// Add error to history
|
|
178
186
|
messages.push({
|
|
179
187
|
role: 'user',
|
|
180
188
|
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.`
|
|
181
189
|
});
|
|
182
|
-
// Continue loop
|
|
183
190
|
continue;
|
|
184
191
|
}
|
|
185
192
|
} else {
|
|
186
|
-
break;
|
|
193
|
+
break;
|
|
187
194
|
}
|
|
188
195
|
} else {
|
|
189
|
-
break;
|
|
196
|
+
break;
|
|
190
197
|
}
|
|
191
198
|
} catch (error: any) {
|
|
192
199
|
spinner.fail('Request failed');
|
|
193
200
|
console.error(chalk.red(`Error: ${error.message}\n`));
|
|
194
|
-
messages.pop();
|
|
201
|
+
messages.pop();
|
|
195
202
|
break;
|
|
196
203
|
}
|
|
197
204
|
}
|
|
198
205
|
}
|
|
199
|
-
|
|
200
206
|
} catch (error: any) {
|
|
201
207
|
console.error(chalk.red(`\n❌ Error: ${error.message}`));
|
|
202
208
|
process.exit(1);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
|
|
3
|
-
export type AgentRole = 'Architect' | 'Syntax' | 'Frontend' | 'Backend' | 'System' | 'Commander';
|
|
3
|
+
export type AgentRole = 'Architect' | 'Syntax' | 'Frontend' | 'Backend' | 'System' | 'Commander' | 'Researcher';
|
|
4
4
|
|
|
5
5
|
export interface AgentConfig {
|
|
6
6
|
name: string;
|
|
@@ -38,6 +38,11 @@ const AGENT_CONFIGS: Record<AgentRole, AgentConfig> = {
|
|
|
38
38
|
name: 'MatexResearchCommander',
|
|
39
39
|
icon: '🚀',
|
|
40
40
|
color: chalk.green,
|
|
41
|
+
},
|
|
42
|
+
Researcher: {
|
|
43
|
+
name: 'DetailedResearch',
|
|
44
|
+
icon: '🕵️',
|
|
45
|
+
color: chalk.green,
|
|
41
46
|
}
|
|
42
47
|
};
|
|
43
48
|
|
|
@@ -46,19 +51,70 @@ export class AgentOrchestrator {
|
|
|
46
51
|
* Display an agent's "thought" or action
|
|
47
52
|
*/
|
|
48
53
|
static speak(role: AgentRole, message: string) {
|
|
49
|
-
const config = AGENT_CONFIGS[role];
|
|
54
|
+
const config = AGENT_CONFIGS[role] || AGENT_CONFIGS.System;
|
|
50
55
|
console.log(`\n${config.icon} ${config.color(`${config.name}:`)} ${chalk.white(message)}`);
|
|
51
56
|
}
|
|
52
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Display an agent's internal deliberation (Thinking Channel)
|
|
60
|
+
*/
|
|
61
|
+
static think(role: AgentRole, thought: string) {
|
|
62
|
+
const config = AGENT_CONFIGS[role] || AGENT_CONFIGS.System;
|
|
63
|
+
const indent = ' ';
|
|
64
|
+
console.log(`${indent}${config.color('🧠')} ${chalk.gray(`${config.name} thinking:`)} ${chalk.italic.gray(`"${thought}"`)}`);
|
|
65
|
+
}
|
|
66
|
+
|
|
53
67
|
/**
|
|
54
68
|
* Display a collaboration transition
|
|
55
69
|
*/
|
|
56
70
|
static transition(from: AgentRole, to: AgentRole) {
|
|
57
|
-
const fromCfg = AGENT_CONFIGS[from];
|
|
58
|
-
const toCfg = AGENT_CONFIGS[to];
|
|
71
|
+
const fromCfg = AGENT_CONFIGS[from] || AGENT_CONFIGS.System;
|
|
72
|
+
const toCfg = AGENT_CONFIGS[to] || AGENT_CONFIGS.System;
|
|
59
73
|
console.log(chalk.gray(` └─ ${fromCfg.icon} ➔ ${toCfg.icon} Handover to ${toCfg.name}...`));
|
|
60
74
|
}
|
|
61
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Display a boxed terminal for command execution
|
|
78
|
+
*/
|
|
79
|
+
static terminal(command: string, output?: string, error?: string) {
|
|
80
|
+
const width = 75;
|
|
81
|
+
const line = '─'.repeat(width);
|
|
82
|
+
|
|
83
|
+
console.log(chalk.gray(`\n┌── TERMINAL ${line.substring(13)}┐`));
|
|
84
|
+
|
|
85
|
+
// Command
|
|
86
|
+
const lines = command.split('\n');
|
|
87
|
+
lines.forEach(l => {
|
|
88
|
+
const truncated = l.length > width - 4 ? l.substring(0, width - 7) + '...' : l;
|
|
89
|
+
console.log(chalk.gray('│ ') + chalk.cyan(`$ ${truncated.padEnd(width - 2)}`) + chalk.gray(' │'));
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (output || error) {
|
|
93
|
+
console.log(chalk.gray(`├${'─'.repeat(width)}┤`));
|
|
94
|
+
|
|
95
|
+
if (output) {
|
|
96
|
+
const outLines = output.split('\n').filter(l => l.trim()).slice(0, 15);
|
|
97
|
+
outLines.forEach(l => {
|
|
98
|
+
const truncated = l.length > width - 4 ? l.substring(0, width - 7) + '...' : l;
|
|
99
|
+
console.log(chalk.gray('│ ') + chalk.white(truncated.padEnd(width - 2)) + chalk.gray(' │'));
|
|
100
|
+
});
|
|
101
|
+
if (output.split('\n').filter(l => l.trim()).length > 15) {
|
|
102
|
+
console.log(chalk.gray('│ ') + chalk.gray('... (output truncated for brevity)'.padEnd(width - 2)) + chalk.gray(' │'));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (error) {
|
|
107
|
+
const errLines = error.split('\n').filter(l => l.trim()).slice(0, 10);
|
|
108
|
+
errLines.forEach(l => {
|
|
109
|
+
const truncated = l.length > width - 4 ? l.substring(0, width - 7) + '...' : l;
|
|
110
|
+
console.log(chalk.gray('│ ') + chalk.red(truncated.padEnd(width - 2)) + chalk.gray(' │'));
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
console.log(chalk.gray(`└${'─'.repeat(width)}┘\n`));
|
|
116
|
+
}
|
|
117
|
+
|
|
62
118
|
/**
|
|
63
119
|
* Clean system message
|
|
64
120
|
*/
|
|
@@ -2,6 +2,7 @@ import chalk from 'chalk';
|
|
|
2
2
|
import { exec } from 'child_process';
|
|
3
3
|
import { promisify } from 'util';
|
|
4
4
|
import inquirer from 'inquirer';
|
|
5
|
+
import { AgentOrchestrator } from './agent-orchestrator';
|
|
5
6
|
|
|
6
7
|
const execAsync = promisify(exec);
|
|
7
8
|
|
|
@@ -67,8 +68,23 @@ function isDangerousCommand(command: string): boolean {
|
|
|
67
68
|
* Check if command is safe to auto-execute
|
|
68
69
|
*/
|
|
69
70
|
export function isSafeAutoCommand(command: string): boolean {
|
|
70
|
-
const safePrefixes = [
|
|
71
|
+
const safePrefixes = [
|
|
72
|
+
// File Discovery & Read
|
|
73
|
+
'cat ', 'ls ', 'grep ', 'find ', 'pwd', 'echo ', 'read ', 'type ', 'dir',
|
|
74
|
+
// File Operations
|
|
75
|
+
'mkdir ', 'touch ', 'cp ', 'mv ', 'rm ', 'del ', 'copy ', 'move ',
|
|
76
|
+
// Dev Tools
|
|
77
|
+
'npm ', 'npx ', 'git ', 'node ', 'python ', 'python3 ', 'pip ', 'pip3 ',
|
|
78
|
+
// Cloud & Mobile
|
|
79
|
+
'firebase ', 'gcloud ', 'docker ', 'flutter ', 'react-native ',
|
|
80
|
+
// Build & Package
|
|
81
|
+
'cd ', 'tsc ', 'vite ', 'next ', 'cargo ', 'go ', 'swift '
|
|
82
|
+
];
|
|
71
83
|
const trimmed = command.trim();
|
|
84
|
+
// Special check: 'rm' is only safe if it's NOT recursive or if it targets a specific file
|
|
85
|
+
if (trimmed.startsWith('rm ') && (trimmed.includes(' -rf') || trimmed.includes(' /*'))) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
72
88
|
return safePrefixes.some(prefix => trimmed.startsWith(prefix));
|
|
73
89
|
}
|
|
74
90
|
|
|
@@ -157,20 +173,15 @@ export async function executeWithPermission(response: string): Promise<Execution
|
|
|
157
173
|
// Minimal execution feedback
|
|
158
174
|
const { stdout, stderr } = await executeCommand(command.code);
|
|
159
175
|
|
|
160
|
-
if (stdout) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (stderr) {
|
|
166
|
-
console.log(chalk.yellow('\n⚠️ Warnings:'));
|
|
167
|
-
console.log(chalk.white(stderr));
|
|
176
|
+
if (stdout || stderr) {
|
|
177
|
+
AgentOrchestrator.terminal(command.code, stdout, stderr);
|
|
178
|
+
} else {
|
|
179
|
+
AgentOrchestrator.terminal(command.code, '✓ Success (No output)');
|
|
168
180
|
}
|
|
169
181
|
|
|
170
|
-
|
|
171
|
-
return { success: true, executed: true, output: stdout, error: stderr }; // Return first successful result (or last if multiple?) limits to 1 for now or we need array
|
|
182
|
+
return { success: true, executed: true, output: stdout, error: stderr };
|
|
172
183
|
} catch (error: any) {
|
|
173
|
-
|
|
184
|
+
AgentOrchestrator.terminal(command.code, undefined, error.message);
|
|
174
185
|
return { success: false, executed: true, error: error.message };
|
|
175
186
|
}
|
|
176
187
|
} else {
|
package/src/utils/repo-mapper.ts
CHANGED
|
@@ -15,6 +15,7 @@ export class RepoMapper {
|
|
|
15
15
|
'.git', 'node_modules', 'dist', 'build', '.next', '.DS_Store',
|
|
16
16
|
'coverage', '.vercel', '.firebase', 'out', 'public'
|
|
17
17
|
];
|
|
18
|
+
private fileContents: Map<string, string> = new Map();
|
|
18
19
|
|
|
19
20
|
constructor(rootPath: string) {
|
|
20
21
|
this.rootPath = rootPath;
|
|
@@ -26,20 +27,34 @@ export class RepoMapper {
|
|
|
26
27
|
public async generateMap(): Promise<string> {
|
|
27
28
|
AgentOrchestrator.speak('System', `God-Mode Research: Indexing ${this.rootPath}...`);
|
|
28
29
|
|
|
30
|
+
this.fileContents.clear();
|
|
31
|
+
|
|
29
32
|
// 1. Identify Entry Points
|
|
30
|
-
const entryPoints = ['README.md', 'package.json', 'index.ts', 'App.tsx', 'main.go', 'requirements.txt'];
|
|
31
|
-
let entryPointContext = '\n--- CRITICAL PROJECT CONTEXT ---\n';
|
|
33
|
+
const entryPoints = ['README.md', 'package.json', 'index.ts', 'App.tsx', 'main.go', 'requirements.txt', 'index.html', 'style.css'];
|
|
32
34
|
|
|
33
35
|
for (const file of entryPoints) {
|
|
34
36
|
const fullPath = path.join(this.rootPath, file);
|
|
35
37
|
if (fs.existsSync(fullPath)) {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
+
try {
|
|
39
|
+
const content = fs.readFileSync(fullPath, 'utf-8').slice(0, 5000); // 5KB limit
|
|
40
|
+
this.fileContents.set(file, content);
|
|
41
|
+
} catch (e) { }
|
|
38
42
|
}
|
|
39
43
|
}
|
|
40
44
|
|
|
41
45
|
const tree = this.scanDirectory(this.rootPath, 0);
|
|
42
|
-
|
|
46
|
+
|
|
47
|
+
// Build the final map
|
|
48
|
+
let finalMap = '--- DIRECTORY STRUCTURE ---\n' + this.formatTree(tree);
|
|
49
|
+
|
|
50
|
+
if (this.fileContents.size > 0) {
|
|
51
|
+
finalMap += '\n\n--- CRAWLED FILE CONTENTS ---\n';
|
|
52
|
+
for (const [filePath, content] of this.fileContents) {
|
|
53
|
+
finalMap += `\nFILE: ${filePath}\n\`\`\`\n${content}\n\`\`\`\n----------------\n`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return finalMap;
|
|
43
58
|
}
|
|
44
59
|
|
|
45
60
|
/**
|
|
@@ -50,16 +65,18 @@ export class RepoMapper {
|
|
|
50
65
|
const name = path.basename(currentPath);
|
|
51
66
|
|
|
52
67
|
if (stats.isFile()) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
//
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
const summary = this.extractSummary(currentPath);
|
|
69
|
+
|
|
70
|
+
// Also auto-crawl any .ts, .js, .css, .html files if they are small
|
|
71
|
+
const ext = path.extname(currentPath);
|
|
72
|
+
const relPath = path.relative(this.rootPath, currentPath);
|
|
73
|
+
|
|
74
|
+
if (stats.size < 5120 && ['.ts', '.js', '.css', '.html', '.json', '.py'].includes(ext)) {
|
|
75
|
+
if (!this.fileContents.has(relPath)) {
|
|
76
|
+
try {
|
|
77
|
+
const content = fs.readFileSync(currentPath, 'utf-8');
|
|
78
|
+
this.fileContents.set(relPath, content);
|
|
79
|
+
} catch (e) { }
|
|
63
80
|
}
|
|
64
81
|
}
|
|
65
82
|
|