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