@mohanscodex/spectra-code 0.4.5

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 (319) hide show
  1. package/README.md +275 -0
  2. package/dist/package.json +62 -0
  3. package/dist/src/agents/definitions.d.ts +16 -0
  4. package/dist/src/agents/definitions.d.ts.map +1 -0
  5. package/dist/src/agents/definitions.js +148 -0
  6. package/dist/src/agents/definitions.js.map +1 -0
  7. package/dist/src/agents/registry.d.ts +11 -0
  8. package/dist/src/agents/registry.d.ts.map +1 -0
  9. package/dist/src/agents/registry.js +13 -0
  10. package/dist/src/agents/registry.js.map +1 -0
  11. package/dist/src/cli.d.ts +3 -0
  12. package/dist/src/cli.d.ts.map +1 -0
  13. package/dist/src/cli.js +436 -0
  14. package/dist/src/cli.js.map +1 -0
  15. package/dist/src/commands/agent.d.ts +3 -0
  16. package/dist/src/commands/agent.d.ts.map +1 -0
  17. package/dist/src/commands/agent.js +28 -0
  18. package/dist/src/commands/agent.js.map +1 -0
  19. package/dist/src/commands/db.d.ts +3 -0
  20. package/dist/src/commands/db.d.ts.map +1 -0
  21. package/dist/src/commands/db.js +47 -0
  22. package/dist/src/commands/db.js.map +1 -0
  23. package/dist/src/commands/doctor.d.ts +12 -0
  24. package/dist/src/commands/doctor.d.ts.map +1 -0
  25. package/dist/src/commands/doctor.js +59 -0
  26. package/dist/src/commands/doctor.js.map +1 -0
  27. package/dist/src/commands/mcp.d.ts +9 -0
  28. package/dist/src/commands/mcp.d.ts.map +1 -0
  29. package/dist/src/commands/mcp.js +208 -0
  30. package/dist/src/commands/mcp.js.map +1 -0
  31. package/dist/src/commands/plugin.d.ts +3 -0
  32. package/dist/src/commands/plugin.d.ts.map +1 -0
  33. package/dist/src/commands/plugin.js +36 -0
  34. package/dist/src/commands/plugin.js.map +1 -0
  35. package/dist/src/commands/session.d.ts +3 -0
  36. package/dist/src/commands/session.d.ts.map +1 -0
  37. package/dist/src/commands/session.js +49 -0
  38. package/dist/src/commands/session.js.map +1 -0
  39. package/dist/src/index.d.ts +19 -0
  40. package/dist/src/index.d.ts.map +1 -0
  41. package/dist/src/index.js +17 -0
  42. package/dist/src/index.js.map +1 -0
  43. package/dist/src/integrations/acp/index.d.ts +2 -0
  44. package/dist/src/integrations/acp/index.d.ts.map +1 -0
  45. package/dist/src/integrations/acp/index.js +2 -0
  46. package/dist/src/integrations/acp/index.js.map +1 -0
  47. package/dist/src/integrations/acp/server.d.ts +11 -0
  48. package/dist/src/integrations/acp/server.d.ts.map +1 -0
  49. package/dist/src/integrations/acp/server.js +220 -0
  50. package/dist/src/integrations/acp/server.js.map +1 -0
  51. package/dist/src/integrations/custom-tools/index.d.ts +3 -0
  52. package/dist/src/integrations/custom-tools/index.d.ts.map +1 -0
  53. package/dist/src/integrations/custom-tools/index.js +2 -0
  54. package/dist/src/integrations/custom-tools/index.js.map +1 -0
  55. package/dist/src/integrations/custom-tools/loader.d.ts +16 -0
  56. package/dist/src/integrations/custom-tools/loader.d.ts.map +1 -0
  57. package/dist/src/integrations/custom-tools/loader.js +95 -0
  58. package/dist/src/integrations/custom-tools/loader.js.map +1 -0
  59. package/dist/src/integrations/mcp/client.d.ts +32 -0
  60. package/dist/src/integrations/mcp/client.d.ts.map +1 -0
  61. package/dist/src/integrations/mcp/client.js +117 -0
  62. package/dist/src/integrations/mcp/client.js.map +1 -0
  63. package/dist/src/integrations/mcp/index.d.ts +3 -0
  64. package/dist/src/integrations/mcp/index.d.ts.map +1 -0
  65. package/dist/src/integrations/mcp/index.js +2 -0
  66. package/dist/src/integrations/mcp/index.js.map +1 -0
  67. package/dist/src/security/doom-loop.d.ts +22 -0
  68. package/dist/src/security/doom-loop.d.ts.map +1 -0
  69. package/dist/src/security/doom-loop.js +72 -0
  70. package/dist/src/security/doom-loop.js.map +1 -0
  71. package/dist/src/security/index.d.ts +46 -0
  72. package/dist/src/security/index.d.ts.map +1 -0
  73. package/dist/src/security/index.js +362 -0
  74. package/dist/src/security/index.js.map +1 -0
  75. package/dist/src/security/path-safety.d.ts +15 -0
  76. package/dist/src/security/path-safety.d.ts.map +1 -0
  77. package/dist/src/security/path-safety.js +57 -0
  78. package/dist/src/security/path-safety.js.map +1 -0
  79. package/dist/src/security/permissions.d.ts +7 -0
  80. package/dist/src/security/permissions.d.ts.map +1 -0
  81. package/dist/src/security/permissions.js +41 -0
  82. package/dist/src/security/permissions.js.map +1 -0
  83. package/dist/src/security/read-tracker.d.ts +20 -0
  84. package/dist/src/security/read-tracker.d.ts.map +1 -0
  85. package/dist/src/security/read-tracker.js +73 -0
  86. package/dist/src/security/read-tracker.js.map +1 -0
  87. package/dist/src/security/ssrf-guard.d.ts +19 -0
  88. package/dist/src/security/ssrf-guard.d.ts.map +1 -0
  89. package/dist/src/security/ssrf-guard.js +98 -0
  90. package/dist/src/security/ssrf-guard.js.map +1 -0
  91. package/dist/src/security/types.d.ts +70 -0
  92. package/dist/src/security/types.d.ts.map +1 -0
  93. package/dist/src/security/types.js +2 -0
  94. package/dist/src/security/types.js.map +1 -0
  95. package/dist/src/security/wildcard.d.ts +5 -0
  96. package/dist/src/security/wildcard.d.ts.map +1 -0
  97. package/dist/src/security/wildcard.js +50 -0
  98. package/dist/src/security/wildcard.js.map +1 -0
  99. package/dist/src/services/auth-store.d.ts +25 -0
  100. package/dist/src/services/auth-store.d.ts.map +1 -0
  101. package/dist/src/services/auth-store.js +40 -0
  102. package/dist/src/services/auth-store.js.map +1 -0
  103. package/dist/src/services/config.d.ts +66 -0
  104. package/dist/src/services/config.d.ts.map +1 -0
  105. package/dist/src/services/config.js +83 -0
  106. package/dist/src/services/config.js.map +1 -0
  107. package/dist/src/services/context.d.ts +7 -0
  108. package/dist/src/services/context.d.ts.map +1 -0
  109. package/dist/src/services/context.js +23 -0
  110. package/dist/src/services/context.js.map +1 -0
  111. package/dist/src/services/custom-providers.d.ts +5 -0
  112. package/dist/src/services/custom-providers.d.ts.map +1 -0
  113. package/dist/src/services/custom-providers.js +213 -0
  114. package/dist/src/services/custom-providers.js.map +1 -0
  115. package/dist/src/services/session-store.d.ts +76 -0
  116. package/dist/src/services/session-store.d.ts.map +1 -0
  117. package/dist/src/services/session-store.js +199 -0
  118. package/dist/src/services/session-store.js.map +1 -0
  119. package/dist/src/services/snapshot-manager.d.ts +46 -0
  120. package/dist/src/services/snapshot-manager.d.ts.map +1 -0
  121. package/dist/src/services/snapshot-manager.js +183 -0
  122. package/dist/src/services/snapshot-manager.js.map +1 -0
  123. package/dist/src/tools/edit.d.ts +3 -0
  124. package/dist/src/tools/edit.d.ts.map +1 -0
  125. package/dist/src/tools/edit.js +57 -0
  126. package/dist/src/tools/edit.js.map +1 -0
  127. package/dist/src/tools/glob.d.ts +3 -0
  128. package/dist/src/tools/glob.d.ts.map +1 -0
  129. package/dist/src/tools/glob.js +46 -0
  130. package/dist/src/tools/glob.js.map +1 -0
  131. package/dist/src/tools/grep.d.ts +3 -0
  132. package/dist/src/tools/grep.d.ts.map +1 -0
  133. package/dist/src/tools/grep.js +50 -0
  134. package/dist/src/tools/grep.js.map +1 -0
  135. package/dist/src/tools/index.d.ts +26 -0
  136. package/dist/src/tools/index.d.ts.map +1 -0
  137. package/dist/src/tools/index.js +202 -0
  138. package/dist/src/tools/index.js.map +1 -0
  139. package/dist/src/tools/mcp-tool.d.ts +5 -0
  140. package/dist/src/tools/mcp-tool.d.ts.map +1 -0
  141. package/dist/src/tools/mcp-tool.js +82 -0
  142. package/dist/src/tools/mcp-tool.js.map +1 -0
  143. package/dist/src/tools/read.d.ts +3 -0
  144. package/dist/src/tools/read.d.ts.map +1 -0
  145. package/dist/src/tools/read.js +48 -0
  146. package/dist/src/tools/read.js.map +1 -0
  147. package/dist/src/tools/shell.d.ts +3 -0
  148. package/dist/src/tools/shell.d.ts.map +1 -0
  149. package/dist/src/tools/shell.js +266 -0
  150. package/dist/src/tools/shell.js.map +1 -0
  151. package/dist/src/tools/task.d.ts +3 -0
  152. package/dist/src/tools/task.d.ts.map +1 -0
  153. package/dist/src/tools/task.js +75 -0
  154. package/dist/src/tools/task.js.map +1 -0
  155. package/dist/src/tools/types.d.ts +18 -0
  156. package/dist/src/tools/types.d.ts.map +1 -0
  157. package/dist/src/tools/types.js +2 -0
  158. package/dist/src/tools/types.js.map +1 -0
  159. package/dist/src/tools/utils.d.ts +4 -0
  160. package/dist/src/tools/utils.d.ts.map +1 -0
  161. package/dist/src/tools/utils.js +10 -0
  162. package/dist/src/tools/utils.js.map +1 -0
  163. package/dist/src/tools/web-fetch.d.ts +3 -0
  164. package/dist/src/tools/web-fetch.d.ts.map +1 -0
  165. package/dist/src/tools/web-fetch.js +81 -0
  166. package/dist/src/tools/web-fetch.js.map +1 -0
  167. package/dist/src/tools/write.d.ts +3 -0
  168. package/dist/src/tools/write.d.ts.map +1 -0
  169. package/dist/src/tools/write.js +28 -0
  170. package/dist/src/tools/write.js.map +1 -0
  171. package/dist/src/tui/app-constants.d.ts +3 -0
  172. package/dist/src/tui/app-constants.d.ts.map +1 -0
  173. package/dist/src/tui/app-constants.js +4 -0
  174. package/dist/src/tui/app-constants.js.map +1 -0
  175. package/dist/src/tui/app.d.ts +5 -0
  176. package/dist/src/tui/app.d.ts.map +1 -0
  177. package/dist/src/tui/app.js +322 -0
  178. package/dist/src/tui/app.js.map +1 -0
  179. package/dist/src/tui/commands.d.ts +61 -0
  180. package/dist/src/tui/commands.d.ts.map +1 -0
  181. package/dist/src/tui/commands.js +95 -0
  182. package/dist/src/tui/commands.js.map +1 -0
  183. package/dist/src/tui/components/chat-area.d.ts +9 -0
  184. package/dist/src/tui/components/chat-area.d.ts.map +1 -0
  185. package/dist/src/tui/components/chat-area.js +12 -0
  186. package/dist/src/tui/components/chat-area.js.map +1 -0
  187. package/dist/src/tui/components/command-palette.d.ts +18 -0
  188. package/dist/src/tui/components/command-palette.d.ts.map +1 -0
  189. package/dist/src/tui/components/command-palette.js +50 -0
  190. package/dist/src/tui/components/command-palette.js.map +1 -0
  191. package/dist/src/tui/components/message.d.ts +9 -0
  192. package/dist/src/tui/components/message.d.ts.map +1 -0
  193. package/dist/src/tui/components/message.js +116 -0
  194. package/dist/src/tui/components/message.js.map +1 -0
  195. package/dist/src/tui/components/slash-autocomplete.d.ts +14 -0
  196. package/dist/src/tui/components/slash-autocomplete.d.ts.map +1 -0
  197. package/dist/src/tui/components/slash-autocomplete.js +29 -0
  198. package/dist/src/tui/components/slash-autocomplete.js.map +1 -0
  199. package/dist/src/tui/components/toast.d.ts +8 -0
  200. package/dist/src/tui/components/toast.d.ts.map +1 -0
  201. package/dist/src/tui/components/toast.js +29 -0
  202. package/dist/src/tui/components/toast.js.map +1 -0
  203. package/dist/src/tui/hooks/use-agent.d.ts +20 -0
  204. package/dist/src/tui/hooks/use-agent.d.ts.map +1 -0
  205. package/dist/src/tui/hooks/use-agent.js +129 -0
  206. package/dist/src/tui/hooks/use-agent.js.map +1 -0
  207. package/dist/src/tui/hooks/use-app-keyboard.d.ts +53 -0
  208. package/dist/src/tui/hooks/use-app-keyboard.d.ts.map +1 -0
  209. package/dist/src/tui/hooks/use-app-keyboard.js +155 -0
  210. package/dist/src/tui/hooks/use-app-keyboard.js.map +1 -0
  211. package/dist/src/tui/hooks/use-chat-submit.d.ts +61 -0
  212. package/dist/src/tui/hooks/use-chat-submit.d.ts.map +1 -0
  213. package/dist/src/tui/hooks/use-chat-submit.js +269 -0
  214. package/dist/src/tui/hooks/use-chat-submit.js.map +1 -0
  215. package/dist/src/tui/hooks/use-permission-queue.d.ts +10 -0
  216. package/dist/src/tui/hooks/use-permission-queue.d.ts.map +1 -0
  217. package/dist/src/tui/hooks/use-permission-queue.js +26 -0
  218. package/dist/src/tui/hooks/use-permission-queue.js.map +1 -0
  219. package/dist/src/tui/hooks/use-revert.d.ts +26 -0
  220. package/dist/src/tui/hooks/use-revert.d.ts.map +1 -0
  221. package/dist/src/tui/hooks/use-revert.js +88 -0
  222. package/dist/src/tui/hooks/use-revert.js.map +1 -0
  223. package/dist/src/tui/index.d.ts +5 -0
  224. package/dist/src/tui/index.d.ts.map +1 -0
  225. package/dist/src/tui/index.js +38 -0
  226. package/dist/src/tui/index.js.map +1 -0
  227. package/dist/src/tui/prompt-bar.d.ts +29 -0
  228. package/dist/src/tui/prompt-bar.d.ts.map +1 -0
  229. package/dist/src/tui/prompt-bar.js +41 -0
  230. package/dist/src/tui/prompt-bar.js.map +1 -0
  231. package/dist/src/tui/slash-commands.d.ts +20 -0
  232. package/dist/src/tui/slash-commands.d.ts.map +1 -0
  233. package/dist/src/tui/slash-commands.js +30 -0
  234. package/dist/src/tui/slash-commands.js.map +1 -0
  235. package/dist/src/tui/theme.d.ts +29 -0
  236. package/dist/src/tui/theme.d.ts.map +1 -0
  237. package/dist/src/tui/theme.js +54 -0
  238. package/dist/src/tui/theme.js.map +1 -0
  239. package/dist/src/tui/tips.d.ts +2 -0
  240. package/dist/src/tui/tips.d.ts.map +1 -0
  241. package/dist/src/tui/tips.js +40 -0
  242. package/dist/src/tui/tips.js.map +1 -0
  243. package/dist/src/tui/types.d.ts +34 -0
  244. package/dist/src/tui/types.d.ts.map +1 -0
  245. package/dist/src/tui/types.js +2 -0
  246. package/dist/src/tui/types.js.map +1 -0
  247. package/dist/src/tui/ui/about-dialog.d.ts +8 -0
  248. package/dist/src/tui/ui/about-dialog.d.ts.map +1 -0
  249. package/dist/src/tui/ui/about-dialog.js +21 -0
  250. package/dist/src/tui/ui/about-dialog.js.map +1 -0
  251. package/dist/src/tui/ui/agent-switcher.d.ts +10 -0
  252. package/dist/src/tui/ui/agent-switcher.d.ts.map +1 -0
  253. package/dist/src/tui/ui/agent-switcher.js +77 -0
  254. package/dist/src/tui/ui/agent-switcher.js.map +1 -0
  255. package/dist/src/tui/ui/debug-dialog.d.ts +15 -0
  256. package/dist/src/tui/ui/debug-dialog.d.ts.map +1 -0
  257. package/dist/src/tui/ui/debug-dialog.js +74 -0
  258. package/dist/src/tui/ui/debug-dialog.js.map +1 -0
  259. package/dist/src/tui/ui/doctor-dialog.d.ts +9 -0
  260. package/dist/src/tui/ui/doctor-dialog.d.ts.map +1 -0
  261. package/dist/src/tui/ui/doctor-dialog.js +45 -0
  262. package/dist/src/tui/ui/doctor-dialog.js.map +1 -0
  263. package/dist/src/tui/ui/manage-providers-dialog.d.ts +10 -0
  264. package/dist/src/tui/ui/manage-providers-dialog.d.ts.map +1 -0
  265. package/dist/src/tui/ui/manage-providers-dialog.js +257 -0
  266. package/dist/src/tui/ui/manage-providers-dialog.js.map +1 -0
  267. package/dist/src/tui/ui/mcp-toggle-dialog.d.ts +8 -0
  268. package/dist/src/tui/ui/mcp-toggle-dialog.d.ts.map +1 -0
  269. package/dist/src/tui/ui/mcp-toggle-dialog.js +89 -0
  270. package/dist/src/tui/ui/mcp-toggle-dialog.js.map +1 -0
  271. package/dist/src/tui/ui/message-controls.d.ts +16 -0
  272. package/dist/src/tui/ui/message-controls.d.ts.map +1 -0
  273. package/dist/src/tui/ui/message-controls.js +102 -0
  274. package/dist/src/tui/ui/message-controls.js.map +1 -0
  275. package/dist/src/tui/ui/model-switcher.d.ts +10 -0
  276. package/dist/src/tui/ui/model-switcher.d.ts.map +1 -0
  277. package/dist/src/tui/ui/model-switcher.js +139 -0
  278. package/dist/src/tui/ui/model-switcher.js.map +1 -0
  279. package/dist/src/tui/ui/permission-dialog.d.ts +12 -0
  280. package/dist/src/tui/ui/permission-dialog.d.ts.map +1 -0
  281. package/dist/src/tui/ui/permission-dialog.js +37 -0
  282. package/dist/src/tui/ui/permission-dialog.js.map +1 -0
  283. package/dist/src/tui/ui/provider-dialog.d.ts +11 -0
  284. package/dist/src/tui/ui/provider-dialog.d.ts.map +1 -0
  285. package/dist/src/tui/ui/provider-dialog.js +232 -0
  286. package/dist/src/tui/ui/provider-dialog.js.map +1 -0
  287. package/dist/src/tui/ui/session-list.d.ts +23 -0
  288. package/dist/src/tui/ui/session-list.d.ts.map +1 -0
  289. package/dist/src/tui/ui/session-list.js +147 -0
  290. package/dist/src/tui/ui/session-list.js.map +1 -0
  291. package/dist/src/tui/ui/thinking-effort-dialog.d.ts +11 -0
  292. package/dist/src/tui/ui/thinking-effort-dialog.d.ts.map +1 -0
  293. package/dist/src/tui/ui/thinking-effort-dialog.js +79 -0
  294. package/dist/src/tui/ui/thinking-effort-dialog.js.map +1 -0
  295. package/dist/src/tui/utils/model-config.d.ts +9 -0
  296. package/dist/src/tui/utils/model-config.d.ts.map +1 -0
  297. package/dist/src/tui/utils/model-config.js +63 -0
  298. package/dist/src/tui/utils/model-config.js.map +1 -0
  299. package/dist/src/tui/utils/session-messages.d.ts +22 -0
  300. package/dist/src/tui/utils/session-messages.d.ts.map +1 -0
  301. package/dist/src/tui/utils/session-messages.js +62 -0
  302. package/dist/src/tui/utils/session-messages.js.map +1 -0
  303. package/dist/src/tui/utils.d.ts +6 -0
  304. package/dist/src/tui/utils.d.ts.map +1 -0
  305. package/dist/src/tui/utils.js +23 -0
  306. package/dist/src/tui/utils.js.map +1 -0
  307. package/dist/src/tui/variant-cycle.d.ts +10 -0
  308. package/dist/src/tui/variant-cycle.d.ts.map +1 -0
  309. package/dist/src/tui/variant-cycle.js +64 -0
  310. package/dist/src/tui/variant-cycle.js.map +1 -0
  311. package/dist/src/utils/paths.d.ts +10 -0
  312. package/dist/src/utils/paths.d.ts.map +1 -0
  313. package/dist/src/utils/paths.js +106 -0
  314. package/dist/src/utils/paths.js.map +1 -0
  315. package/dist/src/utils/platform.d.ts +10 -0
  316. package/dist/src/utils/platform.d.ts.map +1 -0
  317. package/dist/src/utils/platform.js +133 -0
  318. package/dist/src/utils/platform.js.map +1 -0
  319. package/package.json +62 -0
