@theihtisham/agent-shadow-brain 4.0.3 → 5.0.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 (53) hide show
  1. package/README.md +515 -305
  2. package/dist/adapters/index.d.ts.map +1 -1
  3. package/dist/adapters/index.js +1 -0
  4. package/dist/adapters/index.js.map +1 -1
  5. package/dist/brain/auto-setup.d.ts +54 -0
  6. package/dist/brain/auto-setup.d.ts.map +1 -0
  7. package/dist/brain/auto-setup.js +660 -0
  8. package/dist/brain/auto-setup.js.map +1 -0
  9. package/dist/brain/brain-portability.d.ts +81 -0
  10. package/dist/brain/brain-portability.d.ts.map +1 -0
  11. package/dist/brain/brain-portability.js +329 -0
  12. package/dist/brain/brain-portability.js.map +1 -0
  13. package/dist/brain/collective-learning.d.ts +54 -0
  14. package/dist/brain/collective-learning.d.ts.map +1 -0
  15. package/dist/brain/collective-learning.js +357 -0
  16. package/dist/brain/collective-learning.js.map +1 -0
  17. package/dist/brain/consensus-engine.d.ts +65 -0
  18. package/dist/brain/consensus-engine.d.ts.map +1 -0
  19. package/dist/brain/consensus-engine.js +385 -0
  20. package/dist/brain/consensus-engine.js.map +1 -0
  21. package/dist/brain/context-recall.d.ts +49 -0
  22. package/dist/brain/context-recall.d.ts.map +1 -0
  23. package/dist/brain/context-recall.js +502 -0
  24. package/dist/brain/context-recall.js.map +1 -0
  25. package/dist/brain/hierarchical-memory.d.ts +49 -0
  26. package/dist/brain/hierarchical-memory.d.ts.map +1 -0
  27. package/dist/brain/hierarchical-memory.js +451 -0
  28. package/dist/brain/hierarchical-memory.js.map +1 -0
  29. package/dist/brain/mcp-server.d.ts +12 -0
  30. package/dist/brain/mcp-server.d.ts.map +1 -1
  31. package/dist/brain/mcp-server.js +396 -37
  32. package/dist/brain/mcp-server.js.map +1 -1
  33. package/dist/brain/orchestrator.d.ts +34 -0
  34. package/dist/brain/orchestrator.d.ts.map +1 -1
  35. package/dist/brain/orchestrator.js +83 -1
  36. package/dist/brain/orchestrator.js.map +1 -1
  37. package/dist/brain/plugin-system.d.ts +97 -0
  38. package/dist/brain/plugin-system.d.ts.map +1 -0
  39. package/dist/brain/plugin-system.js +404 -0
  40. package/dist/brain/plugin-system.js.map +1 -0
  41. package/dist/cli.js +429 -3
  42. package/dist/cli.js.map +1 -1
  43. package/dist/dashboard/server.d.ts +4 -0
  44. package/dist/dashboard/server.d.ts.map +1 -1
  45. package/dist/dashboard/server.js +453 -330
  46. package/dist/dashboard/server.js.map +1 -1
  47. package/dist/index.d.ts +8 -1
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +10 -1
  50. package/dist/index.js.map +1 -1
  51. package/dist/types.d.ts +201 -1
  52. package/dist/types.d.ts.map +1 -1
  53. package/package.json +32 -4
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // src/cli.ts — CLI entry point for Shadow Brain v4.0.0
2
+ // src/cli.ts — CLI entry point for Shadow Brain v5.0.1
3
3
  import { Command } from 'commander';
4
4
  import chalk from 'chalk';
5
5
  import Conf from 'conf';
@@ -7,7 +7,7 @@ import * as fs from 'fs';
7
7
  import * as path from 'path';
8
8
  import { Orchestrator } from './brain/orchestrator.js';
9
9
  import { detectRunningAgents, createAdapter } from './adapters/index.js';
