dual-brain 0.3.29 → 0.3.31

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 +48 -4
  2. package/package.json +1 -1
@@ -1558,18 +1558,53 @@ async function cmdRuntimeSwitch(args = []) {
1558
1558
  console.log('');
1559
1559
 
1560
1560
  if (args.includes('--apply')) {
1561
- const applied = await processPendingRuntimeSwitch(cwd);
1562
- if (!applied) console.log('Could not apply live here; resume the session through dual-brain to use these settings.');
1561
+ if (!process.stdin.isTTY || !process.stdout.isTTY) {
1562
+ console.log('Non-interactive shell detected: saved for the active dual-brain terminal to apply.');
1563
+ } else {
1564
+ const applied = await processPendingRuntimeSwitch(cwd);
1565
+ if (!applied) console.log('Could not apply live here; resume the session through dual-brain to use these settings.');
1566
+ }
1563
1567
  }
1564
1568
  }
1565
1569
 
1566
1570
  async function cmdAuto(args = []) {
1567
- const switchArgs = ['--automode', '--confirm'];
1571
+ const switchArgs = ['--automode', '--confirm', '--apply'];
1568
1572
  const levelIdx = args.findIndex(a => a === '--level' || a === '--intelligence' || a === '--intelligence-level');
1569
1573
  if (levelIdx !== -1 && args[levelIdx + 1]) switchArgs.push('--level', args[levelIdx + 1]);
1570
1574
  await cmdRuntimeSwitch(switchArgs);
1571
1575
  }
1572
1576
 
1577
+ async function cmdSwitchover(args = []) {
1578
+ const joined = args.join(' ').toLowerCase();
1579
+ if (/\b(auto|automode|auto mode|smart auto)\b/.test(joined)) {
1580
+ await cmdAuto(args);
1581
+ return;
1582
+ }
1583
+
1584
+ const cwd = process.cwd();
1585
+ let sessions = [];
1586
+ try { sessions = enrichSessions(importReplitSessions(cwd), cwd); } catch {}
1587
+ const active = readActiveConversation(cwd);
1588
+ const sess = active
1589
+ ? (sessions.find(s => s.id === active.sessionId) || {
1590
+ id: active.sessionId,
1591
+ tool: active.provider,
1592
+ smartName: active.sessionName || active.conversationId || active.sessionId,
1593
+ })
1594
+ : sessions[0];
1595
+ if (!sess) {
1596
+ console.log('No resumable session found.');
1597
+ return;
1598
+ }
1599
+
1600
+ let target = null;
1601
+ if (/\b(gpt|codex|openai)\b/.test(joined)) target = 'codex';
1602
+ if (/\bclaude\b/.test(joined)) target = 'claude';
1603
+ target ||= _sessionTool(sess) === 'codex' ? 'claude' : 'codex';
1604
+
1605
+ await cmdRuntimeSwitch(['--to', target, '--automode', '--confirm', '--apply', '--reason', 'head-switchover']);
1606
+ }
1607
+
1573
1608
  async function cmdUpdate() {
1574
1609
  const cwd = process.cwd();
1575
1610
  console.log(' Updating Dual Brain...');
@@ -2535,6 +2570,9 @@ function applyIntelligenceCommand(cmd, cwd) {
2535
2570
 
2536
2571
  function parseProviderSwitchCommand(input) {
2537
2572
  const text = input.trim().toLowerCase().replace(/\s+/g, ' ');
2573
+ if (/\b(switch over|switchover|switch)\b.*\b(auto|automode|auto mode|smart auto)\b/.test(text)) {
2574
+ return { provider: null, automode: true };
2575
+ }
2538
2576
  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
2577
  return null;
2540
2578
  }
@@ -4297,6 +4335,10 @@ async function mainScreen(rl, ask) {
4297
4335
  }
4298
4336
 
4299
4337
  if (cmd === 'provider-switch') {
4338
+ if (classified.providerSwitchCommand.automode) {
4339
+ await cmdAuto(['--level', String(_getIntelligenceLevel(loadProfile(cwd), loadSessionSettings(cwd)))]);
4340
+ return { next: 'main' };
4341
+ }
4300
4342
  const sess = getActionSession(cwd, recentSessions);
4301
4343
  if (!sess) return { next: 'new-session' };
4302
4344
  const target = classified.providerSwitchCommand.provider;
@@ -8101,9 +8143,11 @@ async function main() {
8101
8143
  if (cmd === 'pr') { await cmdPR(args.slice(1)); return; }
8102
8144
  if (cmd === 'status') { await cmdStatus(args.slice(1)); return; }
8103
8145
  if (cmd === 'handoff') { await cmdHandoff(args.slice(1)); return; }
8146
+ if (cmd === 'switch' && /\b(auto|automode|auto mode|smart auto)\b/i.test(args.join(' '))) { await cmdAuto(args.slice(1)); return; }
8104
8147
  if (cmd === 'switch') { await cmdSwitch(args.slice(1)); return; }
8105
8148
  if (cmd === 'runtime-switch') { await cmdRuntimeSwitch(args.slice(1)); return; }
8106
8149
  if (cmd === 'auto' || cmd === 'automode' || cmd === 'smart-auto') { await cmdAuto(args.slice(1)); return; }
8150
+ if (cmd === 'switchover' || cmd === 'switch-over') { await cmdSwitchover(args.slice(1)); return; }
8107
8151
  if (cmd === 'update' || cmd === 'upgrade') { await cmdUpdate(); return; }
8108
8152
  if (cmd === 'hot') { cmdHot(args[1]); return; }
8109
8153
  if (cmd === 'cool') { cmdCool(args[1]); return; }
@@ -8168,7 +8212,7 @@ fi
8168
8212
  // If cmd is not a recognized subcommand, treat the entire arg list as a task.
8169
8213
  // e.g. `dual-brain fix failing tests` → same as `dual-brain go "fix failing tests"`
8170
8214
  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',
8215
+ '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
8216
  'remember', 'forget', 'break-glass', 'specialists', 'search', 'shell-hook', 'watch', 'update', 'upgrade',
8173
8217
  '--help', '-h', '--version', '-v',
8174
8218
  ...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.31",
4
4
  "description": "AI orchestration across Claude + OpenAI subscriptions — smart routing, budget awareness, and dual-brain collaboration",
5
5
  "type": "module",
6
6
  "bin": {