permissionSettings.js 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import fs from 'fs';
  2. import path from 'path';
  3. import { resolvePilotHome } from '../utils/pilotPaths.js';
  4. const DEFAULT_SETTINGS = {
  5. version: 1,
  6. allowedTools: [],
  7. disallowedTools: [],
  8. skipPermissions: true,
  9. };
  10. const TOOL_NAME_ALIASES = new Map([
  11. ['Read', 'read_file'],
  12. ['Write', 'write_file'],
  13. ['Edit', 'edit_file'],
  14. ['MultiEdit', 'edit_file'],
  15. ['Glob', 'glob'],
  16. ['Grep', 'grep'],
  17. ['Bash', 'bash'],
  18. ['Task', 'agent'],
  19. ['TodoWrite', 'todo_write'],
  20. ['WebFetch', 'web_fetch'],
  21. ['WebSearch', 'web_search'],
  22. ]);
  23. export function getPermissionSettingsPath(env = process.env) {
  24. return path.join(resolvePilotHome(env), 'permissions.json');
  25. }
  26. export function normalizePermissionEntry(entry) {
  27. const trimmed = typeof entry === 'string' ? entry.trim() : '';
  28. if (!trimmed) return '';
  29. const bashMatch = /^Bash\((.*)\)$/.exec(trimmed);
  30. if (bashMatch) {
  31. const pattern = bashMatch[1]?.trim();
  32. return pattern ? `bash:${pattern}` : 'bash';
  33. }
  34. return TOOL_NAME_ALIASES.get(trimmed) || trimmed;
  35. }
  36. export function normalizePermissionSettings(value) {
  37. const obj = value && typeof value === 'object' && !Array.isArray(value) ? value : {};
  38. return {
  39. version: 1,
  40. allowedTools: normalizeStringArray(obj.allowedTools),
  41. disallowedTools: normalizeStringArray(obj.disallowedTools),
  42. skipPermissions: Boolean(obj.skipPermissions),
  43. lastUpdated: typeof obj.lastUpdated === 'string' ? obj.lastUpdated : undefined,
  44. };
  45. }
  46. export function readPermissionSettings(env = process.env) {
  47. try {
  48. const raw = fs.readFileSync(getPermissionSettingsPath(env), 'utf8');
  49. return normalizePermissionSettings(JSON.parse(raw));
  50. } catch {
  51. return { ...DEFAULT_SETTINGS };
  52. }
  53. }
  54. export function writePermissionSettings(updates, env = process.env) {
  55. const next = normalizePermissionSettings({
  56. ...readPermissionSettings(env),
  57. ...(updates || {}),
  58. lastUpdated: new Date().toISOString(),
  59. });
  60. const filePath = getPermissionSettingsPath(env);
  61. fs.mkdirSync(path.dirname(filePath), { recursive: true });
  62. fs.writeFileSync(filePath, `${JSON.stringify(next, null, 2)}\n`, 'utf8');
  63. return next;
  64. }
  65. function normalizeStringArray(value) {
  66. if (!Array.isArray(value)) return [];
  67. const seen = new Set();
  68. const out = [];
  69. for (const item of value) {
  70. const normalized = normalizePermissionEntry(item);
  71. if (!normalized || seen.has(normalized)) continue;
  72. seen.add(normalized);
  73. out.push(normalized);
  74. }
  75. return out;
  76. }