nexusforge-cli 1.1.1 → 1.2.1

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 (62) hide show
  1. package/dist/components/App.d.ts.map +1 -1
  2. package/dist/components/App.js +183 -17
  3. package/dist/components/App.js.map +1 -1
  4. package/dist/index.js +462 -10
  5. package/dist/index.js.map +1 -1
  6. package/dist/modules/commandEngine.d.ts +70 -0
  7. package/dist/modules/commandEngine.d.ts.map +1 -0
  8. package/dist/modules/commandEngine.js +672 -0
  9. package/dist/modules/commandEngine.js.map +1 -0
  10. package/dist/modules/contextBuilder.d.ts +51 -0
  11. package/dist/modules/contextBuilder.d.ts.map +1 -0
  12. package/dist/modules/contextBuilder.js +725 -0
  13. package/dist/modules/contextBuilder.js.map +1 -0
  14. package/dist/modules/domainDetector.d.ts +64 -0
  15. package/dist/modules/domainDetector.d.ts.map +1 -0
  16. package/dist/modules/domainDetector.js +722 -0
  17. package/dist/modules/domainDetector.js.map +1 -0
  18. package/dist/modules/fileOperations.d.ts +99 -0
  19. package/dist/modules/fileOperations.d.ts.map +1 -0
  20. package/dist/modules/fileOperations.js +543 -0
  21. package/dist/modules/fileOperations.js.map +1 -0
  22. package/dist/modules/forgeEngine.d.ts +153 -0
  23. package/dist/modules/forgeEngine.d.ts.map +1 -0
  24. package/dist/modules/forgeEngine.js +652 -0
  25. package/dist/modules/forgeEngine.js.map +1 -0
  26. package/dist/modules/gitManager.d.ts +151 -0
  27. package/dist/modules/gitManager.d.ts.map +1 -0
  28. package/dist/modules/gitManager.js +539 -0
  29. package/dist/modules/gitManager.js.map +1 -0
  30. package/dist/modules/index.d.ts +25 -0
  31. package/dist/modules/index.d.ts.map +1 -0
  32. package/dist/modules/index.js +25 -0
  33. package/dist/modules/index.js.map +1 -0
  34. package/dist/modules/prdProcessor.d.ts +125 -0
  35. package/dist/modules/prdProcessor.d.ts.map +1 -0
  36. package/dist/modules/prdProcessor.js +466 -0
  37. package/dist/modules/prdProcessor.js.map +1 -0
  38. package/dist/modules/projectScanner.d.ts +105 -0
  39. package/dist/modules/projectScanner.d.ts.map +1 -0
  40. package/dist/modules/projectScanner.js +859 -0
  41. package/dist/modules/projectScanner.js.map +1 -0
  42. package/dist/modules/safetyGuard.d.ts +83 -0
  43. package/dist/modules/safetyGuard.d.ts.map +1 -0
  44. package/dist/modules/safetyGuard.js +492 -0
  45. package/dist/modules/safetyGuard.js.map +1 -0
  46. package/dist/modules/templateManager.d.ts +78 -0
  47. package/dist/modules/templateManager.d.ts.map +1 -0
  48. package/dist/modules/templateManager.js +556 -0
  49. package/dist/modules/templateManager.js.map +1 -0
  50. package/dist/native/index.d.ts +125 -0
  51. package/dist/native/index.d.ts.map +1 -0
  52. package/dist/native/index.js +164 -0
  53. package/dist/native/index.js.map +1 -0
  54. package/dist/services/executor.d.ts +24 -0
  55. package/dist/services/executor.d.ts.map +1 -1
  56. package/dist/services/executor.js +149 -6
  57. package/dist/services/executor.js.map +1 -1
  58. package/dist/services/fileManager.d.ts +134 -0
  59. package/dist/services/fileManager.d.ts.map +1 -0
  60. package/dist/services/fileManager.js +489 -0
  61. package/dist/services/fileManager.js.map +1 -0
  62. package/package.json +1 -1
