@within-7/minto 0.1.7 → 0.2.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 (481) hide show
  1. package/cli.js +155 -37
  2. package/dist/Tool.js +38 -0
  3. package/dist/Tool.js.map +3 -3
  4. package/dist/commands/agents/AgentsCommand.js +52 -26
  5. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  6. package/dist/commands/agents/constants.js +1 -1
  7. package/dist/commands/agents/constants.js.map +1 -1
  8. package/dist/commands/agents/index.js +1 -1
  9. package/dist/commands/bug.js +74 -7
  10. package/dist/commands/bug.js.map +3 -3
  11. package/dist/commands/clear.js +3 -0
  12. package/dist/commands/clear.js.map +2 -2
  13. package/dist/commands/compact.js +37 -0
  14. package/dist/commands/compact.js.map +2 -2
  15. package/dist/commands/context.js +84 -0
  16. package/dist/commands/context.js.map +7 -0
  17. package/dist/commands/ctx_viz.js +18 -10
  18. package/dist/commands/ctx_viz.js.map +2 -2
  19. package/dist/commands/doctor.js +158 -12
  20. package/dist/commands/doctor.js.map +2 -2
  21. package/dist/commands/export.js +156 -0
  22. package/dist/commands/export.js.map +7 -0
  23. package/dist/commands/mcp-interactive.js +21 -12
  24. package/dist/commands/mcp-interactive.js.map +2 -2
  25. package/dist/commands/model.js +6 -5
  26. package/dist/commands/model.js.map +2 -2
  27. package/dist/commands/permissions.js +86 -0
  28. package/dist/commands/permissions.js.map +7 -0
  29. package/dist/commands/quit.js +3 -1
  30. package/dist/commands/quit.js.map +2 -2
  31. package/dist/commands/sandbox.js +104 -0
  32. package/dist/commands/sandbox.js.map +7 -0
  33. package/dist/commands/status.js +58 -0
  34. package/dist/commands/status.js.map +7 -0
  35. package/dist/commands/tasks.js +108 -0
  36. package/dist/commands/tasks.js.map +7 -0
  37. package/dist/commands/todos.js +123 -0
  38. package/dist/commands/todos.js.map +7 -0
  39. package/dist/commands.js +20 -2
  40. package/dist/commands.js.map +2 -2
  41. package/dist/components/AgentThinkingBlock.js +10 -18
  42. package/dist/components/AgentThinkingBlock.js.map +2 -2
  43. package/dist/components/BackgroundTasksPanel.js +78 -29
  44. package/dist/components/BackgroundTasksPanel.js.map +2 -2
  45. package/dist/components/BashStreamingProgress.js +24 -0
  46. package/dist/components/BashStreamingProgress.js.map +7 -0
  47. package/dist/components/CollapsibleHint.js +14 -0
  48. package/dist/components/CollapsibleHint.js.map +7 -0
  49. package/dist/components/FileEditToolUpdatedMessage.js +1 -1
  50. package/dist/components/FileEditToolUpdatedMessage.js.map +2 -2
  51. package/dist/components/HotkeyHelpPanel.js +137 -0
  52. package/dist/components/HotkeyHelpPanel.js.map +7 -0
  53. package/dist/components/Logo.js +5 -5
  54. package/dist/components/Logo.js.map +2 -2
  55. package/dist/components/Message.js +23 -7
  56. package/dist/components/Message.js.map +3 -3
  57. package/dist/components/ModelConfig.js +16 -3
  58. package/dist/components/ModelConfig.js.map +2 -2
  59. package/dist/components/ModelListManager.js +3 -3
  60. package/dist/components/ModelListManager.js.map +2 -2
  61. package/dist/components/ModelSelector/ModelSelector.js +1 -1
  62. package/dist/components/Onboarding.js +19 -14
  63. package/dist/components/Onboarding.js.map +2 -2
  64. package/dist/components/ProgressBar.js +74 -0
  65. package/dist/components/ProgressBar.js.map +7 -0
  66. package/dist/components/PromptInput.js +156 -46
  67. package/dist/components/PromptInput.js.map +2 -2
  68. package/dist/components/RequestStatusIndicator.js +194 -0
  69. package/dist/components/RequestStatusIndicator.js.map +7 -0
  70. package/dist/components/Spinner.js +92 -27
  71. package/dist/components/Spinner.js.map +2 -2
  72. package/dist/components/SpinnerSymbol.js +21 -27
  73. package/dist/components/SpinnerSymbol.js.map +2 -2
  74. package/dist/components/StreamingBashOutput.js +9 -8
  75. package/dist/components/StreamingBashOutput.js.map +2 -2
  76. package/dist/components/SubagentBlock.js +1 -1
  77. package/dist/components/SubagentBlock.js.map +1 -1
  78. package/dist/components/SubagentProgress.js +10 -11
  79. package/dist/components/SubagentProgress.js.map +2 -2
  80. package/dist/components/TaskCard.js +16 -13
  81. package/dist/components/TaskCard.js.map +2 -2
  82. package/dist/components/TodoChangeBlock.js +1 -1
  83. package/dist/components/TodoChangeBlock.js.map +2 -2
  84. package/dist/components/TodoPanel.js +120 -29
  85. package/dist/components/TodoPanel.js.map +3 -3
  86. package/dist/components/TokenCounter.js +74 -0
  87. package/dist/components/TokenCounter.js.map +7 -0
  88. package/dist/components/TokenWarning.js +2 -1
  89. package/dist/components/TokenWarning.js.map +2 -2
  90. package/dist/components/TreeConnector.js +25 -0
  91. package/dist/components/TreeConnector.js.map +7 -0
  92. package/dist/components/TurnCompletionIndicator.js +18 -0
  93. package/dist/components/TurnCompletionIndicator.js.map +7 -0
  94. package/dist/components/messages/AssistantTextMessage.js +5 -2
  95. package/dist/components/messages/AssistantTextMessage.js.map +2 -2
  96. package/dist/components/messages/AssistantThinkingMessage.js +18 -3
  97. package/dist/components/messages/AssistantThinkingMessage.js.map +2 -2
  98. package/dist/components/messages/AssistantToolUseMessage.js +11 -8
  99. package/dist/components/messages/AssistantToolUseMessage.js.map +2 -2
  100. package/dist/components/messages/GroupRenderer.js +53 -0
  101. package/dist/components/messages/GroupRenderer.js.map +7 -0
  102. package/dist/components/messages/NestedTasksPreview.js +12 -0
  103. package/dist/components/messages/NestedTasksPreview.js.map +7 -0
  104. package/dist/components/messages/ParallelTasksGroupView.js +92 -0
  105. package/dist/components/messages/ParallelTasksGroupView.js.map +7 -0
  106. package/dist/components/messages/TaskInModuleView.js +198 -0
  107. package/dist/components/messages/TaskInModuleView.js.map +7 -0
  108. package/dist/components/messages/TaskOutputContent.js +53 -0
  109. package/dist/components/messages/TaskOutputContent.js.map +7 -0
  110. package/dist/components/messages/UserPromptMessage.js +1 -1
  111. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  112. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js +2 -3
  113. package/dist/components/messages/UserToolResultMessage/UserToolSuccessMessage.js.map +2 -2
  114. package/dist/components/permissions/FallbackPermissionRequest.js +4 -4
  115. package/dist/components/permissions/FallbackPermissionRequest.js.map +2 -2
  116. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js +4 -4
  117. package/dist/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.js.map +2 -2
  118. package/dist/constants/colors.js +48 -0
  119. package/dist/constants/colors.js.map +2 -2
  120. package/dist/constants/formatRules.js +102 -0
  121. package/dist/constants/formatRules.js.map +7 -0
  122. package/dist/constants/prompts.js +12 -34
  123. package/dist/constants/prompts.js.map +2 -2
  124. package/dist/constants/symbols.js +64 -6
  125. package/dist/constants/symbols.js.map +2 -2
  126. package/dist/constants/timing.js +5 -0
  127. package/dist/constants/timing.js.map +2 -2
  128. package/dist/core/config/defaults.js +84 -0
  129. package/dist/core/config/defaults.js.map +7 -0
  130. package/dist/core/config/index.js +111 -0
  131. package/dist/core/config/index.js.map +7 -0
  132. package/dist/core/config/loader.js +221 -0
  133. package/dist/core/config/loader.js.map +7 -0
  134. package/dist/core/config/migrations.js +128 -0
  135. package/dist/core/config/migrations.js.map +7 -0
  136. package/dist/core/config/schema.js +178 -0
  137. package/dist/core/config/schema.js.map +7 -0
  138. package/dist/core/costTracker.js +138 -0
  139. package/dist/core/costTracker.js.map +7 -0
  140. package/dist/core/index.js +5 -0
  141. package/dist/core/index.js.map +7 -0
  142. package/dist/core/permissions/auditLog.js +204 -0
  143. package/dist/core/permissions/auditLog.js.map +7 -0
  144. package/dist/core/permissions/engine/index.js +3 -0
  145. package/dist/core/permissions/engine/index.js.map +7 -0
  146. package/dist/core/permissions/engine/permissionEngine.js +106 -0
  147. package/dist/core/permissions/engine/permissionEngine.js.map +7 -0
  148. package/dist/core/permissions/engine/types.js +1 -0
  149. package/dist/core/permissions/engine/types.js.map +7 -0
  150. package/dist/core/permissions/index.js +84 -0
  151. package/dist/core/permissions/index.js.map +7 -0
  152. package/dist/core/permissions/ruleEngine.js +259 -0
  153. package/dist/core/permissions/ruleEngine.js.map +7 -0
  154. package/dist/core/permissions/rules/allowedToolsRule.js +62 -0
  155. package/dist/core/permissions/rules/allowedToolsRule.js.map +7 -0
  156. package/dist/core/permissions/rules/autoEscalationRule.js +291 -0
  157. package/dist/core/permissions/rules/autoEscalationRule.js.map +7 -0
  158. package/dist/core/permissions/rules/index.js +46 -0
  159. package/dist/core/permissions/rules/index.js.map +7 -0
  160. package/dist/core/permissions/rules/planModeRule.js +55 -0
  161. package/dist/core/permissions/rules/planModeRule.js.map +7 -0
  162. package/dist/core/permissions/rules/projectBoundaryRule.js +168 -0
  163. package/dist/core/permissions/rules/projectBoundaryRule.js.map +7 -0
  164. package/dist/core/permissions/rules/safeModeRule.js +65 -0
  165. package/dist/core/permissions/rules/safeModeRule.js.map +7 -0
  166. package/dist/core/permissions/rules/sensitivePathsRule.js +340 -0
  167. package/dist/core/permissions/rules/sensitivePathsRule.js.map +7 -0
  168. package/dist/core/permissions/types.js +127 -0
  169. package/dist/core/permissions/types.js.map +7 -0
  170. package/dist/core/tools/executor.js +143 -0
  171. package/dist/core/tools/executor.js.map +7 -0
  172. package/dist/core/tools/index.js +15 -0
  173. package/dist/core/tools/index.js.map +7 -0
  174. package/dist/core/tools/registry.js +183 -0
  175. package/dist/core/tools/registry.js.map +7 -0
  176. package/dist/core/tools/types.js +1 -0
  177. package/dist/core/tools/types.js.map +7 -0
  178. package/dist/cost-tracker.js +23 -15
  179. package/dist/cost-tracker.js.map +2 -2
  180. package/dist/entrypoints/cli.js +43 -43
  181. package/dist/entrypoints/cli.js.map +2 -2
  182. package/dist/entrypoints/mcp.js +12 -4
  183. package/dist/entrypoints/mcp.js.map +2 -2
  184. package/dist/history.js +14 -3
  185. package/dist/history.js.map +2 -2
  186. package/dist/hooks/useAgentTranscripts.js +116 -0
  187. package/dist/hooks/useAgentTranscripts.js.map +7 -0
  188. package/dist/hooks/useAnimationSync.js +53 -0
  189. package/dist/hooks/useAnimationSync.js.map +7 -0
  190. package/dist/hooks/useArrowKeyHistory.js +4 -2
  191. package/dist/hooks/useArrowKeyHistory.js.map +2 -2
  192. package/dist/hooks/useCanUseTool.js +3 -1
  193. package/dist/hooks/useCanUseTool.js.map +2 -2
  194. package/dist/hooks/useCancelRequest.js +4 -1
  195. package/dist/hooks/useCancelRequest.js.map +2 -2
  196. package/dist/hooks/useExitOnCtrlCD.js +9 -5
  197. package/dist/hooks/useExitOnCtrlCD.js.map +2 -2
  198. package/dist/hooks/useHookStatus.js +40 -0
  199. package/dist/hooks/useHookStatus.js.map +7 -0
  200. package/dist/hooks/useLogMessages.js +17 -1
  201. package/dist/hooks/useLogMessages.js.map +2 -2
  202. package/dist/hooks/useMessageGroups.js +43 -0
  203. package/dist/hooks/useMessageGroups.js.map +7 -0
  204. package/dist/hooks/useTerminalSize.js +62 -6
  205. package/dist/hooks/useTerminalSize.js.map +2 -2
  206. package/dist/hooks/useUnifiedCompletion.js +69 -0
  207. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  208. package/dist/i18n/index.js +109 -0
  209. package/dist/i18n/index.js.map +7 -0
  210. package/dist/i18n/locales/en.js +347 -0
  211. package/dist/i18n/locales/en.js.map +7 -0
  212. package/dist/i18n/locales/index.js +7 -0
  213. package/dist/i18n/locales/index.js.map +7 -0
  214. package/dist/i18n/locales/zh-CN.js +347 -0
  215. package/dist/i18n/locales/zh-CN.js.map +7 -0
  216. package/dist/i18n/types.js +8 -0
  217. package/dist/i18n/types.js.map +7 -0
  218. package/dist/query.js +175 -17
  219. package/dist/query.js.map +3 -3
  220. package/dist/screens/REPL.js +501 -192
  221. package/dist/screens/REPL.js.map +3 -3
  222. package/dist/services/adapters/chatCompletions.js +3 -1
  223. package/dist/services/adapters/chatCompletions.js.map +2 -2
  224. package/dist/services/adapters/messageNormalizer.js +354 -0
  225. package/dist/services/adapters/messageNormalizer.js.map +7 -0
  226. package/dist/services/adapters/responsesAPI.js +6 -3
  227. package/dist/services/adapters/responsesAPI.js.map +2 -2
  228. package/dist/services/checkpointManager.js +386 -0
  229. package/dist/services/checkpointManager.js.map +7 -0
  230. package/dist/services/claude.js +138 -11
  231. package/dist/services/claude.js.map +3 -3
  232. package/dist/services/compressionService.js +50 -1
  233. package/dist/services/compressionService.js.map +2 -2
  234. package/dist/services/contextMonitor.js +162 -0
  235. package/dist/services/contextMonitor.js.map +7 -0
  236. package/dist/services/customCommands.js +60 -41
  237. package/dist/services/customCommands.js.map +2 -2
  238. package/dist/services/hookExecutor.js +173 -1
  239. package/dist/services/hookExecutor.js.map +2 -2
  240. package/dist/services/intelligentCompactor.js +281 -0
  241. package/dist/services/intelligentCompactor.js.map +7 -0
  242. package/dist/services/lspConfig.js +109 -0
  243. package/dist/services/lspConfig.js.map +7 -0
  244. package/dist/services/mcpClient.js +273 -34
  245. package/dist/services/mcpClient.js.map +2 -2
  246. package/dist/services/modelOrchestrator.js +310 -0
  247. package/dist/services/modelOrchestrator.js.map +7 -0
  248. package/dist/services/openai.js +8 -1
  249. package/dist/services/openai.js.map +2 -2
  250. package/dist/services/outputStyles.js +138 -0
  251. package/dist/services/outputStyles.js.map +7 -0
  252. package/dist/services/plugins/index.js +5 -0
  253. package/dist/services/plugins/index.js.map +7 -0
  254. package/dist/services/plugins/lspServers.js +188 -0
  255. package/dist/services/plugins/lspServers.js.map +7 -0
  256. package/dist/services/plugins/pluginRuntime.js +229 -0
  257. package/dist/services/plugins/pluginRuntime.js.map +7 -0
  258. package/dist/services/plugins/pluginValidation.js +219 -0
  259. package/dist/services/plugins/pluginValidation.js.map +7 -0
  260. package/dist/services/plugins/skillMarketplace.js +556 -0
  261. package/dist/services/plugins/skillMarketplace.js.map +7 -0
  262. package/dist/services/responseStateManager.js +37 -3
  263. package/dist/services/responseStateManager.js.map +2 -2
  264. package/dist/services/sandbox/filesystemBoundary.js +300 -0
  265. package/dist/services/sandbox/filesystemBoundary.js.map +7 -0
  266. package/dist/services/sandbox/index.js +14 -0
  267. package/dist/services/sandbox/index.js.map +7 -0
  268. package/dist/services/sandbox/networkProxy.js +293 -0
  269. package/dist/services/sandbox/networkProxy.js.map +7 -0
  270. package/dist/services/sandbox/sandboxController.js +574 -0
  271. package/dist/services/sandbox/sandboxController.js.map +7 -0
  272. package/dist/services/sandbox/types.js +50 -0
  273. package/dist/services/sandbox/types.js.map +7 -0
  274. package/dist/services/sessionMemory.js +266 -0
  275. package/dist/services/sessionMemory.js.map +7 -0
  276. package/dist/services/taskRouter.js +324 -0
  277. package/dist/services/taskRouter.js.map +7 -0
  278. package/dist/tools/ArchitectTool/ArchitectTool.js +7 -1
  279. package/dist/tools/ArchitectTool/ArchitectTool.js.map +2 -2
  280. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js +3 -0
  281. package/dist/tools/AskExpertModelTool/AskExpertModelTool.js.map +2 -2
  282. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +2 -2
  283. package/dist/tools/BaseTool.js +72 -0
  284. package/dist/tools/BaseTool.js.map +7 -0
  285. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js +3 -0
  286. package/dist/tools/BashOutputTool/BashOutputToolResultMessage.js.map +2 -2
  287. package/dist/tools/BashTool/BashTool.js +60 -3
  288. package/dist/tools/BashTool/BashTool.js.map +2 -2
  289. package/dist/tools/BashTool/BashToolResultMessage.js +3 -0
  290. package/dist/tools/BashTool/BashToolResultMessage.js.map +2 -2
  291. package/dist/tools/BashTool/OutputLine.js +54 -0
  292. package/dist/tools/BashTool/OutputLine.js.map +2 -2
  293. package/dist/tools/BashTool/prompt.js +192 -3
  294. package/dist/tools/BashTool/prompt.js.map +2 -2
  295. package/dist/tools/FileEditTool/FileEditTool.js +29 -4
  296. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  297. package/dist/tools/FileWriteTool/FileWriteTool.js +5 -5
  298. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  299. package/dist/tools/GlobTool/GlobTool.js +4 -2
  300. package/dist/tools/GlobTool/GlobTool.js.map +2 -2
  301. package/dist/tools/GrepTool/GrepTool.js +36 -7
  302. package/dist/tools/GrepTool/GrepTool.js.map +2 -2
  303. package/dist/tools/KillShellTool/KillShellToolResultMessage.js +3 -0
  304. package/dist/tools/KillShellTool/KillShellToolResultMessage.js.map +2 -2
  305. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js +109 -0
  306. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +7 -0
  307. package/dist/tools/ListMcpResourcesTool/prompt.js +19 -0
  308. package/dist/tools/ListMcpResourcesTool/prompt.js.map +7 -0
  309. package/dist/tools/LspTool/LspTool.js +664 -0
  310. package/dist/tools/LspTool/LspTool.js.map +7 -0
  311. package/dist/tools/LspTool/prompt.js +27 -0
  312. package/dist/tools/LspTool/prompt.js.map +7 -0
  313. package/dist/tools/MCPTool/MCPTool.js +9 -1
  314. package/dist/tools/MCPTool/MCPTool.js.map +2 -2
  315. package/dist/tools/MemoryReadTool/MemoryReadTool.js +19 -6
  316. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  317. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +6 -6
  318. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  319. package/dist/tools/MultiEditTool/MultiEditTool.js +19 -2
  320. package/dist/tools/MultiEditTool/MultiEditTool.js.map +2 -2
  321. package/dist/tools/NotebookEditTool/NotebookEditTool.js +5 -1
  322. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +2 -2
  323. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +2 -2
  324. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +74 -0
  325. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +7 -0
  326. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +108 -0
  327. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +7 -0
  328. package/dist/tools/PlanModeTool/prompt.js +94 -0
  329. package/dist/tools/PlanModeTool/prompt.js.map +7 -0
  330. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js +130 -0
  331. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +7 -0
  332. package/dist/tools/ReadMcpResourceTool/prompt.js +17 -0
  333. package/dist/tools/ReadMcpResourceTool/prompt.js.map +7 -0
  334. package/dist/tools/SkillTool/SkillTool.js +6 -1
  335. package/dist/tools/SkillTool/SkillTool.js.map +2 -2
  336. package/dist/tools/SlashCommandTool/SlashCommandTool.js +260 -0
  337. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +7 -0
  338. package/dist/tools/SlashCommandTool/prompt.js +35 -0
  339. package/dist/tools/SlashCommandTool/prompt.js.map +7 -0
  340. package/dist/tools/TaskOutputTool/TaskOutputTool.js +189 -0
  341. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +7 -0
  342. package/dist/tools/TaskOutputTool/prompt.js +15 -0
  343. package/dist/tools/TaskOutputTool/prompt.js.map +7 -0
  344. package/dist/tools/TaskTool/TaskTool.js +302 -104
  345. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  346. package/dist/tools/TaskTool/prompt.js.map +2 -2
  347. package/dist/tools/TodoWriteTool/TodoWriteTool.js +42 -77
  348. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +2 -2
  349. package/dist/tools/URLFetcherTool/URLFetcherTool.js +4 -1
  350. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +2 -2
  351. package/dist/tools/URLFetcherTool/cache.js +55 -8
  352. package/dist/tools/URLFetcherTool/cache.js.map +2 -2
  353. package/dist/tools.js +31 -2
  354. package/dist/tools.js.map +2 -2
  355. package/dist/types/hooks.js +4 -0
  356. package/dist/types/hooks.js.map +2 -2
  357. package/dist/types/marketplace.js.map +2 -2
  358. package/dist/types/messageGroup.js +36 -0
  359. package/dist/types/messageGroup.js.map +7 -0
  360. package/dist/types/plugin.js.map +2 -2
  361. package/dist/types/thinking.js +1 -0
  362. package/dist/types/thinking.js.map +7 -0
  363. package/dist/utils/BackgroundShellManager.js +136 -39
  364. package/dist/utils/BackgroundShellManager.js.map +2 -2
  365. package/dist/utils/MessageBatchBuffer.js +102 -0
  366. package/dist/utils/MessageBatchBuffer.js.map +7 -0
  367. package/dist/utils/PersistentShell.js +151 -1
  368. package/dist/utils/PersistentShell.js.map +2 -2
  369. package/dist/utils/agentLoader.js +1 -23
  370. package/dist/utils/agentLoader.js.map +2 -2
  371. package/dist/utils/agentTranscripts.js +641 -0
  372. package/dist/utils/agentTranscripts.js.map +7 -0
  373. package/dist/utils/animationManager.js +213 -0
  374. package/dist/utils/animationManager.js.map +7 -0
  375. package/dist/utils/animationSync.js +110 -0
  376. package/dist/utils/animationSync.js.map +7 -0
  377. package/dist/utils/asyncFile.js +215 -0
  378. package/dist/utils/asyncFile.js.map +7 -0
  379. package/dist/utils/backgroundAgentManager.js +231 -0
  380. package/dist/utils/backgroundAgentManager.js.map +7 -0
  381. package/dist/utils/config.js +63 -7
  382. package/dist/utils/config.js.map +2 -2
  383. package/dist/utils/conversationRecovery.js +19 -0
  384. package/dist/utils/conversationRecovery.js.map +2 -2
  385. package/dist/utils/exit.js +73 -0
  386. package/dist/utils/exit.js.map +7 -0
  387. package/dist/utils/format.js +73 -5
  388. package/dist/utils/format.js.map +2 -2
  389. package/dist/utils/generators.js +76 -6
  390. package/dist/utils/generators.js.map +2 -2
  391. package/dist/utils/globalErrorHandler.js +149 -0
  392. package/dist/utils/globalErrorHandler.js.map +7 -0
  393. package/dist/utils/groupHandlers/index.js +8 -0
  394. package/dist/utils/groupHandlers/index.js.map +7 -0
  395. package/dist/utils/groupHandlers/parallelTasksHandler.js +140 -0
  396. package/dist/utils/groupHandlers/parallelTasksHandler.js.map +7 -0
  397. package/dist/utils/groupHandlers/taskHandler.js +104 -0
  398. package/dist/utils/groupHandlers/taskHandler.js.map +7 -0
  399. package/dist/utils/groupHandlers/types.js +1 -0
  400. package/dist/utils/groupHandlers/types.js.map +7 -0
  401. package/dist/utils/logRotation.js +224 -0
  402. package/dist/utils/logRotation.js.map +7 -0
  403. package/dist/utils/marketplaceManager.js +3 -5
  404. package/dist/utils/marketplaceManager.js.map +2 -2
  405. package/dist/utils/memSafety.js +264 -0
  406. package/dist/utils/memSafety.js.map +7 -0
  407. package/dist/utils/messageGroupManager.js +274 -0
  408. package/dist/utils/messageGroupManager.js.map +7 -0
  409. package/dist/utils/messages.js +13 -4
  410. package/dist/utils/messages.js.map +2 -2
  411. package/dist/utils/model.js +119 -15
  412. package/dist/utils/model.js.map +3 -3
  413. package/dist/utils/permissions/filesystem.js +157 -5
  414. package/dist/utils/permissions/filesystem.js.map +2 -2
  415. package/dist/utils/plan/planMode.js +143 -0
  416. package/dist/utils/plan/planMode.js.map +7 -0
  417. package/dist/utils/pluginLoader.js +17 -21
  418. package/dist/utils/pluginLoader.js.map +2 -2
  419. package/dist/utils/ripgrep.js +55 -2
  420. package/dist/utils/ripgrep.js.map +2 -2
  421. package/dist/utils/sanitizeInput.js +32 -0
  422. package/dist/utils/sanitizeInput.js.map +7 -0
  423. package/dist/utils/secureKeyStorage.js +312 -0
  424. package/dist/utils/secureKeyStorage.js.map +7 -0
  425. package/dist/utils/session/sessionPlugins.js +67 -0
  426. package/dist/utils/session/sessionPlugins.js.map +7 -0
  427. package/dist/utils/taskDisplayUtils.js +257 -0
  428. package/dist/utils/taskDisplayUtils.js.map +7 -0
  429. package/dist/utils/teamConfig.js +2 -1
  430. package/dist/utils/teamConfig.js.map +2 -2
  431. package/dist/utils/todoStorage.js +92 -2
  432. package/dist/utils/todoStorage.js.map +2 -2
  433. package/dist/utils/toolTimeout.js +136 -0
  434. package/dist/utils/toolTimeout.js.map +7 -0
  435. package/dist/utils/tooling/safeRender.js +115 -0
  436. package/dist/utils/tooling/safeRender.js.map +7 -0
  437. package/dist/utils/userFriendlyError.js +346 -0
  438. package/dist/utils/userFriendlyError.js.map +7 -0
  439. package/dist/utils/vendor/ripgrep/arm64-darwin/rg +0 -0
  440. package/dist/version.js +2 -2
  441. package/dist/version.js.map +1 -1
  442. package/package.json +14 -4
  443. package/scripts/postinstall.js +128 -38
  444. package/dist/commands/agents.js +0 -2086
  445. package/dist/commands/agents.js.map +0 -7
  446. package/dist/commands/build.js +0 -74
  447. package/dist/commands/build.js.map +0 -7
  448. package/dist/commands/compression.js +0 -57
  449. package/dist/commands/compression.js.map +0 -7
  450. package/dist/commands/listen.js +0 -37
  451. package/dist/commands/listen.js.map +0 -7
  452. package/dist/commands/login.js +0 -37
  453. package/dist/commands/login.js.map +0 -7
  454. package/dist/commands/logout.js +0 -33
  455. package/dist/commands/logout.js.map +0 -7
  456. package/dist/commands/mcp.js +0 -40
  457. package/dist/commands/mcp.js.map +0 -7
  458. package/dist/commands/mcp_refresh.js +0 -40
  459. package/dist/commands/mcp_refresh.js.map +0 -7
  460. package/dist/commands/modelstatus.js +0 -21
  461. package/dist/commands/modelstatus.js.map +0 -7
  462. package/dist/commands/onboarding.js +0 -36
  463. package/dist/commands/onboarding.js.map +0 -7
  464. package/dist/commands/plugin-interactive.js +0 -446
  465. package/dist/commands/plugin-interactive.js.map +0 -7
  466. package/dist/commands/pr_comments.js +0 -61
  467. package/dist/commands/pr_comments.js.map +0 -7
  468. package/dist/commands/release-notes.js +0 -30
  469. package/dist/commands/release-notes.js.map +0 -7
  470. package/dist/commands/review.js +0 -51
  471. package/dist/commands/review.js.map +0 -7
  472. package/dist/components/Bug.js +0 -147
  473. package/dist/components/Bug.js.map +0 -7
  474. package/dist/components/ModelSelector.js +0 -2062
  475. package/dist/components/ModelSelector.js.map +0 -7
  476. package/dist/components/ModelStatusDisplay.js +0 -87
  477. package/dist/components/ModelStatusDisplay.js.map +0 -7
  478. package/dist/entrypoints/cli-wrapper.js +0 -61
  479. package/dist/entrypoints/cli-wrapper.js.map +0 -7
  480. package/dist/screens/Doctor.js +0 -22
  481. package/dist/screens/Doctor.js.map +0 -7
