@within-7/minto 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/dist/commands/agents/AgentsCommand.js +22 -24
  2. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  3. package/dist/commands/context.js +2 -1
  4. package/dist/commands/context.js.map +2 -2
  5. package/dist/commands/export.js +2 -1
  6. package/dist/commands/export.js.map +2 -2
  7. package/dist/commands/mcp-interactive.js +7 -6
  8. package/dist/commands/mcp-interactive.js.map +2 -2
  9. package/dist/commands/model.js +3 -2
  10. package/dist/commands/model.js.map +2 -2
  11. package/dist/commands/permissions.js +4 -3
  12. package/dist/commands/permissions.js.map +2 -2
  13. package/dist/commands/plugin/AddMarketplaceForm.js +3 -2
  14. package/dist/commands/plugin/AddMarketplaceForm.js.map +2 -2
  15. package/dist/commands/plugin/ConfirmDialog.js +2 -1
  16. package/dist/commands/plugin/ConfirmDialog.js.map +2 -2
  17. package/dist/commands/plugin/ErrorView.js +2 -1
  18. package/dist/commands/plugin/ErrorView.js.map +2 -2
  19. package/dist/commands/plugin/InstalledPluginsByMarketplace.js +5 -4
  20. package/dist/commands/plugin/InstalledPluginsByMarketplace.js.map +2 -2
  21. package/dist/commands/plugin/InstalledPluginsManager.js +5 -4
  22. package/dist/commands/plugin/InstalledPluginsManager.js.map +2 -2
  23. package/dist/commands/plugin/MainMenu.js +2 -1
  24. package/dist/commands/plugin/MainMenu.js.map +2 -2
  25. package/dist/commands/plugin/MarketplaceManager.js +5 -4
  26. package/dist/commands/plugin/MarketplaceManager.js.map +2 -2
  27. package/dist/commands/plugin/MarketplaceSelector.js +4 -3
  28. package/dist/commands/plugin/MarketplaceSelector.js.map +2 -2
  29. package/dist/commands/plugin/PlaceholderScreen.js +3 -2
  30. package/dist/commands/plugin/PlaceholderScreen.js.map +2 -2
  31. package/dist/commands/plugin/PluginBrowser.js +6 -5
  32. package/dist/commands/plugin/PluginBrowser.js.map +2 -2
  33. package/dist/commands/plugin/PluginDetailsInstall.js +5 -4
  34. package/dist/commands/plugin/PluginDetailsInstall.js.map +2 -2
  35. package/dist/commands/plugin/PluginDetailsManage.js +4 -3
  36. package/dist/commands/plugin/PluginDetailsManage.js.map +2 -2
  37. package/dist/commands/plugin.js +16 -15
  38. package/dist/commands/plugin.js.map +2 -2
  39. package/dist/commands/sandbox.js +4 -3
  40. package/dist/commands/sandbox.js.map +2 -2
  41. package/dist/commands/setup.js +2 -1
  42. package/dist/commands/setup.js.map +2 -2
  43. package/dist/commands/status.js +2 -1
  44. package/dist/commands/status.js.map +2 -2
  45. package/dist/commands/undo.js +245 -0
  46. package/dist/commands/undo.js.map +7 -0
  47. package/dist/commands.js +2 -0
  48. package/dist/commands.js.map +2 -2
  49. package/dist/components/AgentThinkingBlock.js +1 -1
  50. package/dist/components/AgentThinkingBlock.js.map +2 -2
  51. package/dist/components/AsciiLogo.js +7 -8
  52. package/dist/components/AsciiLogo.js.map +2 -2
  53. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js +3 -2
  54. package/dist/components/AskUserQuestionDialog/AskUserQuestionDialog.js.map +2 -2
  55. package/dist/components/AskUserQuestionDialog/QuestionView.js +2 -1
  56. package/dist/components/AskUserQuestionDialog/QuestionView.js.map +2 -2
  57. package/dist/components/CollapsibleHint.js +2 -1
  58. package/dist/components/CollapsibleHint.js.map +2 -2
  59. package/dist/components/Config.js +3 -2
  60. package/dist/components/Config.js.map +2 -2
  61. package/dist/components/ConsoleOAuthFlow.js +2 -1
  62. package/dist/components/ConsoleOAuthFlow.js.map +2 -2
  63. package/dist/components/Cost.js +2 -1
  64. package/dist/components/Cost.js.map +2 -2
  65. package/dist/components/HeaderBar.js +13 -8
  66. package/dist/components/HeaderBar.js.map +2 -2
  67. package/dist/components/HistorySearchOverlay.js +4 -3
  68. package/dist/components/HistorySearchOverlay.js.map +2 -2
  69. package/dist/components/HotkeyHelpPanel.js +8 -11
  70. package/dist/components/HotkeyHelpPanel.js.map +2 -2
  71. package/dist/components/InvalidConfigDialog.js +2 -1
  72. package/dist/components/InvalidConfigDialog.js.map +2 -2
  73. package/dist/components/Logo.js +23 -67
  74. package/dist/components/Logo.js.map +2 -2
  75. package/dist/components/MCPServerApprovalDialog.js +2 -1
  76. package/dist/components/MCPServerApprovalDialog.js.map +2 -2
  77. package/dist/components/MCPServerDialogCopy.js +2 -1
  78. package/dist/components/MCPServerDialogCopy.js.map +2 -2
  79. package/dist/components/MCPServerMultiselectDialog.js +2 -1
  80. package/dist/components/MCPServerMultiselectDialog.js.map +2 -2
  81. package/dist/components/MessageSelector.js +4 -3
  82. package/dist/components/MessageSelector.js.map +2 -2
  83. package/dist/components/ModeIndicator.js +2 -1
  84. package/dist/components/ModeIndicator.js.map +2 -2
  85. package/dist/components/ModelConfig.js +4 -3
  86. package/dist/components/ModelConfig.js.map +2 -2
  87. package/dist/components/ModelListManager.js +4 -3
  88. package/dist/components/ModelListManager.js.map +2 -2
  89. package/dist/components/ModelSelector/ModelSelector.js +26 -13
  90. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  91. package/dist/components/Onboarding.js +3 -2
  92. package/dist/components/Onboarding.js.map +2 -2
  93. package/dist/components/OperationSummary.js +130 -0
  94. package/dist/components/OperationSummary.js.map +7 -0
  95. package/dist/components/PromptInput.js +88 -75
  96. package/dist/components/PromptInput.js.map +2 -2
  97. package/dist/components/SensitiveFileWarning.js +31 -0
  98. package/dist/components/SensitiveFileWarning.js.map +7 -0
  99. package/dist/components/Spinner.js +71 -22
  100. package/dist/components/Spinner.js.map +2 -2
  101. package/dist/components/StructuredDiff.js +6 -8
  102. package/dist/components/StructuredDiff.js.map +2 -2
  103. package/dist/components/SubagentBlock.js +4 -2
  104. package/dist/components/SubagentBlock.js.map +2 -2
  105. package/dist/components/SubagentProgress.js +7 -4
  106. package/dist/components/SubagentProgress.js.map +2 -2
  107. package/dist/components/TaskCard.js +14 -11
  108. package/dist/components/TaskCard.js.map +2 -2
  109. package/dist/components/TextInput.js +9 -1
  110. package/dist/components/TextInput.js.map +2 -2
  111. package/dist/components/TodoPanel.js +44 -26
  112. package/dist/components/TodoPanel.js.map +2 -2
  113. package/dist/components/ToolUseLoader.js +2 -2
  114. package/dist/components/ToolUseLoader.js.map +2 -2
  115. package/dist/components/TreeConnector.js +4 -3
  116. package/dist/components/TreeConnector.js.map +2 -2
  117. package/dist/components/TrustDialog.js +2 -1
  118. package/dist/components/TrustDialog.js.map +2 -2
  119. package/dist/components/binary-feedback/BinaryFeedbackView.js +2 -1
  120. package/dist/components/binary-feedback/BinaryFeedbackView.js.map +2 -2
  121. package/dist/components/messages/AssistantTextMessage.js +17 -9
  122. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  123. package/dist/components/messages/AssistantToolUseMessage.js +8 -4
  124. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  125. package/dist/components/messages/GroupRenderer.js +2 -1
  126. package/dist/components/messages/GroupRenderer.js.map +2 -2
  127. package/dist/components/messages/NestedTasksPreview.js +13 -1
  128. package/dist/components/messages/NestedTasksPreview.js.map +2 -2
  129. package/dist/components/messages/ParallelTasksGroupView.js +4 -3
  130. package/dist/components/messages/ParallelTasksGroupView.js.map +2 -2
  131. package/dist/components/messages/TaskInModuleView.js +35 -15
  132. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  133. package/dist/components/messages/TaskOutputContent.js +9 -6
  134. package/dist/components/messages/TaskOutputContent.js.map +2 -2
  135. package/dist/components/messages/UserPromptMessage.js +2 -2
  136. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  137. package/dist/constants/colors.js +90 -72
  138. package/dist/constants/colors.js.map +2 -2
  139. package/dist/constants/toolInputExamples.js +84 -0
  140. package/dist/constants/toolInputExamples.js.map +7 -0
  141. package/dist/core/backupManager.js +321 -0
  142. package/dist/core/backupManager.js.map +7 -0
  143. package/dist/core/costTracker.js +9 -18
  144. package/dist/core/costTracker.js.map +2 -2
  145. package/dist/core/gitAutoCommit.js +287 -0
  146. package/dist/core/gitAutoCommit.js.map +7 -0
  147. package/dist/core/index.js +3 -0
  148. package/dist/core/index.js.map +2 -2
  149. package/dist/core/operationTracker.js +212 -0
  150. package/dist/core/operationTracker.js.map +7 -0
  151. package/dist/core/permissions/rules/allowedToolsRule.js +1 -1
  152. package/dist/core/permissions/rules/allowedToolsRule.js.map +2 -2
  153. package/dist/core/permissions/rules/autoEscalationRule.js +5 -0
  154. package/dist/core/permissions/rules/autoEscalationRule.js.map +2 -2
  155. package/dist/core/permissions/rules/projectBoundaryRule.js +5 -0
  156. package/dist/core/permissions/rules/projectBoundaryRule.js.map +2 -2
  157. package/dist/core/permissions/rules/sensitivePathsRule.js +5 -0
  158. package/dist/core/permissions/rules/sensitivePathsRule.js.map +2 -2
  159. package/dist/core/tokenStats.js +9 -0
  160. package/dist/core/tokenStats.js.map +7 -0
  161. package/dist/core/tokenStatsManager.js +331 -0
  162. package/dist/core/tokenStatsManager.js.map +7 -0
  163. package/dist/entrypoints/cli.js +115 -87
  164. package/dist/entrypoints/cli.js.map +2 -2
  165. package/dist/hooks/useAgentTokenStats.js +72 -0
  166. package/dist/hooks/useAgentTokenStats.js.map +7 -0
  167. package/dist/hooks/useAgentTranscripts.js +30 -6
  168. package/dist/hooks/useAgentTranscripts.js.map +2 -2
  169. package/dist/hooks/useLogMessages.js +12 -1
  170. package/dist/hooks/useLogMessages.js.map +2 -2
  171. package/dist/i18n/locales/en.js +6 -5
  172. package/dist/i18n/locales/en.js.map +2 -2
  173. package/dist/i18n/locales/zh-CN.js +6 -5
  174. package/dist/i18n/locales/zh-CN.js.map +2 -2
  175. package/dist/i18n/types.js.map +1 -1
  176. package/dist/permissions.js +28 -1
  177. package/dist/permissions.js.map +2 -2
  178. package/dist/query.js +78 -4
  179. package/dist/query.js.map +3 -3
  180. package/dist/screens/REPL.js +23 -3
  181. package/dist/screens/REPL.js.map +2 -2
  182. package/dist/services/claude.js +54 -3
  183. package/dist/services/claude.js.map +2 -2
  184. package/dist/services/intelligentCompactor.js +1 -1
  185. package/dist/services/intelligentCompactor.js.map +2 -2
  186. package/dist/services/mcpClient.js +81 -25
  187. package/dist/services/mcpClient.js.map +2 -2
  188. package/dist/services/sandbox/filesystemBoundary.js +58 -17
  189. package/dist/services/sandbox/filesystemBoundary.js.map +2 -2
  190. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -2
  191. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  192. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js +2 -1
  193. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  194. package/dist/tools/BashTool/BashTool.js +22 -3
  195. package/dist/tools/BashTool/BashTool.js.map +2 -2
  196. package/dist/tools/BashTool/prompt.js +178 -34
  197. package/dist/tools/BashTool/prompt.js.map +2 -2
  198. package/dist/tools/FileEditTool/prompt.js +6 -3
  199. package/dist/tools/FileEditTool/prompt.js.map +2 -2
  200. package/dist/tools/FileWriteTool/prompt.js +4 -2
  201. package/dist/tools/FileWriteTool/prompt.js.map +2 -2
  202. package/dist/tools/MultiEditTool/prompt.js +5 -3
  203. package/dist/tools/MultiEditTool/prompt.js.map +2 -2
  204. package/dist/tools/NotebookEditTool/NotebookEditTool.js +2 -1
  205. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  206. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +3 -2
  207. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  208. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +3 -2
  209. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  210. package/dist/tools/PlanModeTool/prompt.js +1 -1
  211. package/dist/tools/PlanModeTool/prompt.js.map +1 -1
  212. package/dist/tools/SkillTool/SkillTool.js +4 -3
  213. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  214. package/dist/tools/SkillTool/prompt.js +1 -1
  215. package/dist/tools/SkillTool/prompt.js.map +1 -1
  216. package/dist/tools/TaskOutputTool/TaskOutputTool.js +3 -2
  217. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +2 -2
  218. package/dist/tools/TaskTool/TaskTool.js +8 -0
  219. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  220. package/dist/utils/CircuitBreaker.js +242 -0
  221. package/dist/utils/CircuitBreaker.js.map +7 -0
  222. package/dist/utils/ask.js +2 -0
  223. package/dist/utils/ask.js.map +2 -2
  224. package/dist/utils/config.js +47 -5
  225. package/dist/utils/config.js.map +2 -2
  226. package/dist/utils/credentials/CredentialStore.js +1 -0
  227. package/dist/utils/credentials/CredentialStore.js.map +7 -0
  228. package/dist/utils/credentials/EncryptedFileStore.js +157 -0
  229. package/dist/utils/credentials/EncryptedFileStore.js.map +7 -0
  230. package/dist/utils/credentials/index.js +37 -0
  231. package/dist/utils/credentials/index.js.map +7 -0
  232. package/dist/utils/credentials/migration.js +82 -0
  233. package/dist/utils/credentials/migration.js.map +7 -0
  234. package/dist/utils/markdown.js +13 -1
  235. package/dist/utils/markdown.js.map +2 -2
  236. package/dist/utils/permissions/filesystem.js +5 -1
  237. package/dist/utils/permissions/filesystem.js.map +2 -2
  238. package/dist/utils/safePath.js +132 -0
  239. package/dist/utils/safePath.js.map +7 -0
  240. package/dist/utils/sensitiveFiles.js +125 -0
  241. package/dist/utils/sensitiveFiles.js.map +7 -0
  242. package/dist/utils/taskDisplayUtils.js +9 -9
  243. package/dist/utils/taskDisplayUtils.js.map +2 -2
  244. package/dist/utils/theme.js +6 -6
  245. package/dist/utils/theme.js.map +1 -1
  246. package/dist/utils/toolRiskClassification.js +207 -0
  247. package/dist/utils/toolRiskClassification.js.map +7 -0
  248. package/dist/utils/tooling/safeRender.js +5 -4
  249. package/dist/utils/tooling/safeRender.js.map +2 -2
  250. package/dist/version.js +2 -2
  251. package/dist/version.js.map +1 -1
  252. package/package.json +9 -7
  253. package/dist/hooks/useCancelRequest.js +0 -31
  254. package/dist/hooks/useCancelRequest.js.map +0 -7
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/permissions/rules/autoEscalationRule.ts"],
4
- "sourcesContent": ["/**\n * Auto-Escalation Rule\n *\n * Automatically escalates permission requirements when detecting\n * high-risk operations, even if safe mode is not explicitly enabled.\n * This provides defense-in-depth by requiring confirmation for\n * particularly dangerous actions regardless of mode.\n */\n\nimport type {\n PermissionRule,\n PermissionContext,\n PermissionResult,\n} from '../engine/types'\nimport { isSensitivePath, getSensitivePathInfo } from './sensitivePathsRule'\nimport {\n isOutsideProject,\n calculateExternalOperationRisk,\n} from './projectBoundaryRule'\nimport { logSecurityEvent } from '../auditLog'\n\n/**\n * Escalation trigger reasons\n */\nexport type EscalationReason =\n | 'sensitive_path' // Accessing sensitive paths\n | 'critical_external' // Critical external operation\n | 'dangerous_command' // Known dangerous command pattern\n | 'bulk_operation' // Bulk file operations\n | 'privilege_escalation' // Commands that might escalate privileges\n | 'network_access' // Network-related commands\n\n/**\n * Patterns that should always trigger escalation\n */\nconst ESCALATION_PATTERNS: Array<{\n pattern: RegExp\n reason: EscalationReason\n description: string\n}> = [\n // Privilege escalation\n {\n pattern: /\\bsudo\\s+/,\n reason: 'privilege_escalation',\n description: 'sudo command',\n },\n {\n pattern: /\\bsu\\s+(-|\\w)/,\n reason: 'privilege_escalation',\n description: 'su command',\n },\n {\n pattern: /\\bchmod\\s+[0-7]*[4-7][0-7]*\\s/,\n reason: 'privilege_escalation',\n description: 'chmod with execute permissions',\n },\n {\n pattern: /\\bchown\\s+/,\n reason: 'privilege_escalation',\n description: 'chown command',\n },\n\n // Dangerous file operations\n {\n pattern: /\\brm\\s+(-r|-rf|-fr)\\s+/,\n reason: 'dangerous_command',\n description: 'recursive delete',\n },\n {\n pattern: /\\bdd\\s+.*if=/,\n reason: 'dangerous_command',\n description: 'dd command',\n },\n {\n pattern: /\\bmkfs\\b/,\n reason: 'dangerous_command',\n description: 'filesystem creation',\n },\n {\n pattern: />\\s*\\/dev\\/(sd|hd|nvme)/,\n reason: 'dangerous_command',\n description: 'write to disk device',\n },\n\n // Network access (potential data exfiltration)\n {\n pattern: /\\bcurl\\s+.*(-d|--data|-F|--form)/,\n reason: 'network_access',\n description: 'curl with data upload',\n },\n {\n pattern: /\\bwget\\s+--post/,\n reason: 'network_access',\n description: 'wget with POST',\n },\n {\n pattern: /\\bnc\\s+/,\n reason: 'network_access',\n description: 'netcat',\n },\n {\n pattern: /\\bssh\\s+/,\n reason: 'network_access',\n description: 'SSH connection',\n },\n {\n pattern: /\\bscp\\s+/,\n reason: 'network_access',\n description: 'SCP file transfer',\n },\n {\n pattern: /\\brsync\\s+.*:/,\n reason: 'network_access',\n description: 'rsync to remote',\n },\n\n // Bulk operations\n {\n pattern: /\\bfind\\s+.*-exec.*\\brm\\b/,\n reason: 'bulk_operation',\n description: 'find with delete',\n },\n {\n pattern: /\\bxargs\\s+.*\\brm\\b/,\n reason: 'bulk_operation',\n description: 'xargs with delete',\n },\n\n // Shell/script execution (potential for hidden actions)\n {\n pattern: /\\beval\\s+/,\n reason: 'dangerous_command',\n description: 'eval command',\n },\n {\n pattern: /\\bsource\\s+/,\n reason: 'dangerous_command',\n description: 'source command',\n },\n {\n pattern: /\\.\\s+\\//,\n reason: 'dangerous_command',\n description: 'dot source',\n },\n]\n\n/**\n * Check if a command matches any escalation pattern\n */\nfunction matchesEscalationPattern(\n command: string,\n): { reason: EscalationReason; description: string } | null {\n for (const { pattern, reason, description } of ESCALATION_PATTERNS) {\n if (pattern.test(command)) {\n return { reason, description }\n }\n }\n return null\n}\n\n/**\n * Get operation type from tool\n */\nfunction getOperationType(\n toolName: string,\n input: Record<string, unknown>,\n): 'read' | 'write' | 'delete' | 'execute' | null {\n switch (toolName) {\n case 'Read':\n case 'FileRead':\n case 'Glob':\n case 'Grep':\n return 'read'\n case 'Write':\n case 'FileWrite':\n case 'Edit':\n case 'FileEdit':\n case 'MultiEdit':\n case 'NotebookEdit':\n return 'write'\n case 'Bash': {\n const command = (input.command as string) || ''\n if (/\\b(rm|del|rmdir|unlink)\\b/.test(command)) {\n return 'delete'\n }\n return 'execute'\n }\n default:\n return null\n }\n}\n\n/**\n * Extract file path from input\n */\nfunction extractFilePath(input: Record<string, unknown>): string | null {\n if (input.file_path) return input.file_path as string\n if (input.filePath) return input.filePath as string\n if (input.path) return input.path as string\n return null\n}\n\n/**\n * Escalation messages by reason\n */\nconst ESCALATION_MESSAGES: Record<EscalationReason, string> = {\n sensitive_path: '\uD83D\uDD10 This operation accesses sensitive files',\n critical_external: '\uD83D\uDEA8 This operation affects files far outside your project',\n dangerous_command: '\u26A0\uFE0F This command is potentially destructive',\n bulk_operation: '\uD83D\uDCE6 This operation affects multiple files',\n privilege_escalation: '\uD83D\uDD11 This command may escalate system privileges',\n network_access: '\uD83C\uDF10 This command accesses the network',\n}\n\n/**\n * Auto-Escalation Rule\n *\n * Requires confirmation for high-risk operations even without safe mode.\n */\nexport const autoEscalationRule: PermissionRule = {\n name: 'auto-escalation',\n description: 'Requires confirmation for high-risk operations',\n priority: 85, // Below sensitive-paths and project-boundary, but above safe-mode\n\n check(context: PermissionContext): PermissionResult {\n const toolName = context.tool.name\n const input = context.input\n\n // For Bash commands, check escalation patterns\n if (toolName === 'Bash') {\n const command = (input.command as string) || ''\n const match = matchesEscalationPattern(command)\n\n if (match) {\n // Log the escalation trigger\n logSecurityEvent({\n eventType: 'security_warning',\n toolName,\n operation: 'execute',\n target: command,\n outcome: 'denied', // Will be 'allowed' if user approves\n riskLevel: 'high',\n context: {\n escalationReason: match.reason,\n escalationDescription: match.description,\n },\n triggeredRule: 'auto-escalation',\n })\n\n return {\n allowed: false,\n promptUser: true,\n reason: `High-risk operation: ${match.description}`,\n message: `${ESCALATION_MESSAGES[match.reason]}\\n\\nCommand: ${command.length > 100 ? command.substring(0, 100) + '...' : command}\\n\\nReason: ${match.description}`,\n permissionKey: `AutoEscalate(${match.reason}:${command.substring(0, 50)})`,\n }\n }\n }\n\n // Check file operations for sensitive paths\n const operation = getOperationType(toolName, input)\n if (operation && operation !== 'read') {\n const filePath = extractFilePath(input)\n\n if (filePath) {\n // Check if it's a sensitive path\n if (isSensitivePath(filePath, operation)) {\n const info = getSensitivePathInfo(filePath)\n\n logSecurityEvent({\n eventType: 'sensitive_path_access',\n toolName,\n operation,\n target: filePath,\n outcome: 'denied',\n riskLevel: 'high',\n context: {\n category: info?.category,\n description: info?.description,\n },\n triggeredRule: 'auto-escalation',\n })\n\n return {\n allowed: false,\n promptUser: true,\n reason: `Sensitive path: ${info?.description || 'unknown'}`,\n message: `${ESCALATION_MESSAGES.sensitive_path}\\n\\nPath: ${filePath}\\nCategory: ${info?.category || 'unknown'}`,\n permissionKey: `AutoEscalate(sensitive:${filePath})`,\n }\n }\n\n // Check if it's a critical external operation\n if (isOutsideProject(filePath)) {\n const risk = calculateExternalOperationRisk(operation, filePath)\n\n if (risk === 'critical' || risk === 'high') {\n logSecurityEvent({\n eventType: 'external_operation',\n toolName,\n operation,\n target: filePath,\n outcome: 'denied',\n riskLevel: risk,\n triggeredRule: 'auto-escalation',\n })\n\n return {\n allowed: false,\n promptUser: true,\n reason: `${risk} risk external operation`,\n message: `${ESCALATION_MESSAGES.critical_external}\\n\\nPath: ${filePath}\\nRisk Level: ${risk.toUpperCase()}`,\n permissionKey: `AutoEscalate(external:${filePath})`,\n }\n }\n }\n }\n }\n\n return { allowed: true }\n },\n}\n\n/**\n * Check if an operation should trigger auto-escalation\n */\nexport function shouldAutoEscalate(\n toolName: string,\n input: Record<string, unknown>,\n): {\n shouldEscalate: boolean\n reason?: EscalationReason\n description?: string\n} {\n // Check command patterns\n if (toolName === 'Bash') {\n const command = (input.command as string) || ''\n const match = matchesEscalationPattern(command)\n if (match) {\n return { shouldEscalate: true, ...match }\n }\n }\n\n // Check file paths\n const filePath = extractFilePath(input)\n if (filePath) {\n const operation = getOperationType(toolName, input)\n\n if (operation && operation !== 'read') {\n if (isSensitivePath(filePath, operation)) {\n return {\n shouldEscalate: true,\n reason: 'sensitive_path',\n description: 'Sensitive file access',\n }\n }\n\n if (isOutsideProject(filePath)) {\n const risk = calculateExternalOperationRisk(operation, filePath)\n if (risk === 'critical' || risk === 'high') {\n return {\n shouldEscalate: true,\n reason: 'critical_external',\n description: `${risk} risk external operation`,\n }\n }\n }\n }\n }\n\n return { shouldEscalate: false }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Auto-Escalation Rule\n *\n * Automatically escalates permission requirements when detecting\n * high-risk operations, even if safe mode is not explicitly enabled.\n * This provides defense-in-depth by requiring confirmation for\n * particularly dangerous actions regardless of mode.\n */\n\nimport type {\n PermissionRule,\n PermissionContext,\n PermissionResult,\n} from '../engine/types'\nimport { isSensitivePath, getSensitivePathInfo } from './sensitivePathsRule'\nimport {\n isOutsideProject,\n calculateExternalOperationRisk,\n} from './projectBoundaryRule'\nimport { logSecurityEvent } from '../auditLog'\n\n/**\n * Escalation trigger reasons\n */\nexport type EscalationReason =\n | 'sensitive_path' // Accessing sensitive paths\n | 'critical_external' // Critical external operation\n | 'dangerous_command' // Known dangerous command pattern\n | 'bulk_operation' // Bulk file operations\n | 'privilege_escalation' // Commands that might escalate privileges\n | 'network_access' // Network-related commands\n\n/**\n * Patterns that should always trigger escalation\n */\nconst ESCALATION_PATTERNS: Array<{\n pattern: RegExp\n reason: EscalationReason\n description: string\n}> = [\n // Privilege escalation\n {\n pattern: /\\bsudo\\s+/,\n reason: 'privilege_escalation',\n description: 'sudo command',\n },\n {\n pattern: /\\bsu\\s+(-|\\w)/,\n reason: 'privilege_escalation',\n description: 'su command',\n },\n {\n pattern: /\\bchmod\\s+[0-7]*[4-7][0-7]*\\s/,\n reason: 'privilege_escalation',\n description: 'chmod with execute permissions',\n },\n {\n pattern: /\\bchown\\s+/,\n reason: 'privilege_escalation',\n description: 'chown command',\n },\n\n // Dangerous file operations\n {\n pattern: /\\brm\\s+(-r|-rf|-fr)\\s+/,\n reason: 'dangerous_command',\n description: 'recursive delete',\n },\n {\n pattern: /\\bdd\\s+.*if=/,\n reason: 'dangerous_command',\n description: 'dd command',\n },\n {\n pattern: /\\bmkfs\\b/,\n reason: 'dangerous_command',\n description: 'filesystem creation',\n },\n {\n pattern: />\\s*\\/dev\\/(sd|hd|nvme)/,\n reason: 'dangerous_command',\n description: 'write to disk device',\n },\n\n // Network access (potential data exfiltration)\n {\n pattern: /\\bcurl\\s+.*(-d|--data|-F|--form)/,\n reason: 'network_access',\n description: 'curl with data upload',\n },\n {\n pattern: /\\bwget\\s+--post/,\n reason: 'network_access',\n description: 'wget with POST',\n },\n {\n pattern: /\\bnc\\s+/,\n reason: 'network_access',\n description: 'netcat',\n },\n {\n pattern: /\\bssh\\s+/,\n reason: 'network_access',\n description: 'SSH connection',\n },\n {\n pattern: /\\bscp\\s+/,\n reason: 'network_access',\n description: 'SCP file transfer',\n },\n {\n pattern: /\\brsync\\s+.*:/,\n reason: 'network_access',\n description: 'rsync to remote',\n },\n\n // Bulk operations\n {\n pattern: /\\bfind\\s+.*-exec.*\\brm\\b/,\n reason: 'bulk_operation',\n description: 'find with delete',\n },\n {\n pattern: /\\bxargs\\s+.*\\brm\\b/,\n reason: 'bulk_operation',\n description: 'xargs with delete',\n },\n\n // Shell/script execution (potential for hidden actions)\n {\n pattern: /\\beval\\s+/,\n reason: 'dangerous_command',\n description: 'eval command',\n },\n {\n pattern: /\\bsource\\s+/,\n reason: 'dangerous_command',\n description: 'source command',\n },\n {\n pattern: /\\.\\s+\\//,\n reason: 'dangerous_command',\n description: 'dot source',\n },\n]\n\n/**\n * Check if a command matches any escalation pattern\n */\nfunction matchesEscalationPattern(\n command: string,\n): { reason: EscalationReason; description: string } | null {\n for (const { pattern, reason, description } of ESCALATION_PATTERNS) {\n if (pattern.test(command)) {\n return { reason, description }\n }\n }\n return null\n}\n\n/**\n * Get operation type from tool\n */\nfunction getOperationType(\n toolName: string,\n input: Record<string, unknown>,\n): 'read' | 'write' | 'delete' | 'execute' | null {\n switch (toolName) {\n case 'View': // Actual API name for FileReadTool\n case 'Read':\n case 'FileRead':\n case 'Glob':\n case 'Grep':\n return 'read'\n case 'Replace': // Actual API name for FileWriteTool\n case 'Write':\n case 'FileWrite':\n case 'Edit':\n case 'FileEdit':\n case 'MultiEdit':\n case 'NotebookEdit':\n case 'NotebookEditCell': // Actual API name for NotebookEditTool\n return 'write'\n case 'Bash': {\n const command = (input.command as string) || ''\n if (/\\b(rm|del|rmdir|unlink)\\b/.test(command)) {\n return 'delete'\n }\n return 'execute'\n }\n default:\n return null\n }\n}\n\n/**\n * Extract file path from input\n */\nfunction extractFilePath(input: Record<string, unknown>): string | null {\n if (input.file_path) return input.file_path as string\n if (input.filePath) return input.filePath as string\n if (input.path) return input.path as string\n return null\n}\n\n/**\n * Escalation messages by reason\n */\nconst ESCALATION_MESSAGES: Record<EscalationReason, string> = {\n sensitive_path: '\uD83D\uDD10 This operation accesses sensitive files',\n critical_external: '\uD83D\uDEA8 This operation affects files far outside your project',\n dangerous_command: '\u26A0\uFE0F This command is potentially destructive',\n bulk_operation: '\uD83D\uDCE6 This operation affects multiple files',\n privilege_escalation: '\uD83D\uDD11 This command may escalate system privileges',\n network_access: '\uD83C\uDF10 This command accesses the network',\n}\n\n/**\n * Auto-Escalation Rule\n *\n * Requires confirmation for high-risk operations even without safe mode.\n */\nexport const autoEscalationRule: PermissionRule = {\n name: 'auto-escalation',\n description: 'Requires confirmation for high-risk operations',\n priority: 85, // Below sensitive-paths and project-boundary, but above safe-mode\n\n check(context: PermissionContext): PermissionResult {\n const toolName = context.tool.name\n const input = context.input\n\n // For Bash commands, check escalation patterns\n if (toolName === 'Bash') {\n const command = (input.command as string) || ''\n const match = matchesEscalationPattern(command)\n\n if (match) {\n // Log the escalation trigger\n logSecurityEvent({\n eventType: 'security_warning',\n toolName,\n operation: 'execute',\n target: command,\n outcome: 'denied', // Will be 'allowed' if user approves\n riskLevel: 'high',\n context: {\n escalationReason: match.reason,\n escalationDescription: match.description,\n },\n triggeredRule: 'auto-escalation',\n })\n\n return {\n allowed: false,\n promptUser: true,\n reason: `High-risk operation: ${match.description}`,\n message: `${ESCALATION_MESSAGES[match.reason]}\\n\\nCommand: ${command.length > 100 ? command.substring(0, 100) + '...' : command}\\n\\nReason: ${match.description}`,\n permissionKey: `AutoEscalate(${match.reason}:${command.substring(0, 50)})`,\n }\n }\n }\n\n // Check file operations for sensitive paths\n const operation = getOperationType(toolName, input)\n if (operation && operation !== 'read') {\n const filePath = extractFilePath(input)\n\n if (filePath) {\n // Check if it's a sensitive path\n if (isSensitivePath(filePath, operation)) {\n const info = getSensitivePathInfo(filePath)\n\n logSecurityEvent({\n eventType: 'sensitive_path_access',\n toolName,\n operation,\n target: filePath,\n outcome: 'denied',\n riskLevel: 'high',\n context: {\n category: info?.category,\n description: info?.description,\n },\n triggeredRule: 'auto-escalation',\n })\n\n return {\n allowed: false,\n promptUser: true,\n reason: `Sensitive path: ${info?.description || 'unknown'}`,\n message: `${ESCALATION_MESSAGES.sensitive_path}\\n\\nPath: ${filePath}\\nCategory: ${info?.category || 'unknown'}`,\n permissionKey: `AutoEscalate(sensitive:${filePath})`,\n }\n }\n\n // Check if it's a critical external operation\n if (isOutsideProject(filePath)) {\n const risk = calculateExternalOperationRisk(operation, filePath)\n\n if (risk === 'critical' || risk === 'high') {\n logSecurityEvent({\n eventType: 'external_operation',\n toolName,\n operation,\n target: filePath,\n outcome: 'denied',\n riskLevel: risk,\n triggeredRule: 'auto-escalation',\n })\n\n return {\n allowed: false,\n promptUser: true,\n reason: `${risk} risk external operation`,\n message: `${ESCALATION_MESSAGES.critical_external}\\n\\nPath: ${filePath}\\nRisk Level: ${risk.toUpperCase()}`,\n permissionKey: `AutoEscalate(external:${filePath})`,\n }\n }\n }\n }\n }\n\n return { allowed: true }\n },\n}\n\n/**\n * Check if an operation should trigger auto-escalation\n */\nexport function shouldAutoEscalate(\n toolName: string,\n input: Record<string, unknown>,\n): {\n shouldEscalate: boolean\n reason?: EscalationReason\n description?: string\n} {\n // Check command patterns\n if (toolName === 'Bash') {\n const command = (input.command as string) || ''\n const match = matchesEscalationPattern(command)\n if (match) {\n return { shouldEscalate: true, ...match }\n }\n }\n\n // Check file paths\n const filePath = extractFilePath(input)\n if (filePath) {\n const operation = getOperationType(toolName, input)\n\n if (operation && operation !== 'read') {\n if (isSensitivePath(filePath, operation)) {\n return {\n shouldEscalate: true,\n reason: 'sensitive_path',\n description: 'Sensitive file access',\n }\n }\n\n if (isOutsideProject(filePath)) {\n const risk = calculateExternalOperationRisk(operation, filePath)\n if (risk === 'critical' || risk === 'high') {\n return {\n shouldEscalate: true,\n reason: 'critical_external',\n description: `${risk} risk external operation`,\n }\n }\n }\n }\n }\n\n return { shouldEscalate: false }\n}\n"],
5
+ "mappings": "AAcA,SAAS,iBAAiB,4BAA4B;AACtD;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,wBAAwB;AAgBjC,MAAM,sBAID;AAAA;AAAA,EAEH;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA;AAAA,EAGA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AAAA,EACA;AAAA,IACE,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,aAAa;AAAA,EACf;AACF;AAKA,SAAS,yBACP,SAC0D;AAC1D,aAAW,EAAE,SAAS,QAAQ,YAAY,KAAK,qBAAqB;AAClE,QAAI,QAAQ,KAAK,OAAO,GAAG;AACzB,aAAO,EAAE,QAAQ,YAAY;AAAA,IAC/B;AAAA,EACF;AACA,SAAO;AACT;AAKA,SAAS,iBACP,UACA,OACgD;AAChD,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAA;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK,QAAQ;AACX,YAAM,UAAW,MAAM,WAAsB;AAC7C,UAAI,4BAA4B,KAAK,OAAO,GAAG;AAC7C,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAKA,SAAS,gBAAgB,OAA+C;AACtE,MAAI,MAAM,UAAW,QAAO,MAAM;AAClC,MAAI,MAAM,SAAU,QAAO,MAAM;AACjC,MAAI,MAAM,KAAM,QAAO,MAAM;AAC7B,SAAO;AACT;AAKA,MAAM,sBAAwD;AAAA,EAC5D,gBAAgB;AAAA,EAChB,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,gBAAgB;AAAA,EAChB,sBAAsB;AAAA,EACtB,gBAAgB;AAClB;AAOO,MAAM,qBAAqC;AAAA,EAChD,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA;AAAA,EAEV,MAAM,SAA8C;AAClD,UAAM,WAAW,QAAQ,KAAK;AAC9B,UAAM,QAAQ,QAAQ;AAGtB,QAAI,aAAa,QAAQ;AACvB,YAAM,UAAW,MAAM,WAAsB;AAC7C,YAAM,QAAQ,yBAAyB,OAAO;AAE9C,UAAI,OAAO;AAET,yBAAiB;AAAA,UACf,WAAW;AAAA,UACX;AAAA,UACA,WAAW;AAAA,UACX,QAAQ;AAAA,UACR,SAAS;AAAA;AAAA,UACT,WAAW;AAAA,UACX,SAAS;AAAA,YACP,kBAAkB,MAAM;AAAA,YACxB,uBAAuB,MAAM;AAAA,UAC/B;AAAA,UACA,eAAe;AAAA,QACjB,CAAC;AAED,eAAO;AAAA,UACL,SAAS;AAAA,UACT,YAAY;AAAA,UACZ,QAAQ,wBAAwB,MAAM,WAAW;AAAA,UACjD,SAAS,GAAG,oBAAoB,MAAM,MAAM,CAAC;AAAA;AAAA,WAAgB,QAAQ,SAAS,MAAM,QAAQ,UAAU,GAAG,GAAG,IAAI,QAAQ,OAAO;AAAA;AAAA,UAAe,MAAM,WAAW;AAAA,UAC/J,eAAe,gBAAgB,MAAM,MAAM,IAAI,QAAQ,UAAU,GAAG,EAAE,CAAC;AAAA,QACzE;AAAA,MACF;AAAA,IACF;AAGA,UAAM,YAAY,iBAAiB,UAAU,KAAK;AAClD,QAAI,aAAa,cAAc,QAAQ;AACrC,YAAM,WAAW,gBAAgB,KAAK;AAEtC,UAAI,UAAU;AAEZ,YAAI,gBAAgB,UAAU,SAAS,GAAG;AACxC,gBAAM,OAAO,qBAAqB,QAAQ;AAE1C,2BAAiB;AAAA,YACf,WAAW;AAAA,YACX;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,WAAW;AAAA,YACX,SAAS;AAAA,cACP,UAAU,MAAM;AAAA,cAChB,aAAa,MAAM;AAAA,YACrB;AAAA,YACA,eAAe;AAAA,UACjB,CAAC;AAED,iBAAO;AAAA,YACL,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,QAAQ,mBAAmB,MAAM,eAAe,SAAS;AAAA,YACzD,SAAS,GAAG,oBAAoB,cAAc;AAAA;AAAA,QAAa,QAAQ;AAAA,YAAe,MAAM,YAAY,SAAS;AAAA,YAC7G,eAAe,0BAA0B,QAAQ;AAAA,UACnD;AAAA,QACF;AAGA,YAAI,iBAAiB,QAAQ,GAAG;AAC9B,gBAAM,OAAO,+BAA+B,WAAW,QAAQ;AAE/D,cAAI,SAAS,cAAc,SAAS,QAAQ;AAC1C,6BAAiB;AAAA,cACf,WAAW;AAAA,cACX;AAAA,cACA;AAAA,cACA,QAAQ;AAAA,cACR,SAAS;AAAA,cACT,WAAW;AAAA,cACX,eAAe;AAAA,YACjB,CAAC;AAED,mBAAO;AAAA,cACL,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,QAAQ,GAAG,IAAI;AAAA,cACf,SAAS,GAAG,oBAAoB,iBAAiB;AAAA;AAAA,QAAa,QAAQ;AAAA,cAAiB,KAAK,YAAY,CAAC;AAAA,cACzG,eAAe,yBAAyB,QAAQ;AAAA,YAClD;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AACF;AAKO,SAAS,mBACd,UACA,OAKA;AAEA,MAAI,aAAa,QAAQ;AACvB,UAAM,UAAW,MAAM,WAAsB;AAC7C,UAAM,QAAQ,yBAAyB,OAAO;AAC9C,QAAI,OAAO;AACT,aAAO,EAAE,gBAAgB,MAAM,GAAG,MAAM;AAAA,IAC1C;AAAA,EACF;AAGA,QAAM,WAAW,gBAAgB,KAAK;AACtC,MAAI,UAAU;AACZ,UAAM,YAAY,iBAAiB,UAAU,KAAK;AAElD,QAAI,aAAa,cAAc,QAAQ;AACrC,UAAI,gBAAgB,UAAU,SAAS,GAAG;AACxC,eAAO;AAAA,UACL,gBAAgB;AAAA,UAChB,QAAQ;AAAA,UACR,aAAa;AAAA,QACf;AAAA,MACF;AAEA,UAAI,iBAAiB,QAAQ,GAAG;AAC9B,cAAM,OAAO,+BAA+B,WAAW,QAAQ;AAC/D,YAAI,SAAS,cAAc,SAAS,QAAQ;AAC1C,iBAAO;AAAA,YACL,gBAAgB;AAAA,YAChB,QAAQ;AAAA,YACR,aAAa,GAAG,IAAI;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,gBAAgB,MAAM;AACjC;",
6
6
  "names": []
