@theihtisham/agent-shadow-brain 6.3.0 → 7.0.0
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/CHANGELOG.md +411 -391
- package/LICENSE +21 -21
- package/README.md +428 -438
- package/dist/adapters/aider.js +13 -13
- package/dist/adapters/base-adapter.js +14 -14
- package/dist/adapters/codex.js +8 -8
- package/dist/adapters/roo-code.js +18 -18
- package/dist/brain/adr-engine.js +11 -11
- package/dist/brain/analyzer.js +30 -30
- package/dist/brain/auto-update.js +1 -1
- package/dist/brain/global-brain.d.ts +52 -63
- package/dist/brain/global-brain.d.ts.map +1 -1
- package/dist/brain/global-brain.js +577 -339
- package/dist/brain/global-brain.js.map +1 -1
- package/dist/brain/health-score.js +19 -19
- package/dist/brain/learning-engine.js +59 -59
- package/dist/brain/mcp-server.d.ts +1 -0
- package/dist/brain/mcp-server.d.ts.map +1 -1
- package/dist/brain/mcp-server.js +16 -6
- package/dist/brain/mcp-server.js.map +1 -1
- package/dist/brain/plugin-system.js +23 -23
- package/dist/brain/pr-generator.js +19 -19
- package/dist/brain/project-context.js +1 -1
- package/dist/brain/project-context.js.map +1 -1
- package/dist/brain/report-generator.js +270 -270
- package/dist/cli.js +105 -34
- package/dist/cli.js.map +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts +1 -1
- package/dist/dashboard/v6-dashboard-html.d.ts.map +1 -1
- package/dist/dashboard/v6-dashboard-html.js +5 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +28 -10
- package/dist/types.d.ts.map +1 -1
- package/dist/watchers/git-watcher.d.ts.map +1 -1
- package/dist/watchers/git-watcher.js +1 -1
- package/dist/watchers/git-watcher.js.map +1 -1
- package/docs/launch/RELEASE_CHECKLIST_v7.0.0.md +24 -0
- package/docs/launch/RELEASE_NOTES_v7.0.0.md +44 -0
- package/package.json +17 -14
- package/docs/launch/README.md +0 -61
package/dist/cli.js
CHANGED
|
@@ -8,22 +8,28 @@ import * as path from 'path';
|
|
|
8
8
|
import * as os from 'os';
|
|
9
9
|
import { Orchestrator } from './brain/orchestrator.js';
|
|
10
10
|
import { detectRunningAgents, createAdapter } from './adapters/index.js';
|
|
11
|
-
const VERSION = '
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
11
|
+
const VERSION = '7.0.0';
|
|
12
|
+
// Defer config reads until a command actually needs provider settings.
|
|
13
|
+
let savedConfig;
|
|
14
|
+
function getConfig() {
|
|
15
|
+
savedConfig ?? (savedConfig = new Conf({
|
|
16
|
+
...(process.env.SHADOW_BRAIN_CONFIG_DIR ? { cwd: process.env.SHADOW_BRAIN_CONFIG_DIR } : {}),
|
|
17
|
+
projectName: 'shadow-brain',
|
|
18
|
+
defaults: {
|
|
19
|
+
provider: 'ollama',
|
|
20
|
+
model: undefined,
|
|
21
|
+
agents: ['claude-code', 'kilo-code', 'cline', 'opencode', 'codex'],
|
|
22
|
+
projectDir: process.cwd(),
|
|
23
|
+
watchMode: true,
|
|
24
|
+
autoInject: true,
|
|
25
|
+
reviewDepth: 'standard',
|
|
26
|
+
brainPersonality: 'balanced',
|
|
27
|
+
},
|
|
28
|
+
}));
|
|
29
|
+
return savedConfig;
|
|
30
|
+
}
|
|
25
31
|
function mergeConfig(cliOpts) {
|
|
26
|
-
const saved =
|
|
32
|
+
const saved = getConfig().store;
|
|
27
33
|
const watchMode = cliOpts.watchMode === false || cliOpts.watch === false
|
|
28
34
|
? false
|
|
29
35
|
: saved.watchMode !== false;
|
|
@@ -393,7 +399,7 @@ const injectCmd = new Command('inject')
|
|
|
393
399
|
const statusCmd = new Command('status')
|
|
394
400
|
.description('Show current Shadow Brain configuration and status')
|
|
395
401
|
.action(async () => {
|
|
396
|
-
const saved =
|
|
402
|
+
const saved = getConfig().store;
|
|
397
403
|
console.log(chalk.magenta.bold(`\n SHADOW BRAIN v${VERSION} Status\n`));
|
|
398
404
|
console.log(chalk.dim(' Provider: ') + chalk.cyan(saved.provider || 'ollama'));
|
|
399
405
|
console.log(chalk.dim(' Model: ') + chalk.cyan(saved.model || '(default)'));
|
|
@@ -431,7 +437,7 @@ const configCmd = new Command('config')
|
|
|
431
437
|
.action(async (key, value, opts) => {
|
|
432
438
|
if (opts?.list) {
|
|
433
439
|
console.log(chalk.magenta.bold('\n SHADOW BRAIN Configuration\n'));
|
|
434
|
-
const saved =
|
|
440
|
+
const saved = getConfig().store;
|
|
435
441
|
for (const [k, v] of Object.entries(saved)) {
|
|
436
442
|
const display = k === 'apiKey' && v ? '••••••••' : String(v);
|
|
437
443
|
console.log(chalk.dim(` ${k}: `) + chalk.cyan(display));
|
|
@@ -440,7 +446,7 @@ const configCmd = new Command('config')
|
|
|
440
446
|
return;
|
|
441
447
|
}
|
|
442
448
|
if (opts?.reset) {
|
|
443
|
-
|
|
449
|
+
getConfig().clear();
|
|
444
450
|
console.log(chalk.green(' Configuration reset to defaults.'));
|
|
445
451
|
return;
|
|
446
452
|
}
|
|
@@ -454,7 +460,7 @@ const configCmd = new Command('config')
|
|
|
454
460
|
parsedValue = Number(value);
|
|
455
461
|
else if (value.includes(','))
|
|
456
462
|
parsedValue = value.split(',');
|
|
457
|
-
|
|
463
|
+
getConfig().set(key, parsedValue);
|
|
458
464
|
console.log(chalk.green(` Set ${key} = ${parsedValue}`));
|
|
459
465
|
return;
|
|
460
466
|
}
|
|
@@ -479,12 +485,12 @@ const setupCmd = new Command('setup')
|
|
|
479
485
|
const provider = await ask(chalk.yellow(' Choose provider [1-4] (default: 1): '));
|
|
480
486
|
const providerMap = { '1': 'ollama', '2': 'anthropic', '3': 'openai', '4': 'openrouter' };
|
|
481
487
|
const chosenProvider = providerMap[provider.trim() || '1'] || 'ollama';
|
|
482
|
-
|
|
488
|
+
getConfig().set('provider', chosenProvider);
|
|
483
489
|
console.log(chalk.green(` ✓ Provider: ${chosenProvider}\n`));
|
|
484
490
|
if (chosenProvider !== 'ollama') {
|
|
485
491
|
const apiKey = await ask(chalk.yellow(` Enter ${chosenProvider} API key: `));
|
|
486
492
|
if (apiKey.trim()) {
|
|
487
|
-
|
|
493
|
+
getConfig().set('apiKey', apiKey.trim());
|
|
488
494
|
console.log(chalk.green(' ✓ API key saved\n'));
|
|
489
495
|
}
|
|
490
496
|
else {
|
|
@@ -504,7 +510,7 @@ const setupCmd = new Command('setup')
|
|
|
504
510
|
const personality = await ask(chalk.yellow(' Choose personality [1-6] (default: 1): '));
|
|
505
511
|
const personalityMap = { '1': 'balanced', '2': 'mentor', '3': 'critic', '4': 'architect', '5': 'security', '6': 'performance' };
|
|
506
512
|
const chosenPersonality = personalityMap[personality.trim() || '1'] || 'balanced';
|
|
507
|
-
|
|
513
|
+
getConfig().set('brainPersonality', chosenPersonality);
|
|
508
514
|
console.log(chalk.green(` ✓ Personality: ${chosenPersonality}\n`));
|
|
509
515
|
console.log(chalk.cyan(' Review Depth:'));
|
|
510
516
|
console.log(chalk.dim(' 1. standard (balanced — default)'));
|
|
@@ -512,14 +518,14 @@ const setupCmd = new Command('setup')
|
|
|
512
518
|
console.log(chalk.dim(' 3. deep (thorough, full diffs)'));
|
|
513
519
|
const depth = await ask(chalk.yellow(' Choose depth [1-3] (default: 1): '));
|
|
514
520
|
const depthMap = { '1': 'standard', '2': 'quick', '3': 'deep' };
|
|
515
|
-
|
|
521
|
+
getConfig().set('reviewDepth', depthMap[depth.trim() || '1'] || 'standard');
|
|
516
522
|
console.log(chalk.green(' ✓ Review depth saved\n'));
|
|
517
523
|
const inject = await ask(chalk.yellow(' Enable auto-injection? [Y/n] (default: Y): '));
|
|
518
|
-
|
|
524
|
+
getConfig().set('autoInject', inject.trim().toLowerCase() !== 'n');
|
|
519
525
|
console.log(chalk.green(` ✓ Auto-injection: ${inject.trim().toLowerCase() !== 'n' ? 'enabled' : 'disabled'}\n`));
|
|
520
526
|
rl.close();
|
|
521
527
|
console.log(chalk.magenta.bold(' Setup complete!\n'));
|
|
522
|
-
console.log(chalk.dim(' Configuration saved to: ') + chalk.cyan(
|
|
528
|
+
console.log(chalk.dim(' Configuration saved to: ') + chalk.cyan(getConfig().path));
|
|
523
529
|
console.log();
|
|
524
530
|
console.log(chalk.dim(' Next steps:'));
|
|
525
531
|
console.log(chalk.cyan(' shadow-brain start .') + chalk.dim(' # Start watching a project'));
|
|
@@ -539,13 +545,13 @@ const doctorCmd = new Command('doctor')
|
|
|
539
545
|
console.log(chalk.magenta.bold('\n SHADOW BRAIN Doctor\n'));
|
|
540
546
|
const checks = [];
|
|
541
547
|
try {
|
|
542
|
-
const saved =
|
|
548
|
+
const saved = getConfig().store;
|
|
543
549
|
checks.push({ name: 'Configuration', status: 'ok', detail: `provider=${saved.provider}, personality=${saved.brainPersonality}` });
|
|
544
550
|
}
|
|
545
551
|
catch {
|
|
546
552
|
checks.push({ name: 'Configuration', status: 'fail', detail: 'Could not read config. Run `shadow-brain setup`.' });
|
|
547
553
|
}
|
|
548
|
-
const provider =
|
|
554
|
+
const provider = getConfig().get('provider') || 'ollama';
|
|
549
555
|
if (provider === 'ollama') {
|
|
550
556
|
try {
|
|
551
557
|
const resp = await fetch('http://localhost:11434/api/tags', { signal: AbortSignal.timeout(3000) });
|
|
@@ -563,18 +569,19 @@ const doctorCmd = new Command('doctor')
|
|
|
563
569
|
}
|
|
564
570
|
}
|
|
565
571
|
else {
|
|
566
|
-
const apiKey =
|
|
572
|
+
const apiKey = getConfig().get('apiKey');
|
|
567
573
|
if (apiKey) {
|
|
568
|
-
checks.push({ name: `${provider} API key`, status: 'ok', detail: 'Key is
|
|
574
|
+
checks.push({ name: `${provider} API key`, status: 'ok', detail: 'Key is configured' });
|
|
569
575
|
}
|
|
570
576
|
else {
|
|
571
577
|
checks.push({ name: `${provider} API key`, status: 'fail', detail: 'No API key configured. Run: shadow-brain config apiKey <key>' });
|
|
572
578
|
}
|
|
573
579
|
}
|
|
574
580
|
const nodeVersion = process.version;
|
|
575
|
-
const major =
|
|
576
|
-
|
|
577
|
-
|
|
581
|
+
const [major, minor] = nodeVersion.slice(1).split('.').map(Number);
|
|
582
|
+
const nodeSupported = (major === 22 && minor >= 12) || major === 24 || major >= 26;
|
|
583
|
+
checks.push({ name: 'Node.js', status: nodeSupported ? 'ok' : 'warn', detail: `${nodeVersion} ${nodeSupported ? '(supported)' : '(requires Node 22.12+, 24.x, or 26+)'}` });
|
|
584
|
+
const projectDir = getConfig().get('projectDir') || process.cwd();
|
|
578
585
|
try {
|
|
579
586
|
const stat = fs.statSync(projectDir);
|
|
580
587
|
checks.push({ name: 'Project directory', status: stat.isDirectory() ? 'ok' : 'fail', detail: projectDir });
|
|
@@ -2457,7 +2464,7 @@ const v5Cmd = new Command('v5')
|
|
|
2457
2464
|
const program = new Command();
|
|
2458
2465
|
program
|
|
2459
2466
|
.name('shadow-brain')
|
|
2460
|
-
.description('Shadow Brain
|
|
2467
|
+
.description('Shadow Brain - durable cross-agent memory, explained recall, and storage health')
|
|
2461
2468
|
.version(VERSION);
|
|
2462
2469
|
program.addCommand(startCmd);
|
|
2463
2470
|
program.addCommand(reviewCmd);
|
|
@@ -5001,5 +5008,69 @@ program.addCommand(asciiCmd);
|
|
|
5001
5008
|
program.addCommand(memesCmd);
|
|
5002
5009
|
program.addCommand(brain3dCmd);
|
|
5003
5010
|
program.addCommand(doppelgangerCmd);
|
|
5004
|
-
|
|
5011
|
+
const storageHealthCmd = new Command('storage-health')
|
|
5012
|
+
.description('Check memory-store readability and report storage errors without loading provider settings')
|
|
5013
|
+
.option('--db <path>', 'Memory-store path (defaults to the global brain)')
|
|
5014
|
+
.option('--json', 'Print machine-readable JSON')
|
|
5015
|
+
.action(async (opts) => {
|
|
5016
|
+
const { getGlobalBrain } = await import('./brain/global-brain.js');
|
|
5017
|
+
const brain = getGlobalBrain(opts.db ? { dbPath: path.resolve(opts.db) } : undefined);
|
|
5018
|
+
try {
|
|
5019
|
+
await brain.init();
|
|
5020
|
+
}
|
|
5021
|
+
catch {
|
|
5022
|
+
process.exitCode = 1;
|
|
5023
|
+
}
|
|
5024
|
+
const health = brain.getStorageHealth();
|
|
5025
|
+
if (opts.json)
|
|
5026
|
+
console.log(JSON.stringify(health, null, 2));
|
|
5027
|
+
else {
|
|
5028
|
+
console.log(`Storage: ${health.status}\nDatabase: ${health.dbPath}\nPending operations: ${health.pendingOperations}`);
|
|
5029
|
+
if (health.lastError)
|
|
5030
|
+
console.log(`${health.lastError.code}: ${health.lastError.message}`);
|
|
5031
|
+
}
|
|
5032
|
+
if (health.initialized)
|
|
5033
|
+
await brain.shutdown();
|
|
5034
|
+
});
|
|
5035
|
+
const recallExplainCmd = new Command('recall-explain')
|
|
5036
|
+
.description('Recall memories with keyword matches, score components, and supporting agent identities')
|
|
5037
|
+
.argument('<query>', 'Keywords to search for')
|
|
5038
|
+
.option('--db <path>', 'Memory-store path (defaults to the global brain)')
|
|
5039
|
+
.option('--project <path>', 'Restrict recall to this project')
|
|
5040
|
+
.option('--limit <number>', 'Maximum results', '10')
|
|
5041
|
+
.option('--min-confidence <number>', 'Minimum heuristic score from 0 to 1', '0')
|
|
5042
|
+
.action(async (query, opts) => {
|
|
5043
|
+
const limit = Number(opts.limit);
|
|
5044
|
+
const minConfidence = Number(opts.minConfidence);
|
|
5045
|
+
if (!Number.isSafeInteger(limit) || limit < 1 || limit > 1000 || !Number.isFinite(minConfidence) || minConfidence < 0 || minConfidence > 1) {
|
|
5046
|
+
console.error('Use --limit between 1 and 1000 and --min-confidence between 0 and 1.');
|
|
5047
|
+
process.exitCode = 1;
|
|
5048
|
+
return;
|
|
5049
|
+
}
|
|
5050
|
+
const { getGlobalBrain, GlobalBrain } = await import('./brain/global-brain.js');
|
|
5051
|
+
const brain = getGlobalBrain(opts.db ? { dbPath: path.resolve(opts.db) } : undefined);
|
|
5052
|
+
try {
|
|
5053
|
+
await brain.init();
|
|
5054
|
+
console.log(JSON.stringify(brain.recallScored({
|
|
5055
|
+
keywords: query.split(/\s+/),
|
|
5056
|
+
projectId: opts.project ? GlobalBrain.projectIdFor(opts.project) : undefined,
|
|
5057
|
+
limit,
|
|
5058
|
+
minConfidence,
|
|
5059
|
+
}), null, 2));
|
|
5060
|
+
}
|
|
5061
|
+
catch (error) {
|
|
5062
|
+
console.error(error instanceof Error ? error.message : 'Recall failed.');
|
|
5063
|
+
process.exitCode = 1;
|
|
5064
|
+
}
|
|
5065
|
+
finally {
|
|
5066
|
+
if (brain.getStorageHealth().initialized)
|
|
5067
|
+
await brain.shutdown();
|
|
5068
|
+
}
|
|
5069
|
+
});
|
|
5070
|
+
program.addCommand(storageHealthCmd);
|
|
5071
|
+
program.addCommand(recallExplainCmd);
|
|
5072
|
+
program.parseAsync().catch((error) => {
|
|
5073
|
+
console.error(error instanceof Error ? error.message : 'Command failed.');
|
|
5074
|
+
process.exitCode = 1;
|
|
5075
|
+
});
|
|
5005
5076
|
//# sourceMappingURL=cli.js.map
|