feat(extension): add defaultTerminalMode and cliFlags settings#23
feat(extension): add defaultTerminalMode and cliFlags settings#23perler wants to merge 2 commits intoes6kr:mainfrom
Conversation
New `claudeSessions.defaultTerminalMode` setting ("ask" | "internal" |
"external", default "ask") lets users skip the terminal picker when
resuming sessions.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Work Server <work@server.local>
New `claudeSessions.cliFlags` setting (string, default "") is appended to the `claude` command when resuming sessions. Enables passing flags like `--dangerously-skip-permissions` without modifying extension code. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Work Server <work@server.local>
📝 WalkthroughWalkthroughThis pull request adds two new VS Code configuration properties to the Claude Sessions extension: Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/vscode-extension/src/extension.ts`:
- Around line 448-499: The cliFlags from getConfig() are interpolated into shell
commands (used in terminal.sendText for the internal path and passed to
resumeSession for the external path) and must be sanitized and only used when
the workspace is trusted; first check vscode.workspace.isTrusted before using
any workspace-provided cliFlags, and if not trusted ignore or reject them. For
trusted workspaces, validate and sanitize cliFlags by removing or rejecting
shell metacharacters (`;`, `&`, `|`, backticks, `$()`, newlines) and/or prefer
splitting flags into a safe array of arguments (e.g., tokenizing on whitespace
and filtering invalid tokens) instead of building a single interpolated shell
string; update the internal flow (where terminal.sendText currently sends
`claude --resume ${item.sessionId}${cliFlags ? \` ${cliFlags}\` : ''}`) to avoid
direct interpolation and the external flow to pass an args array to
resumeSession (instead of a single joined string) so metacharacters are not
interpreted by a shell.
ℹ️ Review info
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Cache: Disabled due to Reviews > Disable Cache setting
Knowledge base: Disabled due to data retention organization setting
📒 Files selected for processing (2)
packages/vscode-extension/package.jsonpackages/vscode-extension/src/extension.ts
| const { defaultTerminalMode } = getConfig() | ||
|
|
||
| let mode: 'internal' | 'external' | ||
| if (defaultTerminalMode === 'internal' || defaultTerminalMode === 'external') { | ||
| mode = defaultTerminalMode | ||
| } else { | ||
| const choice = await vscode.window.showQuickPick( | ||
| [ | ||
| { | ||
| label: '$(terminal) Internal Terminal', | ||
| description: 'Open in VSCode integrated terminal', | ||
| mode: 'internal' as const, | ||
| }, | ||
| { | ||
| label: '$(link-external) External Terminal', | ||
| description: 'Open in system default terminal', | ||
| mode: 'external' as const, | ||
| }, | ||
| ], | ||
| { | ||
| label: '$(link-external) External Terminal', | ||
| description: 'Open in system default terminal', | ||
| mode: 'external' as const, | ||
| }, | ||
| ], | ||
| { | ||
| placeHolder: 'Where to open Claude session?', | ||
| title: 'Resume Session', | ||
| } | ||
| ) | ||
| placeHolder: 'Where to open Claude session?', | ||
| title: 'Resume Session', | ||
| } | ||
| ) | ||
|
|
||
| if (!choice) return | ||
| if (!choice) return | ||
| mode = choice.mode | ||
| } | ||
|
|
||
| // Get project path for cwd | ||
| const folderPath = await session.folderNameToPath(item.projectName) | ||
| const homeDir = process.env.HOME || process.env.USERPROFILE || '' | ||
| const cwd = session.expandHomePath(folderPath, homeDir) | ||
| const { cliFlags } = getConfig() | ||
|
|
||
| if (choice.mode === 'internal') { | ||
| if (mode === 'internal') { | ||
| // Create terminal with proper name and cwd | ||
| const terminal = vscode.window.createTerminal({ | ||
| name: `Claude: ${item.label}`, | ||
| cwd, | ||
| }) | ||
| terminal.show() | ||
| terminal.sendText(`claude --resume ${item.sessionId}`) | ||
| const cmd = `claude --resume ${item.sessionId}${cliFlags ? ` ${cliFlags}` : ''}` | ||
| terminal.sendText(cmd) | ||
| } else { | ||
| // External: spawn detached process | ||
| const extraArgs = cliFlags ? cliFlags.split(/\s+/).filter(Boolean) : [] | ||
| const result = resumeSession({ | ||
| sessionId: item.sessionId, | ||
| cwd, | ||
| args: extraArgs, | ||
| }) |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cd packages/vscode-extension/src && wc -l extension.tsRepository: es6kr/claude-code-sessions
Length of output: 86
🏁 Script executed:
cd packages/vscode-extension/src && sed -n '440,510p' extension.tsRepository: es6kr/claude-code-sessions
Length of output: 2451
🏁 Script executed:
cd packages/vscode-extension/src && grep -n "getConfig\|cliFlags" extension.ts | head -20Repository: es6kr/claude-code-sessions
Length of output: 648
🏁 Script executed:
cd packages/vscode-extension/src && sed -n '19,35p' extension.tsRepository: es6kr/claude-code-sessions
Length of output: 683
🏁 Script executed:
cd packages/vscode-extension/src && grep -n "resumeSession" extension.ts | head -10Repository: es6kr/claude-code-sessions
Length of output: 219
🏁 Script executed:
cd packages/vscode-extension && find . -name "*.ts" -type f -exec grep -l "function resumeSession\|export.*resumeSession" {} \;Repository: es6kr/claude-code-sessions
Length of output: 52
🏁 Script executed:
find packages -name "*.ts" -type f -exec grep -l "export.*resumeSession\|function resumeSession" {} \;Repository: es6kr/claude-code-sessions
Length of output: 153
🏁 Script executed:
cd packages && find . -path "*/core/server*" -type f | head -20Repository: es6kr/claude-code-sessions
Length of output: 52
🏁 Script executed:
cd packages/core/src && grep -n "export.*resumeSession\|function resumeSession" resume.ts server.tsRepository: es6kr/claude-code-sessions
Length of output: 225
🏁 Script executed:
cd packages/core/src && cat -n server.ts | head -100Repository: es6kr/claude-code-sessions
Length of output: 503
🏁 Script executed:
cd packages/core/src && wc -l resume.tsRepository: es6kr/claude-code-sessions
Length of output: 82
🏁 Script executed:
cd packages/core/src && cat -n resume.tsRepository: es6kr/claude-code-sessions
Length of output: 3271
🏁 Script executed:
cd packages/vscode-extension/src && grep -n "isTrusted\|workspace.*trust" extension.tsRepository: es6kr/claude-code-sessions
Length of output: 52
🏁 Script executed:
cd packages && git ls-files | grep -i "package.json" | head -5Repository: es6kr/claude-code-sessions
Length of output: 151
🏁 Script executed:
cd packages/vscode-extension && cat -n package.json | grep -A 5 -B 5 "contributes\|configuration"Repository: es6kr/claude-code-sessions
Length of output: 785
🏁 Script executed:
cd packages/vscode-extension && sed -n '1,200p' package.json | grep -A 20 "contributes"Repository: es6kr/claude-code-sessions
Length of output: 570
🏁 Script executed:
cd packages/vscode-extension && grep -A 10 "cliFlags" package.jsonRepository: es6kr/claude-code-sessions
Length of output: 406
Sanitize cliFlags against command injection before interpolating into shell commands.
Line 490 and the external terminal path (line 494–495) interpolate workspace-provided cliFlags directly into shell commands. Since .vscode/settings.json can be committed to a repository, this enables command injection via shell metacharacters (;, &&, |, backticks, $(), newlines). Add workspace trust verification and remove unsafe characters before passing to terminal or process execution.
Suggested mitigation (trust + sanitization)
+function getCliFlags(): string {
+ const config = vscode.workspace.getConfiguration('claudeSessions')
+ const inspected = config.inspect<string>('cliFlags')
+ const raw =
+ vscode.workspace.isTrusted
+ ? (inspected?.workspaceValue ?? inspected?.globalValue ?? inspected?.defaultValue ?? '')
+ : (inspected?.globalValue ?? inspected?.defaultValue ?? '')
+ const sanitized = String(raw).replace(/[\r\n]/g, ' ').trim()
+ if (/[;&|`$<>]/.test(sanitized)) {
+ vscode.window.showWarningMessage(
+ 'claudeSessions.cliFlags contains unsafe characters and was ignored.'
+ )
+ return ''
+ }
+ return sanitized
+}- const { cliFlags } = getConfig()
+ const cliFlags = getCliFlags()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/vscode-extension/src/extension.ts` around lines 448 - 499, The
cliFlags from getConfig() are interpolated into shell commands (used in
terminal.sendText for the internal path and passed to resumeSession for the
external path) and must be sanitized and only used when the workspace is
trusted; first check vscode.workspace.isTrusted before using any
workspace-provided cliFlags, and if not trusted ignore or reject them. For
trusted workspaces, validate and sanitize cliFlags by removing or rejecting
shell metacharacters (`;`, `&`, `|`, backticks, `$()`, newlines) and/or prefer
splitting flags into a safe array of arguments (e.g., tokenizing on whitespace
and filtering invalid tokens) instead of building a single interpolated shell
string; update the internal flow (where terminal.sendText currently sends
`claude --resume ${item.sessionId}${cliFlags ? \` ${cliFlags}\` : ''}`) to avoid
direct interpolation and the external flow to pass an args array to
resumeSession (instead of a single joined string) so metacharacters are not
interpreted by a shell.
Summary
claudeSessions.defaultTerminalModesetting to control whether sessions open via a picker, in the integrated terminal, or in the system terminalclaudeSessions.cliFlagssetting for passing extra CLI flags to theclaude --resumecommand (e.g.--dangerously-skip-permissions)Both settings are registered as VS Code configuration with sensible defaults.
Test plan
defaultTerminalModeswitches betweenask,internal, andexternalbehaviorcliFlagsarguments are appended to theclaude --resumecommand🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
defaultTerminalModesetting allows customization of how sessions resume. Choose between interactive selection, integrated terminal, or system terminal modes.cliFlagssetting enables appending additional command-line flags to the resume command.