dual-brain 0.3.29 → 0.3.30

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.
Files changed (2) hide show
  1. package/bin/dual-brain.mjs +37 -2
  2. package/package.json +1 -1
@@ -1564,12 +1564,38 @@ async function cmdRuntimeSwitch(args = []) {
1564
1564
  }
1565
1565
 
1566
1566
  async function cmdAuto(args = []) {
1567
- const switchArgs = ['--automode', '--confirm'];
1567
+ const switchArgs = ['--automode', '--confirm', '--apply'];
1568
1568
  const levelIdx = args.findIndex(a => a === '--level' || a === '--intelligence' || a === '--intelligence-level');
1569
1569
  if (levelIdx !== -1 && args[levelIdx + 1]) switchArgs.push('--level', args[levelIdx + 1]);
1570
1570
  await cmdRuntimeSwitch(switchArgs);
1571
1571
  }
1572
1572
 
1573
+ async function cmdSwitchover(args = []) {
1574
+ const cwd = process.cwd();
1575
+ let sessions = [];
1576
+ try { sessions = enrichSessions(importReplitSessions(cwd), cwd); } catch {}
1577
+ const active = readActiveConversation(cwd);
1578
+ const sess = active
1579
+ ? (sessions.find(s => s.id === active.sessionId) || {
1580
+ id: active.sessionId,
1581
+ tool: active.provider,
1582
+ smartName: active.sessionName || active.conversationId || active.sessionId,
1583
+ })
1584
+ : sessions[0];
1585
+ if (!sess) {
1586
+ console.log('No resumable session found.');
1587
+ return;
1588
+ }
1589
+
1590
+ let target = null;
1591
+ const joined = args.join(' ').toLowerCase();
1592
+ if (/\b(gpt|codex|openai)\b/.test(joined)) target = 'codex';
1593
+ if (/\bclaude\b/.test(joined)) target = 'claude';
1594
+ target ||= _sessionTool(sess) === 'codex' ? 'claude' : 'codex';
1595
+
1596
+ await cmdRuntimeSwitch(['--to', target, '--automode', '--confirm', '--apply', '--reason', 'head-switchover']);
1597
+ }
1598
+
1573
1599
  async function cmdUpdate() {
1574
1600
  const cwd = process.cwd();
1575
1601
  console.log(' Updating Dual Brain...');
@@ -2535,6 +2561,9 @@ function applyIntelligenceCommand(cmd, cwd) {
2535
2561
 
2536
2562
  function parseProviderSwitchCommand(input) {
2537
2563
  const text = input.trim().toLowerCase().replace(/\s+/g, ' ');
2564
+ if (/\b(switch over|switchover|switch)\b.*\b(auto|automode|auto mode|smart auto)\b/.test(text)) {
2565
+ return { provider: null, automode: true };
2566
+ }
2538
2567
  if (!/\b(switchover|switch over|switch provider|other provider|continue in (gpt|codex|claude|other provider)|switch (to|into) (gpt|codex|claude|openai))\b/.test(text)) {
2539
2568
  return null;
2540
2569
  }
@@ -4297,6 +4326,10 @@ async function mainScreen(rl, ask) {
4297
4326
  }
4298
4327
 
4299
4328
  if (cmd === 'provider-switch') {
4329
+ if (classified.providerSwitchCommand.automode) {
4330
+ await cmdAuto(['--level', String(_getIntelligenceLevel(loadProfile(cwd), loadSessionSettings(cwd)))]);
4331
+ return { next: 'main' };
4332
+ }
4300
4333
  const sess = getActionSession(cwd, recentSessions);
4301
4334
  if (!sess) return { next: 'new-session' };
4302
4335
  const target = classified.providerSwitchCommand.provider;
@@ -8101,9 +8134,11 @@ async function main() {
8101
8134
  if (cmd === 'pr') { await cmdPR(args.slice(1)); return; }
8102
8135
  if (cmd === 'status') { await cmdStatus(args.slice(1)); return; }
8103
8136
  if (cmd === 'handoff') { await cmdHandoff(args.slice(1)); return; }
8137
+ if (cmd === 'switch' && /\b(auto|automode|auto mode|smart auto)\b/i.test(args.join(' '))) { await cmdAuto(args.slice(1)); return; }
8104
8138
  if (cmd === 'switch') { await cmdSwitch(args.slice(1)); return; }
8105
8139
  if (cmd === 'runtime-switch') { await cmdRuntimeSwitch(args.slice(1)); return; }
8106
8140
  if (cmd === 'auto' || cmd === 'automode' || cmd === 'smart-auto') { await cmdAuto(args.slice(1)); return; }
8141
+ if (cmd === 'switchover' || cmd === 'switch-over') { await cmdSwitchover(args.slice(1)); return; }
8107
8142
  if (cmd === 'update' || cmd === 'upgrade') { await cmdUpdate(); return; }
8108
8143
  if (cmd === 'hot') { cmdHot(args[1]); return; }
8109
8144
  if (cmd === 'cool') { cmdCool(args[1]); return; }
@@ -8168,7 +8203,7 @@ fi
8168
8203
  // If cmd is not a recognized subcommand, treat the entire arg list as a task.
8169
8204
  // e.g. `dual-brain fix failing tests` → same as `dual-brain go "fix failing tests"`
8170
8205
  const KNOWN_COMMANDS = new Set([
8171
- 'menu', 'init', 'install', 'uninstall', 'auth', 'go', 'do', 'plan', 'ship', 'think', 'review', 'pr', 'status', 'handoff', 'switch', 'runtime-switch', 'auto', 'automode', 'smart-auto', 'hot', 'cool',
8206
+ 'menu', 'init', 'install', 'uninstall', 'auth', 'go', 'do', 'plan', 'ship', 'think', 'review', 'pr', 'status', 'handoff', 'switch', 'switchover', 'switch-over', 'runtime-switch', 'auto', 'automode', 'smart-auto', 'hot', 'cool',
8172
8207
  'remember', 'forget', 'break-glass', 'specialists', 'search', 'shell-hook', 'watch', 'update', 'upgrade',
8173
8208
  '--help', '-h', '--version', '-v',
8174
8209
  ...Object.keys(loadSpecialistRegistry()),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dual-brain",
3
- "version": "0.3.29",
3
+ "version": "0.3.30",
4
4
  "description": "AI orchestration across Claude + OpenAI subscriptions — smart routing, budget awareness, and dual-brain collaboration",
5
5
  "type": "module",
6
6
  "bin": {