@oxagen/cli 0.5.0 → 0.6.1

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 (702) hide show
  1. package/README.md +66 -3
  2. package/dist/agent/__tests__/code-graph.test.d.ts +2 -0
  3. package/dist/agent/__tests__/code-graph.test.d.ts.map +1 -0
  4. package/dist/agent/__tests__/code-graph.test.js +83 -0
  5. package/dist/agent/__tests__/code-graph.test.js.map +1 -0
  6. package/dist/agent/__tests__/evaluator.test.d.ts +2 -0
  7. package/dist/agent/__tests__/evaluator.test.d.ts.map +1 -0
  8. package/dist/agent/__tests__/evaluator.test.js +96 -0
  9. package/dist/agent/__tests__/evaluator.test.js.map +1 -0
  10. package/dist/agent/__tests__/fleet-memory.test.d.ts +2 -0
  11. package/dist/agent/__tests__/fleet-memory.test.d.ts.map +1 -0
  12. package/dist/agent/__tests__/fleet-memory.test.js +107 -0
  13. package/dist/agent/__tests__/fleet-memory.test.js.map +1 -0
  14. package/dist/agent/__tests__/fleet-store.test.d.ts +2 -0
  15. package/dist/agent/__tests__/fleet-store.test.d.ts.map +1 -0
  16. package/dist/agent/__tests__/fleet-store.test.js +93 -0
  17. package/dist/agent/__tests__/fleet-store.test.js.map +1 -0
  18. package/dist/agent/__tests__/git-isolation.test.d.ts +2 -0
  19. package/dist/agent/__tests__/git-isolation.test.d.ts.map +1 -0
  20. package/dist/agent/__tests__/git-isolation.test.js +119 -0
  21. package/dist/agent/__tests__/git-isolation.test.js.map +1 -0
  22. package/dist/agent/__tests__/judge.test.d.ts +2 -0
  23. package/dist/agent/__tests__/judge.test.d.ts.map +1 -0
  24. package/dist/agent/__tests__/judge.test.js +140 -0
  25. package/dist/agent/__tests__/judge.test.js.map +1 -0
  26. package/dist/agent/__tests__/loop-errors.test.d.ts +2 -0
  27. package/dist/agent/__tests__/loop-errors.test.d.ts.map +1 -0
  28. package/dist/agent/__tests__/loop-errors.test.js +75 -0
  29. package/dist/agent/__tests__/loop-errors.test.js.map +1 -0
  30. package/dist/agent/__tests__/loop-gating.test.d.ts +2 -0
  31. package/dist/agent/__tests__/loop-gating.test.d.ts.map +1 -0
  32. package/dist/agent/__tests__/loop-gating.test.js +94 -0
  33. package/dist/agent/__tests__/loop-gating.test.js.map +1 -0
  34. package/dist/agent/__tests__/model-router.test.d.ts +2 -0
  35. package/dist/agent/__tests__/model-router.test.d.ts.map +1 -0
  36. package/dist/agent/__tests__/model-router.test.js +138 -0
  37. package/dist/agent/__tests__/model-router.test.js.map +1 -0
  38. package/dist/agent/__tests__/orchestrator-isolation.test.d.ts +2 -0
  39. package/dist/agent/__tests__/orchestrator-isolation.test.d.ts.map +1 -0
  40. package/dist/agent/__tests__/orchestrator-isolation.test.js +134 -0
  41. package/dist/agent/__tests__/orchestrator-isolation.test.js.map +1 -0
  42. package/dist/agent/__tests__/orchestrator.test.d.ts +2 -0
  43. package/dist/agent/__tests__/orchestrator.test.d.ts.map +1 -0
  44. package/dist/agent/__tests__/orchestrator.test.js +201 -0
  45. package/dist/agent/__tests__/orchestrator.test.js.map +1 -0
  46. package/dist/agent/__tests__/permissions.test.d.ts +2 -0
  47. package/dist/agent/__tests__/permissions.test.d.ts.map +1 -0
  48. package/dist/agent/__tests__/permissions.test.js +206 -0
  49. package/dist/agent/__tests__/permissions.test.js.map +1 -0
  50. package/dist/agent/__tests__/pipeline-telemetry.test.d.ts +2 -0
  51. package/dist/agent/__tests__/pipeline-telemetry.test.d.ts.map +1 -0
  52. package/dist/agent/__tests__/pipeline-telemetry.test.js +158 -0
  53. package/dist/agent/__tests__/pipeline-telemetry.test.js.map +1 -0
  54. package/dist/agent/__tests__/pipeline.test.d.ts +2 -0
  55. package/dist/agent/__tests__/pipeline.test.d.ts.map +1 -0
  56. package/dist/agent/__tests__/pipeline.test.js +235 -0
  57. package/dist/agent/__tests__/pipeline.test.js.map +1 -0
  58. package/dist/agent/__tests__/planner.test.d.ts +2 -0
  59. package/dist/agent/__tests__/planner.test.d.ts.map +1 -0
  60. package/dist/agent/__tests__/planner.test.js +98 -0
  61. package/dist/agent/__tests__/planner.test.js.map +1 -0
  62. package/dist/agent/__tests__/prompt-enhancer.test.d.ts +2 -0
  63. package/dist/agent/__tests__/prompt-enhancer.test.d.ts.map +1 -0
  64. package/dist/agent/__tests__/prompt-enhancer.test.js +107 -0
  65. package/dist/agent/__tests__/prompt-enhancer.test.js.map +1 -0
  66. package/dist/agent/__tests__/rate-card.test.d.ts +2 -0
  67. package/dist/agent/__tests__/rate-card.test.d.ts.map +1 -0
  68. package/dist/agent/__tests__/rate-card.test.js +69 -0
  69. package/dist/agent/__tests__/rate-card.test.js.map +1 -0
  70. package/dist/agent/__tests__/system-prompt.test.d.ts +2 -0
  71. package/dist/agent/__tests__/system-prompt.test.d.ts.map +1 -0
  72. package/dist/agent/__tests__/system-prompt.test.js +29 -0
  73. package/dist/agent/__tests__/system-prompt.test.js.map +1 -0
  74. package/dist/agent/__tests__/trace-format-verbose.test.d.ts +2 -0
  75. package/dist/agent/__tests__/trace-format-verbose.test.d.ts.map +1 -0
  76. package/dist/agent/__tests__/trace-format-verbose.test.js +93 -0
  77. package/dist/agent/__tests__/trace-format-verbose.test.js.map +1 -0
  78. package/dist/agent/__tests__/trace-format.test.d.ts +2 -0
  79. package/dist/agent/__tests__/trace-format.test.d.ts.map +1 -0
  80. package/dist/agent/__tests__/trace-format.test.js +104 -0
  81. package/dist/agent/__tests__/trace-format.test.js.map +1 -0
  82. package/dist/agent/__tests__/trace-store.test.d.ts +2 -0
  83. package/dist/agent/__tests__/trace-store.test.d.ts.map +1 -0
  84. package/dist/agent/__tests__/trace-store.test.js +113 -0
  85. package/dist/agent/__tests__/trace-store.test.js.map +1 -0
  86. package/dist/agent/__tests__/verbose-log.test.d.ts +2 -0
  87. package/dist/agent/__tests__/verbose-log.test.d.ts.map +1 -0
  88. package/dist/agent/__tests__/verbose-log.test.js +69 -0
  89. package/dist/agent/__tests__/verbose-log.test.js.map +1 -0
  90. package/dist/agent/code-graph.d.ts +18 -0
  91. package/dist/agent/code-graph.d.ts.map +1 -0
  92. package/dist/agent/code-graph.js +119 -0
  93. package/dist/agent/code-graph.js.map +1 -0
  94. package/dist/agent/env.d.ts +11 -0
  95. package/dist/agent/env.d.ts.map +1 -0
  96. package/dist/agent/env.js +82 -0
  97. package/dist/agent/env.js.map +1 -0
  98. package/dist/agent/evaluator.d.ts +13 -0
  99. package/dist/agent/evaluator.d.ts.map +1 -0
  100. package/dist/agent/evaluator.js +150 -0
  101. package/dist/agent/evaluator.js.map +1 -0
  102. package/dist/agent/fleet/git-isolation.d.ts +142 -0
  103. package/dist/agent/fleet/git-isolation.d.ts.map +1 -0
  104. package/dist/agent/fleet/git-isolation.js +290 -0
  105. package/dist/agent/fleet/git-isolation.js.map +1 -0
  106. package/dist/agent/fleet/memory.d.ts +21 -0
  107. package/dist/agent/fleet/memory.d.ts.map +1 -0
  108. package/dist/agent/fleet/memory.js +129 -0
  109. package/dist/agent/fleet/memory.js.map +1 -0
  110. package/dist/agent/fleet/orchestrator.d.ts +108 -0
  111. package/dist/agent/fleet/orchestrator.d.ts.map +1 -0
  112. package/dist/agent/fleet/orchestrator.js +358 -0
  113. package/dist/agent/fleet/orchestrator.js.map +1 -0
  114. package/dist/agent/fleet/store.d.ts +13 -0
  115. package/dist/agent/fleet/store.d.ts.map +1 -0
  116. package/dist/agent/fleet/store.js +79 -0
  117. package/dist/agent/fleet/store.js.map +1 -0
  118. package/dist/agent/fleet/types.d.ts +107 -0
  119. package/dist/agent/fleet/types.d.ts.map +1 -0
  120. package/dist/agent/fleet/types.js +17 -0
  121. package/dist/agent/fleet/types.js.map +1 -0
  122. package/dist/agent/judge.d.ts +46 -0
  123. package/dist/agent/judge.d.ts.map +1 -0
  124. package/dist/agent/judge.js +182 -0
  125. package/dist/agent/judge.js.map +1 -0
  126. package/dist/agent/loop.d.ts +96 -0
  127. package/dist/agent/loop.d.ts.map +1 -0
  128. package/dist/agent/loop.js +233 -0
  129. package/dist/agent/loop.js.map +1 -0
  130. package/dist/agent/memory.d.ts +14 -0
  131. package/dist/agent/memory.d.ts.map +1 -0
  132. package/dist/agent/memory.js +118 -0
  133. package/dist/agent/memory.js.map +1 -0
  134. package/dist/agent/model-router.d.ts +65 -0
  135. package/dist/agent/model-router.d.ts.map +1 -0
  136. package/dist/agent/model-router.js +118 -0
  137. package/dist/agent/model-router.js.map +1 -0
  138. package/dist/agent/model.d.ts +9 -0
  139. package/dist/agent/model.d.ts.map +1 -0
  140. package/dist/agent/model.js +24 -0
  141. package/dist/agent/model.js.map +1 -0
  142. package/dist/agent/permissions.d.ts +103 -0
  143. package/dist/agent/permissions.d.ts.map +1 -0
  144. package/dist/agent/permissions.js +245 -0
  145. package/dist/agent/permissions.js.map +1 -0
  146. package/dist/agent/pipeline.d.ts +92 -0
  147. package/dist/agent/pipeline.d.ts.map +1 -0
  148. package/dist/agent/pipeline.js +371 -0
  149. package/dist/agent/pipeline.js.map +1 -0
  150. package/dist/agent/planner.d.ts +19 -0
  151. package/dist/agent/planner.d.ts.map +1 -0
  152. package/dist/agent/planner.js +139 -0
  153. package/dist/agent/planner.js.map +1 -0
  154. package/dist/agent/project-context.d.ts +13 -0
  155. package/dist/agent/project-context.d.ts.map +1 -0
  156. package/dist/agent/project-context.js +66 -0
  157. package/dist/agent/project-context.js.map +1 -0
  158. package/dist/agent/prompt-enhancer.d.ts +46 -0
  159. package/dist/agent/prompt-enhancer.d.ts.map +1 -0
  160. package/dist/agent/prompt-enhancer.js +137 -0
  161. package/dist/agent/prompt-enhancer.js.map +1 -0
  162. package/dist/agent/rate-card.d.ts +77 -0
  163. package/dist/agent/rate-card.d.ts.map +1 -0
  164. package/dist/agent/rate-card.js +99 -0
  165. package/dist/agent/rate-card.js.map +1 -0
  166. package/dist/agent/system-prompt.d.ts +14 -0
  167. package/dist/agent/system-prompt.d.ts.map +1 -0
  168. package/dist/agent/system-prompt.js +47 -0
  169. package/dist/agent/system-prompt.js.map +1 -0
  170. package/dist/agent/tools.d.ts +23 -0
  171. package/dist/agent/tools.d.ts.map +1 -0
  172. package/dist/agent/tools.js +354 -0
  173. package/dist/agent/tools.js.map +1 -0
  174. package/dist/agent/trace-format.d.ts +13 -0
  175. package/dist/agent/trace-format.d.ts.map +1 -0
  176. package/dist/agent/trace-format.js +188 -0
  177. package/dist/agent/trace-format.js.map +1 -0
  178. package/dist/agent/trace-store.d.ts +19 -0
  179. package/dist/agent/trace-store.d.ts.map +1 -0
  180. package/dist/agent/trace-store.js +82 -0
  181. package/dist/agent/trace-store.js.map +1 -0
  182. package/dist/agent/trace.d.ts +180 -0
  183. package/dist/agent/trace.d.ts.map +1 -0
  184. package/dist/agent/trace.js +2 -0
  185. package/dist/agent/trace.js.map +1 -0
  186. package/dist/agent/verbose-log.d.ts +8 -0
  187. package/dist/agent/verbose-log.d.ts.map +1 -0
  188. package/dist/agent/verbose-log.js +53 -0
  189. package/dist/agent/verbose-log.js.map +1 -0
  190. package/dist/agents/__tests__/loader.test.d.ts +2 -0
  191. package/dist/agents/__tests__/loader.test.d.ts.map +1 -0
  192. package/dist/agents/__tests__/loader.test.js +88 -0
  193. package/dist/agents/__tests__/loader.test.js.map +1 -0
  194. package/dist/agents/__tests__/tools.test.d.ts +2 -0
  195. package/dist/agents/__tests__/tools.test.d.ts.map +1 -0
  196. package/dist/agents/__tests__/tools.test.js +40 -0
  197. package/dist/agents/__tests__/tools.test.js.map +1 -0
  198. package/dist/agents/index.d.ts +12 -0
  199. package/dist/agents/index.d.ts.map +1 -0
  200. package/dist/agents/index.js +4 -0
  201. package/dist/agents/index.js.map +1 -0
  202. package/dist/agents/loader.d.ts +25 -0
  203. package/dist/agents/loader.d.ts.map +1 -0
  204. package/dist/agents/loader.js +133 -0
  205. package/dist/agents/loader.js.map +1 -0
  206. package/dist/agents/tools.d.ts +14 -0
  207. package/dist/agents/tools.d.ts.map +1 -0
  208. package/dist/agents/tools.js +21 -0
  209. package/dist/agents/tools.js.map +1 -0
  210. package/dist/agents/types.d.ts +27 -0
  211. package/dist/agents/types.d.ts.map +1 -0
  212. package/dist/agents/types.js +11 -0
  213. package/dist/agents/types.js.map +1 -0
  214. package/dist/agents/write.d.ts +10 -0
  215. package/dist/agents/write.d.ts.map +1 -0
  216. package/dist/agents/write.js +28 -0
  217. package/dist/agents/write.js.map +1 -0
  218. package/dist/commands/__tests__/agent.test.d.ts +2 -0
  219. package/dist/commands/__tests__/agent.test.d.ts.map +1 -0
  220. package/dist/commands/__tests__/agent.test.js +82 -0
  221. package/dist/commands/__tests__/agent.test.js.map +1 -0
  222. package/dist/commands/__tests__/command.test.d.ts +2 -0
  223. package/dist/commands/__tests__/command.test.d.ts.map +1 -0
  224. package/dist/commands/__tests__/command.test.js +73 -0
  225. package/dist/commands/__tests__/command.test.js.map +1 -0
  226. package/dist/commands/__tests__/cost.test.d.ts +2 -0
  227. package/dist/commands/__tests__/cost.test.d.ts.map +1 -0
  228. package/dist/commands/__tests__/cost.test.js +139 -0
  229. package/dist/commands/__tests__/cost.test.js.map +1 -0
  230. package/dist/commands/__tests__/graph.pull.test.d.ts +2 -0
  231. package/dist/commands/__tests__/graph.pull.test.d.ts.map +1 -0
  232. package/dist/commands/__tests__/graph.pull.test.js +259 -0
  233. package/dist/commands/__tests__/graph.pull.test.js.map +1 -0
  234. package/dist/commands/__tests__/mcp.test.d.ts +2 -0
  235. package/dist/commands/__tests__/mcp.test.d.ts.map +1 -0
  236. package/dist/commands/__tests__/mcp.test.js +88 -0
  237. package/dist/commands/__tests__/mcp.test.js.map +1 -0
  238. package/dist/commands/__tests__/replay.test.d.ts +2 -0
  239. package/dist/commands/__tests__/replay.test.d.ts.map +1 -0
  240. package/dist/commands/__tests__/replay.test.js +76 -0
  241. package/dist/commands/__tests__/replay.test.js.map +1 -0
  242. package/dist/commands/__tests__/rules.test.d.ts +2 -0
  243. package/dist/commands/__tests__/rules.test.d.ts.map +1 -0
  244. package/dist/commands/__tests__/rules.test.js +95 -0
  245. package/dist/commands/__tests__/rules.test.js.map +1 -0
  246. package/dist/commands/__tests__/settings.test.d.ts +2 -0
  247. package/dist/commands/__tests__/settings.test.d.ts.map +1 -0
  248. package/dist/commands/__tests__/settings.test.js +83 -0
  249. package/dist/commands/__tests__/settings.test.js.map +1 -0
  250. package/dist/commands/agent.d.ts +15 -0
  251. package/dist/commands/agent.d.ts.map +1 -0
  252. package/dist/commands/agent.js +58 -0
  253. package/dist/commands/agent.js.map +1 -0
  254. package/dist/commands/agent.skill.load.d.ts +3 -0
  255. package/dist/commands/agent.skill.load.d.ts.map +1 -0
  256. package/dist/commands/agent.skill.load.js +57 -0
  257. package/dist/commands/agent.skill.load.js.map +1 -0
  258. package/dist/commands/code.d.ts +14 -0
  259. package/dist/commands/code.d.ts.map +1 -0
  260. package/dist/commands/code.js +100 -0
  261. package/dist/commands/code.js.map +1 -0
  262. package/dist/commands/command.d.ts +17 -0
  263. package/dist/commands/command.d.ts.map +1 -0
  264. package/dist/commands/command.js +74 -0
  265. package/dist/commands/command.js.map +1 -0
  266. package/dist/commands/config.d.ts +2 -0
  267. package/dist/commands/config.d.ts.map +1 -0
  268. package/dist/commands/config.js +66 -0
  269. package/dist/commands/config.js.map +1 -0
  270. package/dist/commands/cost.d.ts +10 -0
  271. package/dist/commands/cost.d.ts.map +1 -0
  272. package/dist/commands/cost.js +140 -0
  273. package/dist/commands/cost.js.map +1 -0
  274. package/dist/commands/env.d.ts +19 -0
  275. package/dist/commands/env.d.ts.map +1 -0
  276. package/dist/commands/env.js +64 -0
  277. package/dist/commands/env.js.map +1 -0
  278. package/dist/commands/graph.pull.d.ts +15 -0
  279. package/dist/commands/graph.pull.d.ts.map +1 -0
  280. package/dist/commands/graph.pull.js +137 -0
  281. package/dist/commands/graph.pull.js.map +1 -0
  282. package/dist/commands/graph.search.d.ts +10 -0
  283. package/dist/commands/graph.search.d.ts.map +1 -0
  284. package/dist/commands/graph.search.js +25 -0
  285. package/dist/commands/graph.search.js.map +1 -0
  286. package/dist/commands/graph.status.d.ts +10 -0
  287. package/dist/commands/graph.status.d.ts.map +1 -0
  288. package/dist/commands/graph.status.js +75 -0
  289. package/dist/commands/graph.status.js.map +1 -0
  290. package/dist/commands/mcp.add.d.ts +13 -0
  291. package/dist/commands/mcp.add.d.ts.map +1 -0
  292. package/dist/commands/mcp.add.js +110 -0
  293. package/dist/commands/mcp.add.js.map +1 -0
  294. package/dist/commands/mcp.auth.d.ts +10 -0
  295. package/dist/commands/mcp.auth.d.ts.map +1 -0
  296. package/dist/commands/mcp.auth.js +132 -0
  297. package/dist/commands/mcp.auth.js.map +1 -0
  298. package/dist/commands/mcp.check.d.ts +10 -0
  299. package/dist/commands/mcp.check.d.ts.map +1 -0
  300. package/dist/commands/mcp.check.js +114 -0
  301. package/dist/commands/mcp.check.js.map +1 -0
  302. package/dist/commands/mcp.d.ts +18 -0
  303. package/dist/commands/mcp.d.ts.map +1 -0
  304. package/dist/commands/mcp.js +183 -0
  305. package/dist/commands/mcp.js.map +1 -0
  306. package/dist/commands/mcp.list.d.ts +9 -0
  307. package/dist/commands/mcp.list.d.ts.map +1 -0
  308. package/dist/commands/mcp.list.js +93 -0
  309. package/dist/commands/mcp.list.js.map +1 -0
  310. package/dist/commands/mcp.permit.d.ts +12 -0
  311. package/dist/commands/mcp.permit.d.ts.map +1 -0
  312. package/dist/commands/mcp.permit.js +117 -0
  313. package/dist/commands/mcp.permit.js.map +1 -0
  314. package/dist/commands/mcp.remove.d.ts +9 -0
  315. package/dist/commands/mcp.remove.d.ts.map +1 -0
  316. package/dist/commands/mcp.remove.js +65 -0
  317. package/dist/commands/mcp.remove.js.map +1 -0
  318. package/dist/commands/plugin.org.install_bulk.js +1 -1
  319. package/dist/commands/plugin.org.install_bulk.js.map +1 -1
  320. package/dist/commands/privacy.erase.test.js +7 -0
  321. package/dist/commands/privacy.erase.test.js.map +1 -1
  322. package/dist/commands/replay.d.ts +5 -0
  323. package/dist/commands/replay.d.ts.map +1 -0
  324. package/dist/commands/replay.js +28 -0
  325. package/dist/commands/replay.js.map +1 -0
  326. package/dist/commands/rules.d.ts +19 -0
  327. package/dist/commands/rules.d.ts.map +1 -0
  328. package/dist/commands/rules.js +96 -0
  329. package/dist/commands/rules.js.map +1 -0
  330. package/dist/commands/schema/schema.config.d.ts +3 -0
  331. package/dist/commands/schema/schema.config.d.ts.map +1 -0
  332. package/dist/commands/schema/schema.config.js +34 -0
  333. package/dist/commands/schema/schema.config.js.map +1 -0
  334. package/dist/commands/schema/schema.disable.d.ts +3 -0
  335. package/dist/commands/schema/schema.disable.d.ts.map +1 -0
  336. package/dist/commands/schema/schema.disable.js +22 -0
  337. package/dist/commands/schema/schema.disable.js.map +1 -0
  338. package/dist/commands/schema/schema.enable.d.ts +3 -0
  339. package/dist/commands/schema/schema.enable.d.ts.map +1 -0
  340. package/dist/commands/schema/schema.enable.js +22 -0
  341. package/dist/commands/schema/schema.enable.js.map +1 -0
  342. package/dist/commands/schema/schema.export.d.ts +3 -0
  343. package/dist/commands/schema/schema.export.d.ts.map +1 -0
  344. package/dist/commands/schema/schema.export.js +31 -0
  345. package/dist/commands/schema/schema.export.js.map +1 -0
  346. package/dist/commands/schema/schema.get.d.ts +3 -0
  347. package/dist/commands/schema/schema.get.d.ts.map +1 -0
  348. package/dist/commands/schema/schema.get.js +23 -0
  349. package/dist/commands/schema/schema.get.js.map +1 -0
  350. package/dist/commands/schema/schema.label.d.ts +5 -0
  351. package/dist/commands/schema/schema.label.d.ts.map +1 -0
  352. package/dist/commands/schema/schema.label.js +60 -0
  353. package/dist/commands/schema/schema.label.js.map +1 -0
  354. package/dist/commands/schema/schema.list.d.ts +3 -0
  355. package/dist/commands/schema/schema.list.d.ts.map +1 -0
  356. package/dist/commands/schema/schema.list.js +30 -0
  357. package/dist/commands/schema/schema.list.js.map +1 -0
  358. package/dist/commands/schema/schema.prop.d.ts +5 -0
  359. package/dist/commands/schema/schema.prop.d.ts.map +1 -0
  360. package/dist/commands/schema/schema.prop.js +72 -0
  361. package/dist/commands/schema/schema.prop.js.map +1 -0
  362. package/dist/commands/schema/schema.reconcile.d.ts +10 -0
  363. package/dist/commands/schema/schema.reconcile.d.ts.map +1 -0
  364. package/dist/commands/schema/schema.reconcile.js +65 -0
  365. package/dist/commands/schema/schema.reconcile.js.map +1 -0
  366. package/dist/commands/schema/schema.rel.d.ts +5 -0
  367. package/dist/commands/schema/schema.rel.d.ts.map +1 -0
  368. package/dist/commands/schema/schema.rel.js +65 -0
  369. package/dist/commands/schema/schema.rel.js.map +1 -0
  370. package/dist/commands/schema/schema.version.d.ts +7 -0
  371. package/dist/commands/schema/schema.version.d.ts.map +1 -0
  372. package/dist/commands/schema/schema.version.js +96 -0
  373. package/dist/commands/schema/schema.version.js.map +1 -0
  374. package/dist/commands/secret.d.ts +23 -0
  375. package/dist/commands/secret.d.ts.map +1 -0
  376. package/dist/commands/secret.js +90 -0
  377. package/dist/commands/secret.js.map +1 -0
  378. package/dist/commands/settings.d.ts +10 -0
  379. package/dist/commands/settings.d.ts.map +1 -0
  380. package/dist/commands/settings.js +117 -0
  381. package/dist/commands/settings.js.map +1 -0
  382. package/dist/commands/skill.create.d.ts +3 -0
  383. package/dist/commands/skill.create.d.ts.map +1 -0
  384. package/dist/commands/skill.create.js +52 -0
  385. package/dist/commands/skill.create.js.map +1 -0
  386. package/dist/commands/skill.enable.d.ts +3 -0
  387. package/dist/commands/skill.enable.d.ts.map +1 -0
  388. package/dist/commands/skill.enable.js +31 -0
  389. package/dist/commands/skill.enable.js.map +1 -0
  390. package/dist/commands.test.js +1291 -281
  391. package/dist/commands.test.js.map +1 -1
  392. package/dist/components/DevStatus.d.ts.map +1 -1
  393. package/dist/components/DevStatus.js +3 -2
  394. package/dist/components/DevStatus.js.map +1 -1
  395. package/dist/daemon/client.d.ts +30 -0
  396. package/dist/daemon/client.d.ts.map +1 -0
  397. package/dist/daemon/client.js +97 -0
  398. package/dist/daemon/client.js.map +1 -0
  399. package/dist/daemon/code-graph/builder.d.ts +6 -0
  400. package/dist/daemon/code-graph/builder.d.ts.map +1 -0
  401. package/dist/daemon/code-graph/builder.js +215 -0
  402. package/dist/daemon/code-graph/builder.js.map +1 -0
  403. package/dist/daemon/code-graph/query.d.ts +29 -0
  404. package/dist/daemon/code-graph/query.d.ts.map +1 -0
  405. package/dist/daemon/code-graph/query.js +98 -0
  406. package/dist/daemon/code-graph/query.js.map +1 -0
  407. package/dist/daemon/code-graph/types.d.ts +37 -0
  408. package/dist/daemon/code-graph/types.d.ts.map +1 -0
  409. package/dist/daemon/code-graph/types.js +5 -0
  410. package/dist/daemon/code-graph/types.js.map +1 -0
  411. package/dist/daemon/code-graph/watcher.d.ts +37 -0
  412. package/dist/daemon/code-graph/watcher.d.ts.map +1 -0
  413. package/dist/daemon/code-graph/watcher.js +79 -0
  414. package/dist/daemon/code-graph/watcher.js.map +1 -0
  415. package/dist/daemon/lifecycle.d.ts +6 -0
  416. package/dist/daemon/lifecycle.d.ts.map +1 -0
  417. package/dist/daemon/lifecycle.js +132 -0
  418. package/dist/daemon/lifecycle.js.map +1 -0
  419. package/dist/daemon/protocol.d.ts +113 -0
  420. package/dist/daemon/protocol.d.ts.map +1 -0
  421. package/dist/daemon/protocol.js +16 -0
  422. package/dist/daemon/protocol.js.map +1 -0
  423. package/dist/daemon/server.d.ts +26 -0
  424. package/dist/daemon/server.d.ts.map +1 -0
  425. package/dist/daemon/server.js +168 -0
  426. package/dist/daemon/server.js.map +1 -0
  427. package/dist/index.d.ts +1 -1
  428. package/dist/index.js +559 -357
  429. package/dist/index.js.map +1 -1
  430. package/dist/lib/api.d.ts +5 -0
  431. package/dist/lib/api.d.ts.map +1 -0
  432. package/dist/lib/api.js +52 -0
  433. package/dist/lib/api.js.map +1 -0
  434. package/dist/lib/config.d.ts +5 -0
  435. package/dist/lib/config.d.ts.map +1 -1
  436. package/dist/lib/config.js +8 -2
  437. package/dist/lib/config.js.map +1 -1
  438. package/dist/lib/differential-context.d.ts +46 -0
  439. package/dist/lib/differential-context.d.ts.map +1 -0
  440. package/dist/lib/differential-context.js +89 -0
  441. package/dist/lib/differential-context.js.map +1 -0
  442. package/dist/lib/resolve.d.ts +3 -0
  443. package/dist/lib/resolve.d.ts.map +1 -0
  444. package/dist/lib/resolve.js +29 -0
  445. package/dist/lib/resolve.js.map +1 -0
  446. package/dist/lib/structured-tool-io.d.ts +31 -0
  447. package/dist/lib/structured-tool-io.d.ts.map +1 -0
  448. package/dist/lib/structured-tool-io.js +56 -0
  449. package/dist/lib/structured-tool-io.js.map +1 -0
  450. package/dist/mcp/__tests__/client.test.d.ts +2 -0
  451. package/dist/mcp/__tests__/client.test.d.ts.map +1 -0
  452. package/dist/mcp/__tests__/client.test.js +101 -0
  453. package/dist/mcp/__tests__/client.test.js.map +1 -0
  454. package/dist/mcp/client.d.ts +89 -0
  455. package/dist/mcp/client.d.ts.map +1 -0
  456. package/dist/mcp/client.js +201 -0
  457. package/dist/mcp/client.js.map +1 -0
  458. package/dist/repl/__tests__/_queue_demo.test.d.ts +2 -0
  459. package/dist/repl/__tests__/_queue_demo.test.d.ts.map +1 -0
  460. package/dist/repl/__tests__/_queue_demo.test.js +40 -0
  461. package/dist/repl/__tests__/_queue_demo.test.js.map +1 -0
  462. package/dist/repl/__tests__/components.test.d.ts +2 -0
  463. package/dist/repl/__tests__/components.test.d.ts.map +1 -0
  464. package/dist/repl/__tests__/components.test.js +87 -0
  465. package/dist/repl/__tests__/components.test.js.map +1 -0
  466. package/dist/repl/__tests__/interactive.queue.test.d.ts +2 -0
  467. package/dist/repl/__tests__/interactive.queue.test.d.ts.map +1 -0
  468. package/dist/repl/__tests__/interactive.queue.test.js +124 -0
  469. package/dist/repl/__tests__/interactive.queue.test.js.map +1 -0
  470. package/dist/repl/components.d.ts +76 -0
  471. package/dist/repl/components.d.ts.map +1 -0
  472. package/dist/repl/components.js +182 -0
  473. package/dist/repl/components.js.map +1 -0
  474. package/dist/repl/interactive.d.ts +17 -0
  475. package/dist/repl/interactive.d.ts.map +1 -0
  476. package/dist/repl/interactive.js +439 -0
  477. package/dist/repl/interactive.js.map +1 -0
  478. package/dist/repl/one-shot.d.ts +25 -0
  479. package/dist/repl/one-shot.d.ts.map +1 -0
  480. package/dist/repl/one-shot.js +153 -0
  481. package/dist/repl/one-shot.js.map +1 -0
  482. package/dist/rules/__tests__/enforce.test.d.ts +2 -0
  483. package/dist/rules/__tests__/enforce.test.d.ts.map +1 -0
  484. package/dist/rules/__tests__/enforce.test.js +58 -0
  485. package/dist/rules/__tests__/enforce.test.js.map +1 -0
  486. package/dist/rules/__tests__/loader.test.d.ts +2 -0
  487. package/dist/rules/__tests__/loader.test.d.ts.map +1 -0
  488. package/dist/rules/__tests__/loader.test.js +54 -0
  489. package/dist/rules/__tests__/loader.test.js.map +1 -0
  490. package/dist/rules/enforce.d.ts +23 -0
  491. package/dist/rules/enforce.d.ts.map +1 -0
  492. package/dist/rules/enforce.js +36 -0
  493. package/dist/rules/enforce.js.map +1 -0
  494. package/dist/rules/index.d.ts +10 -0
  495. package/dist/rules/index.d.ts.map +1 -0
  496. package/dist/rules/index.js +4 -0
  497. package/dist/rules/index.js.map +1 -0
  498. package/dist/rules/loader.d.ts +10 -0
  499. package/dist/rules/loader.d.ts.map +1 -0
  500. package/dist/rules/loader.js +77 -0
  501. package/dist/rules/loader.js.map +1 -0
  502. package/dist/rules/types.d.ts +39 -0
  503. package/dist/rules/types.d.ts.map +1 -0
  504. package/dist/rules/types.js +16 -0
  505. package/dist/rules/types.js.map +1 -0
  506. package/dist/rules/write.d.ts +10 -0
  507. package/dist/rules/write.d.ts.map +1 -0
  508. package/dist/rules/write.js +28 -0
  509. package/dist/rules/write.js.map +1 -0
  510. package/dist/settings/__tests__/gate.test.d.ts +2 -0
  511. package/dist/settings/__tests__/gate.test.d.ts.map +1 -0
  512. package/dist/settings/__tests__/gate.test.js +137 -0
  513. package/dist/settings/__tests__/gate.test.js.map +1 -0
  514. package/dist/settings/__tests__/hooks.test.d.ts +2 -0
  515. package/dist/settings/__tests__/hooks.test.d.ts.map +1 -0
  516. package/dist/settings/__tests__/hooks.test.js +103 -0
  517. package/dist/settings/__tests__/hooks.test.js.map +1 -0
  518. package/dist/settings/__tests__/mcp-write.test.d.ts +2 -0
  519. package/dist/settings/__tests__/mcp-write.test.d.ts.map +1 -0
  520. package/dist/settings/__tests__/mcp-write.test.js +77 -0
  521. package/dist/settings/__tests__/mcp-write.test.js.map +1 -0
  522. package/dist/settings/__tests__/permissions-gate.test.d.ts +2 -0
  523. package/dist/settings/__tests__/permissions-gate.test.d.ts.map +1 -0
  524. package/dist/settings/__tests__/permissions-gate.test.js +75 -0
  525. package/dist/settings/__tests__/permissions-gate.test.js.map +1 -0
  526. package/dist/settings/__tests__/resolve.test.d.ts +2 -0
  527. package/dist/settings/__tests__/resolve.test.d.ts.map +1 -0
  528. package/dist/settings/__tests__/resolve.test.js +109 -0
  529. package/dist/settings/__tests__/resolve.test.js.map +1 -0
  530. package/dist/settings/__tests__/runtime.test.d.ts +2 -0
  531. package/dist/settings/__tests__/runtime.test.d.ts.map +1 -0
  532. package/dist/settings/__tests__/runtime.test.js +72 -0
  533. package/dist/settings/__tests__/runtime.test.js.map +1 -0
  534. package/dist/settings/__tests__/schema.test.d.ts +2 -0
  535. package/dist/settings/__tests__/schema.test.d.ts.map +1 -0
  536. package/dist/settings/__tests__/schema.test.js +55 -0
  537. package/dist/settings/__tests__/schema.test.js.map +1 -0
  538. package/dist/settings/__tests__/write.test.d.ts +2 -0
  539. package/dist/settings/__tests__/write.test.d.ts.map +1 -0
  540. package/dist/settings/__tests__/write.test.js +61 -0
  541. package/dist/settings/__tests__/write.test.js.map +1 -0
  542. package/dist/settings/gate.d.ts +34 -0
  543. package/dist/settings/gate.d.ts.map +1 -0
  544. package/dist/settings/gate.js +50 -0
  545. package/dist/settings/gate.js.map +1 -0
  546. package/dist/settings/hooks.d.ts +26 -0
  547. package/dist/settings/hooks.d.ts.map +1 -0
  548. package/dist/settings/hooks.js +115 -0
  549. package/dist/settings/hooks.js.map +1 -0
  550. package/dist/settings/index.d.ts +23 -0
  551. package/dist/settings/index.d.ts.map +1 -0
  552. package/dist/settings/index.js +23 -0
  553. package/dist/settings/index.js.map +1 -0
  554. package/dist/settings/mcp-write.d.ts +41 -0
  555. package/dist/settings/mcp-write.d.ts.map +1 -0
  556. package/dist/settings/mcp-write.js +61 -0
  557. package/dist/settings/mcp-write.js.map +1 -0
  558. package/dist/settings/permissions-gate.d.ts +19 -0
  559. package/dist/settings/permissions-gate.d.ts.map +1 -0
  560. package/dist/settings/permissions-gate.js +103 -0
  561. package/dist/settings/permissions-gate.js.map +1 -0
  562. package/dist/settings/resolve.d.ts +37 -0
  563. package/dist/settings/resolve.d.ts.map +1 -0
  564. package/dist/settings/resolve.js +169 -0
  565. package/dist/settings/resolve.js.map +1 -0
  566. package/dist/settings/runtime.d.ts +28 -0
  567. package/dist/settings/runtime.d.ts.map +1 -0
  568. package/dist/settings/runtime.js +45 -0
  569. package/dist/settings/runtime.js.map +1 -0
  570. package/dist/settings/schema.d.ts +1387 -0
  571. package/dist/settings/schema.d.ts.map +1 -0
  572. package/dist/settings/schema.js +146 -0
  573. package/dist/settings/schema.js.map +1 -0
  574. package/dist/settings/write.d.ts +37 -0
  575. package/dist/settings/write.d.ts.map +1 -0
  576. package/dist/settings/write.js +85 -0
  577. package/dist/settings/write.js.map +1 -0
  578. package/dist/slash/__tests__/expand.test.d.ts +2 -0
  579. package/dist/slash/__tests__/expand.test.d.ts.map +1 -0
  580. package/dist/slash/__tests__/expand.test.js +44 -0
  581. package/dist/slash/__tests__/expand.test.js.map +1 -0
  582. package/dist/slash/__tests__/loader.test.d.ts +2 -0
  583. package/dist/slash/__tests__/loader.test.d.ts.map +1 -0
  584. package/dist/slash/__tests__/loader.test.js +48 -0
  585. package/dist/slash/__tests__/loader.test.js.map +1 -0
  586. package/dist/slash/expand.d.ts +32 -0
  587. package/dist/slash/expand.d.ts.map +1 -0
  588. package/dist/slash/expand.js +48 -0
  589. package/dist/slash/expand.js.map +1 -0
  590. package/dist/slash/index.d.ts +11 -0
  591. package/dist/slash/index.d.ts.map +1 -0
  592. package/dist/slash/index.js +4 -0
  593. package/dist/slash/index.js.map +1 -0
  594. package/dist/slash/loader.d.ts +10 -0
  595. package/dist/slash/loader.d.ts.map +1 -0
  596. package/dist/slash/loader.js +64 -0
  597. package/dist/slash/loader.js.map +1 -0
  598. package/dist/slash/types.d.ts +24 -0
  599. package/dist/slash/types.d.ts.map +1 -0
  600. package/dist/slash/types.js +11 -0
  601. package/dist/slash/types.js.map +1 -0
  602. package/dist/slash/write.d.ts +10 -0
  603. package/dist/slash/write.d.ts.map +1 -0
  604. package/dist/slash/write.js +26 -0
  605. package/dist/slash/write.js.map +1 -0
  606. package/dist/tui/__tests__/app.test.d.ts +2 -0
  607. package/dist/tui/__tests__/app.test.d.ts.map +1 -0
  608. package/dist/tui/__tests__/app.test.js +136 -0
  609. package/dist/tui/__tests__/app.test.js.map +1 -0
  610. package/dist/tui/__tests__/banner.test.d.ts +2 -0
  611. package/dist/tui/__tests__/banner.test.d.ts.map +1 -0
  612. package/dist/tui/__tests__/banner.test.js +15 -0
  613. package/dist/tui/__tests__/banner.test.js.map +1 -0
  614. package/dist/tui/__tests__/command-form.test.d.ts +2 -0
  615. package/dist/tui/__tests__/command-form.test.d.ts.map +1 -0
  616. package/dist/tui/__tests__/command-form.test.js +96 -0
  617. package/dist/tui/__tests__/command-form.test.js.map +1 -0
  618. package/dist/tui/__tests__/command-tree.test.d.ts +2 -0
  619. package/dist/tui/__tests__/command-tree.test.d.ts.map +1 -0
  620. package/dist/tui/__tests__/command-tree.test.js +55 -0
  621. package/dist/tui/__tests__/command-tree.test.js.map +1 -0
  622. package/dist/tui/__tests__/runner.test.d.ts +2 -0
  623. package/dist/tui/__tests__/runner.test.d.ts.map +1 -0
  624. package/dist/tui/__tests__/runner.test.js +38 -0
  625. package/dist/tui/__tests__/runner.test.js.map +1 -0
  626. package/dist/tui/__tests__/theme.test.d.ts +2 -0
  627. package/dist/tui/__tests__/theme.test.d.ts.map +1 -0
  628. package/dist/tui/__tests__/theme.test.js +11 -0
  629. package/dist/tui/__tests__/theme.test.js.map +1 -0
  630. package/dist/tui/agent-view/activity-feed.d.ts +3 -0
  631. package/dist/tui/agent-view/activity-feed.d.ts.map +1 -0
  632. package/dist/tui/agent-view/activity-feed.js +34 -0
  633. package/dist/tui/agent-view/activity-feed.js.map +1 -0
  634. package/dist/tui/agent-view/budget-bar.d.ts +3 -0
  635. package/dist/tui/agent-view/budget-bar.d.ts.map +1 -0
  636. package/dist/tui/agent-view/budget-bar.js +53 -0
  637. package/dist/tui/agent-view/budget-bar.js.map +1 -0
  638. package/dist/tui/agent-view/compile-panel.d.ts +3 -0
  639. package/dist/tui/agent-view/compile-panel.d.ts.map +1 -0
  640. package/dist/tui/agent-view/compile-panel.js +34 -0
  641. package/dist/tui/agent-view/compile-panel.js.map +1 -0
  642. package/dist/tui/agent-view/index.d.ts +4 -0
  643. package/dist/tui/agent-view/index.d.ts.map +1 -0
  644. package/dist/tui/agent-view/index.js +31 -0
  645. package/dist/tui/agent-view/index.js.map +1 -0
  646. package/dist/tui/agent-view/memory-panel.d.ts +3 -0
  647. package/dist/tui/agent-view/memory-panel.d.ts.map +1 -0
  648. package/dist/tui/agent-view/memory-panel.js +80 -0
  649. package/dist/tui/agent-view/memory-panel.js.map +1 -0
  650. package/dist/tui/agent-view/session-panel.d.ts +3 -0
  651. package/dist/tui/agent-view/session-panel.d.ts.map +1 -0
  652. package/dist/tui/agent-view/session-panel.js +44 -0
  653. package/dist/tui/agent-view/session-panel.js.map +1 -0
  654. package/dist/tui/agent-view/status-bar.d.ts +7 -0
  655. package/dist/tui/agent-view/status-bar.d.ts.map +1 -0
  656. package/dist/tui/agent-view/status-bar.js +22 -0
  657. package/dist/tui/agent-view/status-bar.js.map +1 -0
  658. package/dist/tui/app.d.ts +9 -0
  659. package/dist/tui/app.d.ts.map +1 -0
  660. package/dist/tui/app.js +115 -0
  661. package/dist/tui/app.js.map +1 -0
  662. package/dist/tui/banner.d.ts +5 -0
  663. package/dist/tui/banner.d.ts.map +1 -0
  664. package/dist/tui/banner.js +17 -0
  665. package/dist/tui/banner.js.map +1 -0
  666. package/dist/tui/command-form.d.ts +9 -0
  667. package/dist/tui/command-form.d.ts.map +1 -0
  668. package/dist/tui/command-form.js +76 -0
  669. package/dist/tui/command-form.js.map +1 -0
  670. package/dist/tui/command-tree.d.ts +30 -0
  671. package/dist/tui/command-tree.d.ts.map +1 -0
  672. package/dist/tui/command-tree.js +43 -0
  673. package/dist/tui/command-tree.js.map +1 -0
  674. package/dist/tui/fleet-view/agent-row.d.ts +10 -0
  675. package/dist/tui/fleet-view/agent-row.d.ts.map +1 -0
  676. package/dist/tui/fleet-view/agent-row.js +80 -0
  677. package/dist/tui/fleet-view/agent-row.js.map +1 -0
  678. package/dist/tui/fleet-view/dispatch-input.d.ts +5 -0
  679. package/dist/tui/fleet-view/dispatch-input.d.ts.map +1 -0
  680. package/dist/tui/fleet-view/dispatch-input.js +36 -0
  681. package/dist/tui/fleet-view/dispatch-input.js.map +1 -0
  682. package/dist/tui/fleet-view/fleet-app.d.ts +11 -0
  683. package/dist/tui/fleet-view/fleet-app.d.ts.map +1 -0
  684. package/dist/tui/fleet-view/fleet-app.js +95 -0
  685. package/dist/tui/fleet-view/fleet-app.js.map +1 -0
  686. package/dist/tui/fleet-view/fleet-summary.d.ts +6 -0
  687. package/dist/tui/fleet-view/fleet-summary.d.ts.map +1 -0
  688. package/dist/tui/fleet-view/fleet-summary.js +19 -0
  689. package/dist/tui/fleet-view/fleet-summary.js.map +1 -0
  690. package/dist/tui/fleet-view/index.d.ts +16 -0
  691. package/dist/tui/fleet-view/index.d.ts.map +1 -0
  692. package/dist/tui/fleet-view/index.js +65 -0
  693. package/dist/tui/fleet-view/index.js.map +1 -0
  694. package/dist/tui/runner.d.ts +7 -0
  695. package/dist/tui/runner.d.ts.map +1 -0
  696. package/dist/tui/runner.js +36 -0
  697. package/dist/tui/runner.js.map +1 -0
  698. package/dist/tui/theme.d.ts +8 -0
  699. package/dist/tui/theme.d.ts.map +1 -0
  700. package/dist/tui/theme.js +10 -0
  701. package/dist/tui/theme.js.map +1 -0
  702. package/package.json +16 -7