@@ -0,0 +1,722 @@
1
+ /**
2
+ * Domain Detector for NexusForge CLI
3
+ * Automatically identifies project type and loads relevant context
4
+ * Ported from Python nexusforge/modules/knowledge/domain_detector.py
5
+ */
6
+ import * as fs from 'fs';
7
+ import * as path from 'path';
8
+ // ============================================================================
9
+ // ENUMERATIONS
10
+ // ============================================================================
11
+ export var Domain;
12
+ (function (Domain) {
13
+ Domain["AI_ML"] = "ai_ml";
14
+ Domain["WEB_FRONTEND"] = "web_frontend";
15
+ Domain["WEB_BACKEND"] = "web_backend";
16
+ Domain["WEB_FULLSTACK"] = "web_fullstack";
17
+ Domain["RUST_NATIVE"] = "rust_native";
18
+ Domain["TAURI_DESKTOP"] = "tauri_desktop";
19
+ Domain["HVAC_CONTROLS"] = "hvac_controls";
20
+ Domain["ARC_AGI"] = "arc_agi";
21
+ Domain["DATABASE"] = "database";
22
+ Domain["EMBEDDED"] = "embedded";
23
+ Domain["DEVOPS"] = "devops";
24
+ Domain["MOBILE"] = "mobile";
25
+ Domain["GAME_DEV"] = "game_dev";
26
+ Domain["DATA_SCIENCE"] = "data_science";
27
+ Domain["BLOCKCHAIN"] = "blockchain";
28
+ Domain["IOT"] = "iot";
29
+ Domain["SECURITY"] = "security";
30
+ Domain["CLOUD"] = "cloud";
31
+ Domain["API"] = "api";
32
+ Domain["CLI"] = "cli";
33
+ })(Domain || (Domain = {}));
34
+ // ============================================================================
35
+ // DOMAIN DETECTOR CLASS
36
+ // ============================================================================
37
+ export class DomainDetector {
38
+ detectedDomains = [];
39
+ confidenceScores = new Map();
40
+ evidence = new Map();
41
+ projectPath = '';
42
+ // ========================================================================
43
+ // FILE PATTERNS
44
+ // ========================================================================
45
+ static FILE_PATTERNS = [
46
+ // AI/ML
47
+ { patterns: ['*.ipynb', 'model*.py', 'train*.py', 'dataset*.py'], domain: Domain.AI_ML },
48
+ { patterns: ['requirements-ml.txt', 'environment.yml', '*.h5', '*.pth'], domain: Domain.AI_ML },
49
+ { patterns: ['*.onnx', '*.tflite', '*.pb'], domain: Domain.AI_ML },
50
+ // Web Frontend
51
+ { patterns: ['package.json', '*.jsx', '*.tsx', '*.vue', '*.svelte'], domain: Domain.WEB_FRONTEND },
52
+ { patterns: ['index.html', '*.css', '*.scss', 'vite.config.*', 'next.config.*'], domain: Domain.WEB_FRONTEND },
53
+ { patterns: ['webpack.config.*', 'tsconfig.json', 'tailwind.config.*'], domain: Domain.WEB_FRONTEND },
54
+ // Web Backend
55
+ { patterns: ['server.py', 'app.py', 'main.py', 'wsgi.py'], domain: Domain.WEB_BACKEND },
56
+ { patterns: ['views.py'], domain: Domain.WEB_BACKEND },
57
+ // Fullstack
58
+ { patterns: ['next.config.*', 'remix.config.*', 'astro.config.*'], domain: Domain.WEB_FULLSTACK },
59
+ // Rust
60
+ { patterns: ['Cargo.toml', '*.rs', 'Cargo.lock'], domain: Domain.RUST_NATIVE },
61
+ { patterns: ['tauri.conf.json'], domain: Domain.TAURI_DESKTOP },
62
+ // HVAC
63
+ { patterns: ['*bacnet*', '*modbus*', '*hvac*', '*pid*'], domain: Domain.HVAC_CONTROLS },
64
+ { patterns: ['*AHU*', '*VAV*'], domain: Domain.HVAC_CONTROLS },
65
+ // ARC-AGI
66
+ { patterns: ['arc_*.py', 'grid*.py', 'task*.json'], domain: Domain.ARC_AGI },
67
+ // Database
68
+ { patterns: ['*.sql', 'schema.*', '*.prisma'], domain: Domain.DATABASE },
69
+ // Embedded
70
+ { patterns: ['*.ino', 'platformio.ini', 'Arduino*', 'esp*'], domain: Domain.EMBEDDED },
71
+ { patterns: ['*.hex', '*.bin'], domain: Domain.EMBEDDED },
72
+ // DevOps
73
+ { patterns: ['Dockerfile', 'docker-compose*.yml', '.dockerignore'], domain: Domain.DEVOPS },
74
+ { patterns: ['Jenkinsfile', '.gitlab-ci.yml'], domain: Domain.DEVOPS },
75
+ // Mobile
76
+ { patterns: ['*.swift', '*.kt', 'AndroidManifest.xml'], domain: Domain.MOBILE },
77
+ { patterns: ['pubspec.yaml'], domain: Domain.MOBILE },
78
+ // Game Development
79
+ { patterns: ['*.unity', '*.godot', '*.gd', 'project.godot'], domain: Domain.GAME_DEV },
80
+ { patterns: ['*.tscn'], domain: Domain.GAME_DEV },
81
+ // Blockchain
82
+ { patterns: ['*.sol', 'truffle.js', 'hardhat.config.js', 'foundry.toml'], domain: Domain.BLOCKCHAIN },
83
+ // IoT
84
+ { patterns: ['*mqtt*', '*sensor*', '*device*', '*telemetry*'], domain: Domain.IOT },
85
+ { patterns: ['*sequent*', '*i2c*', '*gpio*', '*spi*', '*uart*'], domain: Domain.IOT },
86
+ // Security
87
+ { patterns: ['*.cert', '*.key', '.env*'], domain: Domain.SECURITY },
88
+ // Cloud
89
+ { patterns: ['serverless.yml', 'sam.yaml'], domain: Domain.CLOUD },
90
+ // API
91
+ { patterns: ['openapi.yaml', 'swagger.json', 'api.yaml'], domain: Domain.API },
92
+ { patterns: ['*.graphql', 'schema.graphql'], domain: Domain.API },
93
+ // CLI
94
+ { patterns: ['cli.py', '__main__.py'], domain: Domain.CLI },
95
+ ];
96
+ // ========================================================================
97
+ // MAIN DETECTION
98
+ // ========================================================================
99
+ detectDomains(projectPath, minConfidence = 0.3) {
100
+ this.projectPath = projectPath;
101
+ this.detectedDomains = [];
102
+ this.confidenceScores = new Map();
103
+ this.evidence = new Map();
104
+ // Run all detection methods
105
+ this.detectByFiles();
106
+ this.detectByDependencies();
107
+ this.detectByImports();
108
+ this.detectByKeywords();
109
+ this.detectByStructure();
110
+ this.detectByConfigFiles();
111
+ // Sort by confidence
112
+ const sortedDomains = Array.from(this.confidenceScores.entries())
113
+ .sort((a, b) => b[1] - a[1]);
114
+ // Create results with evidence
115
+ const results = [];
116
+ for (const [domain, score] of sortedDomains) {
117
+ if (score >= minConfidence) {
118
+ results.push({
119
+ domain,
120
+ confidence: score,
121
+ evidence: this.evidence.get(domain) || [],
122
+ });
123
+ }
124
+ }
125
+ return results;
126
+ }
127
+ // ========================================================================
128
+ // FILE-BASED DETECTION
129
+ // ========================================================================
130
+ detectByFiles() {
131
+ for (const { patterns, domain } of DomainDetector.FILE_PATTERNS) {
132
+ let matched = false;
133
+ for (const pattern of patterns) {
134
+ if (this.hasFiles(pattern)) {
135
+ matched = true;
136
+ this.addEvidence(domain, `Found file pattern: ${pattern}`);
137
+ }
138
+ }
139
+ if (matched) {
140
+ this.addConfidence(domain, 0.3);
141
+ }
142
+ }
143
+ }
144
+ // ========================================================================
145
+ // DEPENDENCY-BASED DETECTION
146
+ // ========================================================================
147
+ detectByDependencies() {
148
+ // Python dependencies
149
+ const pythonDeps = this.getPythonDependencies();
150
+ if (pythonDeps.size > 0) {
151
+ const depDomains = [
152
+ // AI/ML
153
+ { deps: ['torch', 'tensorflow', 'keras', 'jax', 'flax'], domain: Domain.AI_ML },
154
+ { deps: ['scikit-learn', 'pandas', 'numpy', 'matplotlib', 'seaborn'], domain: Domain.DATA_SCIENCE },
155
+ { deps: ['transformers', 'datasets', 'tokenizers', 'accelerate'], domain: Domain.AI_ML },
156
+ { deps: ['opencv-python', 'pillow', 'torchvision', 'albumentations'], domain: Domain.AI_ML },
157
+ // Web Backend
158
+ { deps: ['django', 'flask', 'fastapi', 'aiohttp', 'sanic'], domain: Domain.WEB_BACKEND },
159
+ { deps: ['uvicorn', 'gunicorn', 'celery', 'redis'], domain: Domain.WEB_BACKEND },
160
+ // HVAC
161
+ { deps: ['pymodbus', 'bacpypes', 'bacpypes3', 'paho-mqtt'], domain: Domain.HVAC_CONTROLS },
162
+ // Database
163
+ { deps: ['sqlalchemy', 'psycopg2', 'pymongo', 'asyncpg'], domain: Domain.DATABASE },
164
+ { deps: ['alembic', 'peewee', 'tortoise-orm', 'prisma'], domain: Domain.DATABASE },
165
+ // IoT
166
+ { deps: ['paho-mqtt', 'adafruit-circuitpython', 'blynk', 'awsiot'], domain: Domain.IOT },
167
+ { deps: ['smbus2', 'spidev', 'RPi.GPIO', 'pyserial', 'smbus'], domain: Domain.IOT },
168
+ // Security
169
+ { deps: ['cryptography', 'pyjwt', 'passlib', 'bcrypt', 'argon2'], domain: Domain.SECURITY },
170
+ // Cloud
171
+ { deps: ['boto3', 'azure-functions', 'google-cloud', 'pulumi'], domain: Domain.CLOUD },
172
+ // CLI
173
+ { deps: ['click', 'typer', 'argparse', 'rich', 'questionary'], domain: Domain.CLI },
174
+ ];
175
+ for (const { deps, domain } of depDomains) {
176
+ const matchedDeps = deps.filter(dep => pythonDeps.has(dep));
177
+ if (matchedDeps.length > 0) {
178
+ this.addConfidence(domain, 0.4);
179
+ this.addEvidence(domain, `Python deps: ${matchedDeps.slice(0, 3).join(', ')}`);
180
+ }
181
+ }
182
+ }
183
+ // Node dependencies
184
+ const nodeDeps = this.getNodeDependencies();
185
+ if (nodeDeps.size > 0) {
186
+ const depDomains = [
187
+ // Web Frontend
188
+ { deps: ['react', 'vue', '@angular/core', 'svelte', 'solid-js'], domain: Domain.WEB_FRONTEND },
189
+ { deps: ['next', 'nuxt', 'gatsby', 'astro', 'remix'], domain: Domain.WEB_FULLSTACK },
190
+ { deps: ['@tanstack/react-query', 'zustand', 'jotai', 'valtio'], domain: Domain.WEB_FRONTEND },
191
+ // Web Backend
192
+ { deps: ['express', 'fastify', 'koa', '@nestjs/core', 'hono'], domain: Domain.WEB_BACKEND },
193
+ // Mobile
194
+ { deps: ['react-native', 'expo', '@ionic/react', 'capacitor'], domain: Domain.MOBILE },
195
+ // Desktop
196
+ { deps: ['electron', '@tauri-apps/api', '@tauri-apps/cli'], domain: Domain.TAURI_DESKTOP },
197
+ // Blockchain
198
+ { deps: ['web3', 'ethers', 'viem', 'hardhat', 'foundry'], domain: Domain.BLOCKCHAIN },
199
+ // DevOps
200
+ { deps: ['docker', 'kubernetes', 'terraform', 'pulumi'], domain: Domain.DEVOPS },
201
+ ];
202
+ for (const { deps, domain } of depDomains) {
203
+ const matchedDeps = deps.filter(dep => nodeDeps.has(dep));
204
+ if (matchedDeps.length > 0) {
205
+ this.addConfidence(domain, 0.4);
206
+ this.addEvidence(domain, `Node deps: ${matchedDeps.slice(0, 3).join(', ')}`);
207
+ }
208
+ }
209
+ }
210
+ // Rust dependencies
211
+ const rustDeps = this.getRustDependencies();
212
+ if (rustDeps.has('tauri')) {
213
+ this.addConfidence(Domain.TAURI_DESKTOP, 0.8);
214
+ this.addEvidence(Domain.TAURI_DESKTOP, 'Cargo.toml includes tauri');
215
+ }
216
+ const asyncDeps = new Set(['tokio', 'async-std', 'actix-web', 'axum', 'warp']);
217
+ const hasAsyncDeps = [...asyncDeps].some(dep => rustDeps.has(dep));
218
+ if (hasAsyncDeps) {
219
+ this.addConfidence(Domain.RUST_NATIVE, 0.4);
220
+ this.addEvidence(Domain.RUST_NATIVE, 'Async Rust dependencies');
221
+ }
222
+ const embeddedDeps = new Set(['embedded-hal', 'cortex-m', 'esp-hal', 'rp-hal']);
223
+ const hasEmbeddedDeps = [...embeddedDeps].some(dep => rustDeps.has(dep));
224
+ if (hasEmbeddedDeps) {
225
+ this.addConfidence(Domain.EMBEDDED, 0.6);
226
+ this.addEvidence(Domain.EMBEDDED, 'Embedded Rust dependencies');
227
+ }
228
+ }
229
+ // ========================================================================
230
+ // IMPORT AND KEYWORD DETECTION
231
+ // ========================================================================
232
+ detectByImports() {
233
+ const imports = this.scanImports();
234
+ const importPatterns = [
235
+ // AI/ML
236
+ { patterns: ['torch', 'tensorflow', 'keras', 'sklearn', 'jax'], domain: Domain.AI_ML },
237
+ { patterns: ['cv2', 'PIL', 'torchvision', 'transformers'], domain: Domain.AI_ML },
238
+ // Web
239
+ { patterns: ['flask', 'django', 'fastapi', 'aiohttp'], domain: Domain.WEB_BACKEND },
240
+ { patterns: ['react', 'vue', '@angular', 'svelte'], domain: Domain.WEB_FRONTEND },
241
+ // HVAC
242
+ { patterns: ['modbus', 'bacnet', 'bacpypes', 'mqtt'], domain: Domain.HVAC_CONTROLS },
243
+ // Database
244
+ { patterns: ['sqlalchemy', 'pymongo', 'redis', 'psycopg2'], domain: Domain.DATABASE },
245
+ // IoT
246
+ { patterns: ['paho.mqtt', 'awsiot', 'azure.iot', 'smbus'], domain: Domain.IOT },
247
+ { patterns: ['RPi.GPIO', 'adafruit', 'blynk', 'serial'], domain: Domain.IOT },
248
+ // Security
249
+ { patterns: ['cryptography', 'jwt', 'passlib', 'bcrypt'], domain: Domain.SECURITY },
250
+ ];
251
+ for (const { patterns, domain } of importPatterns) {
252
+ const matchingImports = [...imports].filter(imp => patterns.some(p => imp.includes(p)));
253
+ if (matchingImports.length > 0) {
254
+ const count = matchingImports.length;
255
+ this.addConfidence(domain, Math.min(0.1 * count, 0.5));
256
+ this.addEvidence(domain, `Imports: ${matchingImports.slice(0, 3).join(', ')}`);
257
+ }
258
+ }
259
+ }
260
+ detectByKeywords() {
261
+ const keywords = {
262
+ [Domain.AI_ML]: [
263
+ 'model', 'train', 'epoch', 'batch', 'loss', 'accuracy',
264
+ 'neural', 'network', 'dataset', 'tensor', 'gradient',
265
+ 'optimizer', 'forward', 'backward', 'inference',
266
+ ],
267
+ [Domain.HVAC_CONTROLS]: [
268
+ 'temperature', 'setpoint', 'sensor', 'actuator', 'pid',
269
+ 'vav', 'ahu', 'rtu', 'chiller', 'boiler', 'damper', 'valve',
270
+ 'cfm', 'economizer', 'enthalpy', 'humidity',
271
+ ],
272
+ [Domain.ARC_AGI]: [
273
+ 'grid', 'pattern', 'transformation', 'symmetry', 'rotation',
274
+ 'task', 'puzzle', 'abstract', 'reasoning', 'arc',
275
+ ],
276
+ [Domain.DATABASE]: [
277
+ 'query', 'table', 'schema', 'migration', 'index', 'join',
278
+ 'transaction', 'cursor', 'connection', 'orm',
279
+ ],
280
+ [Domain.BLOCKCHAIN]: [
281
+ 'contract', 'blockchain', 'transaction', 'wallet', 'mining',
282
+ 'consensus', 'hash', 'block', 'chain', 'solidity', 'ethereum',
283
+ ],
284
+ [Domain.GAME_DEV]: [
285
+ 'sprite', 'collision', 'physics', 'render', 'scene',
286
+ 'player', 'enemy', 'level', 'score', 'game', 'unity',
287
+ ],
288
+ [Domain.IOT]: [
289
+ 'sensor', 'device', 'mqtt', 'telemetry', 'gpio', 'i2c',
290
+ 'relay', 'actuator', 'embedded', 'arduino', 'raspberry',
291
+ 'sequent', 'modbus', 'edge', 'gateway', 'protocol', 'firmware',
292
+ ],
293
+ [Domain.SECURITY]: [
294
+ 'auth', 'token', 'encrypt', 'decrypt', 'hash', 'salt',
295
+ 'jwt', 'oauth', 'security', 'permission', 'rbac',
296
+ ],
297
+ [Domain.DEVOPS]: [
298
+ 'deploy', 'container', 'kubernetes', 'docker', 'ci/cd',
299
+ 'pipeline', 'terraform', 'ansible', 'helm', 'infrastructure',
300
+ ],
301
+ [Domain.WEB_FRONTEND]: [],
302
+ [Domain.WEB_BACKEND]: [],
303
+ [Domain.WEB_FULLSTACK]: [],
304
+ [Domain.RUST_NATIVE]: [],
305
+ [Domain.TAURI_DESKTOP]: [],
306
+ [Domain.EMBEDDED]: [],
307
+ [Domain.MOBILE]: [],
308
+ [Domain.DATA_SCIENCE]: [],
309
+ [Domain.CLOUD]: [],
310
+ [Domain.API]: [],
311
+ [Domain.CLI]: [],
312
+ };
313
+ for (const [domain, domainKeywords] of Object.entries(keywords)) {
314
+ if (domainKeywords.length === 0)
315
+ continue;
316
+ const keywordCount = this.countKeywords(domainKeywords);
317
+ if (keywordCount > 10) {
318
+ const confidence = Math.min(keywordCount / 100, 0.5);
319
+ this.addConfidence(domain, confidence);
320
+ this.addEvidence(domain, `Found ${keywordCount} domain keywords`);
321
+ }
322
+ }
323
+ }
324
+ // ========================================================================
325
+ // STRUCTURE AND CONFIG DETECTION
326
+ // ========================================================================
327
+ detectByStructure() {
328
+ const structurePatterns = {
329
+ [Domain.WEB_FRONTEND]: ['src/components', 'src/pages', 'public', 'src/styles'],
330
+ [Domain.WEB_BACKEND]: ['routes', 'controllers', 'models', 'middleware', 'api'],
331
+ [Domain.WEB_FULLSTACK]: ['app', 'pages', 'api', 'components'],
332
+ [Domain.AI_ML]: ['notebooks', 'models', 'data', 'experiments', 'checkpoints'],
333
+ [Domain.HVAC_CONTROLS]: ['sequences', 'points', 'graphics', 'alarms', 'controllers'],
334
+ [Domain.MOBILE]: ['ios', 'android', 'lib', 'assets'],
335
+ [Domain.GAME_DEV]: ['assets', 'scenes', 'scripts', 'prefabs', 'resources'],
336
+ [Domain.IOT]: ['devices', 'sensors', 'mqtt', 'telemetry', 'hardware', 'firmware'],
337
+ [Domain.DEVOPS]: ['kubernetes', 'terraform', 'ansible', 'helm', 'docker'],
338
+ [Domain.API]: ['api', 'routes', 'endpoints', 'schemas'],
339
+ [Domain.RUST_NATIVE]: [],
340
+ [Domain.TAURI_DESKTOP]: [],
341
+ [Domain.ARC_AGI]: [],
342
+ [Domain.DATABASE]: [],
343
+ [Domain.EMBEDDED]: [],
344
+ [Domain.DATA_SCIENCE]: [],
345
+ [Domain.BLOCKCHAIN]: [],
346
+ [Domain.SECURITY]: [],
347
+ [Domain.CLOUD]: [],
348
+ [Domain.CLI]: [],
349
+ };
350
+ for (const [domain, patterns] of Object.entries(structurePatterns)) {
351
+ if (patterns.length === 0)
352
+ continue;
353
+ const matches = patterns.filter(p => fs.existsSync(path.join(this.projectPath, p)));
354
+ if (matches.length >= 2) {
355
+ const confidence = 0.3 * (matches.length / patterns.length);
356
+ this.addConfidence(domain, confidence);
357
+ this.addEvidence(domain, `Project structure: ${matches.slice(0, 3).join(', ')}`);
358
+ }
359
+ }
360
+ }
361
+ detectByConfigFiles() {
362
+ const configPatterns = {
363
+ [Domain.WEB_FRONTEND]: [
364
+ 'vite.config.ts', 'webpack.config.js', 'next.config.js',
365
+ 'tailwind.config.js', 'postcss.config.js',
366
+ ],
367
+ [Domain.WEB_BACKEND]: [
368
+ 'wsgi.py', 'asgi.py', 'uvicorn.py', 'gunicorn.conf.py',
369
+ ],
370
+ [Domain.RUST_NATIVE]: ['Cargo.toml', 'rust-toolchain.toml'],
371
+ [Domain.TAURI_DESKTOP]: ['tauri.conf.json', 'src-tauri/tauri.conf.json'],
372
+ [Domain.MOBILE]: ['AndroidManifest.xml', 'Info.plist', 'expo.json'],
373
+ [Domain.DEVOPS]: ['Dockerfile', 'docker-compose.yml', 'k8s.yaml'],
374
+ [Domain.DATABASE]: ['prisma/schema.prisma', 'alembic.ini'],
375
+ [Domain.IOT]: ['platformio.ini', 'esphome.yaml', 'mqtt.conf'],
376
+ [Domain.WEB_FULLSTACK]: [],
377
+ [Domain.AI_ML]: [],
378
+ [Domain.HVAC_CONTROLS]: [],
379
+ [Domain.ARC_AGI]: [],
380
+ [Domain.EMBEDDED]: [],
381
+ [Domain.DATA_SCIENCE]: [],
382
+ [Domain.GAME_DEV]: [],
383
+ [Domain.BLOCKCHAIN]: [],
384
+ [Domain.SECURITY]: [],
385
+ [Domain.CLOUD]: [],
386
+ [Domain.API]: [],
387
+ [Domain.CLI]: [],
388
+ };
389
+ for (const [domain, configs] of Object.entries(configPatterns)) {
390
+ if (configs.length === 0)
391
+ continue;
392
+ const foundConfigs = configs.filter(config => fs.existsSync(path.join(this.projectPath, config)));
393
+ if (foundConfigs.length > 0) {
394
+ this.addConfidence(domain, 0.4);
395
+ this.addEvidence(domain, `Config files: ${foundConfigs.slice(0, 2).join(', ')}`);
396
+ }
397
+ }
398
+ }
399
+ // ========================================================================
400
+ // HELPER METHODS
401
+ // ========================================================================
402
+ hasFiles(pattern) {
403
+ if (pattern.includes('*')) {
404
+ // Simple glob matching
405
+ const files = this.findFiles(pattern);
406
+ return files.length > 0;
407
+ }
408
+ return fs.existsSync(path.join(this.projectPath, pattern));
409
+ }
410
+ findFiles(pattern, maxDepth = 3) {
411
+ const results = [];
412
+ const regex = this.patternToRegex(pattern);
413
+ const scan = (dir, depth) => {
414
+ if (depth > maxDepth)
415
+ return;
416
+ try {
417
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
418
+ for (const entry of entries) {
419
+ const fullPath = path.join(dir, entry.name);
420
+ const relativePath = path.relative(this.projectPath, fullPath);
421
+ if (entry.isDirectory()) {
422
+ if (!this.shouldIgnoreDir(entry.name)) {
423
+ scan(fullPath, depth + 1);
424
+ }
425
+ }
426
+ else if (regex.test(relativePath) || regex.test(entry.name)) {
427
+ results.push(relativePath);
428
+ }
429
+ }
430
+ }
431
+ catch {
432
+ // Ignore errors
433
+ }
434
+ };
435
+ scan(this.projectPath, 0);
436
+ return results;
437
+ }
438
+ patternToRegex(pattern) {
439
+ const escaped = pattern
440
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&')
441
+ .replace(/\*/g, '.*')
442
+ .replace(/\?/g, '.');
443
+ return new RegExp(escaped, 'i');
444
+ }
445
+ shouldIgnoreDir(name) {
446
+ const ignoreDirs = new Set([
447
+ '.git', 'node_modules', '__pycache__', '.nexusforge',
448
+ 'venv', 'env', 'dist', 'build', 'target', '.next',
449
+ 'coverage', '.pytest_cache', '.mypy_cache',
450
+ ]);
451
+ return ignoreDirs.has(name) || name.startsWith('.');
452
+ }
453
+ addConfidence(domain, score) {
454
+ const current = this.confidenceScores.get(domain) || 0;
455
+ this.confidenceScores.set(domain, Math.min(current + score, 1.0));
456
+ }
457
+ addEvidence(domain, evidenceItem) {
458
+ const current = this.evidence.get(domain) || [];
459
+ current.push(evidenceItem);
460
+ this.evidence.set(domain, current);
461
+ }
462
+ getPythonDependencies() {
463
+ const deps = new Set();
464
+ // requirements.txt
465
+ const reqFile = path.join(this.projectPath, 'requirements.txt');
466
+ if (fs.existsSync(reqFile)) {
467
+ try {
468
+ const content = fs.readFileSync(reqFile, 'utf-8');
469
+ for (const line of content.split('\n')) {
470
+ if (line && !line.startsWith('#')) {
471
+ const pkg = line.split('==')[0].split('>=')[0].split('~=')[0].split('[')[0].trim();
472
+ deps.add(pkg.toLowerCase());
473
+ }
474
+ }
475
+ }
476
+ catch {
477
+ // Ignore errors
478
+ }
479
+ }
480
+ // pyproject.toml (basic parsing)
481
+ const pyproject = path.join(this.projectPath, 'pyproject.toml');
482
+ if (fs.existsSync(pyproject)) {
483
+ try {
484
+ const content = fs.readFileSync(pyproject, 'utf-8');
485
+ // Simple regex to extract dependencies
486
+ const depMatches = content.match(/dependencies\s*=\s*\[([\s\S]*?)\]/);
487
+ if (depMatches) {
488
+ const depsStr = depMatches[1];
489
+ const pkgPattern = /"([^">=<~!]+)/g;
490
+ let match;
491
+ while ((match = pkgPattern.exec(depsStr)) !== null) {
492
+ deps.add(match[1].toLowerCase().trim());
493
+ }
494
+ }
495
+ }
496
+ catch {
497
+ // Ignore errors
498
+ }
499
+ }
500
+ return deps;
501
+ }
502
+ getNodeDependencies() {
503
+ const deps = new Set();
504
+ const pkgJson = path.join(this.projectPath, 'package.json');
505
+ if (fs.existsSync(pkgJson)) {
506
+ try {
507
+ const content = JSON.parse(fs.readFileSync(pkgJson, 'utf-8'));
508
+ const allDeps = {
509
+ ...content.dependencies,
510
+ ...content.devDependencies,
511
+ };
512
+ for (const dep of Object.keys(allDeps)) {
513
+ deps.add(dep);
514
+ }
515
+ }
516
+ catch {
517
+ // Ignore errors
518
+ }
519
+ }
520
+ return deps;
521
+ }
522
+ getRustDependencies() {
523
+ const deps = new Set();
524
+ const cargoToml = path.join(this.projectPath, 'Cargo.toml');
525
+ if (fs.existsSync(cargoToml)) {
526
+ try {
527
+ const content = fs.readFileSync(cargoToml, 'utf-8');
528
+ // Simple regex to extract dependencies
529
+ const depSection = content.match(/\[dependencies\]([\s\S]*?)(?:\[|$)/);
530
+ if (depSection) {
531
+ const lines = depSection[1].split('\n');
532
+ for (const line of lines) {
533
+ const match = line.match(/^(\w+)\s*=/);
534
+ if (match) {
535
+ deps.add(match[1]);
536
+ }
537
+ }
538
+ }
539
+ }
540
+ catch {
541
+ // Ignore errors
542
+ }
543
+ }
544
+ return deps;
545
+ }
546
+ scanImports() {
547
+ const imports = new Set();
548
+ let filesScanned = 0;
549
+ const maxFiles = 100;
550
+ const scan = (dir) => {
551
+ if (filesScanned >= maxFiles)
552
+ return;
553
+ try {
554
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
555
+ for (const entry of entries) {
556
+ if (filesScanned >= maxFiles)
557
+ break;
558
+ const fullPath = path.join(dir, entry.name);
559
+ if (entry.isDirectory()) {
560
+ if (!this.shouldIgnoreDir(entry.name)) {
561
+ scan(fullPath);
562
+ }
563
+ }
564
+ else if (entry.name.endsWith('.py')) {
565
+ try {
566
+ const content = fs.readFileSync(fullPath, 'utf-8');
567
+ const importPattern = /^(?:from\s+(\S+)|import\s+(\S+))/gm;
568
+ let match;
569
+ while ((match = importPattern.exec(content)) !== null) {
570
+ const imp = (match[1] || match[2]).split('.')[0];
571
+ imports.add(imp);
572
+ }
573
+ filesScanned++;
574
+ }
575
+ catch {
576
+ // Ignore errors
577
+ }
578
+ }
579
+ else if (/\.[jt]sx?$/.test(entry.name)) {
580
+ try {
581
+ const content = fs.readFileSync(fullPath, 'utf-8');
582
+ const importPattern = /import\s+.*?\s+from\s+['"](.+?)['"]/g;
583
+ let match;
584
+ while ((match = importPattern.exec(content)) !== null) {
585
+ const imp = match[1].split('/')[0].replace('@', '');
586
+ imports.add(imp);
587
+ }
588
+ filesScanned++;
589
+ }
590
+ catch {
591
+ // Ignore errors
592
+ }
593
+ }
594
+ }
595
+ }
596
+ catch {
597
+ // Ignore errors
598
+ }
599
+ };
600
+ scan(this.projectPath);
601
+ return imports;
602
+ }
603
+ countKeywords(keywords) {
604
+ let count = 0;
605
+ let filesChecked = 0;
606
+ const maxFiles = 50;
607
+ const extensions = new Set(['.py', '.js', '.ts', '.rs', '.go', '.java', '.tsx', '.jsx']);
608
+ const scan = (dir) => {
609
+ if (filesChecked >= maxFiles)
610
+ return;
611
+ try {
612
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
613
+ for (const entry of entries) {
614
+ if (filesChecked >= maxFiles)
615
+ break;
616
+ const fullPath = path.join(dir, entry.name);
617
+ if (entry.isDirectory()) {
618
+ if (!this.shouldIgnoreDir(entry.name)) {
619
+ scan(fullPath);
620
+ }
621
+ }
622
+ else if (extensions.has(path.extname(entry.name))) {
623
+ try {
624
+ const content = fs.readFileSync(fullPath, 'utf-8').toLowerCase();
625
+ for (const keyword of keywords) {
626
+ const regex = new RegExp(keyword.toLowerCase(), 'g');
627
+ const matches = content.match(regex);
628
+ if (matches) {
629
+ count += matches.length;
630
+ }
631
+ }
632
+ filesChecked++;
633
+ }
634
+ catch {
635
+ // Ignore errors
636
+ }
637
+ }
638
+ }
639
+ }
640
+ catch {
641
+ // Ignore errors
642
+ }
643
+ };
644
+ scan(this.projectPath);
645
+ return count;
646
+ }
647
+ // ========================================================================
648
+ // CONTEXT GENERATION
649
+ // ========================================================================
650
+ getDomainContext(domains) {
651
+ const contextMap = {
652
+ [Domain.AI_ML]: 'AI/ML project detected. Loading PyTorch, TensorFlow, HuggingFace patterns. GPU acceleration available.',
653
+ [Domain.WEB_FRONTEND]: 'Frontend project detected. Loading React/Vue/Svelte patterns, modern build tools (Vite, Webpack).',
654
+ [Domain.WEB_BACKEND]: 'Backend project detected. Loading FastAPI/Django/Express patterns, RESTful API best practices.',
655
+ [Domain.WEB_FULLSTACK]: 'Full-stack project detected. Loading Next.js/Remix/SvelteKit patterns, SSR/SSG capabilities.',
656
+ [Domain.HVAC_CONTROLS]: 'HVAC controls detected. Loading BACnet/Modbus protocols, ASHRAE standards, PID control logic.',
657
+ [Domain.RUST_NATIVE]: 'Rust project detected. Loading Rust patterns, cargo ecosystem, systems programming best practices.',
658
+ [Domain.TAURI_DESKTOP]: 'Tauri desktop app detected. Loading Tauri APIs, IPC patterns, cross-platform development.',
659
+ [Domain.IOT]: 'IoT project detected. Loading MQTT patterns, sensor protocols, Sequent Microsystems, edge computing.',
660
+ [Domain.DATABASE]: 'Database project detected. Loading SQL/NoSQL patterns, ORMs, migrations, query optimization.',
661
+ [Domain.EMBEDDED]: 'Embedded systems detected. Loading microcontroller patterns, real-time constraints, hardware interfaces.',
662
+ [Domain.DEVOPS]: 'DevOps project detected. Loading Docker, Kubernetes, CI/CD pipelines, infrastructure as code.',
663
+ [Domain.MOBILE]: 'Mobile app detected. Loading React Native/Flutter patterns, mobile-specific APIs, app deployment.',
664
+ [Domain.GAME_DEV]: 'Game development detected. Loading game engines, physics, rendering, asset management patterns.',
665
+ [Domain.DATA_SCIENCE]: 'Data science project detected. Loading pandas, numpy, visualization, statistical analysis patterns.',
666
+ [Domain.BLOCKCHAIN]: 'Blockchain project detected. Loading smart contracts, Web3, Ethereum/Solidity patterns.',
667
+ [Domain.SECURITY]: 'Security-focused project detected. Loading authentication, encryption, security best practices.',
668
+ [Domain.CLOUD]: 'Cloud project detected. Loading AWS/Azure/GCP patterns, serverless, cloud-native architectures.',
669
+ [Domain.API]: 'API project detected. Loading OpenAPI/GraphQL specifications, API design patterns.',
670
+ [Domain.CLI]: 'CLI application detected. Loading argument parsing, terminal UI, command patterns.',
671
+ [Domain.ARC_AGI]: 'ARC-AGI project detected. Loading grid patterns, transformations, abstract reasoning.',
672
+ };
673
+ const context = new Map();
674
+ for (const result of domains) {
675
+ context.set(result.domain, contextMap[result.domain] || `${result.domain} detected`);
676
+ }
677
+ return context;
678
+ }
679
+ getDetectionSummary() {
680
+ if (this.confidenceScores.size === 0) {
681
+ return 'No domains detected';
682
+ }
683
+ const lines = ['Domain Detection Results:\n'];
684
+ const sortedResults = Array.from(this.confidenceScores.entries())
685
+ .sort((a, b) => b[1] - a[1]);
686
+ for (const [domain, score] of sortedResults) {
687
+ if (score > 0.3) {
688
+ const confidenceBar = '█'.repeat(Math.floor(score * 10));
689
+ lines.push(` ${domain.padEnd(20)} ${confidenceBar.padEnd(10)} ${score.toFixed(2)}`);
690
+ const domainEvidence = this.evidence.get(domain);
691
+ if (domainEvidence) {
692
+ for (const evidence of domainEvidence.slice(0, 2)) {
693
+ lines.push(` └─ ${evidence}`);
694
+ }
695
+ }
696
+ }
697
+ }
698
+ return lines.join('\n');
699
+ }
700
+ }
701
+ // ============================================================================
702
+ // UTILITY FUNCTIONS
703
+ // ============================================================================
704
+ let detectorInstance = null;
705
+ export function getDomainDetector() {
706
+ if (!detectorInstance) {
707
+ detectorInstance = new DomainDetector();
708
+ }
709
+ return detectorInstance;
710
+ }
711
+ export function resetDomainDetector() {
712
+ detectorInstance = null;
713
+ }
714
+ export function detectProjectDomains(projectPath, minConfidence = 0.3) {
715
+ const detector = new DomainDetector();
716
+ return detector.detectDomains(projectPath, minConfidence);
717
+ }
718
+ export function getPrimaryDomain(projectPath) {
719
+ const results = detectProjectDomains(projectPath);
720
+ return results.length > 0 ? results[0].domain : null;
721
+ }
722
+ //# sourceMappingURL=domainDetector.js.map