dual-brain 0.2.12 → 0.2.13
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/bin/dual-brain.mjs +47 -23
- package/package.json +1 -1
package/bin/dual-brain.mjs
CHANGED
|
@@ -20,6 +20,24 @@ import {
|
|
|
20
20
|
|
|
21
21
|
import { detectTask, primeAgentRegistry } from '../src/detect.mjs';
|
|
22
22
|
|
|
23
|
+
// ─── Claude launch helper ────────────────────────────────────────────────────
|
|
24
|
+
// Builds launch args respecting user's bypass preference from profile.
|
|
25
|
+
// Never hardcode --dangerously-skip-permissions — it's a user choice.
|
|
26
|
+
|
|
27
|
+
function _claudeResumeArgs(sessionId, cwd) {
|
|
28
|
+
const args = ['--resume', sessionId];
|
|
29
|
+
const prof = loadProfile(cwd || process.cwd());
|
|
30
|
+
if (prof.bypassPermissions) args.push('--dangerously-skip-permissions');
|
|
31
|
+
return args;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function _claudeNewArgs(cwd) {
|
|
35
|
+
const args = [];
|
|
36
|
+
const prof = loadProfile(cwd || process.cwd());
|
|
37
|
+
if (prof.bypassPermissions) args.push('--dangerously-skip-permissions');
|
|
38
|
+
return args;
|
|
39
|
+
}
|
|
40
|
+
|
|
23
41
|
// ─── Agent/skill registry cache (populated at startup) ───────────────────────
|
|
24
42
|
// These are set by _primeRegistryCache() so classifyInput can use them
|
|
25
43
|
// synchronously without async overhead on each keystroke.
|
|
@@ -2286,10 +2304,12 @@ async function mainScreen(rl, ask) {
|
|
|
2286
2304
|
// ── One-time default shell prompt for returning users (never asked before) ─
|
|
2287
2305
|
if (profile.setupComplete && !profile.defaultShellAsked) {
|
|
2288
2306
|
if (dashSpinner) { dashSpinner.stop(); dashSpinner = null; }
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2307
|
+
try {
|
|
2308
|
+
const wantsDefault = await askDefaultShell(cwd, rl, fx);
|
|
2309
|
+
profile.defaultShellAsked = true;
|
|
2310
|
+
profile.isDefaultShell = wantsDefault;
|
|
2311
|
+
saveProfile(profile, { cwd });
|
|
2312
|
+
} catch { profile.defaultShellAsked = true; }
|
|
2293
2313
|
}
|
|
2294
2314
|
|
|
2295
2315
|
const claudeSub = profile?.providers?.claude;
|
|
@@ -2312,17 +2332,20 @@ async function mainScreen(rl, ask) {
|
|
|
2312
2332
|
syncSessionMirror(cwd);
|
|
2313
2333
|
} catch {}
|
|
2314
2334
|
|
|
2315
|
-
// Auto-refresh expired subscriptions
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
const
|
|
2320
|
-
if (
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
if (
|
|
2325
|
-
|
|
2335
|
+
// Auto-refresh expired subscriptions (skip during dashboard load — don't block)
|
|
2336
|
+
// Users can manually run 'j' (claude login) or 'k' (codex login) from the menu
|
|
2337
|
+
if ((claudeExpired || openaiExpired) && !dashSpinner) {
|
|
2338
|
+
try {
|
|
2339
|
+
const { spawnSync } = await import('node:child_process');
|
|
2340
|
+
if (claudeExpired) {
|
|
2341
|
+
const r = spawnSync('claude', ['auth', 'login'], { stdio: 'pipe', timeout: 5000 });
|
|
2342
|
+
if (r.status === 0) { claudeSub.expiresAt = null; saveProfile(profile, { cwd }); }
|
|
2343
|
+
}
|
|
2344
|
+
if (openaiExpired) {
|
|
2345
|
+
const r = spawnSync('codex', ['login'], { stdio: 'pipe', timeout: 5000 });
|
|
2346
|
+
if (r.status === 0) { openaiSub.expiresAt = null; saveProfile(profile, { cwd }); }
|
|
2347
|
+
}
|
|
2348
|
+
} catch {}
|
|
2326
2349
|
}
|
|
2327
2350
|
|
|
2328
2351
|
// Build session index in background (powers search + smart resume)
|
|
@@ -2331,8 +2354,9 @@ async function mainScreen(rl, ask) {
|
|
|
2331
2354
|
buildSessionIndex(cwd);
|
|
2332
2355
|
} catch {}
|
|
2333
2356
|
|
|
2334
|
-
// Gather recent sessions
|
|
2335
|
-
|
|
2357
|
+
// Gather recent sessions (wrapped — never hang the dashboard)
|
|
2358
|
+
let allSessions = [];
|
|
2359
|
+
try { allSessions = enrichSessions(importReplitSessions(cwd), cwd); } catch {}
|
|
2336
2360
|
const recentSessions = allSessions.slice(0, 3);
|
|
2337
2361
|
const staleCount = allSessions.filter(s => {
|
|
2338
2362
|
const ageMs = s.lastActive ? Date.now() - new Date(s.lastActive).getTime() : 0;
|
|
@@ -2414,7 +2438,7 @@ async function mainScreen(rl, ask) {
|
|
|
2414
2438
|
if (cardChoice === 'resume') {
|
|
2415
2439
|
const { spawnSync } = await import('node:child_process');
|
|
2416
2440
|
process.stdout.write(` Launching: claude --resume ${interrupted.sessionId}\n\n`);
|
|
2417
|
-
spawnSync('claude',
|
|
2441
|
+
spawnSync('claude', _claudeResumeArgs(interrupted.sessionId, cwd), { stdio: 'inherit' });
|
|
2418
2442
|
saveTerminalState(cwd, getTerminalId(), interrupted.sessionId, 'claude');
|
|
2419
2443
|
return { next: 'main' };
|
|
2420
2444
|
}
|
|
@@ -3082,7 +3106,7 @@ async function mainScreen(rl, ask) {
|
|
|
3082
3106
|
const sess = recentSessions[0];
|
|
3083
3107
|
const { spawnSync } = await import('node:child_process');
|
|
3084
3108
|
process.stdout.write(`\n Launching: claude --resume ${sess.id}\n\n`);
|
|
3085
|
-
spawnSync('claude',
|
|
3109
|
+
spawnSync('claude', _claudeResumeArgs(sess.id, cwd), { stdio: 'inherit' });
|
|
3086
3110
|
saveTerminalState(cwd, getTerminalId(), sess.id, sess.tool || 'claude');
|
|
3087
3111
|
return { next: 'main' };
|
|
3088
3112
|
}
|
|
@@ -3101,7 +3125,7 @@ async function mainScreen(rl, ask) {
|
|
|
3101
3125
|
} catch {}
|
|
3102
3126
|
const { spawnSync } = await import('node:child_process');
|
|
3103
3127
|
process.stdout.write(`\n Launching: claude --resume ${sess.id}\n\n`);
|
|
3104
|
-
spawnSync('claude',
|
|
3128
|
+
spawnSync('claude', _claudeResumeArgs(sess.id, cwd), { stdio: 'inherit' });
|
|
3105
3129
|
saveTerminalState(cwd, getTerminalId(), sess.id, sess.tool || 'claude');
|
|
3106
3130
|
return { next: 'main' };
|
|
3107
3131
|
}
|
|
@@ -5089,7 +5113,7 @@ async function sessionDetailScreen(rl, ask, ctx = {}) {
|
|
|
5089
5113
|
console.log(`\n Launching: claude --resume ${sess.id}\n`);
|
|
5090
5114
|
try {
|
|
5091
5115
|
const { spawnSync } = await import('node:child_process');
|
|
5092
|
-
spawnSync('claude',
|
|
5116
|
+
spawnSync('claude', _claudeResumeArgs(sess.id, cwd), { stdio: 'inherit' });
|
|
5093
5117
|
} catch {
|
|
5094
5118
|
console.log(' Could not launch claude CLI. Run manually:');
|
|
5095
5119
|
console.log(` claude --resume ${sess.id}`);
|
|
@@ -5239,7 +5263,7 @@ async function sessionsScreen(rl, ask) {
|
|
|
5239
5263
|
process.stdout.write('\n');
|
|
5240
5264
|
process.stdout.write(`\n Launching: claude --resume ${sess.id}\n\n`);
|
|
5241
5265
|
const { spawnSync } = await import('node:child_process');
|
|
5242
|
-
spawnSync('claude',
|
|
5266
|
+
spawnSync('claude', _claudeResumeArgs(sess.id, cwd), { stdio: 'inherit' });
|
|
5243
5267
|
saveTerminalState(cwd, getTerminalId(), sess.id, sess.tool || 'claude');
|
|
5244
5268
|
resolve({ next: 'main' });
|
|
5245
5269
|
return;
|
|
@@ -5387,7 +5411,7 @@ async function sessionManageScreen(rl, ask, ctx = {}) {
|
|
|
5387
5411
|
if (choice === 'o') {
|
|
5388
5412
|
const { spawnSync } = await import('node:child_process');
|
|
5389
5413
|
console.log(`\n Launching: claude --resume ${sess.id}\n`);
|
|
5390
|
-
spawnSync('claude',
|
|
5414
|
+
spawnSync('claude', _claudeResumeArgs(sess.id, cwd), { stdio: 'inherit' });
|
|
5391
5415
|
return { next: 'sessions' };
|
|
5392
5416
|
}
|
|
5393
5417
|
|
package/package.json
CHANGED