@@ -0,0 +1,61 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { mkdtempSync, rmSync, readFileSync, existsSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ import { writeSettingsValue, writeStarterSettings } from "../write.js";
6
+ import { loadSettings, getScopePaths, clearSettingsCache } from "../resolve.js";
7
+ let dir;
8
+ let userPath;
9
+ beforeEach(() => {
10
+ dir = mkdtempSync(join(tmpdir(), "oxagen-write-"));
11
+ userPath = join(dir, "user-settings.json");
12
+ clearSettingsCache();
13
+ });
14
+ afterEach(() => {
15
+ rmSync(dir, { recursive: true, force: true });
16
+ clearSettingsCache();
17
+ });
18
+ describe("writeSettingsValue", () => {
19
+ it("writes a scalar into the project scope and round-trips through loadSettings", () => {
20
+ const path = writeSettingsValue({ scope: "project", key: "model", value: "a/b", cwd: dir });
21
+ expect(existsSync(path)).toBe(true);
22
+ expect(path).toBe(getScopePaths({ cwd: dir }).project);
23
+ const reread = loadSettings({ cwd: dir, userSettingsPath: userPath, noCache: true }).settings;
24
+ expect(reread.model).toBe("a/b");
25
+ });
26
+ it("writes an env var via the env.NAME form", () => {
27
+ writeSettingsValue({ scope: "local", key: "env.MY_TOKEN", value: "sek", cwd: dir });
28
+ const reread = loadSettings({ cwd: dir, userSettingsPath: userPath, noCache: true }).settings;
29
+ expect(reread.env?.MY_TOKEN).toBe("sek");
30
+ });
31
+ it("merges into an existing file rather than clobbering it", () => {
32
+ writeSettingsValue({ scope: "project", key: "model", value: "a/b", cwd: dir });
33
+ writeSettingsValue({ scope: "project", key: "env.K", value: "v", cwd: dir });
34
+ const reread = loadSettings({ cwd: dir, userSettingsPath: userPath, noCache: true }).settings;
35
+ expect(reread.model).toBe("a/b");
36
+ expect(reread.env?.K).toBe("v");
37
+ });
38
+ it("rejects an unsupported key", () => {
39
+ expect(() => writeSettingsValue({ scope: "project", key: "permissions", value: "x", cwd: dir })).toThrow(/cannot set/);
40
+ });
41
+ it("rejects an empty env name", () => {
42
+ expect(() => writeSettingsValue({ scope: "project", key: "env.", value: "x", cwd: dir })).toThrow();
43
+ });
44
+ });
45
+ describe("writeStarterSettings", () => {
46
+ it("creates a valid starter file and is idempotent", () => {
47
+ const first = writeStarterSettings({ scope: "project", cwd: dir });
48
+ expect(first.created).toBe(true);
49
+ const doc = JSON.parse(readFileSync(first.path, "utf8"));
50
+ expect(doc["$schema"]).toBeTruthy();
51
+ expect(doc["permissions"]).toBeTruthy();
52
+ const second = writeStarterSettings({ scope: "project", cwd: dir });
53
+ expect(second.created).toBe(false);
54
+ });
55
+ it("starter file passes validation via loadSettings", () => {
56
+ writeStarterSettings({ scope: "project", cwd: dir });
57
+ const resolved = loadSettings({ cwd: dir, userSettingsPath: userPath, noCache: true });
58
+ expect(resolved.scopes.find((s) => s.scope === "project")?.error).toBeUndefined();
59
+ });
60
+ });
61
+ //# sourceMappingURL=write.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write.test.js","sourceRoot":"","sources":["../../../src/settings/__tests__/write.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * gate.ts — Wraps the agent's local tools with the settings-driven permission
3
+ * gate and PreToolUse/PostToolUse hooks.
4
+ *
5
+ * This is the single chokepoint where `settings.json` becomes load-bearing for
6
+ * tool execution: every tool's `execute` is intercepted to (1) evaluate the
7
+ * permission rules and (2) fire hooks. A denied call or a blocking PreToolUse
8
+ * hook returns a plain string the model reads instead of running the tool — the
9
+ * loop continues, the side effect never happens.
10
+ */
11
+ import type { ToolSet } from "ai";
12
+ import type { Hooks, Permissions } from "./schema.js";
13
+ export interface ToolGateContext {
14
+ cwd: string;
15
+ permissions?: Permissions;
16
+ hooks?: Hooks;
17
+ /** Aborts in-flight hook commands when the turn is cancelled. */
18
+ signal?: AbortSignal;
19
+ /** Notified whenever a tool call is blocked (for surfacing in the UI/logs). */
20
+ onBlocked?: (toolName: string, reason: string) => void;
21
+ /**
22
+ * Map from a permission deny entry (e.g. `Edit(migrations/**)`) to a human
23
+ * message. When a workspace rule's guard produces the deny, the agent sees the
24
+ * rule text instead of the raw glob, so it self-corrects. (See the rules
25
+ * module / adherence loop.)
26
+ */
27
+ denyReasons?: Record<string, string>;
28
+ }
29
+ /**
30
+ * Return a copy of `tools` whose executes are gated. Tools without an `execute`
31
+ * (none today, but the type allows it) pass through untouched.
32
+ */
33
+ export declare function wrapToolsWithGate(tools: ToolSet, ctx: ToolGateContext): ToolSet;
34
+ //# sourceMappingURL=gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.d.ts","sourceRoot":"","sources":["../../src/settings/gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAGlC,OAAO,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,iEAAiE;IACjE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvD;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAID;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,eAAe,GAAG,OAAO,CAwD/E"}
@@ -0,0 +1,50 @@
1
+ import { runHooks } from "./hooks.js";
2
+ import { evaluateLocalPermission } from "./permissions-gate.js";
3
+ /**
4
+ * Return a copy of `tools` whose executes are gated. Tools without an `execute`
5
+ * (none today, but the type allows it) pass through untouched.
6
+ */
7
+ export function wrapToolsWithGate(tools, ctx) {
8
+ // Nothing to enforce → hand back the original set (zero overhead).
9
+ if (!ctx.permissions && !ctx.hooks)
10
+ return tools;
11
+ const out = {};
12
+ for (const [name, original] of Object.entries(tools)) {
13
+ const exec = original.execute;
14
+ if (!exec) {
15
+ out[name] = original;
16
+ continue;
17
+ }
18
+ const gated = async (input, options) => {
19
+ const perm = evaluateLocalPermission(name, input, ctx.permissions);
20
+ if (perm.decision === "deny") {
21
+ const ruleMessage = perm.rule ? ctx.denyReasons?.[perm.rule] : undefined;
22
+ const reason = ruleMessage
23
+ ? `Blocked by ${ruleMessage}`
24
+ : `Permission denied: \`${name}\` ${perm.reason}.`;
25
+ ctx.onBlocked?.(name, ruleMessage ?? perm.reason);
26
+ return `⛔ ${reason}`;
27
+ }
28
+ const pre = await runHooks(ctx.hooks, { event: "PreToolUse", cwd: ctx.cwd, tool: { name, input } }, ctx.signal);
29
+ if (pre.blocked) {
30
+ const reason = pre.reason ?? "blocked by PreToolUse hook";
31
+ ctx.onBlocked?.(name, reason);
32
+ return `⛔ Blocked by PreToolUse hook: ${reason}`;
33
+ }
34
+ // The AI SDK types a generic tool's output as `any`; narrow to `unknown`
35
+ // so we handle it safely (and never re-leak `any` to callers).
36
+ const result = await exec(input, options);
37
+ // PostToolUse is observational — its exit code never blocks.
38
+ await runHooks(ctx.hooks, {
39
+ event: "PostToolUse",
40
+ cwd: ctx.cwd,
41
+ tool: { name, input },
42
+ toolResult: typeof result === "string" ? result.slice(0, 2000) : undefined,
43
+ }, ctx.signal);
44
+ return result;
45
+ };
46
+ out[name] = { ...original, execute: gated };
47
+ }
48
+ return out;
49
+ }
50
+ //# sourceMappingURL=gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gate.js","sourceRoot":"","sources":["../../src/settings/gate.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAC;AAsBhE;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,GAAoB;IACpE,mEAAmE;IACnE,IAAI,CAAC,GAAG,CAAC,WAAW,IAAI,CAAC,GAAG,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IAEjD,MAAM,GAAG,GAAY,EAAE,CAAC;IACxB,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAkC,CAAC;QACzD,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,GAAG,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;YACrB,SAAS;QACX,CAAC;QAED,MAAM,KAAK,GAAgB,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;YAClD,MAAM,IAAI,GAAG,uBAAuB,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC;YACnE,IAAI,IAAI,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;gBAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBACzE,MAAM,MAAM,GAAG,WAAW;oBACxB,CAAC,CAAC,cAAc,WAAW,EAAE;oBAC7B,CAAC,CAAC,wBAAwB,IAAI,MAAM,IAAI,CAAC,MAAM,GAAG,CAAC;gBACrD,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC;gBAClD,OAAO,KAAK,MAAM,EAAE,CAAC;YACvB,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CACxB,GAAG,CAAC,KAAK,EACT,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAC5D,GAAG,CAAC,MAAM,CACX,CAAC;YACF,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;gBAChB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,4BAA4B,CAAC;gBAC1D,GAAG,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAC9B,OAAO,iCAAiC,MAAM,EAAE,CAAC;YACnD,CAAC;YAED,yEAAyE;YACzE,+DAA+D;YAC/D,MAAM,MAAM,GAAY,MAAM,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAEnD,6DAA6D;YAC7D,MAAM,QAAQ,CACZ,GAAG,CAAC,KAAK,EACT;gBACE,KAAK,EAAE,aAAa;gBACpB,GAAG,EAAE,GAAG,CAAC,GAAG;gBACZ,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE;gBACrB,UAAU,EAAE,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;aAC3E,EACD,GAAG,CAAC,MAAM,CACX,CAAC;YAEF,OAAO,MAAM,CAAC;QAChB,CAAC,CAAC;QAEF,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC9C,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,26 @@
1
+ import type { HookEvent, Hooks } from "./schema.js";
2
+ export interface HookPayload {
3
+ event: HookEvent;
4
+ cwd: string;
5
+ /** Present for PreToolUse / PostToolUse. */
6
+ tool?: {
7
+ name: string;
8
+ input: unknown;
9
+ };
10
+ /** Present for PostToolUse: the (clipped) result string the tool returned. */
11
+ toolResult?: string;
12
+ }
13
+ export interface HookRunOutcome {
14
+ /** PreToolUse only: a hook blocked the tool (non-zero exit). */
15
+ blocked: boolean;
16
+ /** Human-readable reason when blocked (hook stderr/stdout). */
17
+ reason?: string;
18
+ /** Concatenated stdout of all hooks that ran (used for SessionStart context). */
19
+ output: string;
20
+ }
21
+ /**
22
+ * Run all hooks registered for an event. Returns whether the action should be
23
+ * blocked (PreToolUse) and any captured stdout (SessionStart context).
24
+ */
25
+ export declare function runHooks(hooks: Hooks | undefined, payload: HookPayload, signal?: AbortSignal): Promise<HookRunOutcome>;
26
+ //# sourceMappingURL=hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../../src/settings/hooks.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAc,SAAS,EAAe,KAAK,EAAE,MAAM,aAAa,CAAC;AAI7E,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,SAAS,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,4CAA4C;IAC5C,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IACxC,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;IACjB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,MAAM,EAAE,MAAM,CAAC;CAChB;AA4ED;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,KAAK,GAAG,SAAS,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,CAAC,EAAE,WAAW,GACnB,OAAO,CAAC,cAAc,CAAC,CA6BzB"}
@@ -0,0 +1,115 @@
1
+ /**
2
+ * hooks.ts — The lifecycle hook engine for the CLI agent loop.
3
+ *
4
+ * Hooks are shell commands declared in `settings.json` that fire on agent
5
+ * lifecycle events. They receive the event payload as JSON on stdin (Claude Code
6
+ * parity), so a hook can inspect what the agent is about to do.
7
+ *
8
+ * Three events are wired today, each with distinct, load-bearing behavior:
9
+ *
10
+ * - SessionStart runs once before the turn. Anything a hook prints to stdout
11
+ * is appended to the system prompt as additional context
12
+ * (e.g. inject the current sprint, on-call notes, a changelog).
13
+ * - PreToolUse runs before a tool executes. A non-zero exit BLOCKS the tool
14
+ * — the model receives the hook's message instead of running it
15
+ * (e.g. forbid `git push`, gate writes to protected paths).
16
+ * - PostToolUse runs after a tool executes (side effects only — auto-format a
17
+ * file after write_file, emit a notification). Never blocks.
18
+ *
19
+ * Matchers are globs over the tool name (PreToolUse / PostToolUse). SessionStart
20
+ * ignores the matcher and runs every action.
21
+ */
22
+ import { spawn } from "node:child_process";
23
+ import { matchGlob } from "@oxagen/mcp-config/permissions";
24
+ const DEFAULT_HOOK_TIMEOUT_MS = 60_000;
25
+ /** Run one hook command, feeding the payload JSON on stdin. Never throws. */
26
+ function execHook(action, payloadJson, cwd, signal) {
27
+ return new Promise((resolvePromise) => {
28
+ const child = spawn("/bin/bash", ["-c", action.command], {
29
+ cwd,
30
+ env: process.env,
31
+ stdio: ["pipe", "pipe", "pipe"],
32
+ });
33
+ let stdout = "";
34
+ let stderr = "";
35
+ let settled = false;
36
+ const finish = (result) => {
37
+ if (settled)
38
+ return;
39
+ settled = true;
40
+ clearTimeout(timer);
41
+ resolvePromise(result);
42
+ };
43
+ const timeoutMs = Math.min(action.timeoutMs ?? DEFAULT_HOOK_TIMEOUT_MS, 600_000);
44
+ const timer = setTimeout(() => {
45
+ child.kill("SIGKILL");
46
+ finish({ code: 124, stdout, stderr: stderr + `\n[hook timed out after ${timeoutMs}ms]` });
47
+ }, timeoutMs);
48
+ const onAbort = () => {
49
+ child.kill("SIGKILL");
50
+ finish({ code: 130, stdout, stderr: stderr + "\n[hook aborted]" });
51
+ };
52
+ if (signal) {
53
+ if (signal.aborted)
54
+ onAbort();
55
+ else
56
+ signal.addEventListener("abort", onAbort, { once: true });
57
+ }
58
+ child.stdout.on("data", (d) => (stdout += d.toString()));
59
+ child.stderr.on("data", (d) => (stderr += d.toString()));
60
+ child.on("error", (err) => finish({ code: 1, stdout, stderr: stderr + String(err) }));
61
+ child.on("close", (code) => finish({ code: code ?? 0, stdout, stderr }));
62
+ // A hook that exits before reading stdin makes the write below emit EPIPE
63
+ // asynchronously on the stdin stream. Swallow it — the exit code is what
64
+ // matters, and an unhandled stream error would otherwise crash the process.
65
+ child.stdin.on("error", () => { });
66
+ try {
67
+ child.stdin.write(payloadJson);
68
+ child.stdin.end();
69
+ }
70
+ catch {
71
+ /* stdin may already be closed if the command exits immediately */
72
+ }
73
+ });
74
+ }
75
+ /** Which matchers apply for this event + tool. SessionStart ignores the matcher. */
76
+ function selectMatchers(event, matchers, toolName) {
77
+ if (event === "SessionStart")
78
+ return matchers;
79
+ if (!toolName)
80
+ return [];
81
+ return matchers.filter((m) => matchGlob(m.matcher ?? "*", toolName));
82
+ }
83
+ /**
84
+ * Run all hooks registered for an event. Returns whether the action should be
85
+ * blocked (PreToolUse) and any captured stdout (SessionStart context).
86
+ */
87
+ export async function runHooks(hooks, payload, signal) {
88
+ const none = { blocked: false, output: "" };
89
+ if (!hooks)
90
+ return none;
91
+ const matchers = hooks[payload.event];
92
+ if (!matchers || matchers.length === 0)
93
+ return none;
94
+ const selected = selectMatchers(payload.event, matchers, payload.tool?.name);
95
+ if (selected.length === 0)
96
+ return none;
97
+ const payloadJson = JSON.stringify(payload);
98
+ const outputs = [];
99
+ for (const matcher of selected) {
100
+ for (const action of matcher.hooks) {
101
+ const result = await execHook(action, payloadJson, payload.cwd, signal);
102
+ if (result.stdout.trim())
103
+ outputs.push(result.stdout.trim());
104
+ // PreToolUse is the only blocking event: a non-zero exit vetoes the tool.
105
+ if (payload.event === "PreToolUse" && result.code !== 0) {
106
+ const reason = result.stderr.trim() ||
107
+ result.stdout.trim() ||
108
+ `hook \`${action.command}\` exited ${result.code}`;
109
+ return { blocked: true, reason, output: outputs.join("\n") };
110
+ }
111
+ }
112
+ }
113
+ return { blocked: false, output: outputs.join("\n") };
114
+ }
115
+ //# sourceMappingURL=hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../src/settings/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAG3D,MAAM,uBAAuB,GAAG,MAAM,CAAC;AA0BvC,6EAA6E;AAC7E,SAAS,QAAQ,CACf,MAAkB,EAClB,WAAmB,EACnB,GAAW,EACX,MAAoB;IAEpB,OAAO,IAAI,OAAO,CAAC,CAAC,cAAc,EAAE,EAAE;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;YACvD,GAAG;YACH,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;SAChC,CAAC,CAAC;QAEH,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,MAAM,GAAG,EAAE,CAAC;QAChB,IAAI,OAAO,GAAG,KAAK,CAAC;QACpB,MAAM,MAAM,GAAG,CAAC,MAAkB,EAAE,EAAE;YACpC,IAAI,OAAO;gBAAE,OAAO;YACpB,OAAO,GAAG,IAAI,CAAC;YACf,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,cAAc,CAAC,MAAM,CAAC,CAAC;QACzB,CAAC,CAAC;QAEF,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,IAAI,uBAAuB,EAAE,OAAO,CAAC,CAAC;QACjF,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,2BAA2B,SAAS,KAAK,EAAE,CAAC,CAAC;QAC5F,CAAC,EAAE,SAAS,CAAC,CAAC;QAEd,MAAM,OAAO,GAAG,GAAG,EAAE;YACnB,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;YACtB,MAAM,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAAC,CAAC;QACrE,CAAC,CAAC;QACF,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,MAAM,CAAC,OAAO;gBAAE,OAAO,EAAE,CAAC;;gBACzB,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACjE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;QACjE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;QACtF,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;QAEzE,0EAA0E;QAC1E,yEAAyE;QACzE,4EAA4E;QAC5E,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAClC,IAAI,CAAC;YACH,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAC/B,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,kEAAkE;QACpE,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,oFAAoF;AACpF,SAAS,cAAc,CACrB,KAAgB,EAChB,QAAuB,EACvB,QAA4B;IAE5B,IAAI,KAAK,KAAK,cAAc;QAAE,OAAO,QAAQ,CAAC;IAC9C,IAAI,CAAC,QAAQ;QAAE,OAAO,EAAE,CAAC;IACzB,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,IAAI,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC;AACvE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,KAAwB,EACxB,OAAoB,EACpB,MAAoB;IAEpB,MAAM,IAAI,GAAmB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC5D,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpD,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC7E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACxE,IAAI,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;gBAAE,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YAE7D,0EAA0E;YAC1E,IAAI,OAAO,CAAC,KAAK,KAAK,YAAY,IAAI,MAAM,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACxD,MAAM,MAAM,GACV,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;oBACpB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE;oBACpB,UAAU,MAAM,CAAC,OAAO,aAAa,MAAM,CAAC,IAAI,EAAE,CAAC;gBACrD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/D,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACxD,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @module settings — The unified `settings.json` driver for the Oxagen CLI.
3
+ *
4
+ * One hierarchical settings file (user → project → local) configures the CLI's
5
+ * model, environment, platform URL, tool permissions, and lifecycle hooks —
6
+ * the spine the MCP-client, agents, commands, and skills subsystems plug into.
7
+ *
8
+ * Public surface:
9
+ * - loadSettings / getScopePaths / clearSettingsCache — resolution
10
+ * - applySettingsToEnv — startup projection
11
+ * - wrapToolsWithGate — permission + hook gate
12
+ * - runHooks — lifecycle hook engine
13
+ * - writeSettingsValue / writeStarterSettings — `oxagen settings` writes
14
+ */
15
+ export { oxagenSettingsSchema, permissionsSchema, hooksSchema, HOOK_EVENTS, type OxagenSettings, type Permissions, type PermissionMode, type Hooks, type HookMatcher, type HookAction, type HookEvent, } from "./schema.js";
16
+ export { loadSettings, getScopePaths, clearSettingsCache, type ResolvedSettings, type ResolvedScopeFile, type ResolveSettingsOptions, type SettingsScope, } from "./resolve.js";
17
+ export { applySettingsToEnv, type AppliedSettingsEnv } from "./runtime.js";
18
+ export { wrapToolsWithGate, type ToolGateContext } from "./gate.js";
19
+ export { runHooks, type HookPayload, type HookRunOutcome } from "./hooks.js";
20
+ export { evaluateLocalPermission, parseRule, type LocalPermissionResult, } from "./permissions-gate.js";
21
+ export { writeSettingsValue, writeStarterSettings, readScopeDoc, writeScopeDoc, SETTABLE_KEYS, type WriteValueOptions, type InitOptions, } from "./write.js";
22
+ export { writeMcpServer, removeMcpServer, setMcpServerDisabled, findServerScope, type WriteMcpServerOptions, type McpMutateOptions, } from "./mcp-write.js";
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,WAAW,EACX,KAAK,cAAc,EACnB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,KAAK,EACV,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,GACf,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,EAClB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,GACnB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,kBAAkB,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAE3E,OAAO,EAAE,iBAAiB,EAAE,KAAK,eAAe,EAAE,MAAM,WAAW,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAE,KAAK,WAAW,EAAE,KAAK,cAAc,EAAE,MAAM,YAAY,CAAC;AAE7E,OAAO,EACL,uBAAuB,EACvB,SAAS,EACT,KAAK,qBAAqB,GAC3B,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,aAAa,EACb,KAAK,iBAAiB,EACtB,KAAK,WAAW,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,GACtB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * @module settings — The unified `settings.json` driver for the Oxagen CLI.
3
+ *
4
+ * One hierarchical settings file (user → project → local) configures the CLI's
5
+ * model, environment, platform URL, tool permissions, and lifecycle hooks —
6
+ * the spine the MCP-client, agents, commands, and skills subsystems plug into.
7
+ *
8
+ * Public surface:
9
+ * - loadSettings / getScopePaths / clearSettingsCache — resolution
10
+ * - applySettingsToEnv — startup projection
11
+ * - wrapToolsWithGate — permission + hook gate
12
+ * - runHooks — lifecycle hook engine
13
+ * - writeSettingsValue / writeStarterSettings — `oxagen settings` writes
14
+ */
15
+ export { oxagenSettingsSchema, permissionsSchema, hooksSchema, HOOK_EVENTS, } from "./schema.js";
16
+ export { loadSettings, getScopePaths, clearSettingsCache, } from "./resolve.js";
17
+ export { applySettingsToEnv } from "./runtime.js";
18
+ export { wrapToolsWithGate } from "./gate.js";
19
+ export { runHooks } from "./hooks.js";
20
+ export { evaluateLocalPermission, parseRule, } from "./permissions-gate.js";
21
+ export { writeSettingsValue, writeStarterSettings, readScopeDoc, writeScopeDoc, SETTABLE_KEYS, } from "./write.js";
22
+ export { writeMcpServer, removeMcpServer, setMcpServerDisabled, findServerScope, } from "./mcp-write.js";
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/settings/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,WAAW,EACX,WAAW,GAQZ,MAAM,aAAa,CAAC;AAErB,OAAO,EACL,YAAY,EACZ,aAAa,EACb,kBAAkB,GAKnB,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,kBAAkB,EAA2B,MAAM,cAAc,CAAC;AAE3E,OAAO,EAAE,iBAAiB,EAAwB,MAAM,WAAW,CAAC;AAEpE,OAAO,EAAE,QAAQ,EAAyC,MAAM,YAAY,CAAC;AAE7E,OAAO,EACL,uBAAuB,EACvB,SAAS,GAEV,MAAM,uBAAuB,CAAC;AAE/B,OAAO,EACL,kBAAkB,EAClB,oBAAoB,EACpB,YAAY,EACZ,aAAa,EACb,aAAa,GAGd,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,cAAc,EACd,eAAe,EACf,oBAAoB,EACpB,eAAe,GAGhB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * mcp-write.ts — Writers for `oxagen mcp add/remove/enable/disable`.
3
+ *
4
+ * MCP servers live in the `mcpServers` map of a single scope file. `add` writes
5
+ * to a chosen scope (default project); `remove`/`enable`/`disable` auto-detect
6
+ * which scope defines the server (highest precedence first) unless a scope is
7
+ * given. Every write validates the whole document against the schema first.
8
+ */
9
+ import type { McpServerConfig } from "@oxagen/mcp-config/schema";
10
+ import { type SettingsScope, type ResolveSettingsOptions } from "./resolve.js";
11
+ type Ctx = Pick<ResolveSettingsOptions, "cwd" | "userSettingsPath" | "projectDirName">;
12
+ /** Find the highest-precedence scope that defines a server, if any. */
13
+ export declare function findServerScope(name: string, ctx?: Ctx): {
14
+ scope: SettingsScope;
15
+ path: string;
16
+ } | null;
17
+ export interface WriteMcpServerOptions extends Ctx {
18
+ scope?: SettingsScope;
19
+ name: string;
20
+ config: McpServerConfig;
21
+ }
22
+ /** Add or replace an MCP server in a scope file (default: project). */
23
+ export declare function writeMcpServer(opts: WriteMcpServerOptions): string;
24
+ export interface McpMutateOptions extends Ctx {
25
+ scope?: SettingsScope;
26
+ name: string;
27
+ }
28
+ /** Remove a server. Returns the path touched and whether it existed. */
29
+ export declare function removeMcpServer(opts: McpMutateOptions): {
30
+ path: string;
31
+ found: boolean;
32
+ };
33
+ /** Toggle a server's `disabled` flag. Returns the path and whether it existed. */
34
+ export declare function setMcpServerDisabled(opts: McpMutateOptions & {
35
+ disabled: boolean;
36
+ }): {
37
+ path: string;
38
+ found: boolean;
39
+ };
40
+ export {};
41
+ //# sourceMappingURL=mcp-write.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-write.d.ts","sourceRoot":"","sources":["../../src/settings/mcp-write.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAiB,KAAK,aAAa,EAAE,KAAK,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAI9F,KAAK,GAAG,GAAG,IAAI,CAAC,sBAAsB,EAAE,KAAK,GAAG,kBAAkB,GAAG,gBAAgB,CAAC,CAAC;AAQvF,uEAAuE;AACvE,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,GAAQ,GACZ;IAAE,KAAK,EAAE,aAAa,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAO/C;AAED,MAAM,WAAW,qBAAsB,SAAQ,GAAG;IAChD,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,uEAAuE;AACvE,wBAAgB,cAAc,CAAC,IAAI,EAAE,qBAAqB,GAAG,MAAM,CASlE;AAED,MAAM,WAAW,gBAAiB,SAAQ,GAAG;IAC3C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,IAAI,EAAE,gBAAgB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAYxF;AAED,kFAAkF;AAClF,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,gBAAgB,GAAG;IAAE,QAAQ,EAAE,OAAO,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,CAalC"}
@@ -0,0 +1,61 @@
1
+ import { getScopePaths } from "./resolve.js";
2
+ import { readScopeDoc, writeScopeDoc } from "./write.js";
3
+ const SCOPE_ORDER = ["local", "project", "user"];
4
+ function serversOf(doc) {
5
+ return doc["mcpServers"] ?? {};
6
+ }
7
+ /** Find the highest-precedence scope that defines a server, if any. */
8
+ export function findServerScope(name, ctx = {}) {
9
+ const paths = getScopePaths(ctx);
10
+ for (const scope of SCOPE_ORDER) {
11
+ const path = paths[scope];
12
+ if (name in serversOf(readScopeDoc(path)))
13
+ return { scope, path };
14
+ }
15
+ return null;
16
+ }
17
+ /** Add or replace an MCP server in a scope file (default: project). */
18
+ export function writeMcpServer(opts) {
19
+ const scope = opts.scope ?? "project";
20
+ const path = getScopePaths(opts)[scope];
21
+ const doc = readScopeDoc(path);
22
+ const servers = serversOf(doc);
23
+ servers[opts.name] = opts.config;
24
+ doc["mcpServers"] = servers;
25
+ writeScopeDoc(path, doc);
26
+ return path;
27
+ }
28
+ /** Remove a server. Returns the path touched and whether it existed. */
29
+ export function removeMcpServer(opts) {
30
+ const target = opts.scope
31
+ ? { scope: opts.scope, path: getScopePaths(opts)[opts.scope] }
32
+ : findServerScope(opts.name, opts);
33
+ if (!target)
34
+ return { path: getScopePaths(opts).project, found: false };
35
+ const doc = readScopeDoc(target.path);
36
+ const servers = serversOf(doc);
37
+ if (!(opts.name in servers))
38
+ return { path: target.path, found: false };
39
+ delete servers[opts.name];
40
+ doc["mcpServers"] = servers;
41
+ writeScopeDoc(target.path, doc);
42
+ return { path: target.path, found: true };
43
+ }
44
+ /** Toggle a server's `disabled` flag. Returns the path and whether it existed. */
45
+ export function setMcpServerDisabled(opts) {
46
+ const target = opts.scope
47
+ ? { scope: opts.scope, path: getScopePaths(opts)[opts.scope] }
48
+ : findServerScope(opts.name, opts);
49
+ if (!target)
50
+ return { path: getScopePaths(opts).project, found: false };
51
+ const doc = readScopeDoc(target.path);
52
+ const servers = serversOf(doc);
53
+ const existing = servers[opts.name];
54
+ if (!existing)
55
+ return { path: target.path, found: false };
56
+ servers[opts.name] = { ...existing, disabled: opts.disabled };
57
+ doc["mcpServers"] = servers;
58
+ writeScopeDoc(target.path, doc);
59
+ return { path: target.path, found: true };
60
+ }
61
+ //# sourceMappingURL=mcp-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-write.js","sourceRoot":"","sources":["../../src/settings/mcp-write.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { Permissions } from "./schema.js";
2
+ export interface LocalPermissionResult {
3
+ decision: "allow" | "deny";
4
+ reason: string;
5
+ /** The rule string that produced an explicit allow/deny, if any. */
6
+ rule?: string;
7
+ }
8
+ /** The canonical permission name for a tool (e.g. read_file → Read; mcp tools unchanged). */
9
+ export declare function canonicalToolName(toolName: string): string;
10
+ interface ParsedRule {
11
+ tool: string;
12
+ pattern?: string;
13
+ }
14
+ /** Parse "Bash(git*)" → { tool: "Bash", pattern: "git*" }; "Edit" → { tool: "Edit" }. */
15
+ export declare function parseRule(rule: string): ParsedRule;
16
+ /** Evaluate whether a local tool call is permitted under the resolved permissions. */
17
+ export declare function evaluateLocalPermission(toolName: string, input: unknown, permissions: Permissions | undefined): LocalPermissionResult;
18
+ export {};
19
+ //# sourceMappingURL=permissions-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions-gate.d.ts","sourceRoot":"","sources":["../../src/settings/permissions-gate.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,oEAAoE;IACpE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AA0BD,6FAA6F;AAC7F,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AASD,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,yFAAyF;AACzF,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAKlD;AAYD,sFAAsF;AACtF,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,OAAO,EACd,WAAW,EAAE,WAAW,GAAG,SAAS,GACnC,qBAAqB,CAyBvB"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * permissions-gate.ts — Evaluates `settings.permissions` for the agent's local
3
+ * tools (read_file/write_file/edit_file/bash/…).
4
+ *
5
+ * Rules use Claude Code's syntax: a canonical tool name, optionally narrowed by
6
+ * a glob over the call's "subject" (the command for Bash, the path for a write,
7
+ * the pattern for a search):
8
+ *
9
+ * "Bash" any shell command
10
+ * "Bash(git push*)" shell commands starting with "git push"
11
+ * "Write(.env*)" writes whose path matches ".env*"
12
+ * "Edit" any surgical edit
13
+ *
14
+ * Decision order (deny always wins, matching the MCP gate and Claude Code):
15
+ * 1. a `deny` rule matches → deny
16
+ * 2. an `allow` rule matches → allow
17
+ * 3. defaultMode "bypassPermissions" → allow
18
+ * 4. defaultMode "deny" → deny (deny-by-default; only allow-listed pass)
19
+ * 5. otherwise (default/acceptEdits) → allow
20
+ *
21
+ * When no `permissions` block is configured, every call is allowed — this
22
+ * preserves the CLI's historical "runs against your own repo" behavior until a
23
+ * user opts into gating.
24
+ */
25
+ import { matchGlob } from "@oxagen/mcp-config/permissions";
26
+ /** Local tool id → canonical permission name used in rule strings. */
27
+ const CANONICAL = {
28
+ read_file: "Read",
29
+ list_dir: "Read",
30
+ glob: "Read",
31
+ grep: "Read",
32
+ code_graph: "Read",
33
+ write_file: "Write",
34
+ edit_file: "Edit",
35
+ bash: "Bash",
36
+ };
37
+ /** Local tool id → the input field used as the rule "subject". */
38
+ const SUBJECT_FIELD = {
39
+ read_file: "path",
40
+ list_dir: "path",
41
+ glob: "pattern",
42
+ grep: "pattern",
43
+ code_graph: "query",
44
+ write_file: "path",
45
+ edit_file: "path",
46
+ bash: "command",
47
+ };
48
+ /** The canonical permission name for a tool (e.g. read_file → Read; mcp tools unchanged). */
49
+ export function canonicalToolName(toolName) {
50
+ return CANONICAL[toolName] ?? toolName;
51
+ }
52
+ function subjectOf(toolName, input) {
53
+ const field = SUBJECT_FIELD[toolName];
54
+ if (!field || input === null || typeof input !== "object")
55
+ return "";
56
+ const value = input[field];
57
+ return typeof value === "string" ? value : "";
58
+ }
59
+ /** Parse "Bash(git*)" → { tool: "Bash", pattern: "git*" }; "Edit" → { tool: "Edit" }. */
60
+ export function parseRule(rule) {
61
+ const trimmed = rule.trim();
62
+ const open = trimmed.indexOf("(");
63
+ if (open === -1 || !trimmed.endsWith(")"))
64
+ return { tool: trimmed };
65
+ return { tool: trimmed.slice(0, open).trim(), pattern: trimmed.slice(open + 1, -1).trim() };
66
+ }
67
+ function ruleMatches(rule, canonical, subject) {
68
+ const parsed = parseRule(rule);
69
+ // The tool token is glob-matched against the canonical name. For local tools
70
+ // this is an exact compare ("Bash" === "Bash"); for MCP tools it lets a rule
71
+ // like `mcp__github__*` match `mcp__github__create_issue`.
72
+ if (!matchGlob(parsed.tool, canonical))
73
+ return false;
74
+ if (parsed.pattern === undefined || parsed.pattern === "")
75
+ return true;
76
+ return matchGlob(parsed.pattern, subject);
77
+ }
78
+ /** Evaluate whether a local tool call is permitted under the resolved permissions. */
79
+ export function evaluateLocalPermission(toolName, input, permissions) {
80
+ if (!permissions)
81
+ return { decision: "allow", reason: "no permissions configured" };
82
+ const canonical = CANONICAL[toolName] ?? toolName;
83
+ const subject = subjectOf(toolName, input);
84
+ for (const rule of permissions.deny ?? []) {
85
+ if (ruleMatches(rule, canonical, subject)) {
86
+ return { decision: "deny", reason: `denied by rule "${rule}"`, rule };
87
+ }
88
+ }
89
+ for (const rule of permissions.allow ?? []) {
90
+ if (ruleMatches(rule, canonical, subject)) {
91
+ return { decision: "allow", reason: `allowed by rule "${rule}"`, rule };
92
+ }
93
+ }
94
+ const mode = permissions.defaultMode ?? "default";
95
+ if (mode === "bypassPermissions") {
96
+ return { decision: "allow", reason: "defaultMode: bypassPermissions" };
97
+ }
98
+ if (mode === "deny") {
99
+ return { decision: "deny", reason: "defaultMode: deny (no allow rule matched)" };
100
+ }
101
+ return { decision: "allow", reason: `defaultMode: ${mode}` };
102
+ }
103
+ //# sourceMappingURL=permissions-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions-gate.js","sourceRoot":"","sources":["../../src/settings/permissions-gate.ts"],"names":[],"mappings":"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"}