@@ -0,0 +1,72 @@
1
+ export class DoomLoopDetector {
2
+ callHistory = [];
3
+ consecutiveReads = 0;
4
+ patchFailures = new Map();
5
+ writeThreshold;
6
+ readOnlyThreshold;
7
+ patchThreshold;
8
+ constructor(config) {
9
+ this.writeThreshold = config?.writeRepeatThreshold ?? 3;
10
+ this.readOnlyThreshold = config?.readOnlyRepeatThreshold ?? 8;
11
+ this.patchThreshold = config?.patchSpiralThreshold ?? 4;
12
+ }
13
+ recordToolCall(tool, args) {
14
+ const argsKey = JSON.stringify(args);
15
+ const now = Date.now();
16
+ const recent = this.callHistory.filter((c) => now - c.firstTime < 60000);
17
+ this.callHistory = recent;
18
+ const existing = this.callHistory.find((c) => c.tool === tool && c.args === argsKey);
19
+ if (existing) {
20
+ existing.count++;
21
+ if (existing.count >= this.writeThreshold) {
22
+ return {
23
+ ok: false,
24
+ action: "stop",
25
+ message: `Doom loop detected: '${tool}' called ${existing.count} times with identical arguments. Breaking loop.`,
26
+ };
27
+ }
28
+ }
29
+ else {
30
+ this.callHistory.push({ tool, args: argsKey, count: 1, firstTime: now });
31
+ }
32
+ return { ok: true };
33
+ }
34
+ recordToolResult(tool, isSuccess) {
35
+ const writeTools = new Set(["edit", "write", "apply_patch", "bash"]);
36
+ if (isSuccess && writeTools.has(tool)) {
37
+ this.consecutiveReads = 0;
38
+ }
39
+ else if (!writeTools.has(tool)) {
40
+ this.consecutiveReads++;
41
+ }
42
+ if (this.consecutiveReads >= this.readOnlyThreshold) {
43
+ return {
44
+ ok: false,
45
+ action: "warn",
46
+ message: `Read-only loop detected: ${this.consecutiveReads} consecutive reads with no writes. Consider switching agents or stopping.`,
47
+ };
48
+ }
49
+ return { ok: true };
50
+ }
51
+ recordPatchFailure(filePath) {
52
+ const failures = (this.patchFailures.get(filePath) ?? 0) + 1;
53
+ this.patchFailures.set(filePath, failures);
54
+ if (failures >= this.patchThreshold) {
55
+ return {
56
+ ok: false,
57
+ action: "warn",
58
+ message: `Patch spiral on '${filePath}': ${failures} consecutive failures. Consider using write instead of edit.`,
59
+ };
60
+ }
61
+ return { ok: true };
62
+ }
63
+ recordPatchSuccess(filePath) {
64
+ this.patchFailures.delete(filePath);
65
+ }
66
+ reset() {
67
+ this.callHistory = [];
68
+ this.consecutiveReads = 0;
69
+ this.patchFailures.clear();
70
+ }
71
+ }
72
+ //# sourceMappingURL=doom-loop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doom-loop.js","sourceRoot":"","sources":["../../../src/security/doom-loop.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { Rule, Ruleset, PermissionAction, PermissionConfig, PermissionRequest, PermissionResponse, SecurityConfig, ToolCapabilities } from "./types.js";
2
+ import { PathSafety } from "./path-safety.js";
3
+ import { ReadTracker } from "./read-tracker.js";
4
+ import { DoomLoopDetector } from "./doom-loop.js";
5
+ import { SsrfGuard } from "./ssrf-guard.js";
6
+ export type { Rule, Ruleset, PermissionAction, SecurityConfig, ToolCapabilities };
7
+ export { evaluate, fromConfig } from "./permissions.js";
8
+ export { PathSafety } from "./path-safety.js";
9
+ export { ReadTracker } from "./read-tracker.js";
10
+ export { DoomLoopDetector } from "./doom-loop.js";
11
+ export { SsrfGuard } from "./ssrf-guard.js";
12
+ export declare class PermissionDeniedError extends Error {
13
+ readonly permission: string;
14
+ readonly pattern: string;
15
+ constructor(permission: string, pattern: string);
16
+ }
17
+ type PermissionListener = (req: PermissionRequest) => void;
18
+ interface PermissionManagerOptions {
19
+ config?: PermissionConfig;
20
+ security?: SecurityConfig;
21
+ sessionRuleset?: Ruleset;
22
+ restoredApprovals?: Ruleset;
23
+ cwd?: string;
24
+ onPersist?: (approvedRules: Ruleset) => void;
25
+ }
26
+ export declare function createSecurityManager(options?: PermissionManagerOptions): {
27
+ getReadTracker: () => ReadTracker;
28
+ getDoomLoop: () => DoomLoopDetector;
29
+ getSsrfGuard: () => SsrfGuard;
30
+ getPathSafety: () => PathSafety;
31
+ checkPath: (rawPath: string) => void;
32
+ checkPermission: (permission: string, patterns: string[], tool?: string, details?: string) => Promise<void>;
33
+ extractToolPatterns: (toolName: string, args: Record<string, unknown>) => {
34
+ toolPatterns: string[];
35
+ externalPaths: string[];
36
+ pathPatterns: string[];
37
+ };
38
+ setListener: (fn: PermissionListener | null) => void;
39
+ addApproval: (rules: Rule[]) => void;
40
+ respondToRequest: (id: string, response: PermissionResponse) => void;
41
+ getRuleset: () => Ruleset;
42
+ getApprovedConfig: () => PermissionConfig;
43
+ readonly pendingCount: number;
44
+ };
45
+ export type SecurityManager = ReturnType<typeof createSecurityManager>;
46
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/security/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EACjD,iBAAiB,EAAE,kBAAkB,EACrC,cAAc,EAAE,gBAAgB,EACjC,MAAM,YAAY,CAAA;AAEnB,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAM3C,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,gBAAgB,EAAE,CAAA;AACjF,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAwF3C,qBAAa,qBAAsB,SAAQ,KAAK;aAE5B,UAAU,EAAE,MAAM;aAClB,OAAO,EAAE,MAAM;gBADf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM;CAKlC;AAaD,KAAK,kBAAkB,GAAG,CAAC,GAAG,EAAE,iBAAiB,KAAK,IAAI,CAAA;AAE1D,UAAU,wBAAwB;IAChC,MAAM,CAAC,EAAE,gBAAgB,CAAA;IACzB,QAAQ,CAAC,EAAE,cAAc,CAAA;IACzB,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,SAAS,CAAC,EAAE,CAAC,aAAa,EAAE,OAAO,KAAK,IAAI,CAAA;CAC7C;AAED,wBAAgB,qBAAqB,CAAC,OAAO,GAAE,wBAA6B;0BAmC/C,WAAW;uBACd,gBAAgB;wBACf,SAAS;yBACR,UAAU;yBAgBR,MAAM,KAAG,IAAI;kCAkB3B,MAAM,YACR,MAAM,EAAE,SACX,MAAM,YACH,MAAM,KACf,OAAO,CAAC,IAAI,CAAC;oCAgJJ,MAAM,QACV,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAC5B;QAAE,YAAY,EAAE,MAAM,EAAE,CAAC;QAAC,aAAa,EAAE,MAAM,EAAE,CAAC;QAAC,YAAY,EAAE,MAAM,EAAE,CAAA;KAAE;sBAnMrD,kBAAkB,GAAG,IAAI,KAAG,IAAI;yBAI7B,IAAI,EAAE,KAAG,IAAI;2BAyHX,MAAM,YAAY,kBAAkB,KAAG,IAAI;sBAjIlD,OAAO;6BAiBA,gBAAgB;;EA6Q/C;AAED,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
@@ -0,0 +1,362 @@
1
+ import { evaluate, fromConfig } from "./permissions.js";
2
+ import { PathSafety } from "./path-safety.js";
3
+ import { ReadTracker } from "./read-tracker.js";
4
+ import { DoomLoopDetector } from "./doom-loop.js";
5
+ import { SsrfGuard } from "./ssrf-guard.js";
6
+ import { isInsideWorkingDir, canonicalPath, matchWildcard, ensureDirGlob } from "./wildcard.js";
7
+ import { resolve, dirname } from "path";
8
+ import { URL } from "url";
9
+ import { statSync } from "fs";
10
+ export { evaluate, fromConfig } from "./permissions.js";
11
+ export { PathSafety } from "./path-safety.js";
12
+ export { ReadTracker } from "./read-tracker.js";
13
+ export { DoomLoopDetector } from "./doom-loop.js";
14
+ export { SsrfGuard } from "./ssrf-guard.js";
15
+ const BASHLIST_COMMANDS = new Set([
16
+ "shutdown", "reboot", "halt", "poweroff",
17
+ "mkfs", "fdisk", "mkswap", "swapon",
18
+ "telnet", "chroot",
19
+ ]);
20
+ const BASHLIST_PATTERNS = [
21
+ "rm -rf /*", "sudo rm -rf /*", "doas rm -rf /*", "rm -rf ~",
22
+ "rm -rf /home*", "rm -rf /root*",
23
+ "dd if=*of=/dev/*",
24
+ "> /dev/sd*", "> /dev/hd*", "> /dev/nvme*",
25
+ ":(){ :|:& };:*",
26
+ "curl * | sh", "curl * | bash", "curl * | zsh",
27
+ "wget * | sh", "wget * | bash", "wget * | zsh",
28
+ "sudo chmod 777 /*", "sudo chown -R /*", "sudo chown -R /",
29
+ "cat .env | curl *", "cat .env | wget *",
30
+ "git push --force origin main", "git push --force origin master",
31
+ "git push -f origin main", "git push -f origin master",
32
+ "git push --force --no-verify origin main",
33
+ "git push --force --no-verify origin master",
34
+ ];
35
+ const FILE_COMMANDS = new Set([
36
+ "cat", "cp", "mv", "rm", "mkdir", "touch", "chmod", "chown",
37
+ "ls", "less", "more", "head", "tail", "file", "stat",
38
+ "diff", "cmp", "find", "ln",
39
+ ]);
40
+ const FILE_TOOL_NAMES = new Set(["read", "write", "edit", "grep", "glob"]);
41
+ function unquoteShell(s) {
42
+ if (s.length >= 2) {
43
+ const first = s[0], last = s[s.length - 1];
44
+ if ((first === "'" && last === "'") || (first === '"' && last === '"')) {
45
+ return s.slice(1, -1);
46
+ }
47
+ }
48
+ return s;
49
+ }
50
+ function extractBashPaths(command, cwd) {
51
+ const externalPaths = [];
52
+ const pathPatterns = [];
53
+ for (const firstLine of command.split("\n")) {
54
+ const trimmed = firstLine.trim();
55
+ if (!trimmed)
56
+ continue;
57
+ const segments = trimmed.split(/(?<!\\);/);
58
+ for (const segment of segments) {
59
+ const parts = segment.trim().split(/\s+/).filter(Boolean);
60
+ if (parts.length < 2)
61
+ continue;
62
+ const cmd = (parts[0] || "").toLowerCase();
63
+ if (!FILE_COMMANDS.has(cmd))
64
+ continue;
65
+ for (const arg of parts.slice(1)) {
66
+ if (arg.startsWith("-") || arg.startsWith("--"))
67
+ continue;
68
+ const unquoted = unquoteShell(arg);
69
+ try {
70
+ const resolved = resolve(cwd, unquoted);
71
+ pathPatterns.push(resolved);
72
+ if (!isInsideWorkingDir(unquoted, cwd)) {
73
+ externalPaths.push(resolved);
74
+ }
75
+ }
76
+ catch { }
77
+ }
78
+ }
79
+ }
80
+ return { externalPaths, pathPatterns };
81
+ }
82
+ function isBashBlocked(command) {
83
+ const firstWord = command.trim().split(/\s+/)[0] || "";
84
+ if (BASHLIST_COMMANDS.has(firstWord))
85
+ return true;
86
+ const normalized = command.trim();
87
+ return BASHLIST_PATTERNS.some((p) => matchWildcard(p, normalized));
88
+ }
89
+ export class PermissionDeniedError extends Error {
90
+ permission;
91
+ pattern;
92
+ constructor(permission, pattern) {
93
+ super(`Permission denied: '${permission}' for '${pattern}'`);
94
+ this.permission = permission;
95
+ this.pattern = pattern;
96
+ this.name = "PermissionDeniedError";
97
+ }
98
+ }
99
+ export function createSecurityManager(options = {}) {
100
+ const configRuleset = options.config ? fromConfig(options.config) : [];
101
+ const sessionRuleset = options.sessionRuleset ?? [];
102
+ const restoredFromDisk = options.restoredApprovals ?? [];
103
+ const pathSafety = new PathSafety({
104
+ blockedPaths: options.security?.blockedPaths,
105
+ allowedPaths: options.security?.allowedPaths,
106
+ });
107
+ const readTracker = new ReadTracker({
108
+ mode: options.security?.writeGuard ?? "soft",
109
+ exclude: options.security?.writeGuardExclude,
110
+ });
111
+ const doomLoop = new DoomLoopDetector(options.security?.doomLoop);
112
+ const ssrfGuard = new SsrfGuard(options.security?.ssrf);
113
+ const cwd = options.cwd ?? process.cwd();
114
+ let approvedRuleset = [...restoredFromDisk];
115
+ const pendingRequests = new Map();
116
+ let listener = null;
117
+ const onPersist = options.onPersist;
118
+ function getRuleset() {
119
+ return [...configRuleset, ...approvedRuleset, ...sessionRuleset];
120
+ }
121
+ function setListener(fn) {
122
+ listener = fn;
123
+ }
124
+ function addApproval(rules) {
125
+ approvedRuleset.push(...rules);
126
+ }
127
+ function getReadTracker() { return readTracker; }
128
+ function getDoomLoop() { return doomLoop; }
129
+ function getSsrfGuard() { return ssrfGuard; }
130
+ function getPathSafety() { return pathSafety; }
131
+ function getApprovedConfig() {
132
+ const config = {};
133
+ for (const rule of approvedRuleset) {
134
+ if (rule.action !== "allow")
135
+ continue;
136
+ const existing = config[rule.permission];
137
+ if (typeof existing === "object" && existing !== null) {
138
+ ;
139
+ existing[rule.pattern] = "allow";
140
+ }
141
+ else {
142
+ config[rule.permission] = { [rule.pattern]: "allow" };
143
+ }
144
+ }
145
+ return config;
146
+ }
147
+ function checkPath(rawPath) {
148
+ const result = pathSafety.check(rawPath, cwd);
149
+ if (!result.ok) {
150
+ throw new PermissionDeniedError("path_safety", rawPath);
151
+ }
152
+ }
153
+ function internalPathsOnly(permission, patterns) {
154
+ if (!FILE_TOOL_NAMES.has(permission) && permission !== "external_directory") {
155
+ return false;
156
+ }
157
+ return patterns.every((p) => {
158
+ if (p === "*")
159
+ return false;
160
+ try {
161
+ return isInsideWorkingDir(p, cwd);
162
+ }
163
+ catch {
164
+ return false;
165
+ }
166
+ });
167
+ }
168
+ async function checkPermission(permission, patterns, tool, details) {
169
+ const isBash = permission === "bash" || permission === "shell";
170
+ if (isBash) {
171
+ const command = patterns[0] ?? "";
172
+ if (isBashBlocked(command)) {
173
+ throw new PermissionDeniedError(permission, command);
174
+ }
175
+ }
176
+ const ruleset = getRuleset();
177
+ for (const pattern of patterns) {
178
+ const rule = evaluate(permission, pattern, ruleset);
179
+ if (rule.action === "deny") {
180
+ throw new PermissionDeniedError(permission, pattern);
181
+ }
182
+ if (rule.action === "allow") {
183
+ return;
184
+ }
185
+ }
186
+ if (isBash) {
187
+ return;
188
+ }
189
+ if (internalPathsOnly(permission, patterns)) {
190
+ return;
191
+ }
192
+ await requestApproval(permission, patterns[0], tool, details ?? patterns[0]);
193
+ }
194
+ async function requestApproval(permission, pattern, tool, details) {
195
+ return new Promise((resolve, reject) => {
196
+ const id = Math.random().toString(36).slice(2, 10);
197
+ const alwaysPatterns = generateAlwaysPatterns(permission, pattern);
198
+ const pending = {
199
+ id,
200
+ permission,
201
+ pattern,
202
+ tool: tool ?? permission,
203
+ details: details ?? pattern,
204
+ always: alwaysPatterns,
205
+ resolve,
206
+ reject,
207
+ };
208
+ pendingRequests.set(id, pending);
209
+ listener?.({
210
+ id,
211
+ permission,
212
+ pattern,
213
+ tool: tool ?? permission,
214
+ details: details ?? pattern,
215
+ always: alwaysPatterns,
216
+ });
217
+ setTimeout(() => {
218
+ if (pendingRequests.has(id)) {
219
+ pendingRequests.delete(id);
220
+ reject(new PermissionDeniedError(permission, pattern));
221
+ }
222
+ }, 120000);
223
+ });
224
+ }
225
+ function respondToRequest(id, response) {
226
+ const pending = pendingRequests.get(id);
227
+ if (!pending)
228
+ return;
229
+ pendingRequests.delete(id);
230
+ if (response.action === "deny") {
231
+ pending.reject(new PermissionDeniedError(pending.permission, pending.pattern));
232
+ return;
233
+ }
234
+ if (response.action === "always") {
235
+ for (const alwaysPattern of pending.always) {
236
+ approvedRuleset.push({
237
+ permission: pending.permission,
238
+ pattern: alwaysPattern,
239
+ action: "allow",
240
+ });
241
+ }
242
+ cascadeAutoResolve();
243
+ onPersist?.(approvedRuleset);
244
+ }
245
+ pending.resolve();
246
+ }
247
+ function cascadeAutoResolve() {
248
+ const ruleset = getRuleset();
249
+ for (const [pid, entry] of pendingRequests) {
250
+ const allAllowed = entry.always.every((ap) => evaluate(entry.permission, ap, ruleset).action === "allow");
251
+ if (allAllowed) {
252
+ pendingRequests.delete(pid);
253
+ entry.resolve();
254
+ }
255
+ }
256
+ }
257
+ function generateAlwaysPatterns(permission, pattern) {
258
+ if (permission === "external_directory") {
259
+ const resolved = canonicalPath(pattern, cwd);
260
+ let dir;
261
+ try {
262
+ const st = statSync(resolved);
263
+ dir = st.isDirectory() ? resolved : dirname(resolved);
264
+ }
265
+ catch {
266
+ dir = dirname(resolved);
267
+ }
268
+ return [pattern, ensureDirGlob(dir)];
269
+ }
270
+ if (FILE_TOOL_NAMES.has(permission)) {
271
+ return ["*"];
272
+ }
273
+ if (permission === "bash") {
274
+ const parts = pattern.split(/\s+/);
275
+ if (parts.length >= 2) {
276
+ return [pattern, `${parts[0]} ${parts[1]} *`, `${parts[0]} *`];
277
+ }
278
+ return [`${pattern} *`];
279
+ }
280
+ return [pattern];
281
+ }
282
+ function extractToolPatterns(toolName, args) {
283
+ const toolPatterns = [];
284
+ const externalPaths = [];
285
+ const pathPatterns = [];
286
+ const rawPath = (args.path || args.file_path || args.filePath);
287
+ if (rawPath) {
288
+ pathPatterns.push(rawPath);
289
+ try {
290
+ const abs = resolve(cwd, rawPath);
291
+ pathPatterns.push(abs);
292
+ if (!isInsideWorkingDir(rawPath, cwd)) {
293
+ externalPaths.push(rawPath);
294
+ externalPaths.push(abs);
295
+ }
296
+ }
297
+ catch { }
298
+ }
299
+ if (toolName === "bash" || toolName === "shell") {
300
+ const command = args.command;
301
+ if (command) {
302
+ const firstLine = command.split("\n")[0].trim();
303
+ toolPatterns.push(firstLine);
304
+ const parts = firstLine.split(/\s+/).filter(Boolean);
305
+ if (parts.length >= 2) {
306
+ toolPatterns.push(`${parts[0]} ${parts[1]} *`);
307
+ }
308
+ toolPatterns.push(`${parts[0]} *`);
309
+ const { externalPaths: bashExtPaths, pathPatterns: bashPathPatterns } = extractBashPaths(command, cwd);
310
+ if (bashExtPaths.length > 0) {
311
+ for (const ep of bashExtPaths) {
312
+ if (!externalPaths.some((e) => resolve(cwd, e) === ep)) {
313
+ externalPaths.push(ep);
314
+ }
315
+ }
316
+ }
317
+ for (const pp of bashPathPatterns) {
318
+ if (!pathPatterns.some((p) => resolve(cwd, p) === pp)) {
319
+ pathPatterns.push(pp);
320
+ }
321
+ }
322
+ }
323
+ }
324
+ if (toolName === "web_fetch" || toolName === "webfetch") {
325
+ const url = args.url;
326
+ if (url) {
327
+ try {
328
+ toolPatterns.push(new URL(url).hostname);
329
+ }
330
+ catch { }
331
+ }
332
+ }
333
+ if (toolName === "task") {
334
+ const subagent = (args.subagent_name || args.subagent_type);
335
+ if (subagent)
336
+ toolPatterns.push(subagent);
337
+ }
338
+ if (toolPatterns.length === 0 && pathPatterns.length > 0) {
339
+ toolPatterns.push(...pathPatterns);
340
+ }
341
+ if (toolPatterns.length === 0) {
342
+ toolPatterns.push("*");
343
+ }
344
+ return { toolPatterns, externalPaths, pathPatterns };
345
+ }
346
+ return {
347
+ getReadTracker,
348
+ getDoomLoop,
349
+ getSsrfGuard,
350
+ getPathSafety,
351
+ checkPath,
352
+ checkPermission,
353
+ extractToolPatterns,
354
+ setListener,
355
+ addApproval,
356
+ respondToRequest,
357
+ getRuleset,
358
+ getApprovedConfig,
359
+ get pendingCount() { return pendingRequests.size; },
360
+ };
361
+ }
362
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/security/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ import type { PathSafetyResult } from "./types.js";
2
+ interface PathSafetyConfig {
3
+ blockedPaths: string[];
4
+ allowedPaths: string[];
5
+ }
6
+ export declare class PathSafety {
7
+ private blocked;
8
+ private allowed;
9
+ constructor(config?: Partial<PathSafetyConfig>);
10
+ check(rawPath: string, cwd?: string): PathSafetyResult;
11
+ private isBlocked;
12
+ private isAllowed;
13
+ }
14
+ export {};
15
+ //# sourceMappingURL=path-safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-safety.d.ts","sourceRoot":"","sources":["../../../src/security/path-safety.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAiBlD,UAAU,gBAAgB;IACxB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB;AAED,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC;IAK9C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,gBAAgB;IAkBrE,OAAO,CAAC,SAAS;IAajB,OAAO,CAAC,SAAS;CAQlB"}
@@ -0,0 +1,57 @@
1
+ import { resolve, relative } from "path";
2
+ import { matchWildcard } from "./wildcard.js";
3
+ const DEFAULT_BLOCKED = [
4
+ "**/.ssh/**",
5
+ "**/.aws/credentials",
6
+ "**/.aws/config",
7
+ "**/.gnupg/**",
8
+ "**/.netrc",
9
+ "**/etc/shadow",
10
+ "**/etc/gshadow",
11
+ "**/etc/sudoers",
12
+ "**/.password-store/**",
13
+ "**/.docker/config.json",
14
+ "**/.kube/config",
15
+ ];
16
+ export class PathSafety {
17
+ blocked;
18
+ allowed;
19
+ constructor(config) {
20
+ this.blocked = config?.blockedPaths ?? [...DEFAULT_BLOCKED];
21
+ this.allowed = config?.allowedPaths ?? [];
22
+ }
23
+ check(rawPath, cwd = process.cwd()) {
24
+ if (rawPath.includes("\0")) {
25
+ return { ok: false, reason: "Path contains null bytes" };
26
+ }
27
+ const resolved = resolve(cwd, rawPath);
28
+ if (this.isAllowed(resolved)) {
29
+ return { ok: true, resolvedPath: resolved, displayPath: relative(cwd, resolved) || resolved };
30
+ }
31
+ if (this.isBlocked(resolved)) {
32
+ return { ok: false, reason: `Access denied to sensitive path: ${relative(cwd, resolved) || resolved}` };
33
+ }
34
+ return { ok: true, resolvedPath: resolved, displayPath: relative(cwd, resolved) || resolved };
35
+ }
36
+ isBlocked(fullPath) {
37
+ for (const pattern of this.blocked) {
38
+ if (matchWildcard("**/" + pattern, fullPath) || matchWildcard(pattern, fullPath)) {
39
+ return true;
40
+ }
41
+ const suffixIdx = pattern.replace(/^(\*\*\/)+/, "");
42
+ if (fullPath.replace(/\\/g, "/").endsWith("/" + suffixIdx)) {
43
+ return true;
44
+ }
45
+ }
46
+ return false;
47
+ }
48
+ isAllowed(fullPath) {
49
+ for (const pattern of this.allowed) {
50
+ if (matchWildcard(pattern, fullPath) || matchWildcard("**/" + pattern, fullPath)) {
51
+ return true;
52
+ }
53
+ }
54
+ return false;
55
+ }
56
+ }
57
+ //# sourceMappingURL=path-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-safety.js","sourceRoot":"","sources":["../../../src/security/path-safety.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,eAAe,GAAG;IACtB,YAAY;IACZ,qBAAqB;IACrB,gBAAgB;IAChB,cAAc;IACd,WAAW;IACX,eAAe;IACf,gBAAgB;IAChB,gBAAgB;IAChB,uBAAuB;IACvB,wBAAwB;IACxB,iBAAiB;CAClB,CAAA;AAOD,MAAM,OAAO,UAAU;IACb,OAAO,CAAU;IACjB,OAAO,CAAU;IAEzB,YAAY,MAAkC;QAC5C,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,YAAY,IAAI,CAAC,GAAG,eAAe,CAAC,CAAA;QAC3D,IAAI,CAAC,OAAO,GAAG,MAAM,EAAE,YAAY,IAAI,EAAE,CAAA;IAC3C,CAAC;IAED,KAAK,CAAC,OAAe,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE;QAChD,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAA;QAC1D,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;QAEtC,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,QAAQ,EAAE,CAAA;QAC/F,CAAC;QAED,IAAI,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,QAAQ,EAAE,EAAE,CAAA;QACzG,CAAC;QAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,CAAC,IAAI,QAAQ,EAAE,CAAA;IAC/F,CAAC;IAEO,SAAS,CAAC,QAAgB;QAChC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,aAAa,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,CAAC,IAAI,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACjF,OAAO,IAAI,CAAA;YACb,CAAC;YACD,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAA;YACnD,IAAI,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,GAAG,GAAG,SAAS,CAAC,EAAE,CAAC;gBAC3D,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;IAEO,SAAS,CAAC,QAAgB;QAChC,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,aAAa,CAAC,KAAK,GAAG,OAAO,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACjF,OAAO,IAAI,CAAA;YACb,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAA;IACd,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ import type { Rule, Ruleset, PermissionConfig } from "./types.js";
2
+ export declare function evaluate(permission: string, pattern: string, ...rulesets: Ruleset[]): Rule;
3
+ export declare function fromConfig(config: PermissionConfig): Ruleset;
4
+ export declare function merge(...rulesets: Ruleset[]): Ruleset;
5
+ export declare function disabled(toolNames: string[], ruleset: Ruleset): Set<string>;
6
+ export declare function getCanonicalPermission(toolName: string): string;
7
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../../src/security/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,OAAO,EAAoB,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAGnF,wBAAgB,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAM1F;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAc5D;AAED,wBAAgB,KAAK,CAAC,GAAG,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAErD;AAID,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAW3E;AAED,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE/D"}
@@ -0,0 +1,41 @@
1
+ import { matchWildcard } from "./wildcard.js";
2
+ export function evaluate(permission, pattern, ...rulesets) {
3
+ const rules = rulesets.flat();
4
+ const match = [...rules].reverse().find((rule) => matchWildcard(rule.permission, permission) && matchWildcard(rule.pattern, pattern));
5
+ return match ?? { permission, pattern: "*", action: "ask" };
6
+ }
7
+ export function fromConfig(config) {
8
+ const ruleset = [];
9
+ for (const [key, value] of Object.entries(config)) {
10
+ if (typeof value === "string") {
11
+ ruleset.push({ permission: key, pattern: "*", action: value });
12
+ }
13
+ else if (typeof value === "object" && value !== null) {
14
+ for (const [pattern, action] of Object.entries(value)) {
15
+ ruleset.push({ permission: key, pattern, action });
16
+ }
17
+ }
18
+ }
19
+ return ruleset;
20
+ }
21
+ export function merge(...rulesets) {
22
+ return rulesets.flat();
23
+ }
24
+ const WRITE_TOOL_NAMES = ["edit", "write", "apply_patch"];
25
+ export function disabled(toolNames, ruleset) {
26
+ const result = new Set();
27
+ for (const tool of toolNames) {
28
+ const permission = WRITE_TOOL_NAMES.includes(tool) ? "write" : tool;
29
+ const rule = [...ruleset].reverse().find((r) => matchWildcard(r.permission, permission));
30
+ if (!rule)
31
+ continue;
32
+ if (rule.pattern === "*" && rule.action === "deny") {
33
+ result.add(tool);
34
+ }
35
+ }
36
+ return result;
37
+ }
38
+ export function getCanonicalPermission(toolName) {
39
+ return WRITE_TOOL_NAMES.includes(toolName) ? "write" : toolName;
40
+ }
41
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../../src/security/permissions.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAE7C,MAAM,UAAU,QAAQ,CAAC,UAAkB,EAAE,OAAe,EAAE,GAAG,QAAmB;IAClF,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAA;IAC7B,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CACrC,CAAC,IAAU,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,IAAI,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CACnG,CAAA;IACD,OAAO,KAAK,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAA;AAC7D,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAwB;IACjD,MAAM,OAAO,GAAY,EAAE,CAAA;IAE3B,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,KAAyB,EAAE,CAAC,CAAA;QACpF,CAAC;aAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACvD,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAyC,CAAC,EAAE,CAAC;gBAC1F,OAAO,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;YACpD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,KAAK,CAAC,GAAG,QAAmB;IAC1C,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAA;AACxB,CAAC;AAED,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,aAAa,CAAC,CAAA;AAEzD,MAAM,UAAU,QAAQ,CAAC,SAAmB,EAAE,OAAgB;IAC5D,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAA;IAChC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAA;QACnE,MAAM,IAAI,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAO,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,CAAA;QAC9F,IAAI,CAAC,IAAI;YAAE,SAAQ;QACnB,IAAI,IAAI,CAAC,OAAO,KAAK,GAAG,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YACnD,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAClB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,QAAgB;IACrD,OAAO,gBAAgB,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAA;AACjE,CAAC"}