dual-brain 0.3.35 → 0.3.36
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 +89 -4
- package/package.json +1 -1
package/bin/dual-brain.mjs
CHANGED
|
@@ -6,6 +6,7 @@ import { join, dirname, basename, extname } from 'node:path';
|
|
|
6
6
|
import { fileURLToPath } from 'node:url';
|
|
7
7
|
import { execSync, spawnSync as _spawnSyncTop } from 'node:child_process';
|
|
8
8
|
import { createInterface } from 'node:readline';
|
|
9
|
+
import { randomUUID } from 'node:crypto';
|
|
9
10
|
|
|
10
11
|
import {
|
|
11
12
|
ensureProfile, loadProfile, saveProfile, runOnboarding,
|
|
@@ -68,6 +69,22 @@ function _codexResumeArgs(sessionId, cwd) {
|
|
|
68
69
|
];
|
|
69
70
|
}
|
|
70
71
|
|
|
72
|
+
function _codexNewArgs(cwd) {
|
|
73
|
+
const workspace = cwd || process.cwd();
|
|
74
|
+
if (getEffectiveBypassPermissions(workspace)) {
|
|
75
|
+
return ['--dangerously-bypass-approvals-and-sandbox'];
|
|
76
|
+
}
|
|
77
|
+
const settings = loadSessionSettings(workspace);
|
|
78
|
+
const approvalMode = getEffectiveAutomode(loadProfile(workspace), workspace) ? 'never' : 'on-request';
|
|
79
|
+
return [
|
|
80
|
+
..._codexModelEffortArgs(
|
|
81
|
+
_modelMatchesProvider(settings.headModel, 'codex') ? settings.headModel : null,
|
|
82
|
+
settings.effort,
|
|
83
|
+
),
|
|
84
|
+
..._codexApprovalArgs(workspace, approvalMode),
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
|
|
71
88
|
function _isReplitWorkspace(cwd) {
|
|
72
89
|
const workspace = cwd || process.cwd();
|
|
73
90
|
return !!(
|
|
@@ -4795,11 +4812,79 @@ async function mainScreen(rl, ask) {
|
|
|
4795
4812
|
|
|
4796
4813
|
async function newSessionScreen(rl, ask) {
|
|
4797
4814
|
const cwd = process.cwd();
|
|
4798
|
-
const
|
|
4799
|
-
|
|
4815
|
+
const profile = loadProfile(cwd);
|
|
4816
|
+
const settings = loadSessionSettings(cwd);
|
|
4817
|
+
settings.automode = true;
|
|
4818
|
+
settings.bypassPermissions = false;
|
|
4819
|
+
|
|
4820
|
+
let provider = _modelMatchesProvider(settings.headModel, 'claude') ? 'claude' : 'codex';
|
|
4821
|
+
if (!_modelMatchesProvider(settings.headModel, provider)) {
|
|
4822
|
+
const policy = _headPolicyFor(provider, profile, settings);
|
|
4823
|
+
settings.headModel = policy.model;
|
|
4824
|
+
settings.effort = policy.effort;
|
|
4825
|
+
}
|
|
4826
|
+
saveSessionSettings(cwd, settings);
|
|
4827
|
+
|
|
4828
|
+
const renderStart = () => {
|
|
4829
|
+
const policy = _headPolicyFor(provider, profile, settings);
|
|
4830
|
+
if (!_modelMatchesProvider(settings.headModel, provider)) {
|
|
4831
|
+
settings.headModel = policy.model;
|
|
4832
|
+
settings.effort = policy.effort;
|
|
4833
|
+
saveSessionSettings(cwd, settings);
|
|
4834
|
+
}
|
|
4835
|
+
process.stdout.write('\n');
|
|
4836
|
+
process.stdout.write(' New HEAD Conversation\n\n');
|
|
4837
|
+
process.stdout.write(' Recommended Balanced Session\n');
|
|
4838
|
+
process.stdout.write(` Provider: ${provider === 'codex' ? 'GPT/Codex' : 'Claude'}\n`);
|
|
4839
|
+
process.stdout.write(` Model: ${settings.headModel || policy.model} (${settings.effort || policy.effort || 'default'})\n`);
|
|
4840
|
+
process.stdout.write(' Mode: Smart Auto\n');
|
|
4841
|
+
process.stdout.write(` Permissions: ${provider === 'codex' ? 'never ask + Replit sandbox boundary' : 'auto'}\n\n`);
|
|
4842
|
+
process.stdout.write(' Enter start recommended p start with pasted prompt b back\n\n');
|
|
4843
|
+
};
|
|
4844
|
+
|
|
4845
|
+
renderStart();
|
|
4846
|
+
let choice = (await ask(' Choice: ')).trim().toLowerCase();
|
|
4847
|
+
let initialPrompt = '';
|
|
4848
|
+
if (choice === 'b' || choice === 'q') return { next: 'main' };
|
|
4849
|
+
if (choice === 'p' || choice === 'prompt') {
|
|
4850
|
+
initialPrompt = (await ask(' Initial prompt: ')).trim();
|
|
4851
|
+
}
|
|
4800
4852
|
|
|
4801
|
-
|
|
4802
|
-
|
|
4853
|
+
const policy = _headPolicyFor(provider, profile, settings);
|
|
4854
|
+
if (!_modelMatchesProvider(settings.headModel, provider)) settings.headModel = policy.model;
|
|
4855
|
+
if (!settings.effort) settings.effort = policy.effort;
|
|
4856
|
+
settings.automode = true;
|
|
4857
|
+
settings.bypassPermissions = false;
|
|
4858
|
+
saveSessionSettings(cwd, settings);
|
|
4859
|
+
|
|
4860
|
+
const session = {
|
|
4861
|
+
id: randomUUID(),
|
|
4862
|
+
tool: provider,
|
|
4863
|
+
smartName: 'New HEAD Conversation',
|
|
4864
|
+
firstPrompt: initialPrompt || 'New dual-brain HEAD conversation',
|
|
4865
|
+
};
|
|
4866
|
+
const launchArgs = provider === 'codex'
|
|
4867
|
+
? _codexNewArgs(cwd)
|
|
4868
|
+
: ['--session-id', session.id, ..._claudeNewArgs(cwd)];
|
|
4869
|
+
if (initialPrompt) launchArgs.push(initialPrompt);
|
|
4870
|
+
|
|
4871
|
+
process.stdout.write('\n');
|
|
4872
|
+
process.stdout.write(' Starting HEAD in Smart Auto...\n');
|
|
4873
|
+
process.stdout.write(` Provider: ${provider === 'codex' ? 'GPT/Codex' : 'Claude'}\n`);
|
|
4874
|
+
process.stdout.write(` Model: ${settings.headModel || 'default'}${settings.effort ? ` (${settings.effort})` : ''}\n`);
|
|
4875
|
+
process.stdout.write(` Launch: ${provider} ${launchArgs.join(' ')}\n\n`);
|
|
4876
|
+
|
|
4877
|
+
writeActiveConversation(cwd, session, provider, {
|
|
4878
|
+
model: settings.headModel || null,
|
|
4879
|
+
effort: settings.effort || null,
|
|
4880
|
+
automode: true,
|
|
4881
|
+
bypassPermissions: false,
|
|
4882
|
+
});
|
|
4883
|
+
try {
|
|
4884
|
+
await launchSupervisedHead(provider, launchArgs, cwd, session);
|
|
4885
|
+
} finally {
|
|
4886
|
+
clearActiveConversation(cwd, session.id);
|
|
4887
|
+
}
|
|
4803
4888
|
|
|
4804
4889
|
return { next: 'main' };
|
|
4805
4890
|
}
|
package/package.json
CHANGED