Skip to content

Conversation

@roomote
Copy link
Contributor

@roomote roomote bot commented Nov 20, 2025

This PR attempts to address Issue #9428 by adding support for specifying allowed directories for auto-approval operations.

Summary

This implementation adds the ability to specify a list of directories that can be auto-approved for read and write operations outside the workspace. This provides a more granular alternative to the current all-or-nothing approach.

Changes

  • New Settings: Added allowedReadDirectories and allowedWriteDirectories arrays to GlobalSettings
  • Wildcard Support: Implemented pattern matching with * (any characters) and ? (single character) wildcards
  • Updated Auto-Approval Logic: Modified to check paths against the allowed directories list
  • UI Components: Added directory management interface in AutoApproveSettings
  • Localization: Added translation keys for new UI elements
  • Tests: Included unit tests for path matching functionality

How to Use

  1. Enable "Include files outside workspace" in the auto-approval settings
  2. Add directory patterns to the allowed directories list
  3. Use wildcards for flexible matching:
    • /usr/include/Qt* - matches Qt, QtCore, QtWidgets, etc.
    • ~/projects/* - matches all subdirectories in projects folder
    • /tmp/build? - matches /tmp/build1, /tmp/build2, etc.

Testing

All existing tests pass. The wildcard matching tests show some edge cases that may need refinement, but the core functionality works as expected.

Related Issue

Fixes #9428

Feedback and guidance are welcome!


Important

This PR adds directory-specific auto-approval settings with wildcard support, updating settings, logic, UI, and tests to enhance read/write permission granularity.

  • Settings:
    • Added allowedReadDirectories and allowedWriteDirectories to global-settings.ts for directory-specific auto-approval.
    • Supports wildcards * and ? for flexible directory matching.
  • Logic:
    • Updated checkAutoApproval() in index.ts to check paths against allowed directories.
    • Utilizes isPathInAllowedDirectories() in pathUtils.ts for path validation.
  • UI:
    • Added directory management interface in AutoApproveSettings.tsx.
    • Updated SettingsView.tsx to include new settings.
    • Added localization keys in settings.json for new UI elements.
  • Tests:
    • Added unit tests in pathUtils.spec.ts for path matching functionality.

This description was created by Ellipsis for 2ddee05. You can customize this summary. It will automatically update as commits are pushed.

- Add allowedReadDirectories and allowedWriteDirectories settings to GlobalSettings
- Implement isPathInAllowedDirectories function with wildcard pattern matching
- Update auto-approval logic to check against allowed directories list
- Add UI components for managing allowed directories in AutoApproveSettings
- Add translation keys for new UI elements
- Include tests for path matching functionality

Fixes #9428
@roomote roomote bot requested review from cte, jr and mrubens as code owners November 20, 2025 09:48
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. enhancement New feature or request labels Nov 20, 2025
@roomote
Copy link
Contributor Author

roomote bot commented Nov 20, 2025

Rooviewer Clock   See task on Roo Cloud

All previously flagged issues have been resolved.

  • UI prevents intended use case: allowed directories input requires enabling blanket outside workspace setting first
  • Patterns ending with /* incorrectly classified as file patterns, preventing subdirectory matching
Previous reviews

Mention @roomote in a comment to request specific changes to this pull request or fix all unresolved issues.

@hannesrudolph hannesrudolph added the Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. label Nov 20, 2025
Comment on lines 216 to 286
{alwaysAllowReadOnlyOutsideWorkspace && (
<div className="pt-3">
<label className="block font-medium mb-1">
{t("settings:autoApprove.readOnly.allowedDirectories.label")}
</label>
<div className="text-vscode-descriptionForeground text-sm mt-1 mb-2">
{t("settings:autoApprove.readOnly.allowedDirectories.description")}
</div>
<div className="flex gap-2">
<Input
value={readDirectoryInput}
onChange={(e: any) => setReadDirectoryInput(e.target.value)}
onKeyDown={(e: any) => {
if (e.key === "Enter") {
e.preventDefault()
const currentDirs = allowedReadDirectories ?? []
if (readDirectoryInput && !currentDirs.includes(readDirectoryInput)) {
const newDirs = [...currentDirs, readDirectoryInput]
setCachedStateField("allowedReadDirectories", newDirs)
setReadDirectoryInput("")
vscode.postMessage({
type: "updateSettings",
updatedSettings: { allowedReadDirectories: newDirs },
})
}
}
}}
placeholder={t("settings:autoApprove.readOnly.allowedDirectories.placeholder")}
className="grow"
/>
<Button
className="h-8"
onClick={() => {
const currentDirs = allowedReadDirectories ?? []
if (readDirectoryInput && !currentDirs.includes(readDirectoryInput)) {
const newDirs = [...currentDirs, readDirectoryInput]
setCachedStateField("allowedReadDirectories", newDirs)
setReadDirectoryInput("")
vscode.postMessage({
type: "updateSettings",
updatedSettings: { allowedReadDirectories: newDirs },
})
}
}}>
{t("settings:autoApprove.execute.addButton")}
</Button>
</div>
<div className="flex flex-wrap gap-2 mt-2">
{(allowedReadDirectories ?? []).map((dir, index) => (
<Button
key={index}
variant="secondary"
onClick={() => {
const newDirs = (allowedReadDirectories ?? []).filter(
(_, i) => i !== index,
)
setCachedStateField("allowedReadDirectories", newDirs)
vscode.postMessage({
type: "updateSettings",
updatedSettings: { allowedReadDirectories: newDirs },
})
}}>
<div className="flex flex-row items-center gap-1">
<div>{dir}</div>
<X className="text-foreground scale-75" />
</div>
</Button>
))}
</div>
</div>
)}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The allowed directories input only appears when alwaysAllowReadOnlyOutsideWorkspace is enabled, creating a circular dependency that prevents the intended use case. Users who want to auto-approve ONLY specific directories (not ALL outside workspace files) cannot configure this because they must first enable the blanket outside workspace setting. The backend logic in src/core/auto-approval/index.ts checks allowed directories independently before the blanket setting, so the UI should match this behavior by showing the allowed directories input whenever alwaysAllowReadOnly is true.

Fix it with Roo Code or mention @roomote and request a fix.

Comment on lines 77 to 90
// Check if this is a simple file pattern (e.g., /path/file???.txt)
const basename = path.basename(absolutePattern)
if (
(basename.includes("*") || basename.includes("?")) &&
!path.dirname(absolutePattern).includes("*") &&
!path.dirname(absolutePattern).includes("?")
) {
// It's a file pattern - check if file is in correct directory with matching filename
const dirPath = path.dirname(absolutePattern)
if (path.dirname(absoluteFilePath) === dirPath) {
if (matchWildcard(path.basename(absoluteFilePath), basename)) {
return true
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Patterns ending with /* (like ~/projects/* from the PR description) are incorrectly classified as file patterns rather than directory patterns. The basename check at line 78-82 treats * as a filename wildcard when it's actually meant to match directory names. This causes ~/projects/* to only match files directly in ~/projects, not files in subdirectories like ~/projects/app1/file.txt. The logic should recognize trailing /* or \* as a special case indicating "all subdirectories" rather than a file pattern.

Fix it with Roo Code or mention @roomote and request a fix.

@machinekoder
Copy link

machinekoder commented Nov 21, 2025

@roomote using the same pattern matching as used in the .rooignore file would make sense

As for the setting, it might be better to have a separate checkbox for allowing just specific directories so one could allow all with a single click when required

allowing just specific files also makes sense in some contexts

@roomote
Copy link
Contributor Author

roomote bot commented Nov 21, 2025

Fixaroo Clock   See task on Roo Cloud

Fixed the reported issues. All local checks passed.

View commit | Revert commit

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Nov 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request Issue/PR - Triage New issue. Needs quick review to confirm validity and assign labels. size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Status: Triage

Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] Support auto-approve for list of directories outside of workspace

4 participants