@@ -0,0 +1,291 @@
1
+ import { isSensitivePath, getSensitivePathInfo } from "./sensitivePathsRule.js";
2
+ import {
3
+ isOutsideProject,
4
+ calculateExternalOperationRisk
5
+ } from "./projectBoundaryRule.js";
6
+ import { logSecurityEvent } from "../auditLog.js";
7
+ const ESCALATION_PATTERNS = [
8
+ // Privilege escalation
9
+ {
10
+ pattern: /\bsudo\s+/,
11
+ reason: "privilege_escalation",
12
+ description: "sudo command"
13
+ },
14
+ {
15
+ pattern: /\bsu\s+(-|\w)/,
16
+ reason: "privilege_escalation",
17
+ description: "su command"
18
+ },
19
+ {
20
+ pattern: /\bchmod\s+[0-7]*[4-7][0-7]*\s/,
21
+ reason: "privilege_escalation",
22
+ description: "chmod with execute permissions"
23
+ },
24
+ {
25
+ pattern: /\bchown\s+/,
26
+ reason: "privilege_escalation",
27
+ description: "chown command"
28
+ },
29
+ // Dangerous file operations
30
+ {
31
+ pattern: /\brm\s+(-r|-rf|-fr)\s+/,
32
+ reason: "dangerous_command",
33
+ description: "recursive delete"
34
+ },
35
+ {
36
+ pattern: /\bdd\s+.*if=/,
37
+ reason: "dangerous_command",
38
+ description: "dd command"
39
+ },
40
+ {
41
+ pattern: /\bmkfs\b/,
42
+ reason: "dangerous_command",
43
+ description: "filesystem creation"
44
+ },
45
+ {
46
+ pattern: />\s*\/dev\/(sd|hd|nvme)/,
47
+ reason: "dangerous_command",
48
+ description: "write to disk device"
49
+ },
50
+ // Network access (potential data exfiltration)
51
+ {
52
+ pattern: /\bcurl\s+.*(-d|--data|-F|--form)/,
53
+ reason: "network_access",
54
+ description: "curl with data upload"
55
+ },
56
+ {
57
+ pattern: /\bwget\s+--post/,
58
+ reason: "network_access",
59
+ description: "wget with POST"
60
+ },
61
+ {
62
+ pattern: /\bnc\s+/,
63
+ reason: "network_access",
64
+ description: "netcat"
65
+ },
66
+ {
67
+ pattern: /\bssh\s+/,
68
+ reason: "network_access",
69
+ description: "SSH connection"
70
+ },
71
+ {
72
+ pattern: /\bscp\s+/,
73
+ reason: "network_access",
74
+ description: "SCP file transfer"
75
+ },
76
+ {
77
+ pattern: /\brsync\s+.*:/,
78
+ reason: "network_access",
79
+ description: "rsync to remote"
80
+ },
81
+ // Bulk operations
82
+ {
83
+ pattern: /\bfind\s+.*-exec.*\brm\b/,
84
+ reason: "bulk_operation",
85
+ description: "find with delete"
86
+ },
87
+ {
88
+ pattern: /\bxargs\s+.*\brm\b/,
89
+ reason: "bulk_operation",
90
+ description: "xargs with delete"
91
+ },
92
+ // Shell/script execution (potential for hidden actions)
93
+ {
94
+ pattern: /\beval\s+/,
95
+ reason: "dangerous_command",
96
+ description: "eval command"
97
+ },
98
+ {
99
+ pattern: /\bsource\s+/,
100
+ reason: "dangerous_command",
101
+ description: "source command"
102
+ },
103
+ {
104
+ pattern: /\.\s+\//,
105
+ reason: "dangerous_command",
106
+ description: "dot source"
107
+ }
108
+ ];
109
+ function matchesEscalationPattern(command) {
110
+ for (const { pattern, reason, description } of ESCALATION_PATTERNS) {
111
+ if (pattern.test(command)) {
112
+ return { reason, description };
113
+ }
114
+ }
115
+ return null;
116
+ }
117
+ function getOperationType(toolName, input) {
118
+ switch (toolName) {
119
+ case "Read":
120
+ case "FileRead":
121
+ case "Glob":
122
+ case "Grep":
123
+ return "read";
124
+ case "Write":
125
+ case "FileWrite":
126
+ case "Edit":
127
+ case "FileEdit":
128
+ case "MultiEdit":
129
+ case "NotebookEdit":
130
+ return "write";
131
+ case "Bash": {
132
+ const command = input.command || "";
133
+ if (/\b(rm|del|rmdir|unlink)\b/.test(command)) {
134
+ return "delete";
135
+ }
136
+ return "execute";
137
+ }
138
+ default:
139
+ return null;
140
+ }
141
+ }
142
+ function extractFilePath(input) {
143
+ if (input.file_path) return input.file_path;
144
+ if (input.filePath) return input.filePath;
145
+ if (input.path) return input.path;
146
+ return null;
147
+ }
148
+ const ESCALATION_MESSAGES = {
149
+ sensitive_path: "\u{1F510} This operation accesses sensitive files",
150
+ critical_external: "\u{1F6A8} This operation affects files far outside your project",
151
+ dangerous_command: "\u26A0\uFE0F This command is potentially destructive",
152
+ bulk_operation: "\u{1F4E6} This operation affects multiple files",
153
+ privilege_escalation: "\u{1F511} This command may escalate system privileges",
154
+ network_access: "\u{1F310} This command accesses the network"
155
+ };
156
+ const autoEscalationRule = {
157
+ name: "auto-escalation",
158
+ description: "Requires confirmation for high-risk operations",
159
+ priority: 85,
160
+ // Below sensitive-paths and project-boundary, but above safe-mode
161
+ check(context) {
162
+ const toolName = context.tool.name;
163
+ const input = context.input;
164
+ if (toolName === "Bash") {
165
+ const command = input.command || "";
166
+ const match = matchesEscalationPattern(command);
167
+ if (match) {
168
+ logSecurityEvent({
169
+ eventType: "security_warning",
170
+ toolName,
171
+ operation: "execute",
172
+ target: command,
173
+ outcome: "denied",
174
+ // Will be 'allowed' if user approves
175
+ riskLevel: "high",
176
+ context: {
177
+ escalationReason: match.reason,
178
+ escalationDescription: match.description
179
+ },
180
+ triggeredRule: "auto-escalation"
181
+ });
182
+ return {
183
+ allowed: false,
184
+ promptUser: true,
185
+ reason: `High-risk operation: ${match.description}`,
186
+ message: `${ESCALATION_MESSAGES[match.reason]}
187
+
188
+ Command: ${command.length > 100 ? command.substring(0, 100) + "..." : command}
189
+
190
+ Reason: ${match.description}`,
191
+ permissionKey: `AutoEscalate(${match.reason}:${command.substring(0, 50)})`
192
+ };
193
+ }
194
+ }
195
+ const operation = getOperationType(toolName, input);
196
+ if (operation && operation !== "read") {
197
+ const filePath = extractFilePath(input);
198
+ if (filePath) {
199
+ if (isSensitivePath(filePath, operation)) {
200
+ const info = getSensitivePathInfo(filePath);
201
+ logSecurityEvent({
202
+ eventType: "sensitive_path_access",
203
+ toolName,
204
+ operation,
205
+ target: filePath,
206
+ outcome: "denied",
207
+ riskLevel: "high",
208
+ context: {
209
+ category: info?.category,
210
+ description: info?.description
211
+ },
212
+ triggeredRule: "auto-escalation"
213
+ });
214
+ return {
215
+ allowed: false,
216
+ promptUser: true,
217
+ reason: `Sensitive path: ${info?.description || "unknown"}`,
218
+ message: `${ESCALATION_MESSAGES.sensitive_path}
219
+
220
+ Path: ${filePath}
221
+ Category: ${info?.category || "unknown"}`,
222
+ permissionKey: `AutoEscalate(sensitive:${filePath})`
223
+ };
224
+ }
225
+ if (isOutsideProject(filePath)) {
226
+ const risk = calculateExternalOperationRisk(operation, filePath);
227
+ if (risk === "critical" || risk === "high") {
228
+ logSecurityEvent({
229
+ eventType: "external_operation",
230
+ toolName,
231
+ operation,
232
+ target: filePath,
233
+ outcome: "denied",
234
+ riskLevel: risk,
235
+ triggeredRule: "auto-escalation"
236
+ });
237
+ return {
238
+ allowed: false,
239
+ promptUser: true,
240
+ reason: `${risk} risk external operation`,
241
+ message: `${ESCALATION_MESSAGES.critical_external}
242
+
243
+ Path: ${filePath}
244
+ Risk Level: ${risk.toUpperCase()}`,
245
+ permissionKey: `AutoEscalate(external:${filePath})`
246
+ };
247
+ }
248
+ }
249
+ }
250
+ }
251
+ return { allowed: true };
252
+ }
253
+ };
254
+ function shouldAutoEscalate(toolName, input) {
255
+ if (toolName === "Bash") {
256
+ const command = input.command || "";
257
+ const match = matchesEscalationPattern(command);
258
+ if (match) {
259
+ return { shouldEscalate: true, ...match };
260
+ }
261
+ }
262
+ const filePath = extractFilePath(input);
263
+ if (filePath) {
264
+ const operation = getOperationType(toolName, input);
265
+ if (operation && operation !== "read") {
266
+ if (isSensitivePath(filePath, operation)) {
267
+ return {
268
+ shouldEscalate: true,
269
+ reason: "sensitive_path",
270
+ description: "Sensitive file access"
271
+ };
272
+ }
273
+ if (isOutsideProject(filePath)) {
274
+ const risk = calculateExternalOperationRisk(operation, filePath);
275
+ if (risk === "critical" || risk === "high") {
276
+ return {
277
+ shouldEscalate: true,
278
+ reason: "critical_external",
279
+ description: `${risk} risk external operation`
280
+ };
281
+ }
282
+ }
283
+ }
284
+ }
285
+ return { shouldEscalate: false };
286
+ }
287
+ export {
288
+ autoEscalationRule,
289
+ shouldAutoEscalate
290
+ };
291
+ //# sourceMappingURL=autoEscalationRule.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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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",
6
+ "names": []
7
+ }
@@ -0,0 +1,46 @@
1
+ export * from "./planModeRule.js";
2
+ export * from "./safeModeRule.js";
3
+ export * from "./allowedToolsRule.js";
4
+ export * from "./sensitivePathsRule.js";
5
+ export * from "./projectBoundaryRule.js";
6
+ export * from "./autoEscalationRule.js";
7
+ import { planModeRule } from "./planModeRule.js";
8
+ import { safeModeRule } from "./safeModeRule.js";
9
+ import { allowedToolsRule } from "./allowedToolsRule.js";
10
+ import { sensitivePathsRule } from "./sensitivePathsRule.js";
11
+ import { projectBoundaryRule } from "./projectBoundaryRule.js";
12
+ import { autoEscalationRule } from "./autoEscalationRule.js";
13
+ const builtInRules = [
14
+ sensitivePathsRule,
15
+ // Priority 100 - Sensitive paths always checked first
16
+ projectBoundaryRule,
17
+ // Priority 95 - External operations
18
+ planModeRule,
19
+ // Priority 95 - Plan mode restrictions
20
+ safeModeRule,
21
+ // Priority 90 - Safe mode restrictions
22
+ autoEscalationRule,
23
+ // Priority 85 - Auto-escalation for high-risk ops
24
+ allowedToolsRule
25
+ // Priority 50 - Standard tool permissions
26
+ ];
27
+ const securityRules = [
28
+ sensitivePathsRule,
29
+ projectBoundaryRule,
30
+ autoEscalationRule
31
+ ];
32
+ const modeRules = [planModeRule, safeModeRule];
33
+ function registerBuiltInRules(engine) {
34
+ engine.registerRules(builtInRules);
35
+ }
36
+ function registerSecurityRules(engine) {
37
+ engine.registerRules(securityRules);
38
+ }
39
+ export {
40
+ builtInRules,
41
+ modeRules,
42
+ registerBuiltInRules,
43
+ registerSecurityRules,
44
+ securityRules
45
+ };
46
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/core/permissions/rules/index.ts"],
4
+ "sourcesContent": ["/**\n * Permission Rules Index\n *\n * Export all built-in permission rules.\n * Rules are sorted by priority (highest first):\n * - sensitivePathsRule: 100 (highest - always checked first)\n * - projectBoundaryRule: 95\n * - planModeRule: 95 (same level as project boundary)\n * - safeModeRule: 90\n * - autoEscalationRule: 85\n * - allowedToolsRule: 50 (lowest - checked last)\n */\n\nexport * from './planModeRule'\nexport * from './safeModeRule'\nexport * from './allowedToolsRule'\nexport * from './sensitivePathsRule'\nexport * from './projectBoundaryRule'\nexport * from './autoEscalationRule'\n\nimport { planModeRule } from './planModeRule'\nimport { safeModeRule } from './safeModeRule'\nimport { allowedToolsRule } from './allowedToolsRule'\nimport { sensitivePathsRule } from './sensitivePathsRule'\nimport { projectBoundaryRule } from './projectBoundaryRule'\nimport { autoEscalationRule } from './autoEscalationRule'\nimport type { PermissionRule } from '../engine/types'\n\n/**\n * All built-in permission rules in priority order (highest first)\n */\nexport const builtInRules: PermissionRule[] = [\n sensitivePathsRule, // Priority 100 - Sensitive paths always checked first\n projectBoundaryRule, // Priority 95 - External operations\n planModeRule, // Priority 95 - Plan mode restrictions\n safeModeRule, // Priority 90 - Safe mode restrictions\n autoEscalationRule, // Priority 85 - Auto-escalation for high-risk ops\n allowedToolsRule, // Priority 50 - Standard tool permissions\n]\n\n/**\n * Security-focused rules (high priority)\n */\nexport const securityRules: PermissionRule[] = [\n sensitivePathsRule,\n projectBoundaryRule,\n autoEscalationRule,\n]\n\n/**\n * Mode-based rules\n */\nexport const modeRules: PermissionRule[] = [planModeRule, safeModeRule]\n\n/**\n * Register all built-in rules with an engine\n */\nexport function registerBuiltInRules(engine: {\n registerRules: (rules: PermissionRule[]) => void\n}): void {\n engine.registerRules(builtInRules)\n}\n\n/**\n * Register only security rules with an engine\n */\nexport function registerSecurityRules(engine: {\n registerRules: (rules: PermissionRule[]) => void\n}): void {\n engine.registerRules(securityRules)\n}\n"],
5
+ "mappings": "AAaA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAEd,SAAS,oBAAoB;AAC7B,SAAS,oBAAoB;AAC7B,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AAM5B,MAAM,eAAiC;AAAA,EAC5C;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AACF;AAKO,MAAM,gBAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF;AAKO,MAAM,YAA8B,CAAC,cAAc,YAAY;AAK/D,SAAS,qBAAqB,QAE5B;AACP,SAAO,cAAc,YAAY;AACnC;AAKO,SAAS,sBAAsB,QAE7B;AACP,SAAO,cAAc,aAAa;AACpC;",
6
+ "names": []
7
+ }
@@ -0,0 +1,55 @@
1
+ const WRITE_TOOLS = /* @__PURE__ */ new Set([
2
+ "Edit",
3
+ "Write",
4
+ "MultiEdit",
5
+ "NotebookEdit",
6
+ "Bash"
7
+ // May write files
8
+ ]);
9
+ const READ_ONLY_TOOLS = /* @__PURE__ */ new Set([
10
+ "Read",
11
+ "Glob",
12
+ "Grep",
13
+ "LS",
14
+ "LSP",
15
+ "WebSearch",
16
+ "WebFetch",
17
+ "Task",
18
+ // Can spawn read-only agents
19
+ "TodoWrite",
20
+ // Planning notes
21
+ "AskUserQuestion",
22
+ "EnterPlanMode",
23
+ "ExitPlanMode"
24
+ ]);
25
+ const planModeRule = {
26
+ name: "plan-mode",
27
+ description: "Restricts write operations in plan mode",
28
+ priority: 100,
29
+ // High priority
30
+ check(context) {
31
+ if (!context.planMode) {
32
+ return { allowed: true };
33
+ }
34
+ const toolName = context.tool.name;
35
+ if (READ_ONLY_TOOLS.has(toolName)) {
36
+ return { allowed: true };
37
+ }
38
+ if (WRITE_TOOLS.has(toolName)) {
39
+ return {
40
+ allowed: false,
41
+ reason: `Tool ${toolName} is not allowed in plan mode. Only read-only operations are permitted.`,
42
+ message: "Cannot modify files while in plan mode. Use ExitPlanMode to implement changes."
43
+ };
44
+ }
45
+ if (context.tool.isReadOnly && context.tool.isReadOnly()) {
46
+ return { allowed: true };
47
+ }
48
+ console.warn(`Unknown tool ${toolName} used in plan mode`);
49
+ return { allowed: true };
50
+ }
51
+ };
52
+ export {
53
+ planModeRule
54
+ };
55
+ //# sourceMappingURL=planModeRule.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/core/permissions/rules/planModeRule.ts"],
4
+ "sourcesContent": ["/**\n * Plan Mode Permission Rule\n *\n * Restricts write operations when in plan mode.\n */\n\nimport type {\n PermissionRule,\n PermissionContext,\n PermissionResult,\n} from '../engine/types'\n\n/**\n * Tools that modify state (not allowed in plan mode)\n */\nconst WRITE_TOOLS = new Set([\n 'Edit',\n 'Write',\n 'MultiEdit',\n 'NotebookEdit',\n 'Bash', // May write files\n])\n\n/**\n * Read-only tools (always allowed in plan mode)\n */\nconst READ_ONLY_TOOLS = new Set([\n 'Read',\n 'Glob',\n 'Grep',\n 'LS',\n 'LSP',\n 'WebSearch',\n 'WebFetch',\n 'Task', // Can spawn read-only agents\n 'TodoWrite', // Planning notes\n 'AskUserQuestion',\n 'EnterPlanMode',\n 'ExitPlanMode',\n])\n\n/**\n * Plan Mode Rule\n *\n * When in plan mode, only allow read-only operations.\n */\nexport const planModeRule: PermissionRule = {\n name: 'plan-mode',\n description: 'Restricts write operations in plan mode',\n priority: 100, // High priority\n\n check(context: PermissionContext): PermissionResult {\n // Skip if not in plan mode\n if (!context.planMode) {\n return { allowed: true }\n }\n\n const toolName = context.tool.name\n\n // Always allow read-only tools\n if (READ_ONLY_TOOLS.has(toolName)) {\n return { allowed: true }\n }\n\n // Block write tools in plan mode\n if (WRITE_TOOLS.has(toolName)) {\n return {\n allowed: false,\n reason: `Tool ${toolName} is not allowed in plan mode. Only read-only operations are permitted.`,\n message:\n 'Cannot modify files while in plan mode. Use ExitPlanMode to implement changes.',\n }\n }\n\n // Check if tool explicitly declares read-only\n if (context.tool.isReadOnly && context.tool.isReadOnly()) {\n return { allowed: true }\n }\n\n // Default: allow unknown tools but log warning\n console.warn(`Unknown tool ${toolName} used in plan mode`)\n return { allowed: true }\n },\n}\n"],
5
+ "mappings": "AAeA,MAAM,cAAc,oBAAI,IAAI;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AACF,CAAC;AAKD,MAAM,kBAAkB,oBAAI,IAAI;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EACA;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAOM,MAAM,eAA+B;AAAA,EAC1C,MAAM;AAAA,EACN,aAAa;AAAA,EACb,UAAU;AAAA;AAAA,EAEV,MAAM,SAA8C;AAElD,QAAI,CAAC,QAAQ,UAAU;AACrB,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAEA,UAAM,WAAW,QAAQ,KAAK;AAG9B,QAAI,gBAAgB,IAAI,QAAQ,GAAG;AACjC,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAGA,QAAI,YAAY,IAAI,QAAQ,GAAG;AAC7B,aAAO;AAAA,QACL,SAAS;AAAA,QACT,QAAQ,QAAQ,QAAQ;AAAA,QACxB,SACE;AAAA,MACJ;AAAA,IACF;AAGA,QAAI,QAAQ,KAAK,cAAc,QAAQ,KAAK,WAAW,GAAG;AACxD,aAAO,EAAE,SAAS,KAAK;AAAA,IACzB;AAGA,YAAQ,KAAK,gBAAgB,QAAQ,oBAAoB;AACzD,WAAO,EAAE,SAAS,KAAK;AAAA,EACzB;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,168 @@
1
+ import { resolve, relative, isAbsolute } from "path";
2
+ import { getOriginalCwd } from "../../../utils/state.js";
3
+ function isOutsideProject(filePath) {
4
+ const projectDir = getOriginalCwd();
5
+ const absolutePath = isAbsolute(filePath) ? resolve(filePath) : resolve(projectDir, filePath);
6
+ const relativePath = relative(projectDir, absolutePath);
7
+ return relativePath.startsWith("..") || isAbsolute(relativePath);
8
+ }
9
+ function getRelativeFromProject(filePath) {
10
+ const projectDir = getOriginalCwd();
11
+ const absolutePath = isAbsolute(filePath) ? resolve(filePath) : resolve(projectDir, filePath);
12
+ return relative(projectDir, absolutePath);
13
+ }
14
+ function calculateExternalOperationRisk(operation, filePath) {
15
+ const relativePath = getRelativeFromProject(filePath);
16
+ const levelsUp = (relativePath.match(/\.\./g) || []).length;
17
+ if (levelsUp > 3 || filePath.startsWith("/etc") || filePath.startsWith("/usr")) {
18
+ return "critical";
19
+ }
20
+ if (operation === "delete" || levelsUp >= 2) {
21
+ return "high";
22
+ }
23
+ if (operation === "write" && levelsUp >= 1) {
24
+ return "medium";
25
+ }
26
+ return "low";
27
+ }
28
+ function getOperationType(toolName, input) {
29
+ switch (toolName) {
30
+ case "Read":
31
+ case "FileRead":
32
+ case "Glob":
33
+ case "Grep":
34
+ return "read";
35
+ case "Write":
36
+ case "FileWrite":
37
+ case "Edit":
38
+ case "FileEdit":
39
+ case "MultiEdit":
40
+ case "NotebookEdit":
41
+ return "write";
42
+ case "Bash": {
43
+ const command = input.command || "";
44
+ if (/\b(rm|del|rmdir|unlink)\b/.test(command)) {
45
+ return "delete";
46
+ }
47
+ if (/\b(mv|cp|touch|mkdir|echo\s+.*>|cat\s+.*>|tee)\b/.test(command)) {
48
+ return "write";
49
+ }
50
+ if (/\b(cat|head|tail|less|more|grep|find|ls)\b/.test(command)) {
51
+ return "read";
52
+ }
53
+ return "execute";
54
+ }
55
+ default:
56
+ return null;
57
+ }
58
+ }
59
+ function extractFilePaths(toolName, input) {
60
+ const paths = [];
61
+ if (input.file_path) paths.push(input.file_path);
62
+ if (input.filePath) paths.push(input.filePath);
63
+ if (input.path) paths.push(input.path);
64
+ if (toolName === "Bash") {
65
+ const command = input.command || "";
66
+ const pathMatches = command.matchAll(
67
+ /(?:cat|rm|mv|cp|head|tail|less|more|touch|mkdir|rmdir|>\s*)\s*["']?([^\s"'|&;><]+)/g
68
+ );
69
+ for (const match of pathMatches) {
70
+ if (match[1] && !match[1].startsWith("-")) {
71
+ paths.push(match[1]);
72
+ }
73
+ }
74
+ }
75
+ return paths;
76
+ }
77
+ const RISK_MESSAGES = {
78
+ low: "\u{1F4C1} This file is outside your project directory.",
79
+ medium: "\u26A0\uFE0F This operation modifies a file outside your project.",
80
+ high: "\u{1F536} High-risk operation: This file is significantly outside your project boundary.",
81
+ critical: "\u{1F6A8} Critical: This operation affects system or deeply external files!"
82
+ };
83
+ const projectBoundaryRule = {
84
+ name: "project-boundary",
85
+ description: "Requires confirmation for write/delete operations outside project directory",
86
+ priority: 95,
87
+ // High priority, but below sensitive paths
88
+ check(context) {
89
+ const toolName = context.tool.name;
90
+ const input = context.input;
91
+ const operation = getOperationType(toolName, input);
92
+ if (!operation) {
93
+ return { allowed: true };
94
+ }
95
+ if (operation === "read") {
96
+ return { allowed: true };
97
+ }
98
+ const filePaths = extractFilePaths(toolName, input);
99
+ if (filePaths.length === 0) {
100
+ return { allowed: true };
101
+ }
102
+ const externalPaths = [];
103
+ for (const filePath of filePaths) {
104
+ if (isOutsideProject(filePath)) {
105
+ const relativePath = getRelativeFromProject(filePath);
106
+ const risk = calculateExternalOperationRisk(operation, filePath);
107
+ externalPaths.push({ path: filePath, relativePath, risk });
108
+ }
109
+ }
110
+ if (externalPaths.length === 0) {
111
+ return { allowed: true };
112
+ }
113
+ const riskOrder = [
114
+ "low",
115
+ "medium",
116
+ "high",
117
+ "critical"
118
+ ];
119
+ const highestRisk = externalPaths.reduce((max, curr) => {
120
+ return riskOrder.indexOf(curr.risk) > riskOrder.indexOf(max) ? curr.risk : max;
121
+ }, "low");
122
+ if (highestRisk === "critical") {
123
+ return {
124
+ allowed: false,
125
+ reason: "Critical external operation blocked",
126
+ message: `${RISK_MESSAGES.critical}
127
+
128
+ Paths:
129
+ ${externalPaths.map((p) => ` \u2022 ${p.relativePath}`).join("\n")}
130
+
131
+ This operation is too risky to allow. Please reconsider.`
132
+ };
133
+ }
134
+ const projectDir = getOriginalCwd();
135
+ const pathList = externalPaths.map((p) => ` \u2022 ${p.relativePath} (${p.risk} risk)`).join("\n");
136
+ return {
137
+ allowed: false,
138
+ promptUser: true,
139
+ reason: "External operation requires confirmation",
140
+ message: `${RISK_MESSAGES[highestRisk]}
141
+
142
+ Project: ${projectDir}
143
+
144
+ External paths:
145
+ ${pathList}
146
+
147
+ Operation: ${operation}`,
148
+ permissionKey: `ExternalOp(${operation}:${externalPaths.map((p) => p.path).join(",")})`
149
+ };
150
+ }
151
+ };
152
+ function isExternalOperation(filePath, operation) {
153
+ if (!isOutsideProject(filePath)) {
154
+ return { isExternal: false, risk: null };
155
+ }
156
+ return {
157
+ isExternal: true,
158
+ risk: calculateExternalOperationRisk(operation, filePath)
159
+ };
160
+ }
161
+ export {
162
+ calculateExternalOperationRisk,
163
+ getRelativeFromProject,
164
+ isExternalOperation,
165
+ isOutsideProject,
166
+ projectBoundaryRule
167
+ };
168
+ //# sourceMappingURL=projectBoundaryRule.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 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": "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",
6
+ "names": []
7
+ }