10
- const VERSION = '4.0.0';
10
+ const VERSION = '5.0.1';
11
11
  const config = new Conf({
12
12
  projectName: 'shadow-brain',
13
13
  defaults: {
@@ -2179,11 +2179,256 @@ const v4Cmd = new Command('v4')
2179
2179
  process.exit(1);
2180
2180
  }
2181
2181
  });
2182
+ // ─── v5.0.0 INFINITE INTELLIGENCE COMMANDS ──────────────────────────────────
2183
+ const memoryCmd = new Command('memory')
2184
+ .description('v5.0.0 — Hierarchical infinite memory (raw → summary → pattern → principle)')
2185
+ .addCommand(new Command('stats')
2186
+ .description('Show hierarchical memory statistics')
2187
+ .action(async () => {
2188
+ const { HierarchicalMemory } = await import('./brain/hierarchical-memory.js');
2189
+ const hm = new HierarchicalMemory();
2190
+ const stats = hm.stats();
2191
+ console.log(chalk.magenta.bold(`\n HIERARCHICAL MEMORY STATS\n`));
2192
+ console.log(chalk ` {cyan Raw entries:} ${stats.rawCount}`);
2193
+ console.log(chalk ` {cyan Summary entries:} ${stats.summaryCount}`);
2194
+ console.log(chalk ` {cyan Pattern entries:} ${stats.patternCount}`);
2195
+ console.log(chalk ` {cyan Principle entries:} ${stats.principleCount}`);
2196
+ console.log(chalk ` {cyan Total entries:} ${stats.totalEntries}`);
2197
+ console.log(chalk ` {cyan Total size:} ${stats.totalSizeMB.toFixed(3)} MB`);
2198
+ console.log(chalk ` {cyan Compression ratio:} ${(stats.compressionRatio * 100).toFixed(1)}%`);
2199
+ console.log(chalk ` {cyan Retention:} INFINITE`);
2200
+ console.log(chalk ` {cyan Drill-down depth:} ${stats.drillDownDepth} tiers\n`);
2201
+ }))
2202
+ .addCommand(new Command('search')
2203
+ .description('Search hierarchical memory')
2204
+ .argument('<query>', 'Search query')
2205
+ .action(async (query) => {
2206
+ const { HierarchicalMemory } = await import('./brain/hierarchical-memory.js');
2207
+ const hm = new HierarchicalMemory();
2208
+ const results = hm.search(query, 10);
2209
+ if (results.length === 0) {
2210
+ console.log(chalk.yellow(' No results found.'));
2211
+ return;
2212
+ }
2213
+ console.log(chalk.magenta.bold(`\n MEMORY SEARCH: "${query}"\n`));
2214
+ for (const entry of results) {
2215
+ const tierColors = { raw: 'dim', summary: 'cyan', pattern: 'magenta', principle: 'green' };
2216
+ const color = tierColors[entry.tier] || 'white';
2217
+ console.log(chalk ` {${color} [${entry.tier.toUpperCase()}]} ${entry.content.slice(0, 120).replace(/\n/g, ' ')}...`);
2218
+ console.log(chalk ` {dim Category: ${entry.category} | Confidence: ${(entry.confidence * 100).toFixed(0)}% | Importance: ${entry.importance.toFixed(2)}}`);
2219
+ }
2220
+ console.log();
2221
+ }))
2222
+ .addCommand(new Command('drilldown')
2223
+ .description('Drill down from a higher-tier entry to raw sources')
2224
+ .argument('<id>', 'Entry ID (first 8 chars)')
2225
+ .action(async (id) => {
2226
+ const { HierarchicalMemory } = await import('./brain/hierarchical-memory.js');
2227
+ const hm = new HierarchicalMemory();
2228
+ const allEntries = [...hm.getByTier('principle'), ...hm.getByTier('pattern'), ...hm.getByTier('summary')];
2229
+ const match = allEntries.find(e => e.id.startsWith(id));
2230
+ if (!match) {
2231
+ console.log(chalk.yellow(' Entry not found.'));
2232
+ return;
2233
+ }
2234
+ const levels = hm.drillDown(match.id);
2235
+ console.log(chalk.magenta.bold(`\n DRILL-DOWN from [${match.tier}] ${match.content.slice(0, 80)}...\n`));
2236
+ for (let i = 0; i < levels.length; i++) {
2237
+ const tier = levels[i][0]?.tier ?? '?';
2238
+ console.log(chalk ` {cyan Level ${i} [${tier}]}: ${levels[i].length} entries`);
2239
+ for (const entry of levels[i].slice(0, 3)) {
2240
+ console.log(chalk ` {dim ${entry.content.slice(0, 100).replace(/\n/g, ' ')}}`);
2241
+ }
2242
+ }
2243
+ console.log();
2244
+ }));
2245
+ const recallCmd = new Command('recall')
2246
+ .description('v5.0.0 — Context-triggered associative recall')
2247
+ .addCommand(new Command('activate')
2248
+ .description('Activate memories for a specific file/context')
2249
+ .argument('<file>', 'File path or context description')
2250
+ .option('-c, --category <cat>', 'Category filter')
2251
+ .option('-k, --keywords <kw>', 'Comma-separated keywords')
2252
+ .action(async (file, opts) => {
2253
+ const { HierarchicalMemory } = await import('./brain/hierarchical-memory.js');
2254
+ const { ContextRecall } = await import('./brain/context-recall.js');
2255
+ const hm = new HierarchicalMemory();
2256
+ const cr = new ContextRecall(hm);
2257
+ const now = new Date();
2258
+ const results = cr.recall({
2259
+ currentFile: file,
2260
+ currentCategory: opts.category || 'general',
2261
+ recentEdits: [],
2262
+ projectType: 'auto',
2263
+ keywords: opts.keywords?.split(',') || [],
2264
+ timeOfDay: now.getHours(),
2265
+ dayOfWeek: now.getDay(),
2266
+ }, 15);
2267
+ if (results.length === 0) {
2268
+ console.log(chalk.yellow(' No memories activated for this context.'));
2269
+ return;
2270
+ }
2271
+ console.log(chalk.magenta.bold(`\n CONTEXT RECALL: ${file}\n`));
2272
+ console.log(chalk ` {cyan Activated ${results.length} memories}\n`);
2273
+ for (const r of results) {
2274
+ const pct = (r.relevanceScore * 100).toFixed(0);
2275
+ const triggers = r.activatedTriggers.join(', ');
2276
+ console.log(chalk ` {green ${pct}%} [{dim ${r.entry.tier}}] ${r.entry.content.slice(0, 100).replace(/\n/g, ' ')}`);
2277
+ console.log(chalk ` {dim Triggers: ${triggers}}`);
2278
+ }
2279
+ console.log();
2280
+ }))
2281
+ .addCommand(new Command('summary')
2282
+ .description('Get a summary of what the brain knows about current context')
2283
+ .argument('<file>', 'File path')
2284
+ .action(async (file) => {
2285
+ const { HierarchicalMemory } = await import('./brain/hierarchical-memory.js');
2286
+ const { ContextRecall } = await import('./brain/context-recall.js');
2287
+ const hm = new HierarchicalMemory();
2288
+ const cr = new ContextRecall(hm);
2289
+ const summary = cr.getContextSummary({ currentFile: file });
2290
+ console.log(chalk.magenta.bold(`\n CONTEXT SUMMARY\n`));
2291
+ console.log(summary);
2292
+ console.log();
2293
+ }));
2294
+ const consensusCmd = new Command('consensus')
2295
+ .description('v5.0.0 — Multi-agent consensus protocol')
2296
+ .addCommand(new Command('stats')
2297
+ .description('Show consensus engine statistics')
2298
+ .action(async () => {
2299
+ const { ConsensusEngine } = await import('./brain/consensus-engine.js');
2300
+ const ce = new ConsensusEngine();
2301
+ const stats = ce.getStats();
2302
+ console.log(chalk.magenta.bold(`\n CONSENSUS ENGINE STATS\n`));
2303
+ console.log(chalk ` {cyan Total proposals:} ${stats.totalProposals}`);
2304
+ console.log(chalk ` {cyan Accepted:} ${stats.acceptedCount}`);
2305
+ console.log(chalk ` {cyan Rejected:} ${stats.rejectedCount}`);
2306
+ console.log(chalk ` {cyan Conflicts:} ${stats.conflictCount}`);
2307
+ console.log(chalk ` {cyan Pending:} ${stats.pendingCount}`);
2308
+ console.log(chalk ` {cyan Avg agreement:} ${(stats.averageAgreement * 100).toFixed(1)}%`);
2309
+ console.log(chalk ` {cyan Known agents:} ${stats.agentCount}`);
2310
+ if (stats.topTrustedAgents.length > 0) {
2311
+ console.log(chalk `\n {bold Top Trusted Agents:}`);
2312
+ for (const agent of stats.topTrustedAgents) {
2313
+ console.log(chalk ` {green ${agent.agent}}: trust=${(agent.score * 100).toFixed(0)}%, accuracy=${(agent.accuracy * 100).toFixed(0)}%`);
2314
+ }
2315
+ }
2316
+ console.log();
2317
+ }))
2318
+ .addCommand(new Command('trust')
2319
+ .description('Show trust scores for all agents')
2320
+ .action(async () => {
2321
+ const { ConsensusEngine } = await import('./brain/consensus-engine.js');
2322
+ const ce = new ConsensusEngine();
2323
+ const scores = ce.getTrustScores();
2324
+ if (scores.length === 0) {
2325
+ console.log(chalk.yellow(' No trust scores recorded yet.'));
2326
+ return;
2327
+ }
2328
+ console.log(chalk.magenta.bold(`\n AGENT TRUST SCORES\n`));
2329
+ for (const t of scores) {
2330
+ const bar = '█'.repeat(Math.round(t.score * 20));
2331
+ console.log(chalk ` {cyan ${t.agent.slice(0, 20)}}: ${(t.score * 100).toFixed(0)}% ${bar}`);
2332
+ }
2333
+ console.log();
2334
+ }));
2335
+ const collectiveCmd = new Command('collective')
2336
+ .description('v5.0.0 — Cross-project collective learning')
2337
+ .addCommand(new Command('stats')
2338
+ .description('Show collective learning statistics')
2339
+ .action(async () => {
2340
+ const { CollectiveLearning } = await import('./brain/collective-learning.js');
2341
+ const cl = new CollectiveLearning(process.cwd());
2342
+ const stats = cl.getStats();
2343
+ console.log(chalk.magenta.bold(`\n COLLECTIVE LEARNING STATS\n`));
2344
+ console.log(chalk ` {cyan Total rules:} ${stats.totalRules}`);
2345
+ console.log(chalk ` {cyan Verified rules:} ${stats.verifiedRules}`);
2346
+ console.log(chalk ` {cyan Avg accuracy:} ${(stats.averageAccuracy * 100).toFixed(1)}%`);
2347
+ console.log(chalk ` {cyan Consensus rate:} ${(stats.consensusRate * 100).toFixed(1)}%`);
2348
+ console.log(chalk ` {cyan Network size:} ${stats.networkSize} projects`);
2349
+ console.log(chalk ` {cyan Recent adoptions:} ${stats.recentAdoptions}`);
2350
+ if (stats.topCategories.length > 0) {
2351
+ console.log(chalk `\n {bold Top Categories:}`);
2352
+ for (const cat of stats.topCategories.slice(0, 5)) {
2353
+ console.log(chalk ` ${cat.category}: ${cat.count} rules`);
2354
+ }
2355
+ }
2356
+ console.log();
2357
+ }))
2358
+ .addCommand(new Command('rules')
2359
+ .description('List verified collective rules')
2360
+ .option('-c, --category <cat>', 'Filter by category')
2361
+ .action(async (opts) => {
2362
+ const { CollectiveLearning } = await import('./brain/collective-learning.js');
2363
+ const cl = new CollectiveLearning(process.cwd());
2364
+ const rules = cl.getVerifiedRules();
2365
+ if (rules.length === 0) {
2366
+ console.log(chalk.yellow(' No verified collective rules yet.'));
2367
+ return;
2368
+ }
2369
+ console.log(chalk.magenta.bold(`\n VERIFIED COLLECTIVE RULES (${rules.length})\n`));
2370
+ for (const rule of rules.slice(0, 20)) {
2371
+ const acc = (rule.accuracy * 100).toFixed(0);
2372
+ const viral = (rule.viralScore * 100).toFixed(0);
2373
+ console.log(chalk ` {green [${rule.category}]} ${rule.content.slice(0, 100)}`);
2374
+ console.log(chalk ` {dim Accuracy: ${acc}% | Viral: ${viral}% | Verified by: ${rule.verifiedBy.length} projects}`);
2375
+ }
2376
+ console.log();
2377
+ }));
2378
+ const v5Cmd = new Command('v5')
2379
+ .description('Run ALL v5.0.0 infinite intelligence analyses at once')
2380
+ .argument('[project-dir]', 'Project directory', process.cwd())
2381
+ .option('--json', 'Output as JSON')
2382
+ .action(async (projectDir, opts) => {
2383
+ const brainConfig = mergeConfig({ projectDir, watchMode: false });
2384
+ const orchestrator = new Orchestrator(brainConfig);
2385
+ try {
2386
+ console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — v5.0.0 Infinite Intelligence Full Scan\n`));
2387
+ console.log(chalk.cyan(' Running ALL modules: v3.0.0 + v4.0.0 + v5.0.0...'));
2388
+ console.log(chalk.dim(' Hierarchical Memory | Context Recall | Consensus | Collective Learning'));
2389
+ console.log(chalk.dim(' TurboQuant | SSSP | CAIP | Self-Evolution | Predictive | Knowledge Graph | Swarm | Adversarial\n'));
2390
+ const results = await orchestrator.runFullHyperAnalysis();
2391
+ // v5.0.0 Infinite Intelligence results
2392
+ const status = orchestrator.getStatus();
2393
+ const hmStats = status.hierarchicalMemoryStats;
2394
+ const crStats = status.contextRecallStats;
2395
+ const ceStats = status.consensusStats;
2396
+ const clStats = status.collectiveLearningStats;
2397
+ console.log(chalk.bold(' v5.0.0 Infinite Intelligence:'));
2398
+ if (hmStats) {
2399
+ console.log(chalk ` {magenta Hierarchical Memory:} ${hmStats.totalEntries} entries (${hmStats.rawCount} raw, ${hmStats.summaryCount} summary, ${hmStats.patternCount} pattern, ${hmStats.principleCount} principle)`);
2400
+ console.log(chalk ` {magenta Compression:} ${(hmStats.compressionRatio * 100).toFixed(1)}% | Retention: INFINITE`);
2401
+ }
2402
+ if (crStats) {
2403
+ console.log(chalk ` {magenta Context Recall:} ${crStats.triggerCount} learned triggers, ${crStats.linkCount} activation links`);
2404
+ }
2405
+ if (ceStats) {
2406
+ console.log(chalk ` {magenta Consensus:} ${ceStats.totalProposals} proposals, ${ceStats.acceptedCount} accepted, ${ceStats.agentCount} agents`);
2407
+ }
2408
+ if (clStats) {
2409
+ console.log(chalk ` {magenta Collective:} ${clStats.totalRules} rules, ${clStats.verifiedRules} verified, ${(clStats.averageAccuracy * 100).toFixed(0)}% avg accuracy`);
2410
+ }
2411
+ // v4.0.0 results
2412
+ console.log(chalk.bold('\n v4.0.0 Hyper-Intelligence:'));
2413
+ const turbo = results.turboMemoryStats;
2414
+ console.log(chalk ` {cyan TurboQuant:} ${turbo ? `${turbo.totalEntries} entries, ${(turbo.compressionRatio * 100).toFixed(1)}% compressed` : 'N/A'}`);
2415
+ console.log(chalk ` {cyan Evolution:} gen ${results.evolutionSnapshot?.generation ?? 0}, fitness ${results.evolutionSnapshot?.bestFitness?.toFixed(3) ?? 'N/A'}`);
2416
+ // v3.0.0 results
2417
+ console.log(chalk.bold(`\n v3.0.0 Findings: ${results.total}\n`));
2418
+ if (opts.json) {
2419
+ console.log(JSON.stringify({ v3: results, v5: { hmStats, crStats, ceStats, clStats } }, null, 2));
2420
+ }
2421
+ }
2422
+ catch (err) {
2423
+ console.error(chalk.red(' Error:'), err.message);
2424
+ process.exit(1);
2425
+ }
2426
+ });
2182
2427
  // ─── MAIN ─────────────────────────────────────────────────────────────────────
2183
2428
  const program = new Command();
2184
2429
  program
2185
2430
  .name('shadow-brain')
2186
- .description('Shadow Brain v4.0.0 — Hyper-Intelligence Layer for AI Coding Agents with Infinite Memory & Self-Evolution')
2431
+ .description('Shadow Brain v5.0.1 — Infinite Intelligence Layer for AI Coding Agents with Zero-Config Setup, MCP Server, Rich Dashboard, Hierarchical Memory, Context Recall, Consensus & Collective Learning')
2187
2432
  .version(VERSION);
2188
2433
  program.addCommand(startCmd);
2189
2434
  program.addCommand(reviewCmd);
@@ -2238,5 +2483,186 @@ program.addCommand(graphCmd);
2238
2483
  program.addCommand(swarmCmd);
2239
2484
  program.addCommand(defenseCmd);
2240
2485
  program.addCommand(v4Cmd);
2486
+ program.addCommand(memoryCmd);
2487
+ program.addCommand(recallCmd);
2488
+ program.addCommand(consensusCmd);
2489
+ program.addCommand(collectiveCmd);
2490
+ program.addCommand(v5Cmd);
2491
+ // ─── v5.0.1 COMMANDS ────────────────────────────────────────────────────────────
2492
+ // off — Stop Shadow Brain (alias for killing the process, clean shutdown)
2493
+ const offCmd = new Command('off')
2494
+ .description('Stop Shadow Brain and clean up')
2495
+ .action(async () => {
2496
+ console.log(chalk.magenta.bold('\n SHADOW BRAIN v' + VERSION + ' — Shutting down'));
2497
+ try {
2498
+ const { default: execaDefault } = await import('execa');
2499
+ const exec = execaDefault;
2500
+ try {
2501
+ if (process.platform === 'win32') {
2502
+ await exec('taskkill', ['/F', '/IM', 'node.exe', '/FI', 'WINDOWTITLE eq shadow-brain*'], { reject: false });
2503
+ }
2504
+ else {
2505
+ await exec('pkill', ['-f', 'shadow-brain'], { reject: false });
2506
+ }
2507
+ }
2508
+ catch { /* no process found */ }
2509
+ console.log(chalk.green(' Shadow Brain stopped successfully.'));
2510
+ }
2511
+ catch {
2512
+ console.log(chalk.yellow(' No running Shadow Brain instance found.'));
2513
+ }
2514
+ process.exit(0);
2515
+ });
2516
+ // ask — Natural language query against brain state
2517
+ const askCmd = new Command('ask')
2518
+ .description('Ask Shadow Brain a question about your project')
2519
+ .argument('<question>', 'Natural language question')
2520
+ .option('-p, --provider <provider>', 'LLM provider')
2521
+ .option('-m, --model <model>', 'LLM model')
2522
+ .action(async (question, opts) => {
2523
+ console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — Ask`));
2524
+ console.log(chalk.dim(' Question: ') + chalk.cyan(question));
2525
+ try {
2526
+ const brainConfig = mergeConfig({ ...opts, projectDir: process.cwd() });
2527
+ const orchestrator = new Orchestrator(brainConfig);
2528
+ await orchestrator.start();
2529
+ // Get project context and build a prompt
2530
+ const status = orchestrator.getStatus();
2531
+ const prompt = `You are Shadow Brain, an expert AI coding intelligence layer. Based on the following project context, answer the user's question concisely.\n\nProject: ${status.projectDir}\nProvider: ${status.provider}\nHealth Score: ${status.healthScore || 'N/A'}\nInsights Generated: ${status.insightsGenerated}\nFiles Reviewed: ${status.filesReviewed}\n\nQuestion: ${question}\n\nAnswer:`;
2532
+ // Use the LLM client directly via the analyzer's prompt builder
2533
+ const llm = new (await import('./brain/llm-client.js')).LLMClient({
2534
+ provider: brainConfig.provider,
2535
+ apiKey: brainConfig.apiKey,
2536
+ model: brainConfig.model,
2537
+ });
2538
+ const answer = await llm.complete(prompt);
2539
+ console.log(chalk.green('\n ' + answer));
2540
+ await orchestrator.stop();
2541
+ }
2542
+ catch (err) {
2543
+ console.error(chalk.red(' Error:'), err.message);
2544
+ process.exit(1);
2545
+ }
2546
+ });
2547
+ // export — Export brain state
2548
+ const exportCmd = new Command('export')
2549
+ .description('Export full brain state to a portable JSON file')
2550
+ .option('-o, --output <dir>', 'Output directory for the export')
2551
+ .action(async (opts) => {
2552
+ console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — Export`));
2553
+ try {
2554
+ const { BrainPortability } = await import('./brain/brain-portability.js');
2555
+ const portability = new BrainPortability(process.cwd(), opts.output);
2556
+ const result = await portability.exportBrain();
2557
+ console.log(chalk.green(' Brain state exported successfully!'));
2558
+ console.log(chalk.dim(' File: ') + chalk.cyan(result.filePath));
2559
+ console.log(chalk.dim(' Size: ') + chalk.cyan((result.sizeBytes / 1024).toFixed(1) + ' KB'));
2560
+ console.log(chalk.dim(' SHA-256: ') + chalk.dim(result.checksum.slice(0, 16) + '...'));
2561
+ }
2562
+ catch (err) {
2563
+ console.error(chalk.red(' Error:'), err.message);
2564
+ process.exit(1);
2565
+ }
2566
+ });
2567
+ // import — Import brain state
2568
+ const importCmd = new Command('import')
2569
+ .description('Import brain state from an export file')
2570
+ .argument('<file>', 'Path to the export JSON file')
2571
+ .option('--merge', 'Merge with existing state instead of replacing')
2572
+ .option('--skip <modules>', 'Comma-separated list of modules to skip')
2573
+ .action(async (file, opts) => {
2574
+ console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — Import`));
2575
+ try {
2576
+ const { BrainPortability } = await import('./brain/brain-portability.js');
2577
+ const portability = new BrainPortability(process.cwd());
2578
+ const result = await portability.importBrain(file, {
2579
+ merge: opts.merge || false,
2580
+ skipModules: opts.skip?.split(',') || [],
2581
+ });
2582
+ console.log(chalk.green(' Brain state imported successfully!'));
2583
+ console.log(chalk.dim(' Imported: ') + chalk.green(result.imported.join(', ') || 'none'));
2584
+ console.log(chalk.dim(' Skipped: ') + chalk.yellow(result.skipped.join(', ') || 'none'));
2585
+ if (result.errors.length > 0) {
2586
+ console.log(chalk.dim(' Errors: ') + chalk.red(result.errors.join('; ')));
2587
+ }
2588
+ }
2589
+ catch (err) {
2590
+ console.error(chalk.red(' Error:'), err.message);
2591
+ process.exit(1);
2592
+ }
2593
+ });
2594
+ // plugin — Manage plugins
2595
+ const pluginCmd = new Command('plugin')
2596
+ .description('Manage Shadow Brain plugins')
2597
+ .addCommand(new Command('list')
2598
+ .description('List installed plugins')
2599
+ .action(async () => {
2600
+ console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — Plugins`));
2601
+ try {
2602
+ const { PluginSystem } = await import('./brain/plugin-system.js');
2603
+ const ps = new PluginSystem(process.cwd());
2604
+ await ps.loadAll();
2605
+ const plugins = ps.getPlugins();
2606
+ if (plugins.length === 0) {
2607
+ console.log(chalk.dim(' No plugins found.'));
2608
+ console.log(chalk.dim(' Add plugins to: ') + chalk.cyan('shadow-brain-plugins/'));
2609
+ return;
2610
+ }
2611
+ for (const p of plugins) {
2612
+ const status = p.enabled ? chalk.green('active') : chalk.red('disabled');
2613
+ console.log(` ${status} ${chalk.bold(p.manifest.name)} v${p.manifest.version} — ${chalk.dim(p.manifest.description)}`);
2614
+ }
2615
+ }
2616
+ catch (err) {
2617
+ console.error(chalk.red(' Error:'), err.message);
2618
+ }
2619
+ }))
2620
+ .addCommand(new Command('create')
2621
+ .description('Create a new plugin from template')
2622
+ .argument('<name>', 'Plugin name')
2623
+ .action(async (name) => {
2624
+ console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — Create Plugin`));
2625
+ try {
2626
+ const { PluginSystem } = await import('./brain/plugin-system.js');
2627
+ const ps = new PluginSystem(process.cwd());
2628
+ const dir = ps.createTemplate(name);
2629
+ console.log(chalk.green(' Plugin template created!'));
2630
+ console.log(chalk.dim(' Directory: ') + chalk.cyan(dir));
2631
+ console.log(chalk.dim(' Edit manifest.json and index.js to customize.'));
2632
+ }
2633
+ catch (err) {
2634
+ console.error(chalk.red(' Error:'), err.message);
2635
+ process.exit(1);
2636
+ }
2637
+ }))
2638
+ .addCommand(new Command('stats')
2639
+ .description('Show plugin system statistics')
2640
+ .action(async () => {
2641
+ console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} — Plugin Stats`));
2642
+ try {
2643
+ const { PluginSystem } = await import('./brain/plugin-system.js');
2644
+ const ps = new PluginSystem(process.cwd());
2645
+ await ps.loadAll();
2646
+ const stats = ps.getStats();
2647
+ console.log(chalk.dim(' Total plugins: ') + chalk.cyan(String(stats.totalPlugins)));
2648
+ console.log(chalk.dim(' Enabled: ') + chalk.green(String(stats.enabledPlugins)));
2649
+ console.log(chalk.dim(' Disabled: ') + chalk.red(String(stats.disabledPlugins)));
2650
+ console.log(chalk.dim(' Total hooks: ') + chalk.cyan(String(stats.totalHooks)));
2651
+ if (Object.keys(stats.hooksByEvent).length > 0) {
2652
+ console.log(chalk.dim(' Hooks by event:'));
2653
+ for (const [event, count] of Object.entries(stats.hooksByEvent)) {
2654
+ console.log(` ${chalk.cyan(event)}: ${count}`);
2655
+ }
2656
+ }
2657
+ }
2658
+ catch (err) {
2659
+ console.error(chalk.red(' Error:'), err.message);
2660
+ }
2661
+ }));
2662
+ program.addCommand(offCmd);
2663
+ program.addCommand(askCmd);
2664
+ program.addCommand(exportCmd);
2665
+ program.addCommand(importCmd);
2666
+ program.addCommand(pluginCmd);
2241
2667
  program.parse();
2242
2668
  //# sourceMappingURL=cli.js.map