dual-brain 4.7.1 โ 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.
- package/hooks/control-panel.mjs +108 -24
- package/hooks/gpt-work-dispatcher.mjs +4 -5
- package/install.mjs +4 -2
- package/package.json +1 -1
package/hooks/control-panel.mjs
CHANGED
|
@@ -323,7 +323,7 @@ function timeAgo(ts) {
|
|
|
323
323
|
return h + 'h ago';
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
function snippet(s, n =
|
|
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
|
}
|
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
}
|
|
@@ -572,7 +584,7 @@ async function showToolsMenu(rl) {
|
|
|
572
584
|
console.log(` ${bold('[3]')} Decision ledger insights`);
|
|
573
585
|
console.log(` ${bold('[4]')} Run test suite (40 tests)`);
|
|
574
586
|
console.log(` ${bold('[5]')} Session report`);
|
|
575
|
-
console.log(` ${bold('[u]')} Update
|
|
587
|
+
console.log(` ${bold('[u]')} Update Dual Brain ${dim('(' + formatVersionStatus(updateInfo) + ')')}`);
|
|
576
588
|
console.log(` ${bold('[q]')} Back to main menu`);
|
|
577
589
|
console.log('');
|
|
578
590
|
|
|
@@ -617,14 +629,15 @@ function renderFirstRunMenu(providers) {
|
|
|
617
629
|
const updateInfo = checkForUpdate();
|
|
618
630
|
|
|
619
631
|
lines.push('');
|
|
620
|
-
lines.push(` ๐ง ${bold(
|
|
632
|
+
lines.push(` ๐ง ${bold('Data Tools')} ${dim('โ')} ${bold('Dual Brain')} ${dim(`v${VERSION}`)}`);
|
|
621
633
|
lines.push(` ${dim(formatVersionStatus(updateInfo))}`);
|
|
634
|
+
lines.push(` ${dim('Powered by replit-tools by Steve Moraco')}`);
|
|
622
635
|
lines.push('');
|
|
623
636
|
|
|
624
637
|
// Provider status
|
|
625
|
-
const cStat = providers.claude.authed ? 'โ
' : providers.claude.installed ? 'โ ๏ธ' : 'โ';
|
|
626
|
-
const xStat = providers.codex.authed ? 'โ
' : providers.codex.installed ? 'โ ๏ธ' : 'โ';
|
|
627
|
-
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}`);
|
|
628
641
|
|
|
629
642
|
if (providers.claude.authed && providers.codex.authed) {
|
|
630
643
|
lines.push(` ${green('Both providers ready โ full dual-brain mode')}`);
|
|
@@ -654,8 +667,10 @@ function renderFirstRunMenu(providers) {
|
|
|
654
667
|
lines.push('');
|
|
655
668
|
}
|
|
656
669
|
|
|
657
|
-
//
|
|
658
|
-
if (IS_REPLIT &&
|
|
670
|
+
// Data Tools shortcut
|
|
671
|
+
if (IS_REPLIT && existsSync(join(CWD, '.replit-tools'))) {
|
|
672
|
+
lines.push(` ${bold('[t]')} Open Data Tools dashboard`);
|
|
673
|
+
} else if (IS_REPLIT) {
|
|
659
674
|
lines.push(` ${bold('[t]')} Install replit-tools ${dim('(recommended for Replit)')}`);
|
|
660
675
|
}
|
|
661
676
|
|
|
@@ -664,6 +679,8 @@ function renderFirstRunMenu(providers) {
|
|
|
664
679
|
lines.push(` ${bold('[a]')} Auth management`);
|
|
665
680
|
lines.push(` ${bold('[d]')} Dashboard & diagnostics`);
|
|
666
681
|
lines.push(` ${bold('[s]')} Skip โ just shell`);
|
|
682
|
+
lines.push(` ${dim('Enter = new session ยท [?] help')}`);
|
|
683
|
+
|
|
667
684
|
lines.push('');
|
|
668
685
|
|
|
669
686
|
return lines;
|
|
@@ -678,13 +695,14 @@ function renderReturningMenu(providers, sessions) {
|
|
|
678
695
|
const lines = [];
|
|
679
696
|
|
|
680
697
|
lines.push('');
|
|
681
|
-
lines.push(` ๐ง ${bold(
|
|
698
|
+
lines.push(` ๐ง ${bold('Data Tools')} ${dim('โ')} ${bold('Dual Brain')} ${dim(`v${VERSION}`)}`);
|
|
682
699
|
lines.push(` ${dim(formatVersionStatus(updateInfo))}`);
|
|
700
|
+
lines.push(` ${dim('Powered by replit-tools by Steve Moraco')}`);
|
|
683
701
|
lines.push('');
|
|
684
702
|
|
|
685
703
|
// Provider status
|
|
686
|
-
const cStat = providers.claude.authed ? 'โ
' : 'โ ๏ธ';
|
|
687
|
-
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]' : 'โ');
|
|
688
706
|
let modeStatus = pf.uiLabel;
|
|
689
707
|
if (profile.name === 'auto') {
|
|
690
708
|
if (balance.total === 0) {
|
|
@@ -748,14 +766,21 @@ function renderReturningMenu(providers, sessions) {
|
|
|
748
766
|
lines.push('');
|
|
749
767
|
lines.push(` ${dim('โโโ Tools')}`);
|
|
750
768
|
lines.push(` ${bold('[d]')} Dashboard & diagnostics`);
|
|
751
|
-
lines.push(` ${bold('[u]')} Update
|
|
769
|
+
lines.push(` ${bold('[u]')} Update Dual Brain ${dim('(' + formatVersionStatus(updateInfo) + ')')}`);
|
|
752
770
|
|
|
753
|
-
if (IS_REPLIT &&
|
|
771
|
+
if (IS_REPLIT && existsSync(join(CWD, '.replit-tools'))) {
|
|
772
|
+
lines.push(` ${bold('[t]')} Open Data Tools dashboard`);
|
|
773
|
+
} else if (IS_REPLIT) {
|
|
754
774
|
lines.push(` ${bold('[t]')} Install replit-tools`);
|
|
755
775
|
}
|
|
756
776
|
|
|
757
777
|
lines.push('');
|
|
758
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
|
+
}
|
|
759
784
|
lines.push('');
|
|
760
785
|
|
|
761
786
|
return lines;
|
|
@@ -835,7 +860,10 @@ function runSession(cmd, args, label) {
|
|
|
835
860
|
markLaunched();
|
|
836
861
|
const result = spawnSync(cmd, args, { stdio: 'inherit' });
|
|
837
862
|
console.log('');
|
|
838
|
-
|
|
863
|
+
if (result.status !== 0 && result.status !== null) {
|
|
864
|
+
console.log(` ${yellow('Session exited with code ' + result.status + '.')} ${dim('(' + cmd + ' ' + args.join(' ') + ')')}`);
|
|
865
|
+
}
|
|
866
|
+
console.log(' Returned to Data Tools โ Dual Brain.');
|
|
839
867
|
return result.status || 0;
|
|
840
868
|
}
|
|
841
869
|
|
|
@@ -872,6 +900,15 @@ async function mainLoop() {
|
|
|
872
900
|
} else {
|
|
873
901
|
runSession('claude', ['-r', s.id, '--dangerously-skip-permissions'], `Resuming session ${s.id.slice(0, 8)}...`);
|
|
874
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('');
|
|
875
912
|
} else {
|
|
876
913
|
runSession('claude', ['--dangerously-skip-permissions'], 'Starting new session...');
|
|
877
914
|
}
|
|
@@ -890,7 +927,13 @@ async function mainLoop() {
|
|
|
890
927
|
}
|
|
891
928
|
|
|
892
929
|
if (choice === 'n') {
|
|
893
|
-
|
|
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
|
+
}
|
|
894
937
|
continue;
|
|
895
938
|
}
|
|
896
939
|
|
|
@@ -916,9 +959,46 @@ async function mainLoop() {
|
|
|
916
959
|
|
|
917
960
|
if (choice === 'u') {
|
|
918
961
|
console.log('');
|
|
919
|
-
console.log(' Updating
|
|
962
|
+
console.log(' Updating Dual Brain...');
|
|
920
963
|
console.log('');
|
|
921
|
-
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
|
+
}
|
|
970
|
+
continue;
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
if (choice === 't') {
|
|
974
|
+
const dtPath = join(CWD, '.replit-tools');
|
|
975
|
+
if (existsSync(dtPath)) {
|
|
976
|
+
const scriptPath = join(dtPath, 'scripts', 'setup-claude-code.sh');
|
|
977
|
+
if (existsSync(scriptPath)) {
|
|
978
|
+
console.log('');
|
|
979
|
+
console.log(' Opening Data Tools dashboard...');
|
|
980
|
+
console.log('');
|
|
981
|
+
spawnSync('bash', [scriptPath], { stdio: 'inherit', cwd: CWD });
|
|
982
|
+
} else {
|
|
983
|
+
console.log('');
|
|
984
|
+
console.log(` Data Tools present but dashboard script missing.`);
|
|
985
|
+
console.log(` Try: ${cyan('source .replit-tools/scripts/setup-claude-code.sh')}`);
|
|
986
|
+
console.log('');
|
|
987
|
+
}
|
|
988
|
+
} else if (IS_REPLIT) {
|
|
989
|
+
console.log('');
|
|
990
|
+
console.log(' Installing replit-tools (Data Tools)...');
|
|
991
|
+
console.log('');
|
|
992
|
+
spawnSync('npx', ['-y', 'data-tools'], { stdio: 'inherit', cwd: CWD });
|
|
993
|
+
console.log('');
|
|
994
|
+
console.log(' Done. Press Enter to continue...');
|
|
995
|
+
const askOnce = () => new Promise(resolve => rl.question('', resolve));
|
|
996
|
+
await askOnce();
|
|
997
|
+
} else {
|
|
998
|
+
console.log('');
|
|
999
|
+
console.log(` Data Tools is designed for Replit environments.`);
|
|
1000
|
+
console.log('');
|
|
1001
|
+
}
|
|
922
1002
|
continue;
|
|
923
1003
|
}
|
|
924
1004
|
|
|
@@ -948,14 +1028,18 @@ async function mainLoop() {
|
|
|
948
1028
|
continue;
|
|
949
1029
|
}
|
|
950
1030
|
|
|
951
|
-
if (choice === '
|
|
1031
|
+
if (choice === '?') {
|
|
952
1032
|
console.log('');
|
|
953
|
-
console.log('
|
|
1033
|
+
console.log(` ${bold('What is Dual Brain?')}`);
|
|
954
1034
|
console.log('');
|
|
955
|
-
|
|
1035
|
+
console.log(' Dual Brain orchestrates your Claude + Codex subscriptions together.');
|
|
1036
|
+
console.log(' It routes tasks to the right model: search (fast), execute (edits),');
|
|
1037
|
+
console.log(' think (architecture). Both providers work in parallel when possible.');
|
|
956
1038
|
console.log('');
|
|
957
|
-
console.log('
|
|
1039
|
+
console.log(' Modes: Auto adapts to your workflow. Cost-saver minimizes GPT usage.');
|
|
1040
|
+
console.log(' Quality-first uses dual-brain review on all medium+ risk changes.');
|
|
958
1041
|
console.log('');
|
|
1042
|
+
console.log(` ${dim('Press Enter to return...')}`);
|
|
959
1043
|
await ask();
|
|
960
1044
|
continue;
|
|
961
1045
|
}
|
|
@@ -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
|
|
31
|
-
|
|
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/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
|
-
๐ง
|
|
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
|
|
|
@@ -846,7 +848,7 @@ function printReport(env, mode, actions, isDryRun) {
|
|
|
846
848
|
const lines = [];
|
|
847
849
|
|
|
848
850
|
lines.push(br('โ', 'โ'));
|
|
849
|
-
lines.push(ln(`๐ง Dual
|
|
851
|
+
lines.push(ln(`๐ง Data Tools โ Dual Brain v${VERSION}`));
|
|
850
852
|
lines.push(sep());
|
|
851
853
|
|
|
852
854
|
const cAuth = env.claude.authed ? 'โ
' : env.claude.installed ? 'โ ๏ธ' : 'โ';
|
package/package.json
CHANGED