@travisennis/acai 0.0.9 → 0.0.11

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 (403) hide show
  1. package/README.md +51 -760
  2. package/bin/acai +52 -0
  3. package/dist/agent/index.d.ts +12 -2
  4. package/dist/agent/index.d.ts.map +1 -1
  5. package/dist/agent/index.js +380 -199
  6. package/dist/agent/sub-agent.d.ts +23 -0
  7. package/dist/agent/sub-agent.d.ts.map +1 -0
  8. package/dist/agent/sub-agent.js +109 -0
  9. package/dist/cli/index.d.ts +26 -0
  10. package/dist/cli/index.d.ts.map +1 -0
  11. package/dist/{cli.js → cli/index.js} +84 -77
  12. package/dist/{stdin.d.ts → cli/stdin.d.ts} +2 -1
  13. package/dist/cli/stdin.d.ts.map +1 -0
  14. package/dist/{stdin.js → cli/stdin.js} +11 -0
  15. package/dist/commands/copy/index.js +2 -2
  16. package/dist/commands/copy/utils.d.ts.map +1 -1
  17. package/dist/commands/copy/utils.js +15 -13
  18. package/dist/commands/generate-rules/index.d.ts +1 -1
  19. package/dist/commands/generate-rules/index.d.ts.map +1 -1
  20. package/dist/commands/generate-rules/index.js +16 -101
  21. package/dist/commands/generate-rules/service.d.ts +22 -0
  22. package/dist/commands/generate-rules/service.d.ts.map +1 -0
  23. package/dist/commands/generate-rules/service.js +103 -0
  24. package/dist/commands/handoff/index.js +2 -2
  25. package/dist/commands/health/index.js +1 -1
  26. package/dist/commands/health/utils.d.ts +3 -2
  27. package/dist/commands/health/utils.d.ts.map +1 -1
  28. package/dist/commands/health/utils.js +6 -0
  29. package/dist/commands/history/index.d.ts +1 -1
  30. package/dist/commands/history/index.d.ts.map +1 -1
  31. package/dist/commands/history/index.js +17 -18
  32. package/dist/commands/history/types.d.ts +38 -0
  33. package/dist/commands/history/types.d.ts.map +1 -1
  34. package/dist/commands/history/utils.d.ts.map +1 -1
  35. package/dist/commands/history/utils.js +63 -58
  36. package/dist/commands/init/index.d.ts.map +1 -1
  37. package/dist/commands/init/index.js +3 -8
  38. package/dist/commands/init-project/index.d.ts.map +1 -1
  39. package/dist/commands/init-project/index.js +3 -3
  40. package/dist/commands/init-project/utils.d.ts +2 -1
  41. package/dist/commands/init-project/utils.d.ts.map +1 -1
  42. package/dist/commands/init-project/utils.js +10 -2
  43. package/dist/commands/list-tools/index.d.ts.map +1 -1
  44. package/dist/commands/list-tools/index.js +7 -31
  45. package/dist/commands/manager.d.ts +2 -2
  46. package/dist/commands/manager.d.ts.map +1 -1
  47. package/dist/commands/manager.js +55 -33
  48. package/dist/commands/model/index.d.ts.map +1 -1
  49. package/dist/commands/model/index.js +20 -151
  50. package/dist/commands/model/model-panel.d.ts +4 -0
  51. package/dist/commands/model/model-panel.d.ts.map +1 -0
  52. package/dist/commands/model/model-panel.js +144 -0
  53. package/dist/commands/paste/index.d.ts.map +1 -1
  54. package/dist/commands/paste/index.js +59 -62
  55. package/dist/commands/paste/utils.d.ts.map +1 -1
  56. package/dist/commands/paste/utils.js +88 -58
  57. package/dist/commands/pickup/index.d.ts.map +1 -1
  58. package/dist/commands/pickup/index.js +6 -3
  59. package/dist/commands/pickup/utils.js +3 -3
  60. package/dist/commands/resources/index.d.ts.map +1 -1
  61. package/dist/commands/resources/index.js +33 -50
  62. package/dist/commands/review/index.d.ts.map +1 -1
  63. package/dist/commands/review/index.js +3 -117
  64. package/dist/commands/review/review-panel.d.ts +3 -0
  65. package/dist/commands/review/review-panel.d.ts.map +1 -0
  66. package/dist/commands/review/review-panel.js +186 -0
  67. package/dist/commands/review/utils.d.ts +15 -1
  68. package/dist/commands/review/utils.d.ts.map +1 -1
  69. package/dist/commands/review/utils.js +127 -68
  70. package/dist/commands/session/index.d.ts +1 -1
  71. package/dist/commands/session/index.d.ts.map +1 -1
  72. package/dist/commands/session/index.js +124 -135
  73. package/dist/commands/shell/index.d.ts.map +1 -1
  74. package/dist/commands/shell/index.js +16 -1
  75. package/dist/commands/types.d.ts +2 -2
  76. package/dist/commands/types.d.ts.map +1 -1
  77. package/dist/{config.d.ts → config/index.d.ts} +20 -9
  78. package/dist/config/index.d.ts.map +1 -0
  79. package/dist/{config.js → config/index.js} +43 -42
  80. package/dist/execution/index.d.ts.map +1 -1
  81. package/dist/execution/index.js +75 -55
  82. package/dist/index.d.ts +1 -0
  83. package/dist/index.d.ts.map +1 -1
  84. package/dist/index.js +148 -141
  85. package/dist/middleware/cache.d.ts.map +1 -1
  86. package/dist/middleware/cache.js +18 -36
  87. package/dist/models/ai-config.d.ts +1 -0
  88. package/dist/models/ai-config.d.ts.map +1 -1
  89. package/dist/models/ai-config.js +4 -3
  90. package/dist/models/anthropic-provider.d.ts +2 -5
  91. package/dist/models/anthropic-provider.d.ts.map +1 -1
  92. package/dist/models/anthropic-provider.js +3 -70
  93. package/dist/models/deepseek-provider.d.ts +1 -0
  94. package/dist/models/deepseek-provider.d.ts.map +1 -1
  95. package/dist/models/google-provider.d.ts +2 -3
  96. package/dist/models/google-provider.d.ts.map +1 -1
  97. package/dist/models/google-provider.js +0 -26
  98. package/dist/models/groq-provider.d.ts +1 -0
  99. package/dist/models/groq-provider.d.ts.map +1 -1
  100. package/dist/models/manager.d.ts +13 -2
  101. package/dist/models/manager.d.ts.map +1 -1
  102. package/dist/models/manager.js +20 -8
  103. package/dist/models/openai-provider.d.ts +2 -5
  104. package/dist/models/openai-provider.d.ts.map +1 -1
  105. package/dist/models/openai-provider.js +0 -52
  106. package/dist/models/opencode-go-provider.d.ts +25 -0
  107. package/dist/models/opencode-go-provider.d.ts.map +1 -0
  108. package/dist/models/opencode-go-provider.js +78 -0
  109. package/dist/models/opencode-zen-provider.d.ts +7 -3
  110. package/dist/models/opencode-zen-provider.d.ts.map +1 -1
  111. package/dist/models/opencode-zen-provider.js +49 -10
  112. package/dist/models/openrouter-provider.d.ts +27 -31
  113. package/dist/models/openrouter-provider.d.ts.map +1 -1
  114. package/dist/models/openrouter-provider.js +121 -180
  115. package/dist/models/providers.d.ts +3 -3
  116. package/dist/models/providers.d.ts.map +1 -1
  117. package/dist/models/providers.js +6 -0
  118. package/dist/models/xai-provider.d.ts +4 -3
  119. package/dist/models/xai-provider.d.ts.map +1 -1
  120. package/dist/models/xai-provider.js +18 -18
  121. package/dist/modes/manager.d.ts +24 -0
  122. package/dist/modes/manager.d.ts.map +1 -0
  123. package/dist/modes/manager.js +77 -0
  124. package/dist/modes/prompts.d.ts +2 -0
  125. package/dist/modes/prompts.d.ts.map +1 -0
  126. package/dist/modes/prompts.js +142 -0
  127. package/dist/prompts/mentions.d.ts +11 -0
  128. package/dist/prompts/mentions.d.ts.map +1 -0
  129. package/dist/{mentions.js → prompts/mentions.js} +55 -85
  130. package/dist/{prompts.d.ts → prompts/system-prompt.d.ts} +7 -2
  131. package/dist/prompts/system-prompt.d.ts.map +1 -0
  132. package/dist/{prompts.js → prompts/system-prompt.js} +31 -16
  133. package/dist/repl/index.d.ts +174 -0
  134. package/dist/repl/index.d.ts.map +1 -0
  135. package/dist/{repl-new.js → repl/index.js} +397 -76
  136. package/dist/repl/project-status.d.ts +1 -0
  137. package/dist/repl/project-status.d.ts.map +1 -1
  138. package/dist/repl/project-status.js +4 -1
  139. package/dist/sessions/manager.d.ts +92 -0
  140. package/dist/sessions/manager.d.ts.map +1 -1
  141. package/dist/sessions/manager.js +262 -9
  142. package/dist/sessions/summary.d.ts +4 -0
  143. package/dist/sessions/summary.d.ts.map +1 -0
  144. package/dist/sessions/summary.js +30 -0
  145. package/dist/skills/index.d.ts +29 -0
  146. package/dist/skills/index.d.ts.map +1 -0
  147. package/dist/skills/index.js +294 -0
  148. package/dist/subagents/index.d.ts +16 -0
  149. package/dist/subagents/index.d.ts.map +1 -0
  150. package/dist/subagents/index.js +231 -0
  151. package/dist/terminal/control.d.ts +1 -1
  152. package/dist/terminal/control.d.ts.map +1 -1
  153. package/dist/terminal/control.js +3 -3
  154. package/dist/terminal/east-asian-width.d.ts.map +1 -1
  155. package/dist/terminal/east-asian-width.js +404 -351
  156. package/dist/terminal/keys.d.ts +17 -0
  157. package/dist/terminal/keys.d.ts.map +1 -1
  158. package/dist/terminal/keys.js +37 -0
  159. package/dist/terminal/select-prompt.d.ts.map +1 -1
  160. package/dist/terminal/select-prompt.js +24 -12
  161. package/dist/terminal/string-width.d.ts.map +1 -1
  162. package/dist/terminal/string-width.js +25 -27
  163. package/dist/terminal/style.d.ts.map +1 -1
  164. package/dist/terminal/style.js +4 -7
  165. package/dist/terminal/supports-color.d.ts.map +1 -1
  166. package/dist/terminal/supports-color.js +41 -27
  167. package/dist/terminal/table/cell.d.ts +12 -0
  168. package/dist/terminal/table/cell.d.ts.map +1 -1
  169. package/dist/terminal/table/cell.js +40 -25
  170. package/dist/terminal/table/layout-manager.d.ts.map +1 -1
  171. package/dist/terminal/table/layout-manager.js +100 -68
  172. package/dist/terminal/table/utils.d.ts +1 -1
  173. package/dist/terminal/table/utils.d.ts.map +1 -1
  174. package/dist/terminal/table/utils.js +17 -10
  175. package/dist/terminal/wrap-ansi.d.ts.map +1 -1
  176. package/dist/terminal/wrap-ansi.js +174 -105
  177. package/dist/tokens/tracker.d.ts +1 -0
  178. package/dist/tokens/tracker.d.ts.map +1 -1
  179. package/dist/tokens/tracker.js +3 -0
  180. package/dist/tools/agent.d.ts +27 -0
  181. package/dist/tools/agent.d.ts.map +1 -0
  182. package/dist/tools/agent.js +81 -0
  183. package/dist/tools/apply-patch.d.ts +62 -0
  184. package/dist/tools/apply-patch.d.ts.map +1 -0
  185. package/dist/tools/apply-patch.js +377 -0
  186. package/dist/tools/bash.d.ts +4 -3
  187. package/dist/tools/bash.d.ts.map +1 -1
  188. package/dist/tools/bash.js +349 -141
  189. package/dist/tools/directory-tree.d.ts +3 -3
  190. package/dist/tools/directory-tree.d.ts.map +1 -1
  191. package/dist/tools/directory-tree.js +8 -5
  192. package/dist/tools/dynamic-tool-loader.d.ts +3 -6
  193. package/dist/tools/dynamic-tool-loader.d.ts.map +1 -1
  194. package/dist/tools/dynamic-tool-loader.js +20 -4
  195. package/dist/tools/edit-file.d.ts +7 -7
  196. package/dist/tools/edit-file.d.ts.map +1 -1
  197. package/dist/tools/edit-file.js +292 -85
  198. package/dist/tools/glob.d.ts +6 -6
  199. package/dist/tools/glob.d.ts.map +1 -1
  200. package/dist/tools/glob.js +110 -63
  201. package/dist/tools/grep.d.ts +15 -12
  202. package/dist/tools/grep.d.ts.map +1 -1
  203. package/dist/tools/grep.js +315 -193
  204. package/dist/tools/index.d.ts +114 -9
  205. package/dist/tools/index.d.ts.map +1 -1
  206. package/dist/tools/index.js +39 -24
  207. package/dist/tools/ls.d.ts +2 -2
  208. package/dist/tools/ls.d.ts.map +1 -1
  209. package/dist/tools/ls.js +7 -5
  210. package/dist/tools/read-file.d.ts +4 -6
  211. package/dist/tools/read-file.d.ts.map +1 -1
  212. package/dist/tools/read-file.js +84 -39
  213. package/dist/tools/save-file.d.ts +3 -3
  214. package/dist/tools/save-file.d.ts.map +1 -1
  215. package/dist/tools/save-file.js +36 -31
  216. package/dist/tools/skill.d.ts +23 -0
  217. package/dist/tools/skill.d.ts.map +1 -0
  218. package/dist/tools/skill.js +65 -0
  219. package/dist/tools/think.d.ts.map +1 -1
  220. package/dist/tools/think.js +2 -9
  221. package/dist/tools/utils.d.ts +2 -0
  222. package/dist/tools/utils.d.ts.map +1 -1
  223. package/dist/tools/utils.js +12 -0
  224. package/dist/tools/web-fetch.d.ts +50 -0
  225. package/dist/tools/web-fetch.d.ts.map +1 -0
  226. package/dist/tools/web-fetch.js +446 -0
  227. package/dist/tools/web-search.d.ts +44 -0
  228. package/dist/tools/web-search.d.ts.map +1 -0
  229. package/dist/tools/web-search.js +226 -0
  230. package/dist/tui/autocomplete/attachment-provider.d.ts +3 -6
  231. package/dist/tui/autocomplete/attachment-provider.d.ts.map +1 -1
  232. package/dist/tui/autocomplete/attachment-provider.js +25 -78
  233. package/dist/tui/autocomplete/base-provider.d.ts +1 -0
  234. package/dist/tui/autocomplete/base-provider.d.ts.map +1 -1
  235. package/dist/tui/autocomplete/combined-provider.d.ts +1 -4
  236. package/dist/tui/autocomplete/combined-provider.d.ts.map +1 -1
  237. package/dist/tui/autocomplete/combined-provider.js +3 -17
  238. package/dist/tui/autocomplete/command-provider.d.ts +1 -0
  239. package/dist/tui/autocomplete/command-provider.d.ts.map +1 -1
  240. package/dist/tui/autocomplete/command-provider.js +3 -0
  241. package/dist/tui/autocomplete/file-search-provider.d.ts +2 -1
  242. package/dist/tui/autocomplete/file-search-provider.d.ts.map +1 -1
  243. package/dist/tui/autocomplete/file-search-provider.js +37 -17
  244. package/dist/tui/autocomplete/skill-provider.d.ts +17 -0
  245. package/dist/tui/autocomplete/skill-provider.d.ts.map +1 -0
  246. package/dist/tui/autocomplete/skill-provider.js +49 -0
  247. package/dist/tui/autocomplete/utils.d.ts +2 -1
  248. package/dist/tui/autocomplete/utils.d.ts.map +1 -1
  249. package/dist/tui/autocomplete/utils.js +25 -23
  250. package/dist/tui/autocomplete.d.ts +2 -2
  251. package/dist/tui/autocomplete.d.ts.map +1 -1
  252. package/dist/tui/autocomplete.js +3 -5
  253. package/dist/tui/components/assistant-message.d.ts.map +1 -1
  254. package/dist/tui/components/assistant-message.js +0 -4
  255. package/dist/tui/components/editor.d.ts +18 -3
  256. package/dist/tui/components/editor.d.ts.map +1 -1
  257. package/dist/tui/components/editor.js +211 -237
  258. package/dist/tui/components/footer.d.ts +6 -4
  259. package/dist/tui/components/footer.d.ts.map +1 -1
  260. package/dist/tui/components/footer.js +49 -25
  261. package/dist/tui/components/markdown.d.ts +10 -7
  262. package/dist/tui/components/markdown.d.ts.map +1 -1
  263. package/dist/tui/components/markdown.js +57 -39
  264. package/dist/tui/components/modal.d.ts.map +1 -1
  265. package/dist/tui/components/modal.js +35 -33
  266. package/dist/tui/components/notification.d.ts +13 -2
  267. package/dist/tui/components/notification.d.ts.map +1 -1
  268. package/dist/tui/components/notification.js +36 -2
  269. package/dist/tui/components/progress-bar.js +1 -1
  270. package/dist/tui/components/select-list.d.ts +1 -0
  271. package/dist/tui/components/select-list.d.ts.map +1 -1
  272. package/dist/tui/components/select-list.js +14 -11
  273. package/dist/tui/components/text.d.ts +16 -0
  274. package/dist/tui/components/text.d.ts.map +1 -1
  275. package/dist/tui/components/text.js +72 -57
  276. package/dist/tui/components/thinking-block.d.ts +9 -0
  277. package/dist/tui/components/thinking-block.d.ts.map +1 -1
  278. package/dist/tui/components/thinking-block.js +43 -11
  279. package/dist/tui/components/tool-execution.d.ts +5 -1
  280. package/dist/tui/components/tool-execution.d.ts.map +1 -1
  281. package/dist/tui/components/tool-execution.js +19 -10
  282. package/dist/tui/components/user-message.d.ts.map +1 -1
  283. package/dist/tui/components/user-message.js +0 -3
  284. package/dist/tui/components/welcome.d.ts +2 -1
  285. package/dist/tui/components/welcome.d.ts.map +1 -1
  286. package/dist/tui/components/welcome.js +2 -2
  287. package/dist/tui/editor-launcher.d.ts +3 -2
  288. package/dist/tui/editor-launcher.d.ts.map +1 -1
  289. package/dist/tui/index.d.ts +0 -1
  290. package/dist/tui/index.d.ts.map +1 -1
  291. package/dist/tui/terminal.d.ts.map +1 -1
  292. package/dist/tui/terminal.js +10 -2
  293. package/dist/tui/tui.d.ts +43 -0
  294. package/dist/tui/tui.d.ts.map +1 -1
  295. package/dist/tui/tui.js +166 -41
  296. package/dist/tui/utils.d.ts +1 -5
  297. package/dist/tui/utils.d.ts.map +1 -1
  298. package/dist/tui/utils.js +271 -44
  299. package/dist/utils/bash/parse.d.ts +19 -0
  300. package/dist/utils/bash/parse.d.ts.map +1 -0
  301. package/dist/utils/bash/parse.js +223 -0
  302. package/dist/utils/bash/quote.d.ts +6 -0
  303. package/dist/utils/bash/quote.d.ts.map +1 -0
  304. package/dist/utils/bash/quote.js +23 -0
  305. package/dist/utils/bash.d.ts.map +1 -1
  306. package/dist/utils/bash.js +211 -126
  307. package/dist/utils/command-protection.d.ts +28 -0
  308. package/dist/utils/command-protection.d.ts.map +1 -0
  309. package/dist/utils/command-protection.js +324 -0
  310. package/dist/utils/dedent.d.ts.map +1 -0
  311. package/dist/utils/env-expand.d.ts +2 -0
  312. package/dist/utils/env-expand.d.ts.map +1 -0
  313. package/dist/utils/env-expand.js +8 -0
  314. package/dist/utils/filesystem/path-display.d.ts +11 -0
  315. package/dist/utils/filesystem/path-display.d.ts.map +1 -0
  316. package/dist/utils/filesystem/path-display.js +32 -0
  317. package/dist/utils/filesystem/security.d.ts +2 -2
  318. package/dist/utils/filesystem/security.d.ts.map +1 -1
  319. package/dist/utils/filesystem/security.js +28 -30
  320. package/dist/utils/formatting.d.ts.map +1 -0
  321. package/dist/{formatting.js → utils/formatting.js} +1 -1
  322. package/dist/utils/git.d.ts +4 -0
  323. package/dist/utils/git.d.ts.map +1 -1
  324. package/dist/utils/git.js +30 -0
  325. package/dist/utils/glob.d.ts +1 -1
  326. package/dist/utils/glob.d.ts.map +1 -1
  327. package/dist/utils/logger.d.ts.map +1 -0
  328. package/dist/{logger.js → utils/logger.js} +1 -1
  329. package/dist/utils/parsing.d.ts.map +1 -0
  330. package/dist/utils/process.d.ts.map +1 -1
  331. package/dist/utils/process.js +90 -37
  332. package/dist/utils/templates.d.ts +2 -0
  333. package/dist/utils/templates.d.ts.map +1 -0
  334. package/dist/utils/templates.js +24 -0
  335. package/dist/utils/version.d.ts.map +1 -0
  336. package/dist/{version.js → utils/version.js} +1 -1
  337. package/package.json +35 -26
  338. package/dist/cli.d.ts +0 -23
  339. package/dist/cli.d.ts.map +0 -1
  340. package/dist/commands/add-directory/types.d.ts +0 -6
  341. package/dist/commands/add-directory/types.d.ts.map +0 -1
  342. package/dist/commands/add-directory/types.js +0 -1
  343. package/dist/commands/copy/types.d.ts +0 -3
  344. package/dist/commands/copy/types.d.ts.map +0 -1
  345. package/dist/commands/copy/types.js +0 -1
  346. package/dist/commands/exit/index.d.ts +0 -10
  347. package/dist/commands/exit/index.d.ts.map +0 -1
  348. package/dist/commands/exit/index.js +0 -21
  349. package/dist/commands/exit/types.d.ts +0 -8
  350. package/dist/commands/exit/types.d.ts.map +0 -1
  351. package/dist/commands/exit/types.js +0 -1
  352. package/dist/commands/exit/utils.d.ts +0 -2
  353. package/dist/commands/exit/utils.d.ts.map +0 -1
  354. package/dist/commands/exit/utils.js +0 -13
  355. package/dist/commands/prompt/index.d.ts +0 -5
  356. package/dist/commands/prompt/index.d.ts.map +0 -1
  357. package/dist/commands/prompt/index.js +0 -122
  358. package/dist/commands/prompt/types.d.ts +0 -15
  359. package/dist/commands/prompt/types.d.ts.map +0 -1
  360. package/dist/commands/prompt/types.js +0 -1
  361. package/dist/commands/prompt/utils.d.ts +0 -12
  362. package/dist/commands/prompt/utils.d.ts.map +0 -1
  363. package/dist/commands/prompt/utils.js +0 -107
  364. package/dist/commands/reset/index.d.ts +0 -3
  365. package/dist/commands/reset/index.d.ts.map +0 -1
  366. package/dist/commands/reset/index.js +0 -25
  367. package/dist/commands/reset/types.d.ts +0 -1
  368. package/dist/commands/reset/types.d.ts.map +0 -1
  369. package/dist/commands/reset/types.js +0 -3
  370. package/dist/commands/review/types.d.ts +0 -12
  371. package/dist/commands/review/types.d.ts.map +0 -1
  372. package/dist/commands/review/types.js +0 -1
  373. package/dist/commands/save/index.d.ts +0 -3
  374. package/dist/commands/save/index.d.ts.map +0 -1
  375. package/dist/commands/save/index.js +0 -19
  376. package/dist/config.d.ts.map +0 -1
  377. package/dist/dedent.d.ts.map +0 -1
  378. package/dist/formatting.d.ts.map +0 -1
  379. package/dist/logger.d.ts.map +0 -1
  380. package/dist/mentions.d.ts +0 -14
  381. package/dist/mentions.d.ts.map +0 -1
  382. package/dist/parsing.d.ts.map +0 -1
  383. package/dist/prompts.d.ts.map +0 -1
  384. package/dist/repl-new.d.ts +0 -65
  385. package/dist/repl-new.d.ts.map +0 -1
  386. package/dist/skills.d.ts +0 -16
  387. package/dist/skills.d.ts.map +0 -1
  388. package/dist/skills.js +0 -233
  389. package/dist/stdin.d.ts.map +0 -1
  390. package/dist/tui/autocomplete/path-provider.d.ts +0 -21
  391. package/dist/tui/autocomplete/path-provider.d.ts.map +0 -1
  392. package/dist/tui/autocomplete/path-provider.js +0 -164
  393. package/dist/utils/iterables.d.ts +0 -2
  394. package/dist/utils/iterables.d.ts.map +0 -1
  395. package/dist/utils/iterables.js +0 -6
  396. package/dist/version.d.ts.map +0 -1
  397. /package/dist/{dedent.d.ts → utils/dedent.d.ts} +0 -0
  398. /package/dist/{dedent.js → utils/dedent.js} +0 -0
  399. /package/dist/{formatting.d.ts → utils/formatting.d.ts} +0 -0
  400. /package/dist/{logger.d.ts → utils/logger.d.ts} +0 -0
  401. /package/dist/{parsing.d.ts → utils/parsing.d.ts} +0 -0
  402. /package/dist/{parsing.js → utils/parsing.js} +0 -0
  403. /package/dist/{version.d.ts → utils/version.d.ts} +0 -0
