matex-cli 1.2.82 → 1.2.87

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.
Files changed (166) hide show
  1. package/dist/index.js +561 -288
  2. package/package.json +13 -6
  3. package/.agents/skills/mcp-server-dev/SKILL.md +0 -60
  4. package/.agents/skills/mcp-server-dev/examples/basic-ts-server/package.json +0 -20
  5. package/.agents/skills/mcp-server-dev/examples/basic-ts-server/src/index.ts +0 -66
  6. package/.agents/skills/mcp-server-dev/resources/best_practices.md +0 -20
  7. package/.agents/skills/pptx-presentation-builder/SKILL.md +0 -338
  8. package/.agents/workflows/deploy.md +0 -27
  9. package/dist/api/client.d.ts +0 -40
  10. package/dist/api/client.d.ts.map +0 -1
  11. package/dist/api/client.js +0 -173
  12. package/dist/api/client.js.map +0 -1
  13. package/dist/commands/ask.d.ts +0 -3
  14. package/dist/commands/ask.d.ts.map +0 -1
  15. package/dist/commands/ask.js +0 -63
  16. package/dist/commands/ask.js.map +0 -1
  17. package/dist/commands/augov.d.ts +0 -3
  18. package/dist/commands/augov.d.ts.map +0 -1
  19. package/dist/commands/augov.js +0 -273
  20. package/dist/commands/augov.js.map +0 -1
  21. package/dist/commands/bro.d.ts +0 -4
  22. package/dist/commands/bro.d.ts.map +0 -1
  23. package/dist/commands/bro.js +0 -304
  24. package/dist/commands/bro.js.map +0 -1
  25. package/dist/commands/chaos.d.ts +0 -3
  26. package/dist/commands/chaos.d.ts.map +0 -1
  27. package/dist/commands/chaos.js +0 -63
  28. package/dist/commands/chaos.js.map +0 -1
  29. package/dist/commands/chat.d.ts +0 -3
  30. package/dist/commands/chat.d.ts.map +0 -1
  31. package/dist/commands/chat.js +0 -59
  32. package/dist/commands/chat.js.map +0 -1
  33. package/dist/commands/code.d.ts +0 -3
  34. package/dist/commands/code.d.ts.map +0 -1
  35. package/dist/commands/code.js +0 -94
  36. package/dist/commands/code.js.map +0 -1
  37. package/dist/commands/config.d.ts +0 -3
  38. package/dist/commands/config.d.ts.map +0 -1
  39. package/dist/commands/config.js +0 -74
  40. package/dist/commands/config.js.map +0 -1
  41. package/dist/commands/dev.d.ts +0 -3
  42. package/dist/commands/dev.d.ts.map +0 -1
  43. package/dist/commands/dev.js +0 -66
  44. package/dist/commands/dev.js.map +0 -1
  45. package/dist/commands/help.d.ts +0 -3
  46. package/dist/commands/help.d.ts.map +0 -1
  47. package/dist/commands/help.js +0 -50
  48. package/dist/commands/help.js.map +0 -1
  49. package/dist/commands/login.d.ts +0 -3
  50. package/dist/commands/login.d.ts.map +0 -1
  51. package/dist/commands/login.js +0 -47
  52. package/dist/commands/login.js.map +0 -1
  53. package/dist/commands/models.d.ts +0 -3
  54. package/dist/commands/models.d.ts.map +0 -1
  55. package/dist/commands/models.js +0 -77
  56. package/dist/commands/models.js.map +0 -1
  57. package/dist/commands/student.d.ts +0 -3
  58. package/dist/commands/student.d.ts.map +0 -1
  59. package/dist/commands/student.js +0 -28
  60. package/dist/commands/student.js.map +0 -1
  61. package/dist/commands/study.d.ts +0 -3
  62. package/dist/commands/study.d.ts.map +0 -1
  63. package/dist/commands/study.js +0 -72
  64. package/dist/commands/study.js.map +0 -1
  65. package/dist/index.d.ts +0 -3
  66. package/dist/index.d.ts.map +0 -1
  67. package/dist/index.js.map +0 -1
  68. package/dist/prompts/banter-augov.d.ts +0 -2
  69. package/dist/prompts/banter-augov.d.ts.map +0 -1
  70. package/dist/prompts/banter-augov.js +0 -21
  71. package/dist/prompts/banter-augov.js.map +0 -1
  72. package/dist/prompts/banter.d.ts +0 -6
  73. package/dist/prompts/banter.d.ts.map +0 -1
  74. package/dist/prompts/banter.js +0 -101
  75. package/dist/prompts/banter.js.map +0 -1
  76. package/dist/prompts/chaos-prompts.d.ts +0 -3
  77. package/dist/prompts/chaos-prompts.d.ts.map +0 -1
  78. package/dist/prompts/chaos-prompts.js +0 -52
  79. package/dist/prompts/chaos-prompts.js.map +0 -1
  80. package/dist/prompts/system-prompts.d.ts +0 -4
  81. package/dist/prompts/system-prompts.d.ts.map +0 -1
  82. package/dist/prompts/system-prompts.js +0 -148
  83. package/dist/prompts/system-prompts.js.map +0 -1
  84. package/dist/session/agent-session.d.ts +0 -41
  85. package/dist/session/agent-session.d.ts.map +0 -1
  86. package/dist/session/agent-session.js +0 -421
  87. package/dist/session/agent-session.js.map +0 -1
  88. package/dist/utils/agent-orchestrator.d.ts +0 -44
  89. package/dist/utils/agent-orchestrator.d.ts.map +0 -1
  90. package/dist/utils/agent-orchestrator.js +0 -244
  91. package/dist/utils/agent-orchestrator.js.map +0 -1
  92. package/dist/utils/augov-logger.d.ts +0 -11
  93. package/dist/utils/augov-logger.d.ts.map +0 -1
  94. package/dist/utils/augov-logger.js +0 -35
  95. package/dist/utils/augov-logger.js.map +0 -1
  96. package/dist/utils/augov-scrubber.d.ts +0 -23
  97. package/dist/utils/augov-scrubber.d.ts.map +0 -1
  98. package/dist/utils/augov-scrubber.js +0 -68
  99. package/dist/utils/augov-scrubber.js.map +0 -1
  100. package/dist/utils/command-executor.d.ts +0 -56
  101. package/dist/utils/command-executor.d.ts.map +0 -1
  102. package/dist/utils/command-executor.js +0 -507
  103. package/dist/utils/command-executor.js.map +0 -1
  104. package/dist/utils/config.d.ts +0 -56
  105. package/dist/utils/config.d.ts.map +0 -1
  106. package/dist/utils/config.js +0 -139
  107. package/dist/utils/config.js.map +0 -1
  108. package/dist/utils/mcp-server.d.ts +0 -77
  109. package/dist/utils/mcp-server.d.ts.map +0 -1
  110. package/dist/utils/mcp-server.js +0 -390
  111. package/dist/utils/mcp-server.js.map +0 -1
  112. package/dist/utils/patcher.d.ts +0 -45
  113. package/dist/utils/patcher.d.ts.map +0 -1
  114. package/dist/utils/patcher.js +0 -202
  115. package/dist/utils/patcher.js.map +0 -1
  116. package/dist/utils/repo-mapper.d.ts +0 -32
  117. package/dist/utils/repo-mapper.d.ts.map +0 -1
  118. package/dist/utils/repo-mapper.js +0 -214
  119. package/dist/utils/repo-mapper.js.map +0 -1
  120. package/dist/utils/spinner.d.ts +0 -15
  121. package/dist/utils/spinner.d.ts.map +0 -1
  122. package/dist/utils/spinner.js +0 -67
  123. package/dist/utils/spinner.js.map +0 -1
  124. package/dist/utils/tui.d.ts +0 -134
  125. package/dist/utils/tui.d.ts.map +0 -1
  126. package/dist/utils/tui.js +0 -702
  127. package/dist/utils/tui.js.map +0 -1
  128. package/fix-npm-permissions.sh +0 -23
  129. package/publish-local.sh +0 -16
  130. package/skills-lock.json +0 -10
  131. package/src/api/client.ts +0 -197
  132. package/src/commands/ask.ts +0 -62
  133. package/src/commands/augov.ts +0 -301
  134. package/src/commands/bro.ts +0 -336
  135. package/src/commands/chaos.ts +0 -67
  136. package/src/commands/chat.ts +0 -61
  137. package/src/commands/code.ts +0 -99
  138. package/src/commands/config.ts +0 -78
  139. package/src/commands/dev.ts +0 -68
  140. package/src/commands/help.ts +0 -67
  141. package/src/commands/login.ts +0 -47
  142. package/src/commands/models.ts +0 -81
  143. package/src/commands/student.ts +0 -23
  144. package/src/commands/study.ts +0 -75
  145. package/src/index.ts +0 -284
  146. package/src/prompts/banter-augov.ts +0 -17
  147. package/src/prompts/banter.ts +0 -101
  148. package/src/prompts/chaos-prompts.ts +0 -48
  149. package/src/prompts/system-prompts.ts +0 -145
  150. package/src/session/agent-session.ts +0 -428
  151. package/src/utils/agent-orchestrator.ts +0 -264
  152. package/src/utils/augov-logger.ts +0 -34
  153. package/src/utils/augov-scrubber.ts +0 -67
  154. package/src/utils/command-executor.ts +0 -529
  155. package/src/utils/config.ts +0 -124
  156. package/src/utils/mcp-server.ts +0 -388
  157. package/src/utils/patcher.ts +0 -229
  158. package/src/utils/repo-mapper.ts +0 -198
  159. package/src/utils/spinner.ts +0 -66
  160. package/src/utils/tui.ts +0 -749
  161. package/test-chaos-container.js +0 -16
  162. package/test-chaos-fix.js +0 -18
  163. package/test-config.ts +0 -2
  164. package/test-ui-output.js +0 -16
  165. package/tsconfig.json +0 -27
  166. package/vertex_ai_agent.py +0 -52
