matex-cli 1.2.84 → 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.
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "matex-cli",
3
- "version": "1.2.84",
3
+ "version": "1.2.87",
4
4
  "description": "MATEX CLI - The Agentic 'Bro-Swarm' for Engineering. Zero-Cost AI for Students and Pro-Grade Dev Power.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
7
7
  "matex": "bin/matex"
8
8
  },
9
9
  "scripts": {
10
- "build": "tsc",
10
+ "build": "rm -rf dist && esbuild src/index.ts --bundle --platform=node --target=node16 --outfile=dist/index.js --minify",
11
11
  "dev": "tsc --watch",
12
12
  "test": "jest",
13
13
  "postinstall": "echo \"\nšŸš€ MATEX AI :: THE BRO-SWARM IS LIVE!\nšŸ‘‰ Run 'matex help' to meet your engineering brothers and enter the zero-cost student universe.\n\"",
@@ -23,7 +23,7 @@
23
23
  "mac-engineering"
24
24
  ],
25
25
  "files": [
26
- "dist/**/*.js",
26
+ "dist/index.js",
27
27
  "bin",
28
28
  "README.md",
29
29
  "USAGE_GUIDE.md"
@@ -35,16 +35,17 @@
35
35
  "chalk": "^4.1.2",
36
36
  "commander": "^11.1.0",
37
37
  "conf": "^11.0.2",
38
+ "dotenv": "^16.3.1",
38
39
  "inquirer": "^8.2.5",
39
- "ora": "^5.4.1",
40
- "dotenv": "^16.3.1"
40
+ "ora": "^5.4.1"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/inquirer": "^9.0.7",
44
+ "@types/jest": "^29.5.0",
44
45
  "@types/node": "^20.10.0",
45
- "typescript": "^5.3.0",
46
+ "esbuild": "^0.27.3",
46
47
  "jest": "^29.7.0",
47
- "@types/jest": "^29.5.0"
48
+ "typescript": "^5.3.0"
48
49
  },
