dual-brain 4.7.0 → 4.8.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.
@@ -323,7 +323,7 @@ function timeAgo(ts) {
323
323
  return h + 'h ago';
324
324
  }
325
325
 
326
- function snippet(s, n = 15) {
326
+ function snippet(s, n = 35) {
327
327
  const clean = (s || '').replace(/\s+/g, ' ').trim();
328
328
  return clean.length > n ? clean.slice(0, n - 1) + '…' : clean;
329
329
  }
@@ -572,7 +572,7 @@ async function showToolsMenu(rl) {
572
572
  console.log(` ${bold('[3]')} Decision ledger insights`);
573
573
  console.log(` ${bold('[4]')} Run test suite (40 tests)`);
574
574
  console.log(` ${bold('[5]')} Session report`);
575
- console.log(` ${bold('[u]')} Update dual-brain ${dim('(' + formatVersionStatus(updateInfo) + ')')}`);
575
+ console.log(` ${bold('[u]')} Update Dual Brain ${dim('(' + formatVersionStatus(updateInfo) + ')')}`);
576
576
  console.log(` ${bold('[q]')} Back to main menu`);
577
577
  console.log('');
578
578
 
@@ -617,8 +617,9 @@ function renderFirstRunMenu(providers) {
617
617
  const updateInfo = checkForUpdate();
618
618
 
619
619
  lines.push('');
620
- lines.push(` 🧠 ${bold(`Dual-Brain v${VERSION}`)}`);
620
+ lines.push(` 🧠 ${bold('Data Tools')} ${dim('—')} ${bold('Dual Brain')} ${dim(`v${VERSION}`)}`);
621
621
  lines.push(` ${dim(formatVersionStatus(updateInfo))}`);
622
+ lines.push(` ${dim('Powered by replit-tools by Steve Moraco')}`);
622
623
  lines.push('');
623
624
 
624
625
  // Provider status
@@ -654,8 +655,10 @@ function renderFirstRunMenu(providers) {
654
655
  lines.push('');
655
656
  }
656
657
 
657
- // Replit-tools check
658
- if (IS_REPLIT && !existsSync(join(CWD, '.replit-tools'))) {
658
+ // Data Tools shortcut
659
+ if (IS_REPLIT && existsSync(join(CWD, '.replit-tools'))) {
660
+ lines.push(` ${bold('[t]')} Open Data Tools dashboard`);
661
+ } else if (IS_REPLIT) {
659
662
  lines.push(` ${bold('[t]')} Install replit-tools ${dim('(recommended for Replit)')}`);
660
663
  }
661
664
 
@@ -664,6 +667,7 @@ function renderFirstRunMenu(providers) {
664
667
  lines.push(` ${bold('[a]')} Auth management`);
665
668
  lines.push(` ${bold('[d]')} Dashboard & diagnostics`);
666
669
  lines.push(` ${bold('[s]')} Skip — just shell`);
670
+ lines.push(` ${bold('[?]')} What is Dual Brain?`);
667
671
  lines.push('');
668
672
 
669
673
  return lines;
@@ -678,8 +682,9 @@ function renderReturningMenu(providers, sessions) {
678
682
  const lines = [];
679
683
 
680
684
  lines.push('');
681
- lines.push(` 🧠 ${bold(`Dual-Brain v${VERSION}`)}`);
685
+ lines.push(` 🧠 ${bold('Data Tools')} ${dim('—')} ${bold('Dual Brain')} ${dim(`v${VERSION}`)}`);
682
686
  lines.push(` ${dim(formatVersionStatus(updateInfo))}`);
687
+ lines.push(` ${dim('Powered by replit-tools by Steve Moraco')}`);
683
688
  lines.push('');
684
689
 
685
690
  // Provider status
@@ -748,14 +753,16 @@ function renderReturningMenu(providers, sessions) {
748
753
  lines.push('');
749
754
  lines.push(` ${dim('─── Tools')}`);
750
755
  lines.push(` ${bold('[d]')} Dashboard & diagnostics`);
751
- lines.push(` ${bold('[u]')} Update dual-brain ${dim('(' + formatVersionStatus(updateInfo) + ')')}`);
756
+ lines.push(` ${bold('[u]')} Update Dual Brain ${dim('(' + formatVersionStatus(updateInfo) + ')')}`);
752
757
 
753
- if (IS_REPLIT && !existsSync(join(CWD, '.replit-tools'))) {
758
+ if (IS_REPLIT && existsSync(join(CWD, '.replit-tools'))) {
759
+ lines.push(` ${bold('[t]')} Open Data Tools dashboard`);
760
+ } else if (IS_REPLIT) {
754
761
  lines.push(` ${bold('[t]')} Install replit-tools`);
755
762
  }
756
763
 
757
764
  lines.push('');
758
- lines.push(` ${bold('[s]')} Exit to shell`);
765
+ lines.push(` ${bold('[s]')} Exit to shell ${dim('[?] help')}`);
759
766
  lines.push('');
760
767
 
761
768
  return lines;
@@ -835,7 +842,7 @@ function runSession(cmd, args, label) {
835
842
  markLaunched();
836
843
  const result = spawnSync(cmd, args, { stdio: 'inherit' });
837
844
  console.log('');
838
- console.log(' Returned to Dual-Brain.');
845
+ console.log(' Returned to Data Tools — Dual Brain.');
839
846
  return result.status || 0;
840
847
  }
841
848
 
@@ -922,6 +929,38 @@ async function mainLoop() {
922
929
  continue;
923
930
  }
924
931
 
932
+ if (choice === 't') {
933
+ const dtPath = join(CWD, '.replit-tools');
934
+ if (existsSync(dtPath)) {
935
+ const scriptPath = join(dtPath, 'scripts', 'setup-claude-code.sh');
936
+ if (existsSync(scriptPath)) {
937
+ console.log('');
938
+ console.log(' Opening Data Tools dashboard...');
939
+ console.log('');
940
+ spawnSync('bash', [scriptPath], { stdio: 'inherit', cwd: CWD });
941
+ } else {
942
+ console.log('');
943
+ console.log(` Data Tools present but dashboard script missing.`);
944
+ console.log(` Try: ${cyan('source .replit-tools/scripts/setup-claude-code.sh')}`);
945
+ console.log('');
946
+ }
947
+ } else if (IS_REPLIT) {
948
+ console.log('');
949
+ console.log(' Installing replit-tools (Data Tools)...');
950
+ console.log('');
951
+ spawnSync('npx', ['-y', 'data-tools'], { stdio: 'inherit', cwd: CWD });
952
+ console.log('');
953
+ console.log(' Done. Press Enter to continue...');
954
+ const askOnce = () => new Promise(resolve => rl.question('', resolve));
955
+ await askOnce();
956
+ } else {
957
+ console.log('');
958
+ console.log(` Data Tools is designed for Replit environments.`);
959
+ console.log('');
960
+ }
961
+ continue;
962
+ }
963
+
925
964
  if (choice === 'j') {
926
965
  console.log('');
927
966
  console.log(' Starting Claude login...');
@@ -948,14 +987,18 @@ async function mainLoop() {
948
987
  continue;
949
988
  }
950
989
 
951
- if (choice === 't' && IS_REPLIT) {
990
+ if (choice === '?') {
952
991
  console.log('');
953
- console.log(' Installing replit-tools...');
992
+ console.log(` ${bold('What is Dual Brain?')}`);
954
993
  console.log('');
955
- spawnSync('npx', ['-y', 'data-tools'], { stdio: 'inherit', cwd: CWD });
994
+ console.log(' Dual Brain orchestrates your Claude + Codex subscriptions together.');
995
+ console.log(' It routes tasks to the right model: search (fast), execute (edits),');
996
+ console.log(' think (architecture). Both providers work in parallel when possible.');
956
997
  console.log('');
957
- console.log(' replit-tools installed.');
998
+ console.log(' Modes: Auto adapts to your workflow. Cost-saver minimizes GPT usage.');
999
+ console.log(' Quality-first uses dual-brain review on all medium+ risk changes.');
958
1000
  console.log('');
1001
+ console.log(` ${dim('Press Enter to return...')}`);
959
1002
  await ask();
960
1003
  continue;
961
1004
  }
package/install.mjs CHANGED
@@ -44,7 +44,9 @@ if (flag('--version') || flag('-v')) {
44
44
 
45
45
  if (flag('--help') || flag('-h')) {
46
46
  console.log(`
47
- 🧠 dual-brain v${VERSION} — Dual-provider orchestrator for Claude Code
47
+ 🧠 Data Tools — Dual Brain v${VERSION}
48
+ Dual-provider orchestrator for Claude Code
49
+ Powered by replit-tools by Steve Moraco
48
50
 
49
51
  Usage: npx -y dual-brain [command] [options]
50
52
 
@@ -334,6 +336,22 @@ function detectEnvironment() {
334
336
  };
335
337
  }
336
338
 
339
+ // ─── NPM Token Persistence ────────────────────────────────────────────────
340
+
341
+ const NPM_PERSIST = resolve(process.cwd(), '.replit-tools', '.npm-persistent', '.npmrc');
342
+ const NPMRC_HOME = join(process.env.HOME || '', '.npmrc');
343
+
344
+ function restoreNpmToken() {
345
+ if (existsSync(NPMRC_HOME)) return;
346
+ if (!existsSync(NPM_PERSIST)) return;
347
+ try {
348
+ const content = readFileSync(NPM_PERSIST, 'utf8');
349
+ if (content.includes('_authToken')) {
350
+ writeFileSync(NPMRC_HOME, content);
351
+ }
352
+ } catch {}
353
+ }
354
+
337
355
  // ─── Auth Self-Healing ─────────────────────────────────────────────────────
338
356
 
339
357
  function healClaudeAuth(env) {
@@ -830,7 +848,7 @@ function printReport(env, mode, actions, isDryRun) {
830
848
  const lines = [];
831
849
 
832
850
  lines.push(br('╔', '╗'));
833
- lines.push(ln(`🧠 Dual-Brain v${VERSION}`));
851
+ lines.push(ln(`🧠 Data Tools — Dual Brain v${VERSION}`));
834
852
  lines.push(sep());
835
853
 
836
854
  const cAuth = env.claude.authed ? '✅' : env.claude.installed ? '⚠️' : '❌';
@@ -1275,6 +1293,9 @@ async function main() {
1275
1293
  if (subcommand === 'budget') { cmdBudget(); return; }
1276
1294
  if (subcommand === 'explain') { cmdExplain(); return; }
1277
1295
 
1296
+ // Restore npm token if missing (for publish access)
1297
+ restoreNpmToken();
1298
+
1278
1299
  let env = detectEnvironment();
1279
1300
  const startupUpdateInfo = (subcommand === 'update' || dryRun || jsonOut)
1280
1301
  ? null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dual-brain",
3
- "version": "4.7.0",
3
+ "version": "4.8.0",
4
4
  "description": "Dual-provider orchestration for Claude Code — tiered routing, budget balancing, and GPT dual-brain review across Claude + OpenAI subscriptions",
5
5
  "type": "module",
6
6
  "bin": {