Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions main.js
Original file line number Diff line number Diff line change
Expand Up @@ -1391,6 +1391,16 @@ ipcMain.handle('open-terminal', async (_event, sessionId, projectPath, isNew, se
let claudeCmd = harness.binary;
if (cliArgs.length) claudeCmd += ' ' + quoteArgvForShell(shell, cliArgs);

// customArgs is raw shell too, like preLaunchCmd below: the user's shell
// does the quoting, e.g. --settings '{"outputStyle": "Learning"}'
if (sessionOptions?.customArgs) {
const custom = String(sessionOptions.customArgs);
if (/[\r\n]/.test(custom)) {
return { ok: false, error: 'customArgs must not contain newlines' };
}
claudeCmd += ' ' + custom;
}

// preLaunchCmd is raw shell by design (e.g. "aws-vault exec profile --") — block newlines only
if (sessionOptions?.preLaunchCmd) {
const pre = String(sessionOptions.preLaunchCmd);
Expand Down
2 changes: 1 addition & 1 deletion projects.js
Original file line number Diff line number Diff line change
Expand Up @@ -1347,7 +1347,7 @@ function legacyScheduleConfig(cli = {}) {
addDirs: cli['add-dirs'] || '',
dangerouslySkipPermissions: false,
worktree: false, worktreeName: '', chrome: false, mcpEmulation: false,
preLaunchCmd: '',
preLaunchCmd: '', customArgs: '',
// The old runner passed --model. Effort did not exist, so it is pinned
// unset rather than picking up a folder default the old run never had.
model: cli.model || '',
Expand Down
1 change: 1 addition & 0 deletions public/session-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
{ key: 'model', label: 'Model', type: 'text', default: '', more: true, placeholder: 'default', suggestions: ['fable', 'opus', 'sonnet'], description: "Blank uses Claude's default. An alias or a full model name" },
{ key: 'effort', label: 'Effort', type: 'select', default: '', more: true, choices: CLAUDE_EFFORTS, description: "Default uses Claude's own setting" },
{ key: 'allowedTools', label: 'Allowed Tools', type: 'text', default: '', more: true, wide: true, description: 'Tools allowed without a permission prompt (comma-separated)' },
{ key: 'customArgs', label: 'Custom Arguments', type: 'text', default: '', more: true, wide: true, placeholder: `e.g. --settings '{"outputStyle": "Learning"}'`, description: 'Appended to the CLI command, as shell' },
{ key: 'appendSystemPrompt', label: 'Additional System Prompt', type: 'textarea', default: '', more: true, wide: true, description: 'Instructions appended to Claude’s system prompt' },
{ key: 'worktree', label: 'Worktree', type: 'boolean', default: false, description: 'Run each new session in an isolated git worktree' },
{ key: 'worktreeName', label: 'Worktree Name', type: 'text', default: '', placeholder: 'name (optional)' },
Expand Down
4 changes: 2 additions & 2 deletions test/session-config.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,9 @@ test('scheduled launches use current folder defaults with only the selected CLI

test('optional settings wait behind More options until they hold a value', () => {
const empty = SessionConfig.resolveOptions('claude', {}, {});
assert.deepEqual(SessionConfig.fieldsBehindMore('claude', empty), ['model', 'effort', 'allowedTools', 'appendSystemPrompt', 'preLaunchCmd', 'addDirs']);
assert.deepEqual(SessionConfig.fieldsBehindMore('claude', empty), ['model', 'effort', 'allowedTools', 'customArgs', 'appendSystemPrompt', 'preLaunchCmd', 'addDirs']);
const filled = SessionConfig.resolveOptions('claude', { preLaunchCmd: 'aws-vault exec prod --' }, { model: 'opus' });
assert.deepEqual(SessionConfig.fieldsBehindMore('claude', filled), ['effort', 'allowedTools', 'appendSystemPrompt', 'addDirs'],
assert.deepEqual(SessionConfig.fieldsBehindMore('claude', filled), ['effort', 'allowedTools', 'customArgs', 'appendSystemPrompt', 'addDirs'],
'a saved model and a folder pre-launch command stay in view');
assert.deepEqual(SessionConfig.fieldsBehindMore('codex', SessionConfig.resolveOptions('codex', {}, {})), ['codexModel', 'codexEffort', 'preLaunchCmd', 'addDirs']);
assert.ok(!SessionConfig.fieldsBehindMore('claude', empty).includes('permissionMode'), 'the main settings are never tucked away');
Expand Down
Loading