read user-scope Claude config files via a read allow-list (D-80)
The reader opened repo-local .claude markdown but rejected user-scope files under ~/.claude with "path outside workspace" — that dir is global, outside the repo, and files.read was repo-confined (T-102). Per D-76 the Claude config surface is clide-managed, so files.read now resolves a path under an allow-list: the workspace root plus trusted extra read roots (FilesService.extraReadRoots), wired in main.dart to ~/.claude when present. Reads widen; writes stay repo-confined, and the symlink re-check still refuses a config-root symlink that escapes. Off- root paths and `..` traversal are rejected as before. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+11
-1
@@ -166,7 +166,17 @@ Future<void> main() async {
|
||||
final eventSink = _BusEventSink(events);
|
||||
final paneRegistry = PaneRegistry(events: eventSink);
|
||||
registerPaneCommands(dispatcher, paneRegistry);
|
||||
final filesService = FilesService(root: workRoot, events: eventSink);
|
||||
// Trusted read-only roots beyond the workspace: the global Claude
|
||||
// config dir (~/.claude), so the reader can open user-scope skill /
|
||||
// agent / command markdown the Config tab surfaces (D-80, T-195).
|
||||
// The repo-local .claude is already under workRoot.
|
||||
final extraReadRoots = <Directory>[];
|
||||
final claudeHome = Platform.environment['HOME'];
|
||||
if (claudeHome != null) {
|
||||
final globalClaude = Directory('$claudeHome/.claude');
|
||||
if (globalClaude.existsSync()) extraReadRoots.add(globalClaude);
|
||||
}
|
||||
final filesService = FilesService(root: workRoot, events: eventSink, extraReadRoots: extraReadRoots);
|
||||
registerFilesCommands(dispatcher, filesService);
|
||||
// Search reuses the files service's resolved ignore set so the
|
||||
// grep honours the same ignore_files: layering (D-4 / D-79).
|
||||
|
||||
Reference in New Issue
Block a user