( filePath: string, operationType: 'read' | 'write' | 'create', toolPermissionContext: ToolPermissionContext, precomputedPathsToCheck?: readonly string[], )
| 1412 | } |
| 1413 | |
| 1414 | export function generateSuggestions( |
| 1415 | filePath: string, |
| 1416 | operationType: 'read' | 'write' | 'create', |
| 1417 | toolPermissionContext: ToolPermissionContext, |
| 1418 | precomputedPathsToCheck?: readonly string[], |
| 1419 | ): PermissionUpdate[] { |
| 1420 | const isOutsideWorkingDir = !pathInAllowedWorkingPath( |
| 1421 | filePath, |
| 1422 | toolPermissionContext, |
| 1423 | precomputedPathsToCheck, |
| 1424 | ) |
| 1425 | |
| 1426 | if (operationType === 'read' && isOutsideWorkingDir) { |
| 1427 | // For read operations outside working directories, add Read rules |
| 1428 | // IMPORTANT: Include both the symlink path and resolved path so subsequent checks pass |
| 1429 | const dirPath = getDirectoryForPath(filePath) |
| 1430 | const dirsToAdd = getPathsForPermissionCheck(dirPath) |
| 1431 | |
| 1432 | const suggestions = dirsToAdd |
| 1433 | .map(dir => createReadRuleSuggestion(dir, 'session')) |
| 1434 | .filter((s): s is PermissionUpdate => s !== undefined) |
| 1435 | |
| 1436 | return suggestions |
| 1437 | } |
| 1438 | |
| 1439 | // Only suggest setMode:acceptEdits when it would be an upgrade. In auto |
| 1440 | // mode the classifier already auto-approves edits; in bypassPermissions |
| 1441 | // everything is allowed; in acceptEdits it's a no-op. Suggesting it |
| 1442 | // anyway and having the SDK host apply it on "Always allow" silently |
| 1443 | // downgrades auto → acceptEdits, which then prompts for MCP/Bash. |
| 1444 | const shouldSuggestAcceptEdits = |
| 1445 | toolPermissionContext.mode === 'default' || |
| 1446 | toolPermissionContext.mode === 'plan' |
| 1447 | |
| 1448 | if (operationType === 'write' || operationType === 'create') { |
| 1449 | const updates: PermissionUpdate[] = shouldSuggestAcceptEdits |
| 1450 | ? [{ type: 'setMode', mode: 'acceptEdits', destination: 'session' }] |
| 1451 | : [] |
| 1452 | |
| 1453 | if (isOutsideWorkingDir) { |
| 1454 | // For write operations outside working directories, also add the directory |
| 1455 | // IMPORTANT: Include both the symlink path and resolved path so subsequent checks pass |
| 1456 | const dirPath = getDirectoryForPath(filePath) |
| 1457 | const dirsToAdd = getPathsForPermissionCheck(dirPath) |
| 1458 | |
| 1459 | updates.push({ |
| 1460 | type: 'addDirectories', |
| 1461 | directories: dirsToAdd, |
| 1462 | destination: 'session', |
| 1463 | }) |
| 1464 | } |
| 1465 | |
| 1466 | return updates |
| 1467 | } |
| 1468 | |
| 1469 | // For read operations inside working directories, just change mode |
| 1470 | return shouldSuggestAcceptEdits |
| 1471 | ? [{ type: 'setMode', mode: 'acceptEdits', destination: 'session' }] |
no test coverage detected