@@ -0,0 +1,223 @@
1
+ // '<(' is process substitution operator and
2
+ // can be parsed the same as control operator
3
+ const CONTROL = `(?:${[
4
+ "\\|\\|",
5
+ "\\&\\&",
6
+ ";;",
7
+ "\\|\\&",
8
+ "\\<\\(",
9
+ "\\<\\<\\<",
10
+ ">>",
11
+ ">\\&",
12
+ "<\\&",
13
+ "[&;()|<>]",
14
+ ].join("|")})`;
15
+ const controlRe = new RegExp(`^${CONTROL}$`);
16
+ const META = "|&;()<> \t";
17
+ const SINGLE_QUOTE = '"((\\\\"|[^"])*?)"';
18
+ const DOUBLE_QUOTE = "'((\\\\'|[^'])*?)'";
19
+ const hash = /^#$/;
20
+ const SQ = "'";
21
+ const DQ = '"';
22
+ const DS = "$";
23
+ let Token = "";
24
+ const mult = 0x100000000; // Math.pow(16, 8);
25
+ for (let i = 0; i < 4; i++) {
26
+ Token += (mult * Math.random()).toString(16);
27
+ }
28
+ const startsWithToken = new RegExp(`^${Token}`);
29
+ function matchAll(s, r) {
30
+ const origIndex = r.lastIndex;
31
+ const matches = [];
32
+ let matchObj = r.exec(s);
33
+ while (matchObj !== null) {
34
+ matches.push(matchObj);
35
+ if (r.lastIndex === matchObj.index) {
36
+ r.lastIndex += 1;
37
+ }
38
+ matchObj = r.exec(s);
39
+ }
40
+ r.lastIndex = origIndex;
41
+ return matches;
42
+ }
43
+ function getVar(env, pre, key) {
44
+ let r = typeof env === "function" ? env(key) : env[key];
45
+ if (typeof r === "undefined" && key !== "") {
46
+ r = "";
47
+ }
48
+ else if (typeof r === "undefined") {
49
+ r = "$";
50
+ }
51
+ if (typeof r === "object") {
52
+ return pre + Token + JSON.stringify(r) + Token;
53
+ }
54
+ return pre + String(r);
55
+ }
56
+ function parseInternal(string, env, opts = {}) {
57
+ const Bs = opts.escape || "\\";
58
+ const Bareword = `(\\${Bs}["'${META}]|[^\\s'""${META}])+`;
59
+ const chunker = new RegExp([
60
+ `(${CONTROL})`, // control chars
61
+ `(${Bareword}|${SINGLE_QUOTE}|${DOUBLE_QUOTE})+`,
62
+ ].join("|"), "g");
63
+ const matches = matchAll(string, chunker);
64
+ if (matches.length === 0) {
65
+ return [];
66
+ }
67
+ const envToUse = env ?? {};
68
+ let commented = false;
69
+ return matches
70
+ .map(
71
+ // biome-ignore lint:noExcessiveCognitiveComplexity
72
+ (match) => {
73
+ const s = match[0];
74
+ if (!s || commented) {
75
+ return undefined;
76
+ }
77
+ if (controlRe.test(s)) {
78
+ return { op: s };
79
+ }
80
+ // Hand-written scanner/parser for Bash quoting rules:
81
+ //
82
+ // 1. inside single quotes, all characters are printed literally.
83
+ // 2. inside double quotes, all characters are printed literally
84
+ // except variables prefixed by '$' and backslashes followed by
85
+ // either a double quote or another backslash.
86
+ // 3. outside of any quotes, backslashes are treated as escape
87
+ // characters and not printed (unless they are themselves escaped)
88
+ // 4. quote context can switch mid-token if there is no whitespace
89
+ // between the two quote contexts (e.g. all'one'"token" parses as
90
+ // "allonetoken")
91
+ let quote = false;
92
+ let esc = false;
93
+ let out = "";
94
+ let isGlob = false;
95
+ let i = 0;
96
+ function parseEnvVar() {
97
+ i += 1;
98
+ let varend;
99
+ let varname;
100
+ const char = s.charAt(i);
101
+ if (char === "{") {
102
+ i += 1;
103
+ if (s.charAt(i) === "}") {
104
+ throw new Error(`Bad substitution: ${s.slice(i - 2, i + 1)}`);
105
+ }
106
+ varend = s.indexOf("}", i);
107
+ if (varend < 0) {
108
+ throw new Error(`Bad substitution: ${s.slice(i)}`);
109
+ }
110
+ varname = s.slice(i, varend);
111
+ i = varend;
112
+ }
113
+ else if (/[*@#?$!_-]/.test(char)) {
114
+ varname = char;
115
+ i += 1;
116
+ }
117
+ else {
118
+ const slicedFromI = s.slice(i);
119
+ const varendMatch = slicedFromI.match(/[^\w\d_]/);
120
+ if (!varendMatch) {
121
+ varname = slicedFromI;
122
+ i = s.length;
123
+ }
124
+ else {
125
+ varname = slicedFromI.slice(0, varendMatch.index);
126
+ i += (varendMatch.index ?? 0) - 1;
127
+ }
128
+ }
129
+ return getVar(envToUse, "", varname);
130
+ }
131
+ for (i = 0; i < s.length; i++) {
132
+ const c = s.charAt(i);
133
+ isGlob = isGlob || (!quote && (c === "*" || c === "?"));
134
+ if (esc) {
135
+ out += c;
136
+ esc = false;
137
+ }
138
+ else if (quote) {
139
+ if (c === quote) {
140
+ quote = false;
141
+ }
142
+ else if (quote === SQ) {
143
+ out += c;
144
+ }
145
+ else {
146
+ // Double quote
147
+ if (c === Bs) {
148
+ i += 1;
149
+ const charAtI = s.charAt(i);
150
+ if (charAtI === DQ || charAtI === Bs || charAtI === DS) {
151
+ out += charAtI;
152
+ }
153
+ else {
154
+ out += Bs + charAtI;
155
+ }
156
+ }
157
+ else if (c === DS) {
158
+ out += parseEnvVar();
159
+ }
160
+ else {
161
+ out += c;
162
+ }
163
+ }
164
+ }
165
+ else if (c === DQ || c === SQ) {
166
+ quote = c;
167
+ }
168
+ else if (controlRe.test(c)) {
169
+ return { op: s };
170
+ }
171
+ else if (hash.test(c)) {
172
+ commented = true;
173
+ const matchIndex = match.index;
174
+ const commentObj = {
175
+ comment: string.slice((matchIndex ?? 0) + i + 1),
176
+ };
177
+ if (out.length) {
178
+ return [out, commentObj];
179
+ }
180
+ return [commentObj];
181
+ }
182
+ else if (c === Bs) {
183
+ esc = true;
184
+ }
185
+ else if (c === DS) {
186
+ out += parseEnvVar();
187
+ }
188
+ else {
189
+ out += c;
190
+ }
191
+ }
192
+ if (isGlob) {
193
+ return { op: "glob", pattern: out };
194
+ }
195
+ return out;
196
+ })
197
+ .reduce((prev, arg) => {
198
+ // TODO: replace this whole reduce with a concat
199
+ return typeof arg === "undefined" ? prev : prev.concat(arg);
200
+ }, []);
201
+ }
202
+ export function parse(s, env = {}, opts) {
203
+ const mapped = parseInternal(s, env, opts);
204
+ if (typeof env !== "function") {
205
+ return mapped;
206
+ }
207
+ return mapped.reduce((acc, s) => {
208
+ if (typeof s === "object") {
209
+ return acc.concat(s);
210
+ }
211
+ const xs = s.split(RegExp(`(${Token}.*?${Token})`, "g"));
212
+ if (xs.length === 1) {
213
+ return acc.concat(xs[0]);
214
+ }
215
+ return acc.concat(xs.filter(Boolean).map((x) => {
216
+ if (startsWithToken.test(x)) {
217
+ const parts = x.split(Token);
218
+ return JSON.parse(parts[1]);
219
+ }
220
+ return x;
221
+ }));
222
+ }, []);
223
+ }
@@ -0,0 +1,6 @@
1
+ type QuoteArg = string | number | boolean | {
2
+ op: string;
3
+ } | null | undefined;
4
+ export declare function quote(xs: readonly QuoteArg[]): string;
5
+ export {};
6
+ //# sourceMappingURL=quote.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../../../source/utils/bash/quote.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,GAAG,SAAS,CAAC;AAE9E,wBAAgB,KAAK,CAAC,EAAE,EAAE,SAAS,QAAQ,EAAE,GAAG,MAAM,CAyBrD"}
@@ -0,0 +1,23 @@
1
+ export function quote(xs) {
2
+ return xs
3
+ .map((s) => {
4
+ if (s === null || s === undefined) {
5
+ return String(s);
6
+ }
7
+ const str = String(s);
8
+ if (str === "") {
9
+ return "''";
10
+ }
11
+ if (s && typeof s === "object") {
12
+ return s.op.replace(/(.)/g, "\\$1");
13
+ }
14
+ if (/["\s\\]/.test(str) && !/'/.test(str)) {
15
+ return `'${str.replace(/(['])/g, "\\$1")}'`;
16
+ }
17
+ if (/["'\s]/.test(str)) {
18
+ return `"${str.replace(/(["\\$`!])/g, "\\$1")}"`;
19
+ }
20
+ return str.replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, "$1\\$2");
21
+ })
22
+ .join(" ");
23
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../source/utils/bash.ts"],"names":[],"mappings":"AAMA,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,GAAG,EAAE,MAAM,GACV;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CA0EtC;AAED,eAAO,MAAM,UAAU,GACrB,UAAU,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,YAAY,MAAM,EAClB,cAAc,MAAM,EAAE,KACrB,MAkEF,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,OAmHtD,CAAC"}
1
+ {"version":3,"file":"bash.d.ts","sourceRoot":"","sources":["../../source/utils/bash.ts"],"names":[],"mappings":"AAuJA,wBAAgB,aAAa,CAC3B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EAAE,EACrB,GAAG,EAAE,MAAM,GACV;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAiDtC;AAED,eAAO,MAAM,UAAU,GACrB,UAAU,MAAM,GAAG,IAAI,GAAG,SAAS,EACnC,YAAY,MAAM,EAClB,cAAc,MAAM,EAAE,KACrB,MAkEF,CAAC;AA6FF,eAAO,MAAM,iBAAiB,GAAI,YAAY,MAAM,KAAG,OAetD,CAAC"}
@@ -2,63 +2,158 @@ import fs from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
4
  import { isPathWithinAllowedDirs } from "./filesystem/security.js";