7
7
  }
@@ -27,17 +27,22 @@ function calculateExternalOperationRisk(operation, filePath) {
27
27
  }
28
28
  function getOperationType(toolName, input) {
29
29
  switch (toolName) {
30
+ case "View":
31
+ // Actual API name for FileReadTool
30
32
  case "Read":
31
33
  case "FileRead":
32
34
  case "Glob":
33
35
  case "Grep":
34
36
  return "read";
37
+ case "Replace":
38
+ // Actual API name for FileWriteTool
35
39
  case "Write":
36
40
  case "FileWrite":
37
41
  case "Edit":
38
42
  case "FileEdit":
39
43
  case "MultiEdit":
40
44
  case "NotebookEdit":
45
+ case "NotebookEditCell":
41
46
  return "write";
42
47
  case "Bash": {
43
48
  const command = input.command || "";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/permissions/rules/projectBoundaryRule.ts"],
4
- "sourcesContent": ["/**\n * Project Boundary Rule\n *\n * Enforces secondary confirmation for write/delete operations\n * outside the project directory. This prevents accidental modifications\n * to files outside the current working context.\n */\n\nimport type {\n PermissionRule,\n PermissionContext,\n PermissionResult,\n} from '../engine/types'\nimport { resolve, relative, isAbsolute } from 'path'\nimport { getOriginalCwd } from '@utils/state'\n\n/**\n * Operation risk levels for operations outside project directory\n */\nexport type ExternalOperationRisk = 'low' | 'medium' | 'high' | 'critical'\n\n/**\n * Determine if a path is outside the project directory\n */\nexport function isOutsideProject(filePath: string): boolean {\n const projectDir = getOriginalCwd()\n const absolutePath = isAbsolute(filePath)\n ? resolve(filePath)\n : resolve(projectDir, filePath)\n\n const relativePath = relative(projectDir, absolutePath)\n\n // If the relative path starts with '..' or is absolute, it's outside\n return relativePath.startsWith('..') || isAbsolute(relativePath)\n}\n\n/**\n * Get the relative path from project directory (for display)\n */\nexport function getRelativeFromProject(filePath: string): string {\n const projectDir = getOriginalCwd()\n const absolutePath = isAbsolute(filePath)\n ? resolve(filePath)\n : resolve(projectDir, filePath)\n\n return relative(projectDir, absolutePath)\n}\n\n/**\n * Calculate risk level for an external operation\n */\nexport function calculateExternalOperationRisk(\n operation: 'read' | 'write' | 'delete' | 'execute',\n filePath: string,\n): ExternalOperationRisk {\n const relativePath = getRelativeFromProject(filePath)\n\n // Count how many levels up we're going\n const levelsUp = (relativePath.match(/\\.\\./g) || []).length\n\n // Critical: More than 3 levels up or accessing system directories\n if (\n levelsUp > 3 ||\n filePath.startsWith('/etc') ||\n filePath.startsWith('/usr')\n ) {\n return 'critical'\n }\n\n // High: Delete operations or 2-3 levels up\n if (operation === 'delete' || levelsUp >= 2) {\n return 'high'\n }\n\n // Medium: Write operations 1 level up\n if (operation === 'write' && levelsUp >= 1) {\n return 'medium'\n }\n\n // Low: Other cases\n return 'low'\n}\n\n/**\n * Get operation type from tool name\n */\nfunction getOperationType(\n toolName: string,\n input: Record<string, unknown>,\n): 'read' | 'write' | 'delete' | 'execute' | null {\n switch (toolName) {\n case 'Read':\n case 'FileRead':\n case 'Glob':\n case 'Grep':\n return 'read'\n case 'Write':\n case 'FileWrite':\n case 'Edit':\n case 'FileEdit':\n case 'MultiEdit':\n case 'NotebookEdit':\n return 'write'\n case 'Bash': {\n const command = (input.command as string) || ''\n if (/\\b(rm|del|rmdir|unlink)\\b/.test(command)) {\n return 'delete'\n }\n if (/\\b(mv|cp|touch|mkdir|echo\\s+.*>|cat\\s+.*>|tee)\\b/.test(command)) {\n return 'write'\n }\n if (/\\b(cat|head|tail|less|more|grep|find|ls)\\b/.test(command)) {\n return 'read'\n }\n return 'execute'\n }\n default:\n return null\n }\n}\n\n/**\n * Extract file paths from tool input (may return multiple for Bash)\n */\nfunction extractFilePaths(\n toolName: string,\n input: Record<string, unknown>,\n): string[] {\n const paths: string[] = []\n\n // Direct file path tools\n if (input.file_path) paths.push(input.file_path as string)\n if (input.filePath) paths.push(input.filePath as string)\n if (input.path) paths.push(input.path as string)\n\n // For Bash commands, extract all paths\n if (toolName === 'Bash') {\n const command = (input.command as string) || ''\n\n // Match paths after file operation commands\n const pathMatches = command.matchAll(\n /(?:cat|rm|mv|cp|head|tail|less|more|touch|mkdir|rmdir|>\\s*)\\s*[\"']?([^\\s\"'|&;><]+)/g,\n )\n for (const match of pathMatches) {\n if (match[1] && !match[1].startsWith('-')) {\n paths.push(match[1])\n }\n }\n }\n\n return paths\n}\n\n/**\n * Risk level descriptions\n */\nconst RISK_MESSAGES: Record<ExternalOperationRisk, string> = {\n low: '\uD83D\uDCC1 This file is outside your project directory.',\n medium: '\u26A0\uFE0F This operation modifies a file outside your project.',\n high: '\uD83D\uDD36 High-risk operation: This file is significantly outside your project boundary.',\n critical:\n '\uD83D\uDEA8 Critical: This operation affects system or deeply external files!',\n}\n\n/**\n * Project Boundary Rule\n *\n * Requires confirmation for write/delete operations outside project.\n */\nexport const projectBoundaryRule: PermissionRule = {\n name: 'project-boundary',\n description:\n 'Requires confirmation for write/delete operations outside project directory',\n priority: 95, // High priority, but below sensitive paths\n\n check(context: PermissionContext): PermissionResult {\n const toolName = context.tool.name\n const input = context.input\n\n // Get operation type\n const operation = getOperationType(toolName, input)\n if (!operation) {\n return { allowed: true }\n }\n\n // Only check write/delete operations (read is generally safe)\n if (operation === 'read') {\n return { allowed: true }\n }\n\n // Extract file paths\n const filePaths = extractFilePaths(toolName, input)\n if (filePaths.length === 0) {\n return { allowed: true }\n }\n\n // Check each path\n const externalPaths: Array<{\n path: string\n relativePath: string\n risk: ExternalOperationRisk\n }> = []\n\n for (const filePath of filePaths) {\n if (isOutsideProject(filePath)) {\n const relativePath = getRelativeFromProject(filePath)\n const risk = calculateExternalOperationRisk(operation, filePath)\n externalPaths.push({ path: filePath, relativePath, risk })\n }\n }\n\n // If no external paths, allow\n if (externalPaths.length === 0) {\n return { allowed: true }\n }\n\n // Get the highest risk level\n const riskOrder: ExternalOperationRisk[] = [\n 'low',\n 'medium',\n 'high',\n 'critical',\n ]\n const highestRisk = externalPaths.reduce((max, curr) => {\n return riskOrder.indexOf(curr.risk) > riskOrder.indexOf(max)\n ? curr.risk\n : max\n }, 'low' as ExternalOperationRisk)\n\n // Critical operations are blocked\n if (highestRisk === 'critical') {\n return {\n allowed: false,\n reason: 'Critical external operation blocked',\n message: `${RISK_MESSAGES.critical}\\n\\nPaths:\\n${externalPaths.map(p => ` \u2022 ${p.relativePath}`).join('\\n')}\\n\\nThis operation is too risky to allow. Please reconsider.`,\n }\n }\n\n // All other external operations require explicit confirmation\n const projectDir = getOriginalCwd()\n const pathList = externalPaths\n .map(p => ` \u2022 ${p.relativePath} (${p.risk} risk)`)\n .join('\\n')\n\n return {\n allowed: false,\n promptUser: true,\n reason: 'External operation requires confirmation',\n message: `${RISK_MESSAGES[highestRisk]}\\n\\nProject: ${projectDir}\\n\\nExternal paths:\\n${pathList}\\n\\nOperation: ${operation}`,\n permissionKey: `ExternalOp(${operation}:${externalPaths.map(p => p.path).join(',')})`,\n }\n },\n}\n\n/**\n * Check if an operation is outside project (utility function)\n */\nexport function isExternalOperation(\n filePath: string,\n operation: 'read' | 'write' | 'delete' | 'execute',\n): { isExternal: boolean; risk: ExternalOperationRisk | null } {\n if (!isOutsideProject(filePath)) {\n return { isExternal: false, risk: null }\n }\n\n return {\n isExternal: true,\n risk: calculateExternalOperationRisk(operation, filePath),\n }\n}\n"],
5
- "mappings": "AAaA,SAAS,SAAS,UAAU,kBAAkB;AAC9C,SAAS,sBAAsB;AAUxB,SAAS,iBAAiB,UAA2B;AAC1D,QAAM,aAAa,eAAe;AAClC,QAAM,eAAe,WAAW,QAAQ,IACpC,QAAQ,QAAQ,IAChB,QAAQ,YAAY,QAAQ;AAEhC,QAAM,eAAe,SAAS,YAAY,YAAY;AAGtD,SAAO,aAAa,WAAW,IAAI,KAAK,WAAW,YAAY;AACjE;AAKO,SAAS,uBAAuB,UAA0B;AAC/D,QAAM,aAAa,eAAe;AAClC,QAAM,eAAe,WAAW,QAAQ,IACpC,QAAQ,QAAQ,IAChB,QAAQ,YAAY,QAAQ;AAEhC,SAAO,SAAS,YAAY,YAAY;AAC1C;AAKO,SAAS,+BACd,WACA,UACuB;AACvB,QAAM,eAAe,uBAAuB,QAAQ;AAGpD,QAAM,YAAY,aAAa,MAAM,OAAO,KAAK,CAAC,GAAG;AAGrD,MACE,WAAW,KACX,SAAS,WAAW,MAAM,KAC1B,SAAS,WAAW,MAAM,GAC1B;AACA,WAAO;AAAA,EACT;AAGA,MAAI,cAAc,YAAY,YAAY,GAAG;AAC3C,WAAO;AAAA,EACT;AAGA,MAAI,cAAc,WAAW,YAAY,GAAG;AAC1C,WAAO;AAAA,EACT;AAGA,SAAO;AACT;AAKA,SAAS,iBACP,UACA,OACgD;AAChD,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK,QAAQ;AACX,YAAM,UAAW,MAAM,WAAsB;AAC7C,UAAI,4BAA4B,KAAK,OAAO,GAAG;AAC7C,eAAO;AAAA,MACT;AACA,UAAI,mDAAmD,KAAK,OAAO,GAAG;AACpE,eAAO;AAAA,MACT;AACA,UAAI,6CAA6C,KAAK,OAAO,GAAG;AAC9D,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA,IACA;AACE,aAAO;AAAA,EACX;AACF;AAKA,SAAS,iBACP,UACA,OACU;AACV,QAAM,QAAkB,CAAC;AAGzB,MAAI,MAAM,UAAW,OAAM,KAAK,MAAM,SAAmB;AACzD,MAAI,MAAM,SAAU,OAAM,KAAK,MAAM,QAAkB;AACvD,MAAI,MAAM,KAAM,OAAM,KAAK,MAAM,IAAc;AAG/C,MAAI,aAAa,QAAQ;AACvB,UAAM,UAAW,MAAM,WAAsB;AAG7C,UAAM,cAAc,QAAQ;AAAA,MAC1B;AAAA,IACF;AACA,eAAW,SAAS,aAAa;AAC/B,UAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,GAAG;AACzC,cAAM,KAAK,MAAM,CAAC,CAAC;AAAA,MACrB;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAKA,MAAM,gBAAuD;AAAA,EAC3D,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UACE;AACJ;AAOO,MAAM,sBAAsC;AAAA,EACjD,MAAM;AAAA,EACN,aACE;AAAA,EACF,UAAU;AAAA;AAAA,EAEV,MAAM,SAA8C;AAClD,UAAM,WAAW,QAAQ,KAAK;AAC9B,UAAM,QAAQ,QAAQ;AAGtB,UAAM,YAAY,iBAAiB,UAAU,KAAK;AAClD,QAAI,CAAC,WAAW;AACd,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAGA,QAAI,cAAc,QAAQ;AACxB,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAGA,UAAM,YAAY,iBAAiB,UAAU,KAAK;AAClD,QAAI,UAAU,WAAW,GAAG;AAC1B,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAGA,UAAM,gBAID,CAAC;AAEN,eAAW,YAAY,WAAW;AAChC,UAAI,iBAAiB,QAAQ,GAAG;AAC9B,cAAM,eAAe,uBAAuB,QAAQ;AACpD,cAAM,OAAO,+BAA+B,WAAW,QAAQ;AAC/D,sBAAc,KAAK,EAAE,MAAM,UAAU,cAAc,KAAK,CAAC;AAAA,MAC3D;AAAA,IACF;AAGA,QAAI,cAAc,WAAW,GAAG;AAC9B,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAGA,UAAM,YAAqC;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,cAAc,cAAc,OAAO,CAAC,KAAK,SAAS;AACtD,aAAO,UAAU,QAAQ,KAAK,IAAI,IAAI,UAAU,QAAQ,GAAG,IACvD,KAAK,OACL;AAAA,IACN,GAAG,KAA8B;AAGjC,QAAI,gBAAgB,YAAY;AAC9B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,SAAS,GAAG,cAAc,QAAQ;AAAA;AAAA;AAAA,EAAe,cAAc,IAAI,OAAK,YAAO,EAAE,YAAY,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,MAC7G;AAAA,IACF;AAGA,UAAM,aAAa,eAAe;AAClC,UAAM,WAAW,cACd,IAAI,OAAK,YAAO,EAAE,YAAY,KAAK,EAAE,IAAI,QAAQ,EACjD,KAAK,IAAI;AAEZ,WAAO;AAAA,MACL,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,SAAS,GAAG,cAAc,WAAW,CAAC;AAAA;AAAA,WAAgB,UAAU;AAAA;AAAA;AAAA,EAAwB,QAAQ;AAAA;AAAA,aAAkB,SAAS;AAAA,MAC3H,eAAe,cAAc,SAAS,IAAI,cAAc,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC;AAAA,IACpF;AAAA,EACF;AACF;AAKO,SAAS,oBACd,UACA,WAC6D;AAC7D,MAAI,CAAC,iBAAiB,QAAQ,GAAG;AAC/B,WAAO,EAAE,YAAY,OAAO,MAAM,KAAK;AAAA,EACzC;AAEA,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,MAAM,+BAA+B,WAAW,QAAQ;AAAA,EAC1D;AACF;",
4
+ "sourcesContent": ["/**\n * Project Boundary Rule\n *\n * Enforces secondary confirmation for write/delete operations\n * outside the project directory. This prevents accidental modifications\n * to files outside the current working context.\n */\n\nimport type {\n PermissionRule,\n PermissionContext,\n PermissionResult,\n} from '../engine/types'\nimport { resolve, relative, isAbsolute } from 'path'\nimport { getOriginalCwd } from '@utils/state'\n\n/**\n * Operation risk levels for operations outside project directory\n */\nexport type ExternalOperationRisk = 'low' | 'medium' | 'high' | 'critical'\n\n/**\n * Determine if a path is outside the project directory\n */\nexport function isOutsideProject(filePath: string): boolean {\n const projectDir = getOriginalCwd()\n const absolutePath = isAbsolute(filePath)\n ? resolve(filePath)\n : resolve(projectDir, filePath)\n\n const relativePath = relative(projectDir, absolutePath)\n\n // If the relative path starts with '..' or is absolute, it's outside\n return relativePath.startsWith('..') || isAbsolute(relativePath)\n}\n\n/**\n * Get the relative path from project directory (for display)\n */\nexport function getRelativeFromProject(filePath: string): string {\n const projectDir = getOriginalCwd()\n const absolutePath = isAbsolute(filePath)\n ? resolve(filePath)\n : resolve(projectDir, filePath)\n\n return relative(projectDir, absolutePath)\n}\n\n/**\n * Calculate risk level for an external operation\n */\nexport function calculateExternalOperationRisk(\n operation: 'read' | 'write' | 'delete' | 'execute',\n filePath: string,\n): ExternalOperationRisk {\n const relativePath = getRelativeFromProject(filePath)\n\n // Count how many levels up we're going\n const levelsUp = (relativePath.match(/\\.\\./g) || []).length\n\n // Critical: More than 3 levels up or accessing system directories\n if (\n levelsUp > 3 ||\n filePath.startsWith('/etc') ||\n filePath.startsWith('/usr')\n ) {\n return 'critical'\n }\n\n // High: Delete operations or 2-3 levels up\n if (operation === 'delete' || levelsUp >= 2) {\n return 'high'\n }\n\n // Medium: Write operations 1 level up\n if (operation === 'write' && levelsUp >= 1) {\n return 'medium'\n }\n\n // Low: Other cases\n return 'low'\n}\n\n/**\n * Get operation type from tool name\n */\nfunction getOperationType(\n toolName: string,\n input: Record<string, unknown>,\n): 'read' | 'write' | 'delete' | 'execute' | null {\n switch (toolName) {\n case 'View': // Actual API name for FileReadTool\n case 'Read':\n case 'FileRead':\n case 'Glob':\n case 'Grep':\n return 'read'\n case 'Replace': // Actual API name for FileWriteTool\n case 'Write':\n case 'FileWrite':\n case 'Edit':\n case 'FileEdit':\n case 'MultiEdit':\n case 'NotebookEdit':\n case 'NotebookEditCell': // Actual API name for NotebookEditTool\n return 'write'\n case 'Bash': {\n const command = (input.command as string) || ''\n if (/\\b(rm|del|rmdir|unlink)\\b/.test(command)) {\n return 'delete'\n }\n if (/\\b(mv|cp|touch|mkdir|echo\\s+.*>|cat\\s+.*>|tee)\\b/.test(command)) {\n return 'write'\n }\n if (/\\b(cat|head|tail|less|more|grep|find|ls)\\b/.test(command)) {\n return 'read'\n }\n return 'execute'\n }\n default:\n return null\n }\n}\n\n/**\n * Extract file paths from tool input (may return multiple for Bash)\n */\nfunction extractFilePaths(\n toolName: string,\n input: Record<string, unknown>,\n): string[] {\n const paths: string[] = []\n\n // Direct file path tools\n if (input.file_path) paths.push(input.file_path as string)\n if (input.filePath) paths.push(input.filePath as string)\n if (input.path) paths.push(input.path as string)\n\n // For Bash commands, extract all paths\n if (toolName === 'Bash') {\n const command = (input.command as string) || ''\n\n // Match paths after file operation commands\n const pathMatches = command.matchAll(\n /(?:cat|rm|mv|cp|head|tail|less|more|touch|mkdir|rmdir|>\\s*)\\s*[\"']?([^\\s\"'|&;><]+)/g,\n )\n for (const match of pathMatches) {\n if (match[1] && !match[1].startsWith('-')) {\n paths.push(match[1])\n }\n }\n }\n\n return paths\n}\n\n/**\n * Risk level descriptions\n */\nconst RISK_MESSAGES: Record<ExternalOperationRisk, string> = {\n low: '\uD83D\uDCC1 This file is outside your project directory.',\n medium: '\u26A0\uFE0F This operation modifies a file outside your project.',\n high: '\uD83D\uDD36 High-risk operation: This file is significantly outside your project boundary.',\n critical:\n '\uD83D\uDEA8 Critical: This operation affects system or deeply external files!',\n}\n\n/**\n * Project Boundary Rule\n *\n * Requires confirmation for write/delete operations outside project.\n */\nexport const projectBoundaryRule: PermissionRule = {\n name: 'project-boundary',\n description:\n 'Requires confirmation for write/delete operations outside project directory',\n priority: 95, // High priority, but below sensitive paths\n\n check(context: PermissionContext): PermissionResult {\n const toolName = context.tool.name\n const input = context.input\n\n // Get operation type\n const operation = getOperationType(toolName, input)\n if (!operation) {\n return { allowed: true }\n }\n\n // Only check write/delete operations (read is generally safe)\n if (operation === 'read') {\n return { allowed: true }\n }\n\n // Extract file paths\n const filePaths = extractFilePaths(toolName, input)\n if (filePaths.length === 0) {\n return { allowed: true }\n }\n\n // Check each path\n const externalPaths: Array<{\n path: string\n relativePath: string\n risk: ExternalOperationRisk\n }> = []\n\n for (const filePath of filePaths) {\n if (isOutsideProject(filePath)) {\n const relativePath = getRelativeFromProject(filePath)\n const risk = calculateExternalOperationRisk(operation, filePath)\n externalPaths.push({ path: filePath, relativePath, risk })\n }\n }\n\n // If no external paths, allow\n if (externalPaths.length === 0) {\n return { allowed: true }\n }\n\n // Get the highest risk level\n const riskOrder: ExternalOperationRisk[] = [\n 'low',\n 'medium',\n 'high',\n 'critical',\n ]\n const highestRisk = externalPaths.reduce((max, curr) => {\n return riskOrder.indexOf(curr.risk) > riskOrder.indexOf(max)\n ? curr.risk\n : max\n }, 'low' as ExternalOperationRisk)\n\n // Critical operations are blocked\n if (highestRisk === 'critical') {\n return {\n allowed: false,\n reason: 'Critical external operation blocked',\n message: `${RISK_MESSAGES.critical}\\n\\nPaths:\\n${externalPaths.map(p => ` \u2022 ${p.relativePath}`).join('\\n')}\\n\\nThis operation is too risky to allow. Please reconsider.`,\n }\n }\n\n // All other external operations require explicit confirmation\n const projectDir = getOriginalCwd()\n const pathList = externalPaths\n .map(p => ` \u2022 ${p.relativePath} (${p.risk} risk)`)\n .join('\\n')\n\n return {\n allowed: false,\n promptUser: true,\n reason: 'External operation requires confirmation',\n message: `${RISK_MESSAGES[highestRisk]}\\n\\nProject: ${projectDir}\\n\\nExternal paths:\\n${pathList}\\n\\nOperation: ${operation}`,\n permissionKey: `ExternalOp(${operation}:${externalPaths.map(p => p.path).join(',')})`,\n }\n },\n}\n\n/**\n * Check if an operation is outside project (utility function)\n */\nexport function isExternalOperation(\n filePath: string,\n operation: 'read' | 'write' | 'delete' | 'execute',\n): { isExternal: boolean; risk: ExternalOperationRisk | null } {\n if (!isOutsideProject(filePath)) {\n return { isExternal: false, risk: null }\n }\n\n return {\n isExternal: true,\n risk: calculateExternalOperationRisk(operation, filePath),\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -226,17 +226,22 @@ function matchesSensitivePath(filePath, sensitivePath) {
226
226
  }
227
227
  function getOperationType(toolName, input) {
228
228
  switch (toolName) {
229
+ case "View":
230
+ // Actual API name for FileReadTool
229
231
  case "Read":
230
232
  case "FileRead":
231
233
  case "Glob":
232
234
  case "Grep":
233
235
  return "read";
236
+ case "Replace":
237
+ // Actual API name for FileWriteTool
234
238
  case "Write":
235
239
  case "FileWrite":
236
240
  case "Edit":
237
241
  case "FileEdit":
238
242
  case "MultiEdit":
239
243
  case "NotebookEdit":
244
+ case "NotebookEditCell":
240
245
  return "write";
241
246
  case "Bash": {
242
247
  const command = input.command || "";
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/core/permissions/rules/sensitivePathsRule.ts"],
4
- "sourcesContent": ["/**\n * Sensitive Paths Protection Rule\n *\n * Always requires explicit authorization for operations on sensitive paths,\n * regardless of other permissions. These paths contain sensitive data that\n * should never be accessed without user awareness.\n */\n\nimport type {\n PermissionRule,\n PermissionContext,\n PermissionResult,\n} from '../engine/types'\nimport { resolve, normalize } from 'path'\nimport { homedir } from 'os'\n\n/**\n * Categories of sensitive paths with different protection levels\n */\nexport type SensitivePathCategory =\n | 'credentials' // API keys, passwords, tokens\n | 'ssh' // SSH keys and config\n | 'system' // System configuration files\n | 'browser' // Browser data (cookies, history, passwords)\n | 'cloud' // Cloud provider credentials\n | 'development' // Development secrets (env files, etc.)\n | 'wallet' // Cryptocurrency wallets\n\n/**\n * Sensitive path definition\n */\nexport interface SensitivePath {\n /** Pattern to match (supports * wildcards) */\n pattern: string\n /** Category of sensitive data */\n category: SensitivePathCategory\n /** Human-readable description */\n description: string\n /** Whether this path is always blocked (vs requiring confirmation) */\n alwaysBlock?: boolean\n /** Applicable operations (read, write, delete, execute) */\n operations?: ('read' | 'write' | 'delete' | 'execute')[]\n}\n\n/**\n * Default sensitive paths list\n */\nexport const SENSITIVE_PATHS: SensitivePath[] = [\n // SSH\n {\n pattern: '~/.ssh/*',\n category: 'ssh',\n description: 'SSH keys and configuration',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.ssh',\n category: 'ssh',\n description: 'SSH directory',\n operations: ['write', 'delete'],\n },\n\n // Credentials\n {\n pattern: '~/.aws/*',\n category: 'cloud',\n description: 'AWS credentials and configuration',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.config/gcloud/*',\n category: 'cloud',\n description: 'Google Cloud credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.azure/*',\n category: 'cloud',\n description: 'Azure credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.config/gh/*',\n category: 'credentials',\n description: 'GitHub CLI credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.docker/config.json',\n category: 'credentials',\n description: 'Docker registry credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.npmrc',\n category: 'credentials',\n description: 'NPM credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.netrc',\n category: 'credentials',\n description: 'Network credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.gnupg/*',\n category: 'credentials',\n description: 'GPG keys and configuration',\n operations: ['read', 'write', 'delete'],\n },\n\n // Development secrets\n {\n pattern: '**/.env',\n category: 'development',\n description: 'Environment variables file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/.env.*',\n category: 'development',\n description: 'Environment variables file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/credentials.json',\n category: 'development',\n description: 'Credentials file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/secrets.json',\n category: 'development',\n description: 'Secrets file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/secrets.yaml',\n category: 'development',\n description: 'Secrets file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/secrets.yml',\n category: 'development',\n description: 'Secrets file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/*.pem',\n category: 'credentials',\n description: 'Private key file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/*.key',\n category: 'credentials',\n description: 'Private key file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/id_rsa',\n category: 'ssh',\n description: 'SSH private key',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/id_ed25519',\n category: 'ssh',\n description: 'SSH private key',\n operations: ['read', 'write', 'delete'],\n },\n\n // Browser data\n {\n pattern: '~/Library/Application Support/Google/Chrome/*',\n category: 'browser',\n description: 'Chrome browser data',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/Library/Application Support/Firefox/*',\n category: 'browser',\n description: 'Firefox browser data',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.config/google-chrome/*',\n category: 'browser',\n description: 'Chrome browser data (Linux)',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.mozilla/firefox/*',\n category: 'browser',\n description: 'Firefox browser data (Linux)',\n operations: ['read', 'write', 'delete'],\n },\n\n // System configuration\n {\n pattern: '/etc/passwd',\n category: 'system',\n description: 'System user database',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '/etc/shadow',\n category: 'system',\n description: 'System password hashes',\n alwaysBlock: true,\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '/etc/sudoers',\n category: 'system',\n description: 'Sudo configuration',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '/etc/hosts',\n category: 'system',\n description: 'Host file',\n operations: ['write', 'delete'],\n },\n\n // Cryptocurrency wallets\n {\n pattern: '~/.bitcoin/*',\n category: 'wallet',\n description: 'Bitcoin wallet',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.ethereum/*',\n category: 'wallet',\n description: 'Ethereum wallet',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/*wallet*.json',\n category: 'wallet',\n description: 'Wallet file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/*keystore*',\n category: 'wallet',\n description: 'Keystore file',\n operations: ['read', 'write', 'delete'],\n },\n\n // Minto/Claude configuration (protect our own config)\n {\n pattern: '~/.minto.json',\n category: 'credentials',\n description: 'Minto global configuration (may contain API keys)',\n operations: ['delete'], // Only protect delete, read/write allowed for config\n },\n]\n\n/**\n * Expand ~ to home directory and normalize path\n */\nfunction expandPath(pattern: string): string {\n const home = homedir()\n let expanded = pattern.replace(/^~/, home)\n return normalize(expanded)\n}\n\n/**\n * Convert glob pattern to regex\n */\nfunction patternToRegex(pattern: string): RegExp {\n const expanded = expandPath(pattern)\n // Escape special regex characters except * and **\n let regex = expanded\n .replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '<<<DOUBLESTAR>>>')\n .replace(/\\*/g, '[^/]*')\n .replace(/<<<DOUBLESTAR>>>/g, '.*')\n\n return new RegExp(`^${regex}$`, 'i')\n}\n\n/**\n * Check if a path matches a sensitive path pattern\n */\nexport function matchesSensitivePath(\n filePath: string,\n sensitivePath: SensitivePath,\n): boolean {\n const normalizedPath = normalize(resolve(filePath))\n const regex = patternToRegex(sensitivePath.pattern)\n return regex.test(normalizedPath)\n}\n\n/**\n * Get operation type from tool name and input\n */\nfunction getOperationType(\n toolName: string,\n input: Record<string, unknown>,\n): 'read' | 'write' | 'delete' | 'execute' | null {\n switch (toolName) {\n case 'Read':\n case 'FileRead':\n case 'Glob':\n case 'Grep':\n return 'read'\n case 'Write':\n case 'FileWrite':\n case 'Edit':\n case 'FileEdit':\n case 'MultiEdit':\n case 'NotebookEdit':\n return 'write'\n case 'Bash': {\n const command = (input.command as string) || ''\n // Check for delete commands\n if (/\\b(rm|del|rmdir|unlink)\\b/.test(command)) {\n return 'delete'\n }\n // Check for write commands\n if (/\\b(mv|cp|touch|mkdir|echo\\s+.*>|cat\\s+.*>|tee)\\b/.test(command)) {\n return 'write'\n }\n // Check for read commands\n if (/\\b(cat|head|tail|less|more|grep|find|ls)\\b/.test(command)) {\n return 'read'\n }\n return 'execute'\n }\n default:\n return null\n }\n}\n\n/**\n * Extract file path from tool input\n */\nfunction extractFilePath(\n toolName: string,\n input: Record<string, unknown>,\n): string | null {\n // Direct file path tools\n if (input.file_path) return input.file_path as string\n if (input.filePath) return input.filePath as string\n if (input.path) return input.path as string\n\n // For Bash commands, try to extract file paths\n if (toolName === 'Bash') {\n const command = (input.command as string) || ''\n // Simple extraction - look for paths after common commands\n const pathMatch = command.match(\n /(?:cat|rm|mv|cp|head|tail|less|more|touch|mkdir)\\s+[\"']?([^\\s\"'|&;>]+)/,\n )\n if (pathMatch) {\n return pathMatch[1] || null\n }\n }\n\n return null\n}\n\n/**\n * Find matching sensitive paths for a given file path and operation\n */\nexport function findMatchingSensitivePaths(\n filePath: string,\n operation: 'read' | 'write' | 'delete' | 'execute',\n): SensitivePath[] {\n return SENSITIVE_PATHS.filter(sp => {\n // Check if operation is applicable\n if (sp.operations && !sp.operations.includes(operation)) {\n return false\n }\n return matchesSensitivePath(filePath, sp)\n })\n}\n\n/**\n * Sensitive Paths Rule\n *\n * Always prompts for sensitive paths, even if other permissions are granted.\n */\nexport const sensitivePathsRule: PermissionRule = {\n name: 'sensitive-paths',\n description: 'Protects sensitive paths from unauthorized access',\n priority: 100, // Highest priority - checked before all other rules\n\n check(context: PermissionContext): PermissionResult {\n const toolName = context.tool.name\n const input = context.input\n\n // Get operation type\n const operation = getOperationType(toolName, input)\n if (!operation) {\n return { allowed: true }\n }\n\n // Extract file path\n const filePath = extractFilePath(toolName, input)\n if (!filePath) {\n return { allowed: true }\n }\n\n // Find matching sensitive paths\n const matches = findMatchingSensitivePaths(filePath, operation)\n if (matches.length === 0) {\n return { allowed: true }\n }\n\n // Check if any match is always blocked\n const blocked = matches.find(m => m.alwaysBlock)\n if (blocked) {\n return {\n allowed: false,\n reason: `Access to ${blocked.description} is blocked for security`,\n message: `\uD83D\uDD12 Access denied: ${blocked.description} (${blocked.category})`,\n }\n }\n\n // Require explicit user confirmation for sensitive paths\n const categories = [...new Set(matches.map(m => m.category))]\n const descriptions = matches.map(m => m.description).join(', ')\n\n return {\n allowed: false,\n promptUser: true,\n reason: `Sensitive path access requires confirmation`,\n message: `\u26A0\uFE0F Sensitive ${operation} operation on: ${descriptions}\\nCategories: ${categories.join(', ')}`,\n permissionKey: `SensitivePath(${operation}:${filePath})`,\n }\n },\n}\n\n/**\n * Check if a path is sensitive (utility function for external use)\n */\nexport function isSensitivePath(\n filePath: string,\n operation: 'read' | 'write' | 'delete' | 'execute' = 'read',\n): boolean {\n return findMatchingSensitivePaths(filePath, operation).length > 0\n}\n\n/**\n * Get sensitive path info for a file\n */\nexport function getSensitivePathInfo(filePath: string): SensitivePath | null {\n for (const sp of SENSITIVE_PATHS) {\n if (matchesSensitivePath(filePath, sp)) {\n return sp\n }\n }\n return null\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Sensitive Paths Protection Rule\n *\n * Always requires explicit authorization for operations on sensitive paths,\n * regardless of other permissions. These paths contain sensitive data that\n * should never be accessed without user awareness.\n */\n\nimport type {\n PermissionRule,\n PermissionContext,\n PermissionResult,\n} from '../engine/types'\nimport { resolve, normalize } from 'path'\nimport { homedir } from 'os'\n\n/**\n * Categories of sensitive paths with different protection levels\n */\nexport type SensitivePathCategory =\n | 'credentials' // API keys, passwords, tokens\n | 'ssh' // SSH keys and config\n | 'system' // System configuration files\n | 'browser' // Browser data (cookies, history, passwords)\n | 'cloud' // Cloud provider credentials\n | 'development' // Development secrets (env files, etc.)\n | 'wallet' // Cryptocurrency wallets\n\n/**\n * Sensitive path definition\n */\nexport interface SensitivePath {\n /** Pattern to match (supports * wildcards) */\n pattern: string\n /** Category of sensitive data */\n category: SensitivePathCategory\n /** Human-readable description */\n description: string\n /** Whether this path is always blocked (vs requiring confirmation) */\n alwaysBlock?: boolean\n /** Applicable operations (read, write, delete, execute) */\n operations?: ('read' | 'write' | 'delete' | 'execute')[]\n}\n\n/**\n * Default sensitive paths list\n */\nexport const SENSITIVE_PATHS: SensitivePath[] = [\n // SSH\n {\n pattern: '~/.ssh/*',\n category: 'ssh',\n description: 'SSH keys and configuration',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.ssh',\n category: 'ssh',\n description: 'SSH directory',\n operations: ['write', 'delete'],\n },\n\n // Credentials\n {\n pattern: '~/.aws/*',\n category: 'cloud',\n description: 'AWS credentials and configuration',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.config/gcloud/*',\n category: 'cloud',\n description: 'Google Cloud credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.azure/*',\n category: 'cloud',\n description: 'Azure credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.config/gh/*',\n category: 'credentials',\n description: 'GitHub CLI credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.docker/config.json',\n category: 'credentials',\n description: 'Docker registry credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.npmrc',\n category: 'credentials',\n description: 'NPM credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.netrc',\n category: 'credentials',\n description: 'Network credentials',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.gnupg/*',\n category: 'credentials',\n description: 'GPG keys and configuration',\n operations: ['read', 'write', 'delete'],\n },\n\n // Development secrets\n {\n pattern: '**/.env',\n category: 'development',\n description: 'Environment variables file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/.env.*',\n category: 'development',\n description: 'Environment variables file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/credentials.json',\n category: 'development',\n description: 'Credentials file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/secrets.json',\n category: 'development',\n description: 'Secrets file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/secrets.yaml',\n category: 'development',\n description: 'Secrets file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/secrets.yml',\n category: 'development',\n description: 'Secrets file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/*.pem',\n category: 'credentials',\n description: 'Private key file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/*.key',\n category: 'credentials',\n description: 'Private key file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/id_rsa',\n category: 'ssh',\n description: 'SSH private key',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/id_ed25519',\n category: 'ssh',\n description: 'SSH private key',\n operations: ['read', 'write', 'delete'],\n },\n\n // Browser data\n {\n pattern: '~/Library/Application Support/Google/Chrome/*',\n category: 'browser',\n description: 'Chrome browser data',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/Library/Application Support/Firefox/*',\n category: 'browser',\n description: 'Firefox browser data',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.config/google-chrome/*',\n category: 'browser',\n description: 'Chrome browser data (Linux)',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.mozilla/firefox/*',\n category: 'browser',\n description: 'Firefox browser data (Linux)',\n operations: ['read', 'write', 'delete'],\n },\n\n // System configuration\n {\n pattern: '/etc/passwd',\n category: 'system',\n description: 'System user database',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '/etc/shadow',\n category: 'system',\n description: 'System password hashes',\n alwaysBlock: true,\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '/etc/sudoers',\n category: 'system',\n description: 'Sudo configuration',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '/etc/hosts',\n category: 'system',\n description: 'Host file',\n operations: ['write', 'delete'],\n },\n\n // Cryptocurrency wallets\n {\n pattern: '~/.bitcoin/*',\n category: 'wallet',\n description: 'Bitcoin wallet',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '~/.ethereum/*',\n category: 'wallet',\n description: 'Ethereum wallet',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/*wallet*.json',\n category: 'wallet',\n description: 'Wallet file',\n operations: ['read', 'write', 'delete'],\n },\n {\n pattern: '**/*keystore*',\n category: 'wallet',\n description: 'Keystore file',\n operations: ['read', 'write', 'delete'],\n },\n\n // Minto/Claude configuration (protect our own config)\n {\n pattern: '~/.minto.json',\n category: 'credentials',\n description: 'Minto global configuration (may contain API keys)',\n operations: ['delete'], // Only protect delete, read/write allowed for config\n },\n]\n\n/**\n * Expand ~ to home directory and normalize path\n */\nfunction expandPath(pattern: string): string {\n const home = homedir()\n let expanded = pattern.replace(/^~/, home)\n return normalize(expanded)\n}\n\n/**\n * Convert glob pattern to regex\n */\nfunction patternToRegex(pattern: string): RegExp {\n const expanded = expandPath(pattern)\n // Escape special regex characters except * and **\n let regex = expanded\n .replace(/[.+?^${}()|[\\]\\\\]/g, '\\\\$&')\n .replace(/\\*\\*/g, '<<<DOUBLESTAR>>>')\n .replace(/\\*/g, '[^/]*')\n .replace(/<<<DOUBLESTAR>>>/g, '.*')\n\n return new RegExp(`^${regex}$`, 'i')\n}\n\n/**\n * Check if a path matches a sensitive path pattern\n */\nexport function matchesSensitivePath(\n filePath: string,\n sensitivePath: SensitivePath,\n): boolean {\n const normalizedPath = normalize(resolve(filePath))\n const regex = patternToRegex(sensitivePath.pattern)\n return regex.test(normalizedPath)\n}\n\n/**\n * Get operation type from tool name and input\n */\nfunction getOperationType(\n toolName: string,\n input: Record<string, unknown>,\n): 'read' | 'write' | 'delete' | 'execute' | null {\n switch (toolName) {\n case 'View': // Actual API name for FileReadTool\n case 'Read':\n case 'FileRead':\n case 'Glob':\n case 'Grep':\n return 'read'\n case 'Replace': // Actual API name for FileWriteTool\n case 'Write':\n case 'FileWrite':\n case 'Edit':\n case 'FileEdit':\n case 'MultiEdit':\n case 'NotebookEdit':\n case 'NotebookEditCell': // Actual API name for NotebookEditTool\n return 'write'\n case 'Bash': {\n const command = (input.command as string) || ''\n // Check for delete commands\n if (/\\b(rm|del|rmdir|unlink)\\b/.test(command)) {\n return 'delete'\n }\n // Check for write commands\n if (/\\b(mv|cp|touch|mkdir|echo\\s+.*>|cat\\s+.*>|tee)\\b/.test(command)) {\n return 'write'\n }\n // Check for read commands\n if (/\\b(cat|head|tail|less|more|grep|find|ls)\\b/.test(command)) {\n return 'read'\n }\n return 'execute'\n }\n default:\n return null\n }\n}\n\n/**\n * Extract file path from tool input\n */\nfunction extractFilePath(\n toolName: string,\n input: Record<string, unknown>,\n): string | null {\n // Direct file path tools\n if (input.file_path) return input.file_path as string\n if (input.filePath) return input.filePath as string\n if (input.path) return input.path as string\n\n // For Bash commands, try to extract file paths\n if (toolName === 'Bash') {\n const command = (input.command as string) || ''\n // Simple extraction - look for paths after common commands\n const pathMatch = command.match(\n /(?:cat|rm|mv|cp|head|tail|less|more|touch|mkdir)\\s+[\"']?([^\\s\"'|&;>]+)/,\n )\n if (pathMatch) {\n return pathMatch[1] || null\n }\n }\n\n return null\n}\n\n/**\n * Find matching sensitive paths for a given file path and operation\n */\nexport function findMatchingSensitivePaths(\n filePath: string,\n operation: 'read' | 'write' | 'delete' | 'execute',\n): SensitivePath[] {\n return SENSITIVE_PATHS.filter(sp => {\n // Check if operation is applicable\n if (sp.operations && !sp.operations.includes(operation)) {\n return false\n }\n return matchesSensitivePath(filePath, sp)\n })\n}\n\n/**\n * Sensitive Paths Rule\n *\n * Always prompts for sensitive paths, even if other permissions are granted.\n */\nexport const sensitivePathsRule: PermissionRule = {\n name: 'sensitive-paths',\n description: 'Protects sensitive paths from unauthorized access',\n priority: 100, // Highest priority - checked before all other rules\n\n check(context: PermissionContext): PermissionResult {\n const toolName = context.tool.name\n const input = context.input\n\n // Get operation type\n const operation = getOperationType(toolName, input)\n if (!operation) {\n return { allowed: true }\n }\n\n // Extract file path\n const filePath = extractFilePath(toolName, input)\n if (!filePath) {\n return { allowed: true }\n }\n\n // Find matching sensitive paths\n const matches = findMatchingSensitivePaths(filePath, operation)\n if (matches.length === 0) {\n return { allowed: true }\n }\n\n // Check if any match is always blocked\n const blocked = matches.find(m => m.alwaysBlock)\n if (blocked) {\n return {\n allowed: false,\n reason: `Access to ${blocked.description} is blocked for security`,\n message: `\uD83D\uDD12 Access denied: ${blocked.description} (${blocked.category})`,\n }\n }\n\n // Require explicit user confirmation for sensitive paths\n const categories = [...new Set(matches.map(m => m.category))]\n const descriptions = matches.map(m => m.description).join(', ')\n\n return {\n allowed: false,\n promptUser: true,\n reason: `Sensitive path access requires confirmation`,\n message: `\u26A0\uFE0F Sensitive ${operation} operation on: ${descriptions}\\nCategories: ${categories.join(', ')}`,\n permissionKey: `SensitivePath(${operation}:${filePath})`,\n }\n },\n}\n\n/**\n * Check if a path is sensitive (utility function for external use)\n */\nexport function isSensitivePath(\n filePath: string,\n operation: 'read' | 'write' | 'delete' | 'execute' = 'read',\n): boolean {\n return findMatchingSensitivePaths(filePath, operation).length > 0\n}\n\n/**\n * Get sensitive path info for a file\n */\nexport function getSensitivePathInfo(filePath: string): SensitivePath | null {\n for (const sp of SENSITIVE_PATHS) {\n if (matchesSensitivePath(filePath, sp)) {\n return sp\n }\n }\n return null\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,9 @@
1
+ const DEFAULT_ESTIMATION_CONFIG = {
2
+ charsPerToken: 4,
3
+ defaultInputCostPerMillion: 3,
4
+ defaultOutputCostPerMillion: 15
5
+ };
6
+ export {
7
+ DEFAULT_ESTIMATION_CONFIG
8
+ };
9
+ //# sourceMappingURL=tokenStats.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/tokenStats.ts"],
4
+ "sourcesContent": ["/**\n * Token Statistics Types\n *\n * Unified type definitions for token tracking across the application.\n * These types are used by TokenStatsManager to provide consistent\n * token statistics at global, agent, and request levels.\n */\n\n/**\n * Token usage statistics from a single API call\n */\nexport interface TokenUsageRecord {\n /** Input tokens (prompt) */\n inputTokens: number\n /** Output tokens (completion) */\n outputTokens: number\n /** Cache creation tokens (Anthropic-specific) */\n cacheCreationTokens: number\n /** Cache read tokens (Anthropic-specific) */\n cacheReadTokens: number\n /** Total tokens (computed: input + output) */\n totalTokens: number\n /** Estimated cost in USD */\n estimatedCostUSD: number\n /** Data source: 'api' for actual values, 'estimated' for calculated */\n source: 'api' | 'estimated'\n /** Timestamp when this record was created */\n timestamp: number\n /** Model used for this request */\n model: string\n}\n\n/**\n * Aggregated token statistics for a scope (global or per-agent)\n */\nexport interface AggregatedTokenStats {\n /** Total input tokens across all requests */\n totalInputTokens: number\n /** Total output tokens across all requests */\n totalOutputTokens: number\n /** Total cache creation tokens */\n totalCacheCreationTokens: number\n /** Total cache read tokens */\n totalCacheReadTokens: number\n /** Grand total tokens (input + output) */\n grandTotalTokens: number\n /** Total estimated cost in USD */\n totalCostUSD: number\n /** Number of API requests */\n requestCount: number\n /** First request timestamp */\n firstRequestTime?: number\n /** Last request timestamp */\n lastRequestTime?: number\n /** Breakdown by model */\n byModel: Map<string, ModelTokenStats>\n}\n\n/**\n * Per-model token statistics\n */\nexport interface ModelTokenStats {\n /** Model name */\n model: string\n /** Input tokens for this model */\n inputTokens: number\n /** Output tokens for this model */\n outputTokens: number\n /** Total tokens for this model */\n totalTokens: number\n /** Estimated cost for this model */\n estimatedCostUSD: number\n /** Number of requests to this model */\n requestCount: number\n}\n\n/**\n * Scope identifier for hierarchical statistics\n */\nexport type TokenStatsScope =\n | { type: 'global' }\n | { type: 'agent'; agentId: string }\n | { type: 'request'; requestId: string }\n\n/**\n * Event emitted when token stats change\n */\nexport interface TokenStatsEvent {\n /** Type of change */\n eventType: 'usage_recorded' | 'scope_created' | 'scope_completed'\n /** Scope that changed */\n scope: TokenStatsScope\n /** The usage record (for usage_recorded events) */\n usage?: TokenUsageRecord\n /** Current aggregated stats for the scope */\n aggregated: AggregatedTokenStats\n /** Global aggregated stats (always included for convenience) */\n globalStats: AggregatedTokenStats\n}\n\n/**\n * Context for token tracking (passed through the API call chain)\n *\n * This is used to associate token usage with specific agents or tool uses,\n * enabling per-agent token tracking.\n */\nexport interface TokenTrackingContext {\n /** Agent ID if this request is within an agent context */\n agentId?: string\n /** Tool use ID if this request is triggered by a tool */\n toolUseId?: string\n /** Model being used for this request */\n model: string\n}\n\n/**\n * Raw token usage from API response (before processing)\n */\nexport interface RawTokenUsage {\n /** Input tokens from API */\n inputTokens: number\n /** Output tokens from API */\n outputTokens: number\n /** Cache creation tokens (optional, Anthropic-specific) */\n cacheCreationTokens?: number\n /** Cache read tokens (optional, Anthropic/OpenAI) */\n cacheReadTokens?: number\n}\n\n/**\n * Configuration for token estimation when API doesn't return usage\n */\nexport interface TokenEstimationConfig {\n /** Average characters per token (default: 4 for mixed English/Chinese) */\n charsPerToken: number\n /** Default input cost per million tokens in USD */\n defaultInputCostPerMillion: number\n /** Default output cost per million tokens in USD */\n defaultOutputCostPerMillion: number\n}\n\n/**\n * Default estimation configuration\n */\nexport const DEFAULT_ESTIMATION_CONFIG: TokenEstimationConfig = {\n charsPerToken: 4,\n defaultInputCostPerMillion: 3.0,\n defaultOutputCostPerMillion: 15.0,\n}\n"],
5
+ "mappings": "AAgJO,MAAM,4BAAmD;AAAA,EAC9D,eAAe;AAAA,EACf,4BAA4B;AAAA,EAC5B,6BAA6B;AAC/B;",
6
+ "names": []
7
+ }