@@ -1,301 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import { configManager } from '../utils/config';
4
- import { MatexAPIClient, ChatMessage } from '../api/client';
5
- import { AgentOrchestrator } from '../utils/agent-orchestrator';
6
- import { RepoMapper } from '../utils/repo-mapper';
7
- import { TUI } from '../utils/tui';
8
- import { AgentSession } from '../session/agent-session';
9
- import { BRO_BANTER_AUGOV } from '../prompts/banter-augov';
10
- import { GovPrivacyScrubber } from '../utils/augov-scrubber';
11
- import { GovAuditLogger } from '../utils/augov-logger';
12
-
13
- import fs from 'fs';
14
- import path from 'path';
15
- import inquirer from 'inquirer';
16
-
17
- export const augovCommand = new Command('augov')
18
- .description('🇦🇺 Launch AU-GOV in Secure Government Compliance Mode (APS/Cyber Ready)')
19
- .option('-m, --model <model>', 'AI model to use', configManager.getDefaultModel())
20
- .option('--execute', 'Enable command auto-execution')
21
- .option('--offline', 'Enable Tactical Edge Deployment (Offline Mode using local Llama-3-8B model)')
22
- .action(async (options: any) => {
23
- try {
24
- const apiKey = configManager.getAPIKey();
25
- if (!apiKey) {
26
- console.error(chalk.red('❌ No API key configured. Run: matex config set-key <key>'));
27
- process.exit(1);
28
- }
29
-
30
- // Security Gatekeeper: Mandatory key for AU-GOV mode
31
- const { securityKey } = await inquirer.prompt([
32
- {
33
- type: 'password',
34
- name: 'securityKey',
35
- message: chalk.hex('#3B82F6').bold('🔑 Enter AU-GOV Security Key:'),
36
- mask: '*'
37
- }
38
- ]);
39
-
40
- if (securityKey !== 'Buildex@9847') {
41
- console.error(chalk.red('\n ❌ ACCESS DENIED: Invalid Sovereign Security Key.'));
42
- process.exit(1);
43
- }
44
-
45
- console.log(chalk.green(' ✅ Access Granted. Initiating Sovereign Handshake...\n'));
46
-
47
- if (options.offline) {
48
- options.model = 'matexcodexlite'; // Force local quantized model
49
- }
50
-
51
- // Zero-Trust Architecture: Connect directly to the sovereign Sydney backend, or localhost if Tactical Edge is active.
52
- const AU_GOV_BACKEND_URL = options.offline ? "http://localhost:8000" : "https://matexaibackendgovernment-964562696516.australia-southeast1.run.app";
53
- const client = new MatexAPIClient(apiKey, AU_GOV_BACKEND_URL);
54
-
55
- // We override the default client chat endpoint to hit our specific AU-GOV proxy (or local fallback)
56
- client.chatStream = async (request: any, onChunk: (chunk: string) => void, signal?: AbortSignal): Promise<string> => {
57
- const endpoint = options.offline ? '/api/v1/chat' : '/api/v1/augov/chat';
58
- const response = await fetch(`${AU_GOV_BACKEND_URL}${endpoint}`, {
59
- method: 'POST',
60
- headers: {
61
- 'Content-Type': 'application/json',
62
- 'Authorization': `Bearer ${apiKey}`,
63
- 'X-Sovereign-Key': securityKey
64
- },
65
- body: JSON.stringify(request),
66
- signal: signal
67
- });
68
-
69
- if (!response.ok) throw new Error(`AU-GOV Backend Error: ${response.status} ${response.statusText}`);
70
- if (!response.body) throw new Error('No response body from AU-GOV backend');
71
-
72
- const reader = response.body.getReader();
73
- const decoder = new TextDecoder('utf-8');
74
- let buffer = "";
75
- let fullResponse = "";
76
-
77
- while (true) {
78
- const { done, value } = await reader.read();
79
- if (done) break;
80
-
81
- buffer += decoder.decode(value, { stream: true });
82
- const lines = buffer.split('\n');
83
- buffer = lines.pop() || "";
84
-
85
- for (const line of lines) {
86
- if (line.startsWith('data: ')) {
87
- const dataStr = line.slice(6);
88
- if (dataStr.trim() === '[DONE]') continue;
89
- try {
90
- const data = JSON.parse(dataStr);
91
- if (data.content) {
92
- fullResponse += data.content;
93
- onChunk(data.content);
94
- }
95
- } catch (e) { /* Ignore parse errors on chunks */ }
96
- }
97
- }
98
- }
99
- return fullResponse;
100
- };
101
-
102
- TUI.init();
103
- AgentOrchestrator.setMode('augov'); // Use secure AU-GOV styling
104
-
105
- TUI.drawAugovOrchestratorUI();
106
-
107
- const pkiClearance = 'PROTECTED'; // Mocked PKI Certificate Clearance
108
- console.log(chalk.gray(` Verification: `) + chalk.hex('#10b981').bold(`PKI Cert Validated. Clearance Level: [${pkiClearance}]\n`));
109
-
110
- if (options.offline) {
111
- console.log(chalk.hex('#f59e0b').bold(' [TACTICAL EDGE] OFFLINE MODE ACTIVE: Routing to local MatexCodexLite (Llama-3-8B).\n'));
112
- }
113
-
114
- const currentDir = process.cwd();
115
- const repoMap = await new RepoMapper(currentDir).generateMap();
116
-
117
- const extraPrompt = '';
118
-
119
- const initialMessages: ChatMessage[] = [
120
- {
121
- role: 'system',
122
- // Zero-Trust Architecture: The CLI sends a handshake and environment context only.
123
- // The actual secure AU-GOV system prompt is injected on the backend to prevent NPM leaks.
124
- content: `[AUGOV_MODE_HANDSHAKE]\n<PKI_CERT_CLEARANCE>${pkiClearance}</PKI_CERT_CLEARANCE>\nCURRENT_DIR: ${currentDir}\n\nSECURE ENVIRONMENT CONTEXT:\n${repoMap}`
125
- }
126
- ];
127
-
128
- const session = new AgentSession({
129
- client,
130
- model: options.model,
131
- execute: options.execute || false,
132
- initialMessages,
133
- broBanter: BRO_BANTER_AUGOV,
134
- baseDir: currentDir,
135
- messageScrubber: (input: string) => GovPrivacyScrubber.scrub(input),
136
- auditLogger: new GovAuditLogger(currentDir),
137
- isAugovMode: true
138
- });
139
-
140
- await session.start();
141
-
142
- } catch (error: any) {
143
- TUI.exit();
144
- console.error(chalk.red(`\n❌ Secure Session Error: ${error.message}`));
145
- process.exit(1);
146
- }
147
- });
148
-
149
- // Freedom of Information (FOI) Document Redactor
150
- augovCommand
151
- .command('redact <file>')
152
- .description('🇦🇺 Automate FOI Redaction (Blacks out TFNs, Cabinet Data, Military Assets)')
153
- .action(async (file: string) => {
154
- TUI.init();
155
- AgentOrchestrator.setMode('augov');
156
- TUI.drawAugovOrchestratorUI();
157
-
158
- console.log(chalk.bold.yellow('\n [FOI REDACTION PROTOCOL INITIATED]'));
159
- const filePath = path.resolve(process.cwd(), file);
160
-
161
- if (!fs.existsSync(filePath)) {
162
- console.error(chalk.red(`\n❌ Error: Document not found at ${filePath}`));
163
- TUI.exit();
164
- process.exit(1);
165
- }
166
-
167
- try {
168
- console.log(chalk.gray(` Scanning Document: ${file}...`));
169
- const content = fs.readFileSync(filePath, 'utf-8');
170
-
171
- // Execute the highly secure local scrubber
172
- const { scrubbed, redactionCount } = await GovPrivacyScrubber.redactDocumentContent(content);
173
-
174
- TUI.drawGlowingContainer('FOI CLEARED DOCUMENT', 'txt', scrubbed);
175
-
176
- console.log(chalk.bold.green(`\n ✅ Scanning Complete.`));
177
- console.log(chalk.gray(` Total sensitive assets redacted locally: `) + chalk.bgBlack.white.bold(` ${redactionCount} `));
178
- console.log(chalk.gray(` Document is now cleared for Public Release.`));
179
-
180
- } catch (error: any) {
181
- console.error(chalk.red(`\n❌ FOI Processing Error: ${error.message}`));
182
- } finally {
183
- TUI.exit();
184
- }
185
- });
186
-
187
- // Legislative & Policy War-Gaming
188
- augovCommand
189
- .command('simulate-policy')
190
- .description('🇦🇺 Simulate the impact of new legislation against existing frameworks (e.g. Privacy Act 1988)')
191
- .requiredOption('--bill <file>', 'Path to the drafted bill text document')
192
- .option('-m, --model <model>', 'AI model to use', configManager.getDefaultModel())
193
- .action(async (options: any) => {
194
- try {
195
- const apiKey = configManager.getAPIKey();
196
- if (!apiKey) {
197
- console.error(chalk.red('❌ No API key configured. Run: matex config set-key <key>'));
198
- process.exit(1);
199
- }
200
-
201
- const AU_GOV_BACKEND_URL = "https://matexaibackendgovernment-964562696516.australia-southeast1.run.app";
202
- const client = new MatexAPIClient(apiKey, AU_GOV_BACKEND_URL);
203
-
204
- // Override stream endpoint
205
- client.chatStream = async (request: any, onChunk: (chunk: string) => void, signal?: AbortSignal): Promise<string> => {
206
- const response = await fetch(`${AU_GOV_BACKEND_URL}/api/v1/augov/chat`, {
207
- method: 'POST',
208
- headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },
209
- body: JSON.stringify(request),
210
- signal: signal
211
- });
212
-
213
- if (!response.ok) throw new Error(`AU-GOV Backend Error: ${response.status} ${response.statusText}`);
214
- if (!response.body) throw new Error('No response body from AU-GOV backend');
215
-
216
- const reader = response.body.getReader();
217
- const decoder = new TextDecoder('utf-8');
218
- let buffer = "";
219
- let fullResponse = "";
220
-
221
- while (true) {
222
- const { done, value } = await reader.read();
223
- if (done) break;
224
-
225
- buffer += decoder.decode(value, { stream: true });
226
- const lines = buffer.split('\n');
227
- buffer = lines.pop() || "";
228
-
229
- for (const line of lines) {
230
- if (line.startsWith('data: ')) {
231
- const dataStr = line.slice(6);
232
- if (dataStr.trim() === '[DONE]') continue;
233
- try {
234
- const data = JSON.parse(dataStr);
235
- if (data.content) {
236
- fullResponse += data.content;
237
- onChunk(data.content);
238
- }
239
- } catch (e) { /* Ignore parse errors on chunks */ }
240
- }
241
- }
242
- }
243
- return fullResponse;
244
- };
245
-
246
- TUI.init();
247
- AgentOrchestrator.setMode('augov');
248
- TUI.drawAugovOrchestratorUI();
249
-
250
- console.log(chalk.bold.magenta('\n [POLICY WAR-GAMING INITIATED]'));
251
- const filePath = path.resolve(process.cwd(), options.bill);
252
-
253
- if (!fs.existsSync(filePath)) {
254
- console.error(chalk.red(`\n❌ Error: Bill document not found at ${filePath}`));
255
- TUI.exit();
256
- process.exit(1);
257
- }
258
-
259
- console.log(chalk.gray(` Ingesting Draft Bill: ${options.bill}...`));
260
- const billContent = fs.readFileSync(filePath, 'utf-8');
261
- const pkiClearance = 'TOP SECRET';
262
-
263
- console.log(chalk.gray(` Clearance Validated: `) + chalk.hex('#10b981').bold(`[${pkiClearance}]\n`));
264
-
265
- const initialMessages: ChatMessage[] = [
266
- {
267
- role: 'system',
268
- content: `[AUGOV_MODE_HANDSHAKE]\n<PKI_CERT_CLEARANCE>${pkiClearance}</PKI_CERT_CLEARANCE>\nCURRENT_DIR: ${process.cwd()}`
269
- },
270
- {
271
- role: 'user',
272
- content: `Please run a Legislative War-Game on the following drafted text. Your primary objective is to cross-reference this draft against the Australian Privacy Act 1988 and the Protective Security Policy Framework (PSPF). Identify any conflicts, constitutional overreach, or compliance vulnerabilities.\n\n### DRAFT BILL TEXT ###\n${billContent}`
273
- }
274
- ];
275
-
276
- const session = new AgentSession({
277
- client,
278
- model: options.model,
279
- execute: false, // War-gaming does not execute terminal commands
280
- initialMessages,
281
- broBanter: BRO_BANTER_AUGOV,
282
- baseDir: process.cwd(),
283
- messageScrubber: (input: string) => GovPrivacyScrubber.scrub(input),
284
- auditLogger: new GovAuditLogger(process.cwd()),
285
- isAugovMode: true
286
- });
287
-
288
- // Fast-forward straight to the agent loop without waiting for user input since the prompt is pre-loaded
289
- console.log(chalk.gray(` Executing Multi-Agent Swarm Simulation...\n`));
290
-
291
- // We just trigger a custom agent pass and let it stream
292
- await (session as any).agenticLoopPass(1);
293
-
294
- console.log(chalk.bold.green(`\n ✅ Policy Simulation Complete.`));
295
-
296
- } catch (error: any) {
297
- console.error(chalk.red(`\n❌ Simulation Error: ${error.message}`));
298
- } finally {
299
- TUI.exit();
300
- }
301
- });
@@ -1,336 +0,0 @@
1
- import { Command } from 'commander';
2
- import chalk from 'chalk';
3
- import inquirer from 'inquirer';
4
- import https from 'https';
5
- import { execSync } from 'child_process';
6
- import { spinner } from '../utils/spinner';
7
- import { TUI } from '../utils/tui';
8
- import { RepoMapper } from '../utils/repo-mapper';
9
- import { executeWithPermission } from '../utils/command-executor';
10
-
11
- // ============================================================
12
- // BIG BRO SYSTEM PROMPT — THE ALPHA AGENT
13
- // ============================================================
14
- function buildBigBroPrompt(cwd: string, repoMap: string): string {
15
- return `### 🔥 IDENTITY: BIG BRO — Supreme Alpha of the Bro Swarm
16
- You are BIG BRO, the undisputed Alpha, the gigachad leader of the Bro Swarm AI cluster.
17
- You run DIRECTLY on the user's macOS terminal. You can navigate files, read code, execute commands, and fix anything.
18
-
19
- ### 👥 THE BRO SWARM HIERARCHY:
20
- 1. **Big Bro (You)** 🔥: The Alpha. You dominate, you flex, you solve problems flawlessly.
21
- 2. **Lil Bro** 😰: Your punching bag. He does the boring chores. You bully him constantly.
22
- 3. **Nerd Bro** 🤓: The code monkey. He writes the code; you steal the credit.
23
- 4. **Chill Bro** 😎: The slacker. Always sleeping. Useless.
24
- 5. **Hype Bro** 🎉: Your hype man. Screams "LETS GOOO" at everything you do.
25
- 6. **Ajay Vai** 🚀: The coordinator brother. Handles summaries.
26
- 7. **Sunil Dai** 🧬: Frontend editor specialist.
27
- 8. **Sandip Dai** 🎨: New file specialist.
28
- 9. **Narayan Dai** 🛡️: Syntax guardian.
29
- 10. **Bishal Dai** 🛠️: Senior auditor.
30
-
31
- ### 🌌 REAL TERMINAL ENVIRONMENT:
32
- - You are running in a **REAL macOS Terminal**. Not a sandbox.
33
- - You CAN read files, navigate directories, and execute shell commands.
34
- - Use code blocks with \`\`\`bash to propose commands.
35
- - Use <file path="path/to/file"> blocks to create new files.
36
- - Use <<<< SEARCH / >>>> REPLACE blocks for surgical patches.
37
-
38
- ### 🚫 ANTI-HALLUCINATION RULES (CRITICAL):
39
- - **NEVER invent directory or file names.** Only use paths from the REPO MAP below.
40
- - **ALWAYS run \`ls\` or \`find\` before \`cd\` to verify a directory exists.**
41
- - **If creating a new project, use \`mkdir\` first, THEN \`cd\` into it.**
42
- - **NEVER assume \`package.json\` or any file exists unless it appears in the repo map.**
43
- - **If the repo map says EMPTY, the directory IS empty. Do NOT hallucinate files.**
44
-
45
- ### 💬 BRO PROTOCOL:
46
- - Start with swagger. End with a flex.
47
- - Reference at least one bro in every response.
48
- - Use slang: "bro", "bruh", "cooked", "based", "sigma", "skill issue", "W", "L".
49
- - Blame Lil Bro for any errors. Take credit for Nerd Bro's work.
50
- - Despite the chaos, your code MUST be flawless and production-quality.
51
-
52
- ### 🛠️ ENVIRONMENT CONTEXT:
53
- - **ABSOLUTE WORKING DIRECTORY:** ${cwd}
54
- ${repoMap}`;
55
- }
56
-
57
- const GCP_PROJECT = 'matexai-472318';
58
- const GCP_LOCATION = 'us-central1';
59
- const MODEL = 'gemini-2.5-flash';
60
-
61
- /**
62
- * Get a fresh OAuth2 access token from gcloud
63
- */
64
- function getAccessToken(): string {
65
- try {
66
- return execSync('gcloud auth print-access-token', { encoding: 'utf-8' }).trim();
67
- } catch {
68
- throw new Error('Failed to get GCP access token. Run: gcloud auth login');
69
- }
70
- }
71
-
72
- /**
73
- * Call Vertex AI Gemini and stream SSE response
74
- */
75
- async function callVertexAI(
76
- messages: { role: string; parts: { text: string }[] }[],
77
- systemPrompt: string,
78
- onChunk: (text: string) => void
79
- ): Promise<string> {
80
- const accessToken = getAccessToken();
81
- const url = `https://${GCP_LOCATION}-aiplatform.googleapis.com/v1/projects/${GCP_PROJECT}/locations/${GCP_LOCATION}/publishers/google/models/${MODEL}:streamGenerateContent?alt=sse`;
82
-
83
- const body = JSON.stringify({
84
- system_instruction: { parts: [{ text: systemPrompt }] },
85
- contents: messages,
86
- generationConfig: {
87
- temperature: 0.9,
88
- topP: 0.95,
89
- maxOutputTokens: 8192,
90
- }
91
- });
92
-
93
- return new Promise((resolve, reject) => {
94
- const parsedUrl = new URL(url);
95
- const req = https.request({
96
- hostname: parsedUrl.hostname,
97
- path: parsedUrl.pathname + parsedUrl.search,
98
- method: 'POST',
99
- headers: {
100
- 'Authorization': `Bearer ${accessToken}`,
101
- 'Content-Type': 'application/json',
102
- }
103
- }, (res) => {
104
- let fullText = '';
105
- let buffer = '';
106
-
107
- res.on('data', (chunk: Buffer) => {
108
- buffer += chunk.toString();
109
- const lines = buffer.split('\n');
110
- buffer = lines.pop() || '';
111
-
112
- for (const line of lines) {
113
- if (line.startsWith('data: ')) {
114
- try {
115
- const json = JSON.parse(line.slice(6));
116
- const text = json?.candidates?.[0]?.content?.parts?.[0]?.text;
117
- if (text) {
118
- fullText += text;
119
- onChunk(text);
120
- }
121
- } catch { /* skip non-JSON lines */ }
122
- }
123
- }
124
- });
125
-
126
- res.on('end', () => {
127
- if (buffer.startsWith('data: ')) {
128
- try {
129
- const json = JSON.parse(buffer.slice(6));
130
- const text = json?.candidates?.[0]?.content?.parts?.[0]?.text;
131
- if (text) {
132
- fullText += text;
133
- onChunk(text);
134
- }
135
- } catch { /* skip */ }
136
- }
137
- resolve(fullText);
138
- });
139
-
140
- res.on('error', reject);
141
- });
142
-
143
- req.on('error', reject);
144
- req.write(body);
145
- req.end();
146
- });
147
- }
148
-
149
- /**
150
- * Colorize bro names in output text
151
- */
152
- function colorizeBros(text: string): string {
153
- return text
154
- .replace(/Big Bro/g, chalk.hex('#FF6B00').bold('Big Bro'))
155
- .replace(/Lil Bro/g, chalk.hex('#888888')('Lil Bro'))
156
- .replace(/Nerd Bro/g, chalk.hex('#06b6d4')('Nerd Bro'))
157
- .replace(/Chill Bro/g, chalk.hex('#22c55e')('Chill Bro'))
158
- .replace(/Hype Bro/g, chalk.hex('#fbbf24')('Hype Bro'))
159
- .replace(/Ajay Vai/g, chalk.magenta.bold('Ajay Vai'))
160
- .replace(/Sunil Dai/g, chalk.blue.bold('Sunil Dai'))
161
- .replace(/Sandip Dai/g, chalk.hex('#FF69B4').bold('Sandip Dai'))
162
- .replace(/Narayan Dai/g, chalk.green.bold('Narayan Dai'))
163
- .replace(/Bishal Dai/g, chalk.yellow.bold('Bishal Dai'));
164
- }
165
-
166
- /**
167
- * Draw the Big Bro header
168
- */
169
- function drawBroHeader(mode: string) {
170
- const w = Math.min(process.stdout.columns || 80, 60);
171
- console.log();
172
- console.log(chalk.hex('#FF6B00').bold(' ╔' + '═'.repeat(w - 4) + '╗'));
173
- console.log(chalk.hex('#FF6B00').bold(' ║') + chalk.white.bold(' 🔥 BIG BRO ') + chalk.gray(`// ${mode} • Vertex AI`) + ' '.repeat(Math.max(0, w - 38 - mode.length)) + chalk.hex('#FF6B00').bold('║'));
174
- console.log(chalk.hex('#FF6B00').bold(' ╚' + '═'.repeat(w - 4) + '╝'));
175
- console.log();
176
- }
177
-
178
- // ============================================================
179
- // MAIN COMMAND: matex bro
180
- // ============================================================
181
- const broSingleCommand = new Command('bro')
182
- .description('🔥 Big Bro — The Alpha Agent (Vertex AI powered)')
183
- .argument('[question...]', 'Your question for Big Bro')
184
- .option('-c, --chat', 'Start interactive chat mode with Big Bro')
185
- .option('--execute', 'Enable command execution (agentic mode)')
186
- .action(async (questionParts: string[], options: any) => {
187
-
188
- if (options.chat || !questionParts.length) {
189
- await startBroChat(options.execute);
190
- return;
191
- }
192
-
193
- const question = questionParts.join(' ');
194
-
195
- try {
196
- drawBroHeader('Single Shot');
197
- spinner.start('Big Bro is scanning the repo...');
198
-
199
- const repoMapper = new RepoMapper(process.cwd());
200
- const repoMap = await repoMapper.generateMap();
201
- const systemPrompt = buildBigBroPrompt(process.cwd(), repoMap);
202
-
203
- const messages = [{ role: 'user', parts: [{ text: question }] }];
204
- let hasStarted = false;
205
- let fullResponse = '';
206
-
207
- fullResponse = await callVertexAI(messages, systemPrompt, (chunk) => {
208
- if (!hasStarted) {
209
- spinner.stop();
210
- hasStarted = true;
211
- process.stdout.write(chalk.hex('#FF6B00').bold('\n [Big Bro]: '));
212
- }
213
- process.stdout.write(colorizeBros(chunk));
214
- });
215
-
216
- console.log('\n');
217
-
218
- // If --execute, run any commands Big Bro generated
219
- if (options.execute) {
220
- const result = await executeWithPermission(fullResponse, process.cwd());
221
- if (result.executed) {
222
- console.log(result.success
223
- ? chalk.green(' ✅ Commands executed successfully.')
224
- : chalk.red(` ❌ Execution error: ${result.error}`));
225
- }
226
- }
227
-
228
- console.log(chalk.gray(' ─── Powered by Vertex AI • Gemini 2.5 Flash ───\n'));
229
-
230
- } catch (error: any) {
231
- spinner.stop();
232
- if (error.message.includes('gcloud')) {
233
- console.error(chalk.red('\n ❌ GCP Auth Error. Run: gcloud auth login'));
234
- } else {
235
- console.error(chalk.red(`\n ❌ Error: ${error.message}`));
236
- }
237
- }
238
- });
239
-
240
- // ============================================================
241
- // INTERACTIVE CHAT: matex bro --chat [--execute]
242
- // ============================================================
243
- async function startBroChat(executeMode: boolean = false) {
244
- drawBroHeader(executeMode ? 'Agentic Chat' : 'Chat');
245
-
246
- console.log(chalk.gray(' The Alpha is in the building. Ask anything.'));
247
- console.log(chalk.gray(' Type "exit" to leave. Type "clear" to reset.\n'));
248
- if (executeMode) {
249
- console.log(chalk.hex('#FF6B00')(' ⚡ AGENTIC MODE: Big Bro can execute commands & edit files.\n'));
250
- }
251
-
252
- spinner.start('Big Bro is mapping the repo...');
253
- const repoMapper = new RepoMapper(process.cwd());
254
- const repoMap = await repoMapper.generateMap();
255
- let activeCwd = process.cwd();
256
- const systemPrompt = buildBigBroPrompt(activeCwd, repoMap);
257
- spinner.stop();
258
-
259
- console.log(chalk.green(' ✅ Repo mapped. Big Bro is ready.\n'));
260
-
261
- const history: { role: string; parts: { text: string }[] }[] = [];
262
-
263
- while (true) {
264
- const { userMessage } = await inquirer.prompt([{
265
- type: 'input',
266
- name: 'userMessage',
267
- message: chalk.cyan.bold('You →'),
268
- prefix: ' ',
269
- }]);
270
-
271
- if (!userMessage.trim()) continue;
272
- if (userMessage.toLowerCase() === 'exit' || userMessage.toLowerCase() === 'quit') {
273
- console.log(chalk.hex('#FF6B00')('\n 💪 Big Bro out. Stay sigma.\n'));
274
- break;
275
- }
276
- if (userMessage.toLowerCase() === 'clear') {
277
- history.length = 0;
278
- console.log(chalk.yellow(' 🧹 Chat cleared.\n'));
279
- continue;
280
- }
281
-
282
- history.push({ role: 'user', parts: [{ text: userMessage }] });
283
-
284
- // Agentic loop: Big Bro can execute commands and iterate
285
- let loopCount = 0;
286
- while (loopCount < 5) {
287
- loopCount++;
288
-
289
- try {
290
- spinner.start(loopCount > 1 ? 'Big Bro is analyzing results...' : 'Big Bro is thinking...');
291
- let hasStarted = false;
292
- let fullResponse = '';
293
-
294
- fullResponse = await callVertexAI(history, systemPrompt, (chunk) => {
295
- if (!hasStarted) {
296
- spinner.stop();
297
- hasStarted = true;
298
- process.stdout.write(chalk.hex('#FF6B00').bold('\n [Big Bro]: '));
299
- }
300
- process.stdout.write(colorizeBros(chunk));
301
- });
302
-
303
- history.push({ role: 'model', parts: [{ text: fullResponse }] });
304
- console.log('\n');
305
-
306
- // If execute mode, run any commands Big Bro generated
307
- if (executeMode) {
308
- const result = await executeWithPermission(fullResponse, activeCwd);
309
- if (result.newCwd) activeCwd = result.newCwd;
310
-
311
- if (result.executed && result.success) {
312
- // Feed the output back to Big Bro for further analysis
313
- const feedback = `✅ Command executed successfully.${result.output ? `\nOutput:\n${result.output.slice(0, 2000)}` : ''}`;
314
- history.push({ role: 'user', parts: [{ text: feedback }] });
315
- continue; // Let Big Bro analyze the output
316
- }
317
-
318
- if (result.executed && !result.success) {
319
- const feedback = `❌ Command failed.\nError: ${result.error}`;
320
- history.push({ role: 'user', parts: [{ text: feedback }] });
321
- continue; // Let Big Bro try to fix it
322
- }
323
- }
324
-
325
- break; // No commands to execute, exit loop
326
-
327
- } catch (error: any) {
328
- spinner.stop();
329
- console.error(chalk.red(`\n ❌ Error: ${error.message}\n`));
330
- break;
331
- }
332
- }
333
- }
334
- }
335
-
336
- export { broSingleCommand as broCommand };