dual-brain 0.3.18 → 0.3.20
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 +33 -1
- package/install.mjs +19 -1
- package/package.json +1 -1
- package/shell-hook.sh +1 -1
package/bin/dual-brain.mjs
CHANGED
|
@@ -355,6 +355,7 @@ Commands:
|
|
|
355
355
|
--files a,b (specialist commands) Provide file context
|
|
356
356
|
watch [dir] Monitor file changes and suggest actions
|
|
357
357
|
--auto Auto-execute safe suggestions (tests, install)
|
|
358
|
+
menu Open the dual-brain shell menu
|
|
358
359
|
shell-hook Output bash snippet to add dual-brain to your shell
|
|
359
360
|
Usage: dual-brain shell-hook >> ~/.bashrc
|
|
360
361
|
|
|
@@ -2720,6 +2721,8 @@ async function mainScreen(rl, ask) {
|
|
|
2720
2721
|
|
|
2721
2722
|
// ── Continuation card (interrupted work) ─────────────────────────────────
|
|
2722
2723
|
if (interrupted) {
|
|
2724
|
+
if (_spinnerTimeout) clearTimeout(_spinnerTimeout);
|
|
2725
|
+
if (dashSpinner) { try { dashSpinner.stop(); } catch {} dashSpinner = null; }
|
|
2723
2726
|
const DIM = '\x1b[2m', RST = '\x1b[0m', YLW = '\x1b[33m';
|
|
2724
2727
|
process.stdout.write(`\n ${YLW}Continue:${RST} ${interrupted.sessionName}\n`);
|
|
2725
2728
|
if (interrupted.lastState) {
|
|
@@ -6846,6 +6849,35 @@ async function main() {
|
|
|
6846
6849
|
// Interactive-only commands: enter screen state machine (only when TTY)
|
|
6847
6850
|
const isInteractive = process.stdin.isTTY;
|
|
6848
6851
|
|
|
6852
|
+
if (cmd === 'menu') {
|
|
6853
|
+
if (!isInteractive) {
|
|
6854
|
+
process.stderr.write('dual-brain menu requires an interactive terminal.\n');
|
|
6855
|
+
process.exit(1);
|
|
6856
|
+
}
|
|
6857
|
+
const cwd = process.cwd();
|
|
6858
|
+
cleanStaleMarkers(cwd);
|
|
6859
|
+
if (!process.argv.includes('--force') && checkLoopMarker(cwd)) {
|
|
6860
|
+
process.exit(0);
|
|
6861
|
+
}
|
|
6862
|
+
setLoopMarker(cwd);
|
|
6863
|
+
if (profileExists(cwd)) {
|
|
6864
|
+
await runScreens('main');
|
|
6865
|
+
} else {
|
|
6866
|
+
const auth = await detectAuth();
|
|
6867
|
+
const plans = detectPlans();
|
|
6868
|
+
const existingSessions = importReplitSessions(cwd);
|
|
6869
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
6870
|
+
const wizardProfile = await runOnboardingWizard({ auth, plans, existingSessions }, cwd, rl);
|
|
6871
|
+
if (wizardProfile) {
|
|
6872
|
+
saveProfile(wizardProfile, { cwd });
|
|
6873
|
+
await cmdInstall(cwd);
|
|
6874
|
+
}
|
|
6875
|
+
rl.close();
|
|
6876
|
+
await runScreens('main');
|
|
6877
|
+
}
|
|
6878
|
+
return;
|
|
6879
|
+
}
|
|
6880
|
+
|
|
6849
6881
|
if (!cmd) {
|
|
6850
6882
|
if (isInteractive) {
|
|
6851
6883
|
const cwd = process.cwd();
|
|
@@ -7136,7 +7168,7 @@ fi
|
|
|
7136
7168
|
// If cmd is not a recognized subcommand, treat the entire arg list as a task.
|
|
7137
7169
|
// e.g. `dual-brain fix failing tests` → same as `dual-brain go "fix failing tests"`
|
|
7138
7170
|
const KNOWN_COMMANDS = new Set([
|
|
7139
|
-
'init', 'install', 'uninstall', 'auth', 'go', 'do', 'plan', 'ship', 'think', 'review', 'pr', 'status', 'handoff', 'switch', 'hot', 'cool',
|
|
7171
|
+
'menu', 'init', 'install', 'uninstall', 'auth', 'go', 'do', 'plan', 'ship', 'think', 'review', 'pr', 'status', 'handoff', 'switch', 'hot', 'cool',
|
|
7140
7172
|
'remember', 'forget', 'break-glass', 'specialists', 'search', 'shell-hook', 'watch', 'update', 'upgrade',
|
|
7141
7173
|
'--help', '-h', '--version', '-v',
|
|
7142
7174
|
...Object.keys(loadSpecialistRegistry()),
|
package/install.mjs
CHANGED
|
@@ -1064,12 +1064,25 @@ function installDefaultShellLauncher(workspace, actions) {
|
|
|
1064
1064
|
'fi',
|
|
1065
1065
|
quietSetupEnd,
|
|
1066
1066
|
].join('\n');
|
|
1067
|
+
const quietSessionStart = '# >>> dual-brain quiet data-tools session manager >>>';
|
|
1068
|
+
const quietSessionEnd = '# <<< dual-brain quiet data-tools session manager <<<';
|
|
1069
|
+
const quietSessionBlock = [
|
|
1070
|
+
quietSessionStart,
|
|
1071
|
+
'if [ -f "${SESSION_MANAGER}" ]; then',
|
|
1072
|
+
' if [ "${DUAL_BRAIN_DEFAULT_SHELL}" = "true" ]; then',
|
|
1073
|
+
' source "${SESSION_MANAGER}" >/dev/null 2>&1',
|
|
1074
|
+
' else',
|
|
1075
|
+
' source "${SESSION_MANAGER}"',
|
|
1076
|
+
' fi',
|
|
1077
|
+
'fi',
|
|
1078
|
+
quietSessionEnd,
|
|
1079
|
+
].join('\n');
|
|
1067
1080
|
const block = [
|
|
1068
1081
|
start,
|
|
1069
1082
|
'# Added by dual-brain install. Set DUAL_BRAIN_SKIP=1 to bypass.',
|
|
1070
1083
|
'if [ -t 1 ] && [ -z "${DUAL_BRAIN_LOADED}" ] && [ -z "${DUAL_BRAIN_SKIP}" ]; then',
|
|
1071
1084
|
' export DUAL_BRAIN_LOADED=1',
|
|
1072
|
-
' command -v dual-brain >/dev/null 2>&1 && dual-brain',
|
|
1085
|
+
' command -v dual-brain >/dev/null 2>&1 && dual-brain menu',
|
|
1073
1086
|
'fi',
|
|
1074
1087
|
end,
|
|
1075
1088
|
].join('\n');
|
|
@@ -1080,10 +1093,13 @@ function installDefaultShellLauncher(workspace, actions) {
|
|
|
1080
1093
|
const existing = new RegExp(`${esc(start)}[\\s\\S]*?${esc(end)}\\n?`, 'm');
|
|
1081
1094
|
const existingSuppress = new RegExp(`${esc(suppressStart)}[\\s\\S]*?${esc(suppressEnd)}\\n?`, 'm');
|
|
1082
1095
|
const existingQuietSetup = new RegExp(`${esc(quietSetupStart)}[\\s\\S]*?${esc(quietSetupEnd)}\\n?`, 'm');
|
|
1096
|
+
const existingQuietSession = new RegExp(`${esc(quietSessionStart)}[\\s\\S]*?${esc(quietSessionEnd)}\\n?`, 'm');
|
|
1083
1097
|
src = src.replace(existing, '');
|
|
1084
1098
|
src = src.replace(existingSuppress, '');
|
|
1085
1099
|
src = src.replace(existingQuietSetup, '');
|
|
1100
|
+
src = src.replace(existingQuietSession, '');
|
|
1086
1101
|
src = src.replace(/\[ -f "\$\{SETUP_SCRIPT\}" \] && source "\$\{SETUP_SCRIPT\}"\n?/g, '');
|
|
1102
|
+
src = src.replace(/\[ -f "\$\{SESSION_MANAGER\}" \] && source "\$\{SESSION_MANAGER\}"\n?/g, '');
|
|
1087
1103
|
const earlyMarker = '# Claude Code Setup';
|
|
1088
1104
|
const sessionMarker = '# Session Manager (interactive menu)';
|
|
1089
1105
|
if (src.includes(earlyMarker)) src = src.replace(earlyMarker, `${suppressBlock}\n\n${earlyMarker}`);
|
|
@@ -1091,6 +1107,8 @@ function installDefaultShellLauncher(workspace, actions) {
|
|
|
1091
1107
|
else src = `${suppressBlock}\n\n${src.replace(/^\s*/, '')}`;
|
|
1092
1108
|
const setupMarker = 'SETUP_SCRIPT="/home/runner/workspace/.replit-tools/scripts/setup-claude-code.sh"';
|
|
1093
1109
|
if (src.includes(setupMarker)) src = src.replace(setupMarker, `${setupMarker}\n${quietSetupBlock}`);
|
|
1110
|
+
const sessionMgrMarker = 'SESSION_MANAGER="/home/runner/workspace/.replit-tools/scripts/claude-session-manager.sh"';
|
|
1111
|
+
if (src.includes(sessionMgrMarker)) src = src.replace(sessionMgrMarker, `${sessionMgrMarker}\n${quietSessionBlock}`);
|
|
1094
1112
|
const marker = '# Auto-show menu on shell start';
|
|
1095
1113
|
if (src.includes(marker)) src = src.replace(marker, `${block}\n\n${marker}`);
|
|
1096
1114
|
else src = `${src.replace(/\s*$/, '\n\n')}${block}\n`;
|
package/package.json
CHANGED