49
50
  "engines": {
50
51
  "node": ">=16.0.0"
@@ -1,173 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.MatexAPIClient = void 0;
7
- const axios_1 = __importDefault(require("axios"));
8
- class MatexAPIClient {
9
- constructor(apiKey, baseURL = 'https://matexai-backend-550499663766.us-central1.run.app') {
10
- this.sovereignKey = null;
11
- this.apiKey = apiKey;
12
- this.baseURL = baseURL;
13
- this.client = axios_1.default.create({
14
- baseURL: this.baseURL,
15
- headers: {
16
- 'X-API-Key': this.apiKey,
17
- 'Content-Type': 'application/json',
18
- },
19
- timeout: 60000, // 60 seconds
20
- });
21
- }
22
- setSovereignKey(key) {
23
- this.sovereignKey = key;
24
- }
25
- /**
26
- * Send a streaming chat request to the API
27
- */
28
- async chatStream(request, onChunk, signal) {
29
- try {
30
- const response = await this.client.post('/api/v1/chat', {
31
- ...request,
32
- uid: 'cli-user',
33
- }, {
34
- responseType: 'stream',
35
- signal: signal
36
- });
37
- return new Promise((resolve, reject) => {
38
- let fullResponse = '';
39
- let buffer = '';
40
- if (signal) {
41
- if (signal.aborted) {
42
- response.data.destroy();
43
- reject(new Error('canceled'));
44
- return;
45
- }
46
- signal.addEventListener('abort', () => {
47
- response.data.destroy();
48
- reject(new Error('canceled'));
49
- });
50
- }
51
- response.data.on('data', (chunk) => {
52
- buffer += chunk.toString();
53
- const lines = buffer.split('\n');
54
- buffer = lines.pop() || ''; // Keep the last incomplete line
55
- for (const line of lines) {
56
- const trimmed = line.trim();
57
- if (trimmed.startsWith('data: ')) {
58
- const jsonStr = trimmed.substring(6).trim();
59
- if (jsonStr === '[DONE]')
60
- continue;
61
- try {
62
- const parsed = JSON.parse(jsonStr);
63
- if (parsed.content) {
64
- fullResponse += parsed.content;
65
- onChunk(parsed.content);
66
- }
67
- }
68
- catch (e) {
69
- // Ignore malformed JSON chunks
70
- }
71
- }
72
- }
73
- });
74
- response.data.on('end', () => {
75
- resolve(fullResponse);
76
- });
77
- response.data.on('error', (err) => {
78
- reject(err);
79
- });
80
- });
81
- }
82
- catch (error) {
83
- if (error.response) {
84
- // Try to extract detail from data if possible (standard FastAPI error format)
85
- let detail = error.response.statusText;
86
- if (error.response.data && error.response.data.detail) {
87
- detail = error.response.data.detail;
88
- }
89
- throw new Error(`API Error: ${detail}`);
90
- }
91
- else {
92
- throw new Error(`Request failed: ${error.message}`);
93
- }
94
- }
95
- }
96
- /**
97
- * Send a chat request to the API (non-streaming fallback)
98
- */
99
- async chat(request) {
100
- try {
101
- const response = await this.client.post('/api/v1/chat', {
102
- ...request,
103
- uid: 'cli-user', // Placeholder, backend uses API key for auth
104
- });
105
- // Backend always returns SSE format, parse it
106
- return this.handleStreamingResponse(response.data);
107
- }
108
- catch (error) {
109
- if (error.response) {
110
- throw new Error(`API Error: ${error.response.data.detail || error.response.statusText}`);
111
- }
112
- else if (error.request) {
113
- throw new Error('No response from server. Please check your internet connection.');
114
- }
115
- else {
116
- throw new Error(`Request failed: ${error.message}`);
117
- }
118
- }
119
- }
120
- /**
121
- * Handle Server-Sent Events (SSE) streaming response
122
- */
123
- async handleStreamingResponse(data) {
124
- let fullResponse = '';
125
- // Parse SSE format: "data: {...}\n\n"
126
- const lines = data.split('\n');
127
- for (const line of lines) {
128
- const trimmed = line.trim();
129
- if (trimmed.startsWith('data: ')) {
130
- const jsonStr = trimmed.substring(6).trim();
131
- if (jsonStr === '[DONE]') {
132
- continue;
133
- }
134
- try {
135
- const parsed = JSON.parse(jsonStr);
136
- if (parsed.content) {
137
- fullResponse += parsed.content;
138
- }
139
- // Skip other fields like 'done', 'incomplete'
140
- }
141
- catch (e) {
142
- // Skip invalid JSON or non-JSON lines
143
- }
144
- }
145
- }
146
- return fullResponse;
147
- }
148
- /**
149
- * List available API keys (requires Firebase token, not for CLI use)
150
- */
151
- async listAPIKeys() {
152
- const response = await this.client.get('/api/v1/api-keys/list');
153
- return response.data;
154
- }
155
- /**
156
- * Test API key validity
157
- */
158
- async testConnection() {
159
- try {
160
- await this.chat({
161
- messages: [{ role: 'user', content: 'test' }],
162
- model: 'matexcodex',
163
- max_tokens: 10,
164
- });
165
- return true;
166
- }
167
- catch (error) {
168
- return false;
169
- }
170
- }
171
- }
172
- exports.MatexAPIClient = MatexAPIClient;
173
- //# sourceMappingURL=client.js.map
@@ -1,63 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.askCommand = void 0;
7
- const commander_1 = require("commander");
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const config_1 = require("../utils/config");
10
- const client_1 = require("../api/client");
11
- const spinner_1 = require("../utils/spinner");
12
- exports.askCommand = new commander_1.Command('ask')
13
- .description('Ask a single question to MATEX AI')
14
- .argument('<question>', 'Your question')
15
- .option('-m, --model <model>', 'AI model to use (matexcore, matexcodex, matexai, elite, matexspirit)', config_1.configManager.getDefaultModel())
16
- .option('-t, --temperature <number>', 'Temperature (0-1)', '0.7')
17
- .option('--max-tokens <number>', 'Maximum tokens in response', '4000')
18
- .action(async (question, options) => {
19
- try {
20
- // Check for API key
21
- const apiKey = config_1.configManager.getAPIKey();
22
- if (!apiKey) {
23
- console.error(chalk_1.default.red('āŒ No API key configured.'));
24
- console.log(chalk_1.default.yellow('Run: matex config set-key <your-api-key>'));
25
- process.exit(1);
26
- }
27
- // Create API client
28
- const client = new client_1.MatexAPIClient(apiKey, config_1.configManager.getBaseURL());
29
- // Show thinking indicator
30
- spinner_1.spinner.start(`Thinking with ${options.model}...`);
31
- // Send request
32
- const response = await client.chat({
33
- messages: [
34
- { role: 'user', content: question }
35
- ],
36
- model: options.model,
37
- temperature: parseFloat(options.temperature),
38
- max_tokens: parseInt(options.maxTokens),
39
- stream: false,
40
- });
41
- spinner_1.spinner.succeed('Response received!');
42
- // Display response
43
- console.log(chalk_1.default.cyan('\nšŸ’¬ MATEX AI:\n'));
44
- console.log(chalk_1.default.white(response));
45
- console.log();
46
- }
47
- catch (error) {
48
- spinner_1.spinner.fail('Request failed');
49
- if (error.message.includes('403')) {
50
- console.error(chalk_1.default.red('\nāŒ Invalid or revoked API key.'));
51
- console.log(chalk_1.default.yellow('Please check your API key or generate a new one from the MATEX AI platform.'));
52
- }
53
- else if (error.message.includes('429')) {
54
- console.error(chalk_1.default.red('\nāŒ Rate limit exceeded.'));
55
- console.log(chalk_1.default.yellow('Please wait a moment before trying again.'));
56
- }
57
- else {
58
- console.error(chalk_1.default.red(`\nāŒ Error: ${error.message}`));
59
- }
60
- process.exit(1);
61
- }
62
- });
63
- //# sourceMappingURL=ask.js.map
@@ -1,273 +0,0 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.augovCommand = void 0;
7
- const commander_1 = require("commander");
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const config_1 = require("../utils/config");
10
- const client_1 = require("../api/client");
11
- const agent_orchestrator_1 = require("../utils/agent-orchestrator");
12
- const repo_mapper_1 = require("../utils/repo-mapper");
13
- const tui_1 = require("../utils/tui");
14
- const agent_session_1 = require("../session/agent-session");
15
- const banter_augov_1 = require("../prompts/banter-augov");
16
- const augov_scrubber_1 = require("../utils/augov-scrubber");
17
- const augov_logger_1 = require("../utils/augov-logger");
18
- const fs_1 = __importDefault(require("fs"));
19
- const path_1 = __importDefault(require("path"));
20
- const inquirer_1 = __importDefault(require("inquirer"));
21
- exports.augovCommand = new commander_1.Command('augov')
22
- .description('šŸ‡¦šŸ‡ŗ Launch AU-GOV in Secure Government Compliance Mode (APS/Cyber Ready)')
23
- .option('-m, --model <model>', 'AI model to use', config_1.configManager.getDefaultModel())
24
- .option('--execute', 'Enable command auto-execution')
25
- .option('--offline', 'Enable Tactical Edge Deployment (Offline Mode using local Llama-3-8B model)')
26
- .action(async (options) => {
27
- try {
28
- const apiKey = config_1.configManager.getAPIKey();
29
- if (!apiKey) {
30
- console.error(chalk_1.default.red('āŒ No API key configured. Run: matex config set-key <key>'));
31
- process.exit(1);
32
- }
33
- // Security Gatekeeper: Mandatory key for AU-GOV mode
34
- const { securityKey } = await inquirer_1.default.prompt([
35
- {
36
- type: 'password',
37
- name: 'securityKey',
38
- message: chalk_1.default.hex('#3B82F6').bold('šŸ”‘ Enter AU-GOV Security Key:'),
39
- mask: '*'
40
- }
41
- ]);
42
- if (securityKey !== 'Buildex@9847') {
43
- console.error(chalk_1.default.red('\n āŒ ACCESS DENIED: Invalid Sovereign Security Key.'));
44
- process.exit(1);
45
- }
46
- console.log(chalk_1.default.green(' āœ… Access Granted. Initiating Sovereign Handshake...\n'));
47
- if (options.offline) {
48
- options.model = 'matexcodexlite'; // Force local quantized model
49
- }
50
- // Zero-Trust Architecture: Connect directly to the sovereign Sydney backend, or localhost if Tactical Edge is active.
51
- const AU_GOV_BACKEND_URL = options.offline ? "http://localhost:8000" : "https://matexaibackendgovernment-964562696516.australia-southeast1.run.app";
52
- const client = new client_1.MatexAPIClient(apiKey, AU_GOV_BACKEND_URL);
53
- // We override the default client chat endpoint to hit our specific AU-GOV proxy (or local fallback)
54
- client.chatStream = async (request, onChunk, signal) => {
55
- const endpoint = options.offline ? '/api/v1/chat' : '/api/v1/augov/chat';
56
- const response = await fetch(`${AU_GOV_BACKEND_URL}${endpoint}`, {
57
- method: 'POST',
58
- headers: {
59
- 'Content-Type': 'application/json',
60
- 'Authorization': `Bearer ${apiKey}`,
61
- 'X-Sovereign-Key': securityKey
62
- },
63
- body: JSON.stringify(request),
64
- signal: signal
65
- });
66
- if (!response.ok)
67
- throw new Error(`AU-GOV Backend Error: ${response.status} ${response.statusText}`);
68
- if (!response.body)
69
- throw new Error('No response body from AU-GOV backend');
70
- const reader = response.body.getReader();
71
- const decoder = new TextDecoder('utf-8');
72
- let buffer = "";
73
- let fullResponse = "";
74
- while (true) {
75
- const { done, value } = await reader.read();
76
- if (done)
77
- break;
78
- buffer += decoder.decode(value, { stream: true });
79
- const lines = buffer.split('\n');
80
- buffer = lines.pop() || "";
81
- for (const line of lines) {
82
- if (line.startsWith('data: ')) {
83
- const dataStr = line.slice(6);
84
- if (dataStr.trim() === '[DONE]')
85
- continue;
86
- try {
87
- const data = JSON.parse(dataStr);
88
- if (data.content) {
89
- fullResponse += data.content;
90
- onChunk(data.content);
91
- }
92
- }
93
- catch (e) { /* Ignore parse errors on chunks */ }
94
- }
95
- }
96
- }
97
- return fullResponse;
98
- };
99
- tui_1.TUI.init();
100
- agent_orchestrator_1.AgentOrchestrator.setMode('augov'); // Use secure AU-GOV styling
101
- tui_1.TUI.drawAugovOrchestratorUI();
102
- const pkiClearance = 'PROTECTED'; // Mocked PKI Certificate Clearance
103
- console.log(chalk_1.default.gray(` Verification: `) + chalk_1.default.hex('#10b981').bold(`PKI Cert Validated. Clearance Level: [${pkiClearance}]\n`));
104
- if (options.offline) {
105
- console.log(chalk_1.default.hex('#f59e0b').bold(' [TACTICAL EDGE] OFFLINE MODE ACTIVE: Routing to local MatexCodexLite (Llama-3-8B).\n'));
106
- }
107
- const currentDir = process.cwd();
108
- const repoMap = await new repo_mapper_1.RepoMapper(currentDir).generateMap();
109
- const extraPrompt = '';
110
- const initialMessages = [
111
- {
112
- role: 'system',
113
- // Zero-Trust Architecture: The CLI sends a handshake and environment context only.
114
- // The actual secure AU-GOV system prompt is injected on the backend to prevent NPM leaks.
115
- content: `[AUGOV_MODE_HANDSHAKE]\n<PKI_CERT_CLEARANCE>${pkiClearance}</PKI_CERT_CLEARANCE>\nCURRENT_DIR: ${currentDir}\n\nSECURE ENVIRONMENT CONTEXT:\n${repoMap}`
116
- }
117
- ];
118
- const session = new agent_session_1.AgentSession({
119
- client,
120
- model: options.model,
121
- execute: options.execute || false,
122
- initialMessages,
123
- broBanter: banter_augov_1.BRO_BANTER_AUGOV,
124
- baseDir: currentDir,
125
- messageScrubber: (input) => augov_scrubber_1.GovPrivacyScrubber.scrub(input),
126
- auditLogger: new augov_logger_1.GovAuditLogger(currentDir),
127
- isAugovMode: true
128
- });
129
- await session.start();
130
- }
131
- catch (error) {
132
- tui_1.TUI.exit();
133
- console.error(chalk_1.default.red(`\nāŒ Secure Session Error: ${error.message}`));
134
- process.exit(1);
135
- }
136
- });
137
- // Freedom of Information (FOI) Document Redactor
138
- exports.augovCommand
139
- .command('redact <file>')
140
- .description('šŸ‡¦šŸ‡ŗ Automate FOI Redaction (Blacks out TFNs, Cabinet Data, Military Assets)')
141
- .action(async (file) => {
142
- tui_1.TUI.init();
143
- agent_orchestrator_1.AgentOrchestrator.setMode('augov');
144
- tui_1.TUI.drawAugovOrchestratorUI();
145
- console.log(chalk_1.default.bold.yellow('\n [FOI REDACTION PROTOCOL INITIATED]'));
146
- const filePath = path_1.default.resolve(process.cwd(), file);
147
- if (!fs_1.default.existsSync(filePath)) {
148
- console.error(chalk_1.default.red(`\nāŒ Error: Document not found at ${filePath}`));
149
- tui_1.TUI.exit();
150
- process.exit(1);
151
- }
152
- try {
153
- console.log(chalk_1.default.gray(` Scanning Document: ${file}...`));
154
- const content = fs_1.default.readFileSync(filePath, 'utf-8');
155
- // Execute the highly secure local scrubber
156
- const { scrubbed, redactionCount } = await augov_scrubber_1.GovPrivacyScrubber.redactDocumentContent(content);
157
- tui_1.TUI.drawGlowingContainer('FOI CLEARED DOCUMENT', 'txt', scrubbed);
158
- console.log(chalk_1.default.bold.green(`\n āœ… Scanning Complete.`));
159
- console.log(chalk_1.default.gray(` Total sensitive assets redacted locally: `) + chalk_1.default.bgBlack.white.bold(` ${redactionCount} `));
160
- console.log(chalk_1.default.gray(` Document is now cleared for Public Release.`));
161
- }
162
- catch (error) {
163
- console.error(chalk_1.default.red(`\nāŒ FOI Processing Error: ${error.message}`));
164
- }
165
- finally {
166
- tui_1.TUI.exit();
167
- }
168
- });
169
- // Legislative & Policy War-Gaming
170
- exports.augovCommand
171
- .command('simulate-policy')
172
- .description('šŸ‡¦šŸ‡ŗ Simulate the impact of new legislation against existing frameworks (e.g. Privacy Act 1988)')
173
- .requiredOption('--bill <file>', 'Path to the drafted bill text document')
174
- .option('-m, --model <model>', 'AI model to use', config_1.configManager.getDefaultModel())
175
- .action(async (options) => {
176
- try {
177
- const apiKey = config_1.configManager.getAPIKey();
178
- if (!apiKey) {
179
- console.error(chalk_1.default.red('āŒ No API key configured. Run: matex config set-key <key>'));
180
- process.exit(1);
181
- }
182
- const AU_GOV_BACKEND_URL = "https://matexaibackendgovernment-964562696516.australia-southeast1.run.app";
183
- const client = new client_1.MatexAPIClient(apiKey, AU_GOV_BACKEND_URL);
184
- // Override stream endpoint
185
- client.chatStream = async (request, onChunk, signal) => {
186
- const response = await fetch(`${AU_GOV_BACKEND_URL}/api/v1/augov/chat`, {
187
- method: 'POST',
188
- headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${apiKey}` },
189
- body: JSON.stringify(request),
190
- signal: signal
191
- });
192
- if (!response.ok)
193
- throw new Error(`AU-GOV Backend Error: ${response.status} ${response.statusText}`);
194
- if (!response.body)
195
- throw new Error('No response body from AU-GOV backend');
196
- const reader = response.body.getReader();
197
- const decoder = new TextDecoder('utf-8');
198
- let buffer = "";
199
- let fullResponse = "";
200
- while (true) {
201
- const { done, value } = await reader.read();
202
- if (done)
203
- break;
204
- buffer += decoder.decode(value, { stream: true });
205
- const lines = buffer.split('\n');
206
- buffer = lines.pop() || "";
207
- for (const line of lines) {
208
- if (line.startsWith('data: ')) {
209
- const dataStr = line.slice(6);
210
- if (dataStr.trim() === '[DONE]')
211
- continue;
212
- try {
213
- const data = JSON.parse(dataStr);
214
- if (data.content) {
215
- fullResponse += data.content;
216
- onChunk(data.content);
217
- }
218
- }
219
- catch (e) { /* Ignore parse errors on chunks */ }
220
- }
221
- }
222
- }
223
- return fullResponse;
224
- };
225
- tui_1.TUI.init();
226
- agent_orchestrator_1.AgentOrchestrator.setMode('augov');
227
- tui_1.TUI.drawAugovOrchestratorUI();
228
- console.log(chalk_1.default.bold.magenta('\n [POLICY WAR-GAMING INITIATED]'));
229
- const filePath = path_1.default.resolve(process.cwd(), options.bill);
230
- if (!fs_1.default.existsSync(filePath)) {
231
- console.error(chalk_1.default.red(`\nāŒ Error: Bill document not found at ${filePath}`));
232
- tui_1.TUI.exit();
233
- process.exit(1);
234
- }
235
- console.log(chalk_1.default.gray(` Ingesting Draft Bill: ${options.bill}...`));
236
- const billContent = fs_1.default.readFileSync(filePath, 'utf-8');
237
- const pkiClearance = 'TOP SECRET';
238
- console.log(chalk_1.default.gray(` Clearance Validated: `) + chalk_1.default.hex('#10b981').bold(`[${pkiClearance}]\n`));
239
- const initialMessages = [
240
- {
241
- role: 'system',
242
- content: `[AUGOV_MODE_HANDSHAKE]\n<PKI_CERT_CLEARANCE>${pkiClearance}</PKI_CERT_CLEARANCE>\nCURRENT_DIR: ${process.cwd()}`
243
- },
244
- {
245
- role: 'user',
246
- 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}`
247
- }
248
- ];
249
- const session = new agent_session_1.AgentSession({
250
- client,
251
- model: options.model,
252
- execute: false, // War-gaming does not execute terminal commands
253
- initialMessages,
254
- broBanter: banter_augov_1.BRO_BANTER_AUGOV,
255
- baseDir: process.cwd(),
256
- messageScrubber: (input) => augov_scrubber_1.GovPrivacyScrubber.scrub(input),
257
- auditLogger: new augov_logger_1.GovAuditLogger(process.cwd()),
258
- isAugovMode: true
259
- });
260
- // Fast-forward straight to the agent loop without waiting for user input since the prompt is pre-loaded
261
- console.log(chalk_1.default.gray(` Executing Multi-Agent Swarm Simulation...\n`));
262
- // We just trigger a custom agent pass and let it stream
263
- await session.agenticLoopPass(1);
264
- console.log(chalk_1.default.bold.green(`\n āœ… Policy Simulation Complete.`));
265
- }
266
- catch (error) {
267
- console.error(chalk_1.default.red(`\nāŒ Simulation Error: ${error.message}`));
268
- }
269
- finally {
270
- tui_1.TUI.exit();
271
- }
272
- });
273
- //# sourceMappingURL=augov.js.map