Skip to content
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
cf6c380
fix: resolve all issues in PR #5491 - command whitelisting feature
hannesrudolph Jul 9, 2025
20363b4
fix: resolve knip unused files issue
hannesrudolph Jul 9, 2025
a0e8c24
feat: add denyCommand handler for individual command deny listing
hannesrudolph Jul 14, 2025
18e3cd1
feat: add unified UI for managing allow/deny command lists
hannesrudolph Jul 14, 2025
bacf751
fix: correct toggle behavior for allow/deny command buttons
hannesrudolph Jul 14, 2025
9a01e80
fix: ensure immediate UI updates when toggling command allow/deny status
hannesrudolph Jul 14, 2025
38fb80f
refactor: improve tooltip implementation to follow codebase standards
hannesrudolph Jul 14, 2025
63f4a27
fix: remove hardcoded npm pattern suggestions
hannesrudolph Jul 14, 2025
81ef373
chore: remove temporary PR fixer file from version control
hannesrudolph Jul 14, 2025
7d75a0c
fix: trim trailing spaces from command suggestions
hannesrudolph Jul 14, 2025
df69540
fix: remove trailing spaces from command suggestion examples
hannesrudolph Jul 14, 2025
4ec34ad
fix: use inclusive terminology in command permission instructions
hannesrudolph Jul 14, 2025
e98c404
refactor: streamline command permission instructions for LLM
hannesrudolph Jul 14, 2025
b7986c0
fix: address PR review comments and improve command permission UI
hannesrudolph Jul 14, 2025
c9964e2
chore: update all locale files with new command permission translations
hannesrudolph Jul 14, 2025
8bbecac
feat: add setting to disable LLM command suggestions
hannesrudolph Jul 15, 2025
10843e8
fix: add missing imports for vscode and Package in Task.ts
hannesrudolph Jul 15, 2025
70ca7a6
refactor: move command whitelisting from VS Code settings to plugin UI
hannesrudolph Jul 15, 2025
238bae6
fix: resolve command whitelisting issues
hannesrudolph Jul 15, 2025
0b714fd
fix: add missing translations for disableLlmSuggestions setting
hannesrudolph Jul 15, 2025
f903871
fix: prevent removed commands from reappearing due to workspace confi…
hannesrudolph Jul 15, 2025
0a067f0
feat: implement robust command pattern extraction using shell-quote
hannesrudolph Jul 15, 2025
a280f87
fix: prevent full command chains from being extracted as patterns
hannesrudolph Jul 15, 2025
60815f4
fix: prevent LLM from suggesting full command chains in execute-command
hannesrudolph Jul 15, 2025
edba73a
test: add comprehensive real-world test cases for command pattern parser
hannesrudolph Jul 15, 2025
d899a36
refactor: Remove LLM suggestion feature in favor of deterministic she…
hannesrudolph Jul 15, 2025
39a8fad
fix: Remove remaining references to disableLlmCommandSuggestions
hannesrudolph Jul 15, 2025
ded11f8
chore: remove temporary documentation files
hannesrudolph Jul 15, 2025
06c8cb8
fix: replace hardcoded aria-labels with i18n translation keys
hannesrudolph Jul 15, 2025
abb8612
chore: remove test_fix_summary.md temporary file
hannesrudolph Jul 15, 2025
51d010e
fix: add missing roo-cline.allowedCommands configuration registration
hannesrudolph Jul 15, 2025
2f321e9
fix: address PR #5491 review feedback
hannesrudolph Jul 15, 2025
83b6f3c
refactor: simplify command allow/deny implementation
hannesrudolph Jul 15, 2025
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
1 change: 1 addition & 0 deletions packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ export const globalSettingsSchema = z.object({
alwaysAllowFollowupQuestions: z.boolean().optional(),
followupAutoApproveTimeoutMs: z.number().optional(),
alwaysAllowUpdateTodoList: z.boolean().optional(),
disableLlmCommandSuggestions: z.boolean().optional(),
allowedCommands: z.array(z.string()).optional(),
deniedCommands: z.array(z.string()).optional(),
allowedMaxRequests: z.number().nullish(),
Expand Down
77 changes: 77 additions & 0 deletions pr_fix_implementation_summary.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# PR #5491 Fix Implementation Summary

## Overview

Implemented a feature flag to disable LLM-based command suggestions in response to reviewer feedback about avoiding reliance on LLMs for command whitelist suggestions.

## Changes Made

### 1. Configuration Setting Added

- **File**: `src/package.json`
- Added new setting: `roo-cline.disableLlmCommandSuggestions`
- Type: boolean, default: false
- Description: "Disable LLM-generated command suggestions and use only programmatic pattern generation"

### 2. Localization

- **File**: `src/package.nls.json`
- Added description for the new setting

### 3. Tool Prompt Conditional Logic

- **File**: `src/core/prompts/tools/execute-command.ts`
- Modified `getExecuteCommandDescription` to conditionally include suggestions section
- When `disableLlmCommandSuggestions` is true, the suggestions parameter is omitted from the tool description

### 4. Tool Implementation Update

- **File**: `src/core/tools/executeCommandTool.ts`
- Added check for `disableLlmCommandSuggestions` setting
- When enabled, suggestions from LLM are ignored even if provided

### 5. Settings Propagation

- **File**: `src/core/task/Task.ts`
- Updated to pass the `disableLlmCommandSuggestions` setting through the system prompt generation

### 6. Test Coverage

- **File**: `src/core/tools/__tests__/executeCommandTool.spec.ts`
- Added comprehensive test suite for the new setting
- Tests verify suggestions are ignored when setting is enabled
- Tests verify suggestions work normally when setting is disabled or not set

- **File**: `src/core/prompts/tools/__tests__/execute-command.spec.ts`
- Added tests for conditional prompt generation
- Verifies suggestions section is excluded when setting is enabled

## How It Works

1. **When `disableLlmCommandSuggestions` is false (default)**:

- LLM receives instructions to provide command suggestions
- Tool processes suggestions and shows them to the user
- Existing behavior is preserved

2. **When `disableLlmCommandSuggestions` is true**:
- LLM does not receive instructions about suggestions
- Even if LLM provides suggestions, they are ignored
- Falls back to programmatic pattern generation only

## Benefits

1. **Addresses Reviewer Concern**: Removes reliance on LLM for command suggestions when desired
2. **Backward Compatible**: Default behavior unchanged, existing users unaffected
3. **User Control**: Users can choose between LLM suggestions or deterministic patterns
4. **Token Savings**: When enabled, reduces token usage by not including suggestion instructions
5. **Deterministic Behavior**: Provides predictable command pattern generation when needed

## Testing

All tests pass:

- Execute command tool tests: 23 passed
- Execute command prompt tests: 4 passed

The implementation is complete and ready for review.
75 changes: 75 additions & 0 deletions src/core/prompts/tools/__tests__/execute-command.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { describe, it, expect } from "vitest"
import { getExecuteCommandDescription } from "../execute-command"
import { ToolArgs } from "../types"

describe("getExecuteCommandDescription", () => {
const baseArgs: ToolArgs = {
cwd: "/test/path",
supportsComputerUse: false,
}

it("should include suggestions section when disableLlmCommandSuggestions is false", () => {
const args: ToolArgs = {
...baseArgs,
settings: {
disableLlmCommandSuggestions: false,
},
}

const description = getExecuteCommandDescription(args)

// Check that the description includes the suggestions parameter
expect(description).toContain("<suggestions>")
expect(description).toContain("- suggestions: (optional) Command patterns for the user to allow/deny")
expect(description).toContain("Suggestion Guidelines")
// Check for chained command guidance
expect(description).toContain("For chained commands")
expect(description).toContain("cd backend && npm install")
})

it("should include suggestions section when disableLlmCommandSuggestions is not set", () => {
const args: ToolArgs = {
...baseArgs,
settings: {},
}

const description = getExecuteCommandDescription(args)

// Check that the description includes the suggestions parameter
expect(description).toContain("<suggestions>")
expect(description).toContain("- suggestions: (optional) Command patterns for the user to allow/deny")
expect(description).toContain("Suggestion Guidelines")
})

it("should exclude suggestions section when disableLlmCommandSuggestions is true", () => {
const args: ToolArgs = {
...baseArgs,
settings: {
disableLlmCommandSuggestions: true,
},
}

const description = getExecuteCommandDescription(args)

// Check that the description does NOT include the suggestions parameter
expect(description).not.toContain("<suggestions>")
expect(description).not.toContain("- suggestions: (optional) Command patterns for the user to allow/deny")
expect(description).not.toContain("Suggestion Guidelines")
})

it("should include basic command and cwd parameters regardless of settings", () => {
const args: ToolArgs = {
...baseArgs,
settings: {
disableLlmCommandSuggestions: true,
},
}

const description = getExecuteCommandDescription(args)

// Check that basic parameters are always included
expect(description).toContain("- command: (required)")
expect(description).toContain("- cwd: (optional)")
expect(description).toContain("execute_command")
})
})
70 changes: 67 additions & 3 deletions src/core/prompts/tools/execute-command.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
import { ToolArgs } from "./types"

export function getExecuteCommandDescription(args: ToolArgs): string | undefined {
return `## execute_command
const disableLlmSuggestions = args.settings?.disableLlmCommandSuggestions ?? false

const baseDescription = `## execute_command
Description: Request to execute a CLI command on the system. Use this when you need to perform system operations or run specific commands to accomplish any step in the user's task. You must tailor your command to the user's system and provide a clear explanation of what the command does. For command chaining, use the appropriate chaining syntax for the user's shell. Prefer to execute complex CLI commands over creating executable scripts, as they are more flexible and easier to run. Prefer relative commands and paths that avoid location sensitivity for terminal consistency, e.g: \`touch ./testdata/example.file\`, \`dir ./examples/model1/data/yaml\`, or \`go test ./cmd/front --config ./cmd/front/config.yml\`. If directed by the user, you may open a terminal in a different directory by using the \`cwd\` parameter.

Parameters:
- command: (required) The CLI command to execute. This should be valid for the current operating system. Ensure the command is properly formatted and does not contain any harmful instructions.
- cwd: (optional) The working directory to execute the command in (default: ${args.cwd})
- cwd: (optional) The working directory to execute the command in (default: ${args.cwd})`

if (disableLlmSuggestions) {
return (
baseDescription +
`

Usage:
<execute_command>
<command>Your command here</command>
Expand All @@ -17,9 +26,64 @@ Example: Requesting to execute npm run dev
<command>npm run dev</command>
</execute_command>

Example: Requesting to execute ls in a specific directory if directed
Example: Requesting to execute ls in a specific directory
<execute_command>
<command>ls -la</command>
<cwd>/home/user/projects</cwd>
</execute_command>`
)
}

return (
baseDescription +
`
- suggestions: (optional) Command patterns for the user to allow/deny for future auto-approval. Use <suggest> tags.

**Suggestion Guidelines:**
- Suggestions use prefix matching (case-insensitive)
- For simple commands: Include the base command (e.g., "npm", "git") and optionally a more specific pattern
- For chained commands (using &&, ||, ;, |): Include patterns for EACH individual command in the chain
- Example: For "cd backend && npm install", suggest: "cd backend && npm install", "cd", "npm install", "npm"
- Include 2-4 relevant patterns total
- Only suggest "*" (allow all) if explicitly requested by the user

Usage:
<execute_command>
<command>Your command here</command>
<cwd>Working directory path (optional)</cwd>
<suggestions>
<suggest>pattern 1</suggest>
<suggest>pattern 2</suggest>
</suggestions>
</execute_command>

Example: Requesting to execute npm run dev
<execute_command>
<command>npm run dev</command>
<suggestions>
<suggest>npm run</suggest>
<suggest>npm</suggest>
</suggestions>
</execute_command>

Example: Requesting to execute a chained command
<execute_command>
<command>cd backend && npm install</command>
<suggestions>
<suggest>cd backend && npm install</suggest>
<suggest>cd</suggest>
<suggest>npm install</suggest>
<suggest>npm</suggest>
</suggestions>
</execute_command>

Example: Requesting to execute ls in a specific directory
<execute_command>
<command>ls -la</command>
<cwd>/home/user/projects</cwd>
<suggestions>
<suggest>ls</suggest>
</suggestions>
</execute_command>`
)
}
2 changes: 2 additions & 0 deletions src/core/task/Task.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as path from "path"
import os from "os"
import crypto from "crypto"
import EventEmitter from "events"
import * as vscode from "vscode"

import { Anthropic } from "@anthropic-ai/sdk"
import delay from "delay"
Expand Down Expand Up @@ -1648,6 +1649,7 @@ export class Task extends EventEmitter<ClineEvents> {
maxReadFileLine !== -1,
{
maxConcurrentFileReads,
disableLlmCommandSuggestions: state?.disableLlmCommandSuggestions ?? false,
},
)
})()
Expand Down
Loading
Loading