5
- // Validate path arguments to ensure they're within the project
6
- export function validatePaths(command, allowedDirs, cwd) {
7
- // Simple tokenization - split on spaces but respect quotes
8
- const tokens = [];
9
- let current = "";
10
- let inQuotes = false;
11
- let quoteChar = "";
12
- for (let i = 0; i < command.length; i++) {
13
- const char = command[i] ?? "";
14
- if ((char === '"' || char === "'") && !inQuotes) {
15
- inQuotes = true;
16
- quoteChar = char;
17
- current += char;
5
+ function handleNormalMode(state, char, command, tokens) {
6
+ if (/\s/.test(char)) {
7
+ if (state.current) {
8
+ tokens.push(state.current);
9
+ state.current = "";
18
10
  }
19
- else if (char === quoteChar && inQuotes) {
20
- inQuotes = false;
21
- quoteChar = "";
22
- current += char;
11
+ return;
12
+ }
13
+ if (char === "'") {
14
+ state.mode = "single";
15
+ state.current += char;
16
+ return;
17
+ }
18
+ if (char === '"') {
19
+ state.mode = "double";
20
+ state.current += char;
21
+ return;
22
+ }
23
+ if (char === "\\") {
24
+ const next = command[state.i + 1];
25
+ if (next !== undefined) {
26
+ state.current += char + next;
27
+ state.i++;
28
+ return;
23
29
  }
24
- else if (char === " " && !inQuotes) {
25
- if (current) {
26
- tokens.push(current);
27
- current = "";
28
- }
30
+ }
31
+ state.current += char;
32
+ }
33
+ function handleSingleQuoteMode(state, char) {
34
+ state.current += char;
35
+ if (char === "'")
36
+ state.mode = "normal";
37
+ }
38
+ function handleDoubleQuoteMode(state, char, command) {
39
+ state.current += char;
40
+ if (char === "\\") {
41
+ const next = command[state.i + 1];
42
+ if (next !== undefined) {
43
+ state.current += next;
44
+ state.i++;
29
45
  }
30
- else {
31
- current += char;
46
+ return;
47
+ }
48
+ if (char === '"')
49
+ state.mode = "normal";
50
+ }
51
+ // Tokenize shell command respecting quotes and escapes
52
+ function tokenizeShellWords(command) {
53
+ const tokens = [];
54
+ const state = { current: "", mode: "normal", i: 0 };
55
+ for (state.i = 0; state.i < command.length; state.i++) {
56
+ const char = command[state.i] ?? "";
57
+ if (state.mode === "normal")
58
+ handleNormalMode(state, char, command, tokens);
59
+ else if (state.mode === "single")
60
+ handleSingleQuoteMode(state, char);
61
+ else
62
+ handleDoubleQuoteMode(state, char, command);
63
+ }
64
+ if (state.current)
65
+ tokens.push(state.current);
66
+ return tokens;
67
+ }
68
+ // Strip surrounding quotes from a token
69
+ function stripQuotes(token) {
70
+ if ((token.startsWith('"') && token.endsWith('"')) ||
71
+ (token.startsWith("'") && token.endsWith("'"))) {
72
+ return token.slice(1, -1);
73
+ }
74
+ return token;
75
+ }
76
+ // Check if a token is fully quoted (content should not be path-validated)
77
+ function isFullyQuoted(token) {
78
+ if (token.length < 2)
79
+ return false;
80
+ const first = token[0];
81
+ const last = token[token.length - 1];
82
+ return (first === '"' && last === '"') || (first === "'" && last === "'");
83
+ }
84
+ // Compute which tokens should be skipped from path validation
85
+ function computeSkipTokenMask(tokens) {
86
+ const skip = new Array(tokens.length).fill(false);
87
+ const bin = stripQuotes(tokens[0] ?? "");
88
+ const sub = stripQuotes(tokens[1] ?? "");
89
+ // Commands where -m/--message is a string argument (not a path)
90
+ const gitMessageSubs = new Set(["commit", "merge", "tag", "revert", "notes"]);
91
+ if (bin === "git" && gitMessageSubs.has(sub)) {
92
+ let seenDoubleDash = false;
93
+ for (let i = 2; i < tokens.length; i++) {
94
+ const t = stripQuotes(tokens[i] ?? "");
95
+ if (t === "--") {
96
+ seenDoubleDash = true;
97
+ continue;
98
+ }
99
+ if (seenDoubleDash)
100
+ continue;
101
+ // --message=<msg> - skip this entire token
102
+ if (t.startsWith("--message=")) {
103
+ skip[i] = true;
104
+ continue;
105
+ }
106
+ // -m<msg> (attached message) - skip this entire token
107
+ if (/^-m.+/.test(t)) {
108
+ skip[i] = true;
109
+ continue;
110
+ }
111
+ // -m or --message consumes next token
112
+ if (t === "-m" || t === "--message") {
113
+ if (i + 1 < tokens.length)
114
+ skip[i + 1] = true;
115
+ continue;
116
+ }
117
+ // Combined short opts containing m, e.g. -am, -avm
118
+ if (/^-[^-]+$/.test(t) && t.includes("m")) {
119
+ if (i + 1 < tokens.length)
120
+ skip[i + 1] = true;
121
+ }
32
122
  }
33
123
  }
34
- if (current)
35
- tokens.push(current);
124
+ return skip;
125
+ }
126
+ // Validate path arguments to ensure they're within the project
127
+ export function validatePaths(command, allowedDirs, cwd) {
128
+ const tokens = tokenizeShellWords(command);
129
+ const skip = computeSkipTokenMask(tokens);
36
130
  // Check each token that looks like a path
37
131
  for (let i = 1; i < tokens.length; i++) {
38
- // Skip the command itself
39
132
  const token = tokens[i];
40
133
  if (!token)
41
134
  continue;
135
+ // Skip tokens marked by command-aware logic
136
+ if (skip[i])
137
+ continue;
138
+ // Skip fully quoted tokens - they're string arguments, not paths
139
+ // (paths are typically unquoted or only quoted to handle spaces)
140
+ if (isFullyQuoted(token) && token.includes("\n")) {
141
+ continue;
142
+ }
42
143
  // Remove quotes for path checking
43
- const cleanToken = token.replace(/^['"]|['"]$/g, "");
144
+ const cleanToken = stripQuotes(token);
44
145
  // Skip if it's clearly not a path
45
146
  if (cleanToken.startsWith("-") ||
46
147
  cleanToken.includes("://") ||
47
148
  (!cleanToken.includes("/") && cleanToken !== "~")) {
48
149
  continue;
49
150
  }
50
- // Skip git commit messages and other special cases
51
- const prevToken = tokens[i - 1]?.replace(/^['"]|['"]$/g, "");
52
- if (prevToken === "-m" || prevToken === "--message") {
53
- continue;
54
- }
55
151
  try {
56
152
  // Expand ~ to home directory for proper validation
57
153
  const expandedToken = cleanToken.startsWith("~/") || cleanToken === "~"
58
154
  ? path.join(os.homedir(), cleanToken.slice(1))
59
155
  : cleanToken;
60
156
  const resolvedPath = path.resolve(cwd, expandedToken);
61
- // Allow access to explicitly allowed paths
62
157
  if (!isPathWithinAllowedDirs(resolvedPath, allowedDirs)) {
63
158
  return {
64
159
  isValid: false,
@@ -125,6 +220,87 @@ export const resolveCwd = (cwdInput, workingDir, allowedDirs) => {
125
220
  }
126
221
  return target;
127
222
  };
223
+ const mutatingBinaries = new Set([
224
+ "rm",
225
+ "mv",
226
+ "cp",
227
+ "mkdir",
228
+ "rmdir",
229
+ "touch",
230
+ "chmod",
231
+ "chown",
232
+ "ln",
233
+ "truncate",
234
+ "dd",
235
+ "tee",
236
+ ]);
237
+ const npmMutating = new Set([
238
+ "install",
239
+ "uninstall",
240
+ "update",
241
+ "ci",
242
+ "publish",
243
+ "link",
244
+ "dedupe",
245
+ "prune",
246
+ "rebuild",
247
+ "add",
248
+ ]);
249
+ const gitMutating = new Set([
250
+ "add",
251
+ "am",
252
+ "apply",
253
+ "branch",
254
+ "checkout",
255
+ "switch",
256
+ "cherry-pick",
257
+ "clean",
258
+ "commit",
259
+ "merge",
260
+ "mv",
261
+ "pull",
262
+ "push",
263
+ "rebase",
264
+ "reset",
265
+ "revert",
266
+ "stash",
267
+ "tag",
268
+ "worktree",
269
+ "submodule",
270
+ "config",
271
+ ]);
272
+ const actionMutating = new Set(["create", "update", "upgrade", "install"]);
273
+ const packageManagers = new Set(["npm", "pnpm", "yarn"]);
274
+ function isSegmentMutating(seg) {
275
+ const tokens = seg.split(/\s+/);
276
+ if (tokens.length === 0)
277
+ return false;
278
+ const bin = tokens[0];
279
+ if (!bin)
280
+ return false;
281
+ if (tokens.some((t) => actionMutating.has(t))) {
282
+ return true;
283
+ }
284
+ if (bin === "sed" && tokens.some((t) => /^-i/.test(t))) {
285
+ return true;
286
+ }
287
+ if (mutatingBinaries.has(bin)) {
288
+ return true;
289
+ }
290
+ if (bin === "git" && tokens.length > 1) {
291
+ const sub = tokens[1];
292
+ if (typeof sub === "string" && gitMutating.has(sub)) {
293
+ return true;
294
+ }
295
+ }
296
+ if (packageManagers.has(bin) && tokens.length > 1) {
297
+ const sub = tokens[1];
298
+ if (typeof sub === "string" && npmMutating.has(sub)) {
299
+ return true;
300
+ }
301
+ }
302
+ return false;
303
+ }
128
304
  export const isMutatingCommand = (rawCommand) => {
129
305
  const command = rawCommand.trim();
130
306
  // Redirections that write to disk
@@ -136,96 +312,5 @@ export const isMutatingCommand = (rawCommand) => {
136
312
  .split(/\s*(?:&&|\|\||;|\|)\s*/)
137
313
  .map((s) => s.trim())
138
314
  .filter((s) => s.length > 0);
139
- const mutatingBinaries = new Set([
140
- "rm",
141
- "mv",
142
- "cp",
143
- "mkdir",
144
- "rmdir",
145
- "touch",
146
- "chmod",
147
- "chown",
148
- "ln",
149
- "truncate",
150
- "dd",
151
- "tee",
152
- ]);
153
- const npmMutating = new Set([
154
- "install",
155
- "uninstall",
156
- "update",
157
- "ci",
158
- "publish",
159
- "link",
160
- "dedupe",
161
- "prune",
162
- "rebuild",
163
- "add",
164
- ]);
165
- const gitMutating = new Set([
166
- "add",
167
- "am",
168
- "apply",
169
- "branch",
170
- "checkout",
171
- "switch",
172
- "cherry-pick",
173
- "clean",
174
- "commit",
175
- "merge",
176
- "mv",
177
- "pull",
178
- "push",
179
- "rebase",
180
- "reset",
181
- "revert",
182
- "stash",
183
- "tag",
184
- "worktree",
185
- "submodule",
186
- "config",
187
- ]);
188
- // Generic action words that should be considered mutating when present in the command
189
- const actionMutating = new Set(["create", "update", "upgrade", "install"]);
190
- for (const seg of segments) {
191
- const tokens = seg.split(/\s+/);
192
- if (tokens.length === 0)
193
- continue;
194
- const bin = tokens[0];
195
- if (!bin)
196
- continue;
197
- // If any token is an action-like mutating word, consider mutating
198
- if (tokens.some((t) => actionMutating.has(t))) {
199
- return true;
200
- }
201
- // sed -i is mutating
202
- if (bin === "sed") {
203
- if (tokens.some((t) => /^-i/.test(t))) {
204
- return true;
205
- }
206
- // sed without -i is not mutating
207
- }
208
- if (mutatingBinaries.has(bin)) {
209
- return true;
210
- }
211
- if (bin === "git" && tokens.length > 1) {
212
- const sub = tokens[1];
213
- if (typeof sub === "string" && gitMutating.has(sub)) {
214
- return true;
215
- }
216
- }
217
- if (bin === "npm" && tokens.length > 1) {
218
- const sub = tokens[1];
219
- if (typeof sub === "string" && npmMutating.has(sub)) {
220
- return true;
221
- }
222
- }
223
- if ((bin === "pnpm" || bin === "yarn") && tokens.length > 1) {
224
- const sub = tokens[1];
225
- if (typeof sub === "string" && npmMutating.has(sub)) {
226
- return true;
227
- }
228
- }
229
- }
230
- return false;
315
+ return segments.some((seg) => isSegmentMutating(seg));
231
316
  };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Command Protection Module
3
+ * Detects and blocks destructive commands that could cause data loss
4
+ */
5
+ export interface BlockedCommandResult {
6
+ blocked: true;
7
+ reason: string;
8
+ command: string;
9
+ tip: string;
10
+ }
11
+ export interface SafeCommandResult {
12
+ blocked: false;
13
+ }
14
+ /**
15
+ * Result type for command safety check
16
+ */
17
+ export type CommandSafetyResult = BlockedCommandResult | SafeCommandResult;
18
+ /**
19
+ * Detects if a command is destructive and should be blocked
20
+ * @param command - The full command string to check
21
+ * @returns BlockedCommandResult if destructive, SafeCommandResult if safe
22
+ */
23
+ export declare function detectDestructiveCommand(command: string): CommandSafetyResult;
24
+ /**
25
+ * Generate a user-friendly blocked command message
26
+ */
27
+ export declare function formatBlockedCommandMessage(result: BlockedCommandResult): string;
28
+ //# sourceMappingURL=command-protection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-protection.d.ts","sourceRoot":"","sources":["../../source/utils/command-protection.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,KAAK,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,oBAAoB,GAAG,iBAAiB,CAAC;AAE3E;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CA4B7E;AA8UD;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,oBAAoB,GAC3B,MAAM,CAQR"}