dual-brain 4.8.0 → 4.8.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.
@@ -468,8 +468,14 @@ async function showAuthMenu(rl, providers) {
468
468
 
469
469
  if (choice === 'j') {
470
470
  console.log('');
471
- spawnSync('claude', ['login'], { stdio: 'inherit' });
472
- providers.claude.authed = true;
471
+ const r = spawnSync('claude', ['login'], { stdio: 'inherit' });
472
+ const fresh = detectProviders();
473
+ providers.claude = fresh.claude;
474
+ if (providers.claude.authed) {
475
+ console.log(` ${green('Claude authenticated.')}`);
476
+ } else {
477
+ console.log(` ${yellow('Claude login did not complete.')} Try again or check your subscription.`);
478
+ }
473
479
  continue;
474
480
  }
475
481
  if (choice === 'k' && providers.codex.installed) {
@@ -479,7 +485,13 @@ async function showAuthMenu(rl, providers) {
479
485
  console.log(` Open: ${cyan('https://auth.openai.com/codex/device')}`);
480
486
  console.log('');
481
487
  spawnSync(codexPath.stdout.trim(), ['login', '--device-auth'], { stdio: 'inherit' });
482
- providers.codex.authed = true;
488
+ const fresh = detectProviders();
489
+ providers.codex = fresh.codex;
490
+ if (providers.codex.authed) {
491
+ console.log(` ${green('Codex authenticated.')}`);
492
+ } else {
493
+ console.log(` ${yellow('Codex login did not complete.')} Try again.`);
494
+ }
483
495
  }
484
496
  continue;
485
497
  }
@@ -623,9 +635,9 @@ function renderFirstRunMenu(providers) {
623
635
  lines.push('');
624
636
 
625
637
  // Provider status
626
- const cStat = providers.claude.authed ? '✅' : providers.claude.installed ? '⚠️' : '❌';
627
- const xStat = providers.codex.authed ? '✅' : providers.codex.installed ? '⚠️' : '❌';
628
- lines.push(` 🟠 Claude ${cStat} 🟢 Codex ${xStat}`);
638
+ const cStat = providers.claude.authed ? (noColor ? '[OK]' : '✅') : providers.claude.installed ? (noColor ? '[!]' : '⚠️') : (noColor ? '[X]' : '❌');
639
+ const xStat = providers.codex.authed ? (noColor ? '[OK]' : '✅') : providers.codex.installed ? (noColor ? '[!]' : '⚠️') : (noColor ? '[X]' : '❌');
640
+ lines.push(` ${noColor ? '' : '🟠 '}Claude ${cStat} ${noColor ? '' : '🟢 '}Codex ${xStat}`);
629
641
 
630
642
  if (providers.claude.authed && providers.codex.authed) {
631
643
  lines.push(` ${green('Both providers ready — full dual-brain mode')}`);
@@ -667,7 +679,8 @@ function renderFirstRunMenu(providers) {
667
679
  lines.push(` ${bold('[a]')} Auth management`);
668
680
  lines.push(` ${bold('[d]')} Dashboard & diagnostics`);
669
681
  lines.push(` ${bold('[s]')} Skip — just shell`);
670
- lines.push(` ${bold('[?]')} What is Dual Brain?`);
682
+ lines.push(` ${dim('Enter = new session · [?] help')}`);
683
+
671
684
  lines.push('');
672
685
 
673
686
  return lines;
@@ -688,8 +701,8 @@ function renderReturningMenu(providers, sessions) {
688
701
  lines.push('');
689
702
 
690
703
  // Provider status
691
- const cStat = providers.claude.authed ? '✅' : '⚠️';
692
- const xStat = providers.codex.authed ? '✅' : providers.codex.installed ? '⚠️' : '❌';
704
+ const cStat = providers.claude.authed ? (noColor ? '[OK]' : '✅') : (noColor ? '[!]' : '⚠️');
705
+ const xStat = providers.codex.authed ? (noColor ? '[OK]' : '✅') : providers.codex.installed ? (noColor ? '[!]' : '⚠️') : (noColor ? '[X]' : '❌');
693
706
  let modeStatus = pf.uiLabel;
694
707
  if (profile.name === 'auto') {
695
708
  if (balance.total === 0) {
@@ -762,7 +775,12 @@ function renderReturningMenu(providers, sessions) {
762
775
  }
763
776
 
764
777
  lines.push('');
765
- lines.push(` ${bold('[s]')} Exit to shell ${dim('[?] help')}`);
778
+ lines.push(` ${bold('[s]')} Exit to shell`);
779
+ if (sessions.length > 0) {
780
+ lines.push(` ${dim('Enter = continue last · [?] help')}`);
781
+ } else {
782
+ lines.push(` ${dim('Enter = new session · [?] help')}`);
783
+ }
766
784
  lines.push('');
767
785
 
768
786
  return lines;
@@ -842,6 +860,9 @@ function runSession(cmd, args, label) {
842
860
  markLaunched();
843
861
  const result = spawnSync(cmd, args, { stdio: 'inherit' });
844
862
  console.log('');
863
+ if (result.status !== 0 && result.status !== null) {
864
+ console.log(` ${yellow('Session exited with code ' + result.status + '.')} ${dim('(' + cmd + ' ' + args.join(' ') + ')')}`);
865
+ }
845
866
  console.log(' Returned to Data Tools — Dual Brain.');
846
867
  return result.status || 0;
847
868
  }
@@ -879,6 +900,15 @@ async function mainLoop() {
879
900
  } else {
880
901
  runSession('claude', ['-r', s.id, '--dangerously-skip-permissions'], `Resuming session ${s.id.slice(0, 8)}...`);
881
902
  }
903
+ } else if (!providers.claude.authed && !providers.claude.installed) {
904
+ console.log('');
905
+ console.log(` ${yellow('Claude is not installed.')} Install first:`);
906
+ console.log(` ${cyan('curl -fsSL https://claude.ai/install.sh | sh')}`);
907
+ console.log('');
908
+ } else if (!providers.claude.authed) {
909
+ console.log('');
910
+ console.log(` ${yellow('Claude is not authenticated.')} Press ${bold('[j]')} to sign in first.`);
911
+ console.log('');
882
912
  } else {
883
913
  runSession('claude', ['--dangerously-skip-permissions'], 'Starting new session...');
884
914
  }
@@ -897,7 +927,13 @@ async function mainLoop() {
897
927
  }
898
928
 
899
929
  if (choice === 'n') {
900
- runSession('claude', ['--dangerously-skip-permissions'], 'Starting new session...');
930
+ if (!providers.claude.authed) {
931
+ console.log('');
932
+ console.log(` ${yellow('Claude needs to be authenticated first.')} Press ${bold('[j]')} to sign in.`);
933
+ console.log('');
934
+ } else {
935
+ runSession('claude', ['--dangerously-skip-permissions'], 'Starting new session...');
936
+ }
901
937
  continue;
902
938
  }
903
939
 
@@ -923,9 +959,14 @@ async function mainLoop() {
923
959
 
924
960
  if (choice === 'u') {
925
961
  console.log('');
926
- console.log(' Updating dual-brain...');
962
+ console.log(' Updating Dual Brain...');
927
963
  console.log('');
928
- spawnSync('npx', ['-y', 'dual-brain', 'update'], { stdio: 'inherit', cwd: CWD });
964
+ const upd = spawnSync('npx', ['-y', 'dual-brain', 'update'], { stdio: 'inherit', cwd: CWD });
965
+ if (upd.status !== 0) {
966
+ console.log('');
967
+ console.log(` ${yellow('Update failed (exit ' + upd.status + ').')} Try manually: ${cyan('npx -y dual-brain@latest')}`);
968
+ console.log('');
969
+ }
929
970
  continue;
930
971
  }
931
972
 
@@ -27,11 +27,10 @@ const CONFIG_FILE = join(__dirname, '..', 'orchestrator.json');
27
27
  const EXECUTE_WORDS = /\b(edit|write|fix|implement|modify|refactor|delete|commit|test|build|run|add|update|create)\b/i;
28
28
  const SEARCH_WORDS = /\b(explore|search|find|grep|locate|list\s+files|read[-\s]?only|lookup|scan)\b/i;
29
29
  const THINK_WORDS = /\b(plan|design|architect|review|audit|security|code[-\s]?review|threat[-\s]?model|complex[-\s]?debug)\b/i;
30
- const GPT_TIER_SANDBOX = {
31
- search: 'read-only',
32
- execute: 'danger-full-access',
33
- think: 'read-only',
34
- };
30
+ const IS_REPLIT = !!(process.env.REPL_ID || process.env.REPL_SLUG);
31
+ const GPT_TIER_SANDBOX = IS_REPLIT
32
+ ? { search: 'danger-full-access', execute: 'danger-full-access', think: 'danger-full-access' }
33
+ : { search: 'read-only', execute: 'danger-full-access', think: 'read-only' };
35
34
  const GPT_TIER_PROMPTS = {
36
35
  search: 'You are a READ-ONLY search agent. Do NOT edit files.',
37
36
  execute: 'You are an execution agent. Edit files directly.',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dual-brain",
3
- "version": "4.8.0",
3
+ "version": "4.8.1",
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": {