@oxagen/cli 0.6.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 (339) hide show
  1. package/dist/agent/__tests__/judge.test.js +11 -6
  2. package/dist/agent/__tests__/judge.test.js.map +1 -1
  3. package/dist/agent/__tests__/loop-errors.test.js +32 -1
  4. package/dist/agent/__tests__/loop-errors.test.js.map +1 -1
  5. package/dist/agent/__tests__/loop-gating.test.d.ts +2 -0
  6. package/dist/agent/__tests__/loop-gating.test.d.ts.map +1 -0
  7. package/dist/agent/__tests__/loop-gating.test.js +94 -0
  8. package/dist/agent/__tests__/loop-gating.test.js.map +1 -0
  9. package/dist/agent/__tests__/model-router.test.js +16 -0
  10. package/dist/agent/__tests__/model-router.test.js.map +1 -1
  11. package/dist/agent/__tests__/permissions.test.d.ts +2 -0
  12. package/dist/agent/__tests__/permissions.test.d.ts.map +1 -0
  13. package/dist/agent/__tests__/permissions.test.js +206 -0
  14. package/dist/agent/__tests__/permissions.test.js.map +1 -0
  15. package/dist/agent/__tests__/pipeline-telemetry.test.d.ts +2 -0
  16. package/dist/agent/__tests__/pipeline-telemetry.test.d.ts.map +1 -0
  17. package/dist/agent/__tests__/pipeline-telemetry.test.js +158 -0
  18. package/dist/agent/__tests__/pipeline-telemetry.test.js.map +1 -0
  19. package/dist/agent/__tests__/pipeline.test.js +12 -3
  20. package/dist/agent/__tests__/pipeline.test.js.map +1 -1
  21. package/dist/agent/__tests__/rate-card.test.d.ts +2 -0
  22. package/dist/agent/__tests__/rate-card.test.d.ts.map +1 -0
  23. package/dist/agent/__tests__/rate-card.test.js +69 -0
  24. package/dist/agent/__tests__/rate-card.test.js.map +1 -0
  25. package/dist/agent/__tests__/system-prompt.test.d.ts +2 -0
  26. package/dist/agent/__tests__/system-prompt.test.d.ts.map +1 -0
  27. package/dist/agent/__tests__/system-prompt.test.js +29 -0
  28. package/dist/agent/__tests__/system-prompt.test.js.map +1 -0
  29. package/dist/agent/__tests__/trace-format-verbose.test.d.ts +2 -0
  30. package/dist/agent/__tests__/trace-format-verbose.test.d.ts.map +1 -0
  31. package/dist/agent/__tests__/trace-format-verbose.test.js +93 -0
  32. package/dist/agent/__tests__/trace-format-verbose.test.js.map +1 -0
  33. package/dist/agent/__tests__/verbose-log.test.d.ts +2 -0
  34. package/dist/agent/__tests__/verbose-log.test.d.ts.map +1 -0
  35. package/dist/agent/__tests__/verbose-log.test.js +69 -0
  36. package/dist/agent/__tests__/verbose-log.test.js.map +1 -0
  37. package/dist/agent/evaluator.d.ts.map +1 -1
  38. package/dist/agent/evaluator.js +8 -4
  39. package/dist/agent/evaluator.js.map +1 -1
  40. package/dist/agent/fleet/orchestrator.d.ts +5 -0
  41. package/dist/agent/fleet/orchestrator.d.ts.map +1 -1
  42. package/dist/agent/fleet/orchestrator.js +3 -0
  43. package/dist/agent/fleet/orchestrator.js.map +1 -1
  44. package/dist/agent/fleet/types.d.ts +2 -0
  45. package/dist/agent/fleet/types.d.ts.map +1 -1
  46. package/dist/agent/judge.d.ts +11 -3
  47. package/dist/agent/judge.d.ts.map +1 -1
  48. package/dist/agent/judge.js +15 -3
  49. package/dist/agent/judge.js.map +1 -1
  50. package/dist/agent/loop.d.ts +35 -0
  51. package/dist/agent/loop.d.ts.map +1 -1
  52. package/dist/agent/loop.js +147 -48
  53. package/dist/agent/loop.js.map +1 -1
  54. package/dist/agent/model-router.d.ts +5 -19
  55. package/dist/agent/model-router.d.ts.map +1 -1
  56. package/dist/agent/model-router.js +19 -42
  57. package/dist/agent/model-router.js.map +1 -1
  58. package/dist/agent/permissions.d.ts +103 -0
  59. package/dist/agent/permissions.d.ts.map +1 -0
  60. package/dist/agent/permissions.js +245 -0
  61. package/dist/agent/permissions.js.map +1 -0
  62. package/dist/agent/pipeline.d.ts +13 -3
  63. package/dist/agent/pipeline.d.ts.map +1 -1
  64. package/dist/agent/pipeline.js +66 -15
  65. package/dist/agent/pipeline.js.map +1 -1
  66. package/dist/agent/planner.d.ts +3 -0
  67. package/dist/agent/planner.d.ts.map +1 -1
  68. package/dist/agent/planner.js +14 -1
  69. package/dist/agent/planner.js.map +1 -1
  70. package/dist/agent/prompt-enhancer.d.ts +9 -0
  71. package/dist/agent/prompt-enhancer.d.ts.map +1 -1
  72. package/dist/agent/prompt-enhancer.js +23 -1
  73. package/dist/agent/prompt-enhancer.js.map +1 -1
  74. package/dist/agent/rate-card.d.ts +77 -0
  75. package/dist/agent/rate-card.d.ts.map +1 -0
  76. package/dist/agent/rate-card.js +99 -0
  77. package/dist/agent/rate-card.js.map +1 -0
  78. package/dist/agent/system-prompt.d.ts +5 -0
  79. package/dist/agent/system-prompt.d.ts.map +1 -1
  80. package/dist/agent/system-prompt.js +13 -4
  81. package/dist/agent/system-prompt.js.map +1 -1
  82. package/dist/agent/tools.d.ts +8 -4
  83. package/dist/agent/tools.d.ts.map +1 -1
  84. package/dist/agent/tools.js +35 -4
  85. package/dist/agent/tools.js.map +1 -1
  86. package/dist/agent/trace-format.d.ts +7 -0
  87. package/dist/agent/trace-format.d.ts.map +1 -1
  88. package/dist/agent/trace-format.js +114 -0
  89. package/dist/agent/trace-format.js.map +1 -1
  90. package/dist/agent/trace.d.ts +59 -0
  91. package/dist/agent/trace.d.ts.map +1 -1
  92. package/dist/agent/verbose-log.d.ts +8 -0
  93. package/dist/agent/verbose-log.d.ts.map +1 -0
  94. package/dist/agent/verbose-log.js +53 -0
  95. package/dist/agent/verbose-log.js.map +1 -0
  96. package/dist/agents/__tests__/loader.test.d.ts +2 -0
  97. package/dist/agents/__tests__/loader.test.d.ts.map +1 -0
  98. package/dist/agents/__tests__/loader.test.js +88 -0
  99. package/dist/agents/__tests__/loader.test.js.map +1 -0
  100. package/dist/agents/__tests__/tools.test.d.ts +2 -0
  101. package/dist/agents/__tests__/tools.test.d.ts.map +1 -0
  102. package/dist/agents/__tests__/tools.test.js +40 -0
  103. package/dist/agents/__tests__/tools.test.js.map +1 -0
  104. package/dist/agents/index.d.ts +12 -0
  105. package/dist/agents/index.d.ts.map +1 -0
  106. package/dist/agents/index.js +4 -0
  107. package/dist/agents/index.js.map +1 -0
  108. package/dist/agents/loader.d.ts +25 -0
  109. package/dist/agents/loader.d.ts.map +1 -0
  110. package/dist/agents/loader.js +133 -0
  111. package/dist/agents/loader.js.map +1 -0
  112. package/dist/agents/tools.d.ts +14 -0
  113. package/dist/agents/tools.d.ts.map +1 -0
  114. package/dist/agents/tools.js +21 -0
  115. package/dist/agents/tools.js.map +1 -0
  116. package/dist/agents/types.d.ts +27 -0
  117. package/dist/agents/types.d.ts.map +1 -0
  118. package/dist/agents/types.js +11 -0
  119. package/dist/agents/types.js.map +1 -0
  120. package/dist/agents/write.d.ts +10 -0
  121. package/dist/agents/write.d.ts.map +1 -0
  122. package/dist/agents/write.js +28 -0
  123. package/dist/agents/write.js.map +1 -0
  124. package/dist/commands/__tests__/agent.test.d.ts +2 -0
  125. package/dist/commands/__tests__/agent.test.d.ts.map +1 -0
  126. package/dist/commands/__tests__/agent.test.js +82 -0
  127. package/dist/commands/__tests__/agent.test.js.map +1 -0
  128. package/dist/commands/__tests__/command.test.d.ts +2 -0
  129. package/dist/commands/__tests__/command.test.d.ts.map +1 -0
  130. package/dist/commands/__tests__/command.test.js +73 -0
  131. package/dist/commands/__tests__/command.test.js.map +1 -0
  132. package/dist/commands/__tests__/cost.test.d.ts +2 -0
  133. package/dist/commands/__tests__/cost.test.d.ts.map +1 -0
  134. package/dist/commands/__tests__/cost.test.js +139 -0
  135. package/dist/commands/__tests__/cost.test.js.map +1 -0
  136. package/dist/commands/__tests__/graph.pull.test.d.ts +2 -0
  137. package/dist/commands/__tests__/graph.pull.test.d.ts.map +1 -0
  138. package/dist/commands/__tests__/graph.pull.test.js +259 -0
  139. package/dist/commands/__tests__/graph.pull.test.js.map +1 -0
  140. package/dist/commands/__tests__/mcp.test.d.ts +2 -0
  141. package/dist/commands/__tests__/mcp.test.d.ts.map +1 -0
  142. package/dist/commands/__tests__/mcp.test.js +88 -0
  143. package/dist/commands/__tests__/mcp.test.js.map +1 -0
  144. package/dist/commands/__tests__/rules.test.d.ts +2 -0
  145. package/dist/commands/__tests__/rules.test.d.ts.map +1 -0
  146. package/dist/commands/__tests__/rules.test.js +95 -0
  147. package/dist/commands/__tests__/rules.test.js.map +1 -0
  148. package/dist/commands/__tests__/settings.test.d.ts +2 -0
  149. package/dist/commands/__tests__/settings.test.d.ts.map +1 -0
  150. package/dist/commands/__tests__/settings.test.js +83 -0
  151. package/dist/commands/__tests__/settings.test.js.map +1 -0
  152. package/dist/commands/agent.d.ts +15 -0
  153. package/dist/commands/agent.d.ts.map +1 -0
  154. package/dist/commands/agent.js +58 -0
  155. package/dist/commands/agent.js.map +1 -0
  156. package/dist/commands/command.d.ts +17 -0
  157. package/dist/commands/command.d.ts.map +1 -0
  158. package/dist/commands/command.js +74 -0
  159. package/dist/commands/command.js.map +1 -0
  160. package/dist/commands/config.js.map +1 -1
  161. package/dist/commands/cost.d.ts +10 -0
  162. package/dist/commands/cost.d.ts.map +1 -0
  163. package/dist/commands/cost.js +140 -0
  164. package/dist/commands/cost.js.map +1 -0
  165. package/dist/commands/graph.pull.d.ts +15 -0
  166. package/dist/commands/graph.pull.d.ts.map +1 -0
  167. package/dist/commands/graph.pull.js +137 -0
  168. package/dist/commands/graph.pull.js.map +1 -0
  169. package/dist/commands/graph.status.d.ts +10 -0
  170. package/dist/commands/graph.status.d.ts.map +1 -0
  171. package/dist/commands/graph.status.js +75 -0
  172. package/dist/commands/graph.status.js.map +1 -0
  173. package/dist/commands/mcp.d.ts +18 -0
  174. package/dist/commands/mcp.d.ts.map +1 -0
  175. package/dist/commands/mcp.js +183 -0
  176. package/dist/commands/mcp.js.map +1 -0
  177. package/dist/commands/rules.d.ts +19 -0
  178. package/dist/commands/rules.d.ts.map +1 -0
  179. package/dist/commands/rules.js +96 -0
  180. package/dist/commands/rules.js.map +1 -0
  181. package/dist/commands/settings.d.ts +10 -0
  182. package/dist/commands/settings.d.ts.map +1 -0
  183. package/dist/commands/settings.js +117 -0
  184. package/dist/commands/settings.js.map +1 -0
  185. package/dist/index.js +297 -1
  186. package/dist/index.js.map +1 -1
  187. package/dist/lib/config.d.ts +2 -0
  188. package/dist/lib/config.d.ts.map +1 -1
  189. package/dist/lib/config.js.map +1 -1
  190. package/dist/mcp/__tests__/client.test.d.ts +2 -0
  191. package/dist/mcp/__tests__/client.test.d.ts.map +1 -0
  192. package/dist/mcp/__tests__/client.test.js +101 -0
  193. package/dist/mcp/__tests__/client.test.js.map +1 -0
  194. package/dist/mcp/client.d.ts +89 -0
  195. package/dist/mcp/client.d.ts.map +1 -0
  196. package/dist/mcp/client.js +201 -0
  197. package/dist/mcp/client.js.map +1 -0
  198. package/dist/repl/__tests__/components.test.js +50 -1
  199. package/dist/repl/__tests__/components.test.js.map +1 -1
  200. package/dist/repl/components.d.ts +18 -1
  201. package/dist/repl/components.d.ts.map +1 -1
  202. package/dist/repl/components.js +32 -2
  203. package/dist/repl/components.js.map +1 -1
  204. package/dist/repl/interactive.d.ts +5 -0
  205. package/dist/repl/interactive.d.ts.map +1 -1
  206. package/dist/repl/interactive.js +124 -11
  207. package/dist/repl/interactive.js.map +1 -1
  208. package/dist/repl/one-shot.d.ts +16 -0
  209. package/dist/repl/one-shot.d.ts.map +1 -1
  210. package/dist/repl/one-shot.js +71 -1
  211. package/dist/repl/one-shot.js.map +1 -1
  212. package/dist/rules/__tests__/enforce.test.d.ts +2 -0
  213. package/dist/rules/__tests__/enforce.test.d.ts.map +1 -0
  214. package/dist/rules/__tests__/enforce.test.js +58 -0
  215. package/dist/rules/__tests__/enforce.test.js.map +1 -0
  216. package/dist/rules/__tests__/loader.test.d.ts +2 -0
  217. package/dist/rules/__tests__/loader.test.d.ts.map +1 -0
  218. package/dist/rules/__tests__/loader.test.js +54 -0
  219. package/dist/rules/__tests__/loader.test.js.map +1 -0
  220. package/dist/rules/enforce.d.ts +23 -0
  221. package/dist/rules/enforce.d.ts.map +1 -0
  222. package/dist/rules/enforce.js +36 -0
  223. package/dist/rules/enforce.js.map +1 -0
  224. package/dist/rules/index.d.ts +10 -0
  225. package/dist/rules/index.d.ts.map +1 -0
  226. package/dist/rules/index.js +4 -0
  227. package/dist/rules/index.js.map +1 -0
  228. package/dist/rules/loader.d.ts +10 -0
  229. package/dist/rules/loader.d.ts.map +1 -0
  230. package/dist/rules/loader.js +77 -0
  231. package/dist/rules/loader.js.map +1 -0
  232. package/dist/rules/types.d.ts +39 -0
  233. package/dist/rules/types.d.ts.map +1 -0
  234. package/dist/rules/types.js +16 -0
  235. package/dist/rules/types.js.map +1 -0
  236. package/dist/rules/write.d.ts +10 -0
  237. package/dist/rules/write.d.ts.map +1 -0
  238. package/dist/rules/write.js +28 -0
  239. package/dist/rules/write.js.map +1 -0
  240. package/dist/settings/__tests__/gate.test.d.ts +2 -0
  241. package/dist/settings/__tests__/gate.test.d.ts.map +1 -0
  242. package/dist/settings/__tests__/gate.test.js +137 -0
  243. package/dist/settings/__tests__/gate.test.js.map +1 -0
  244. package/dist/settings/__tests__/hooks.test.d.ts +2 -0
  245. package/dist/settings/__tests__/hooks.test.d.ts.map +1 -0
  246. package/dist/settings/__tests__/hooks.test.js +103 -0
  247. package/dist/settings/__tests__/hooks.test.js.map +1 -0
  248. package/dist/settings/__tests__/mcp-write.test.d.ts +2 -0
  249. package/dist/settings/__tests__/mcp-write.test.d.ts.map +1 -0
  250. package/dist/settings/__tests__/mcp-write.test.js +77 -0
  251. package/dist/settings/__tests__/mcp-write.test.js.map +1 -0
  252. package/dist/settings/__tests__/permissions-gate.test.d.ts +2 -0
  253. package/dist/settings/__tests__/permissions-gate.test.d.ts.map +1 -0
  254. package/dist/settings/__tests__/permissions-gate.test.js +75 -0
  255. package/dist/settings/__tests__/permissions-gate.test.js.map +1 -0
  256. package/dist/settings/__tests__/resolve.test.d.ts +2 -0
  257. package/dist/settings/__tests__/resolve.test.d.ts.map +1 -0
  258. package/dist/settings/__tests__/resolve.test.js +109 -0
  259. package/dist/settings/__tests__/resolve.test.js.map +1 -0
  260. package/dist/settings/__tests__/runtime.test.d.ts +2 -0
  261. package/dist/settings/__tests__/runtime.test.d.ts.map +1 -0
  262. package/dist/settings/__tests__/runtime.test.js +72 -0
  263. package/dist/settings/__tests__/runtime.test.js.map +1 -0
  264. package/dist/settings/__tests__/schema.test.d.ts +2 -0
  265. package/dist/settings/__tests__/schema.test.d.ts.map +1 -0
  266. package/dist/settings/__tests__/schema.test.js +55 -0
  267. package/dist/settings/__tests__/schema.test.js.map +1 -0
  268. package/dist/settings/__tests__/write.test.d.ts +2 -0
  269. package/dist/settings/__tests__/write.test.d.ts.map +1 -0
  270. package/dist/settings/__tests__/write.test.js +61 -0
  271. package/dist/settings/__tests__/write.test.js.map +1 -0
  272. package/dist/settings/gate.d.ts +34 -0
  273. package/dist/settings/gate.d.ts.map +1 -0
  274. package/dist/settings/gate.js +50 -0
  275. package/dist/settings/gate.js.map +1 -0
  276. package/dist/settings/hooks.d.ts +26 -0
  277. package/dist/settings/hooks.d.ts.map +1 -0
  278. package/dist/settings/hooks.js +115 -0
  279. package/dist/settings/hooks.js.map +1 -0
  280. package/dist/settings/index.d.ts +23 -0
  281. package/dist/settings/index.d.ts.map +1 -0
  282. package/dist/settings/index.js +23 -0
  283. package/dist/settings/index.js.map +1 -0
  284. package/dist/settings/mcp-write.d.ts +41 -0
  285. package/dist/settings/mcp-write.d.ts.map +1 -0
  286. package/dist/settings/mcp-write.js +61 -0
  287. package/dist/settings/mcp-write.js.map +1 -0
  288. package/dist/settings/permissions-gate.d.ts +19 -0
  289. package/dist/settings/permissions-gate.d.ts.map +1 -0
  290. package/dist/settings/permissions-gate.js +103 -0
  291. package/dist/settings/permissions-gate.js.map +1 -0
  292. package/dist/settings/resolve.d.ts +37 -0
  293. package/dist/settings/resolve.d.ts.map +1 -0
  294. package/dist/settings/resolve.js +169 -0
  295. package/dist/settings/resolve.js.map +1 -0
  296. package/dist/settings/runtime.d.ts +28 -0
  297. package/dist/settings/runtime.d.ts.map +1 -0
  298. package/dist/settings/runtime.js +45 -0
  299. package/dist/settings/runtime.js.map +1 -0
  300. package/dist/settings/schema.d.ts +1387 -0
  301. package/dist/settings/schema.d.ts.map +1 -0
  302. package/dist/settings/schema.js +146 -0
  303. package/dist/settings/schema.js.map +1 -0
  304. package/dist/settings/write.d.ts +37 -0
  305. package/dist/settings/write.d.ts.map +1 -0
  306. package/dist/settings/write.js +85 -0
  307. package/dist/settings/write.js.map +1 -0
  308. package/dist/slash/__tests__/expand.test.d.ts +2 -0
  309. package/dist/slash/__tests__/expand.test.d.ts.map +1 -0
  310. package/dist/slash/__tests__/expand.test.js +44 -0
  311. package/dist/slash/__tests__/expand.test.js.map +1 -0
  312. package/dist/slash/__tests__/loader.test.d.ts +2 -0
  313. package/dist/slash/__tests__/loader.test.d.ts.map +1 -0
  314. package/dist/slash/__tests__/loader.test.js +48 -0
  315. package/dist/slash/__tests__/loader.test.js.map +1 -0
  316. package/dist/slash/expand.d.ts +32 -0
  317. package/dist/slash/expand.d.ts.map +1 -0
  318. package/dist/slash/expand.js +48 -0
  319. package/dist/slash/expand.js.map +1 -0
  320. package/dist/slash/index.d.ts +11 -0
  321. package/dist/slash/index.d.ts.map +1 -0
  322. package/dist/slash/index.js +4 -0
  323. package/dist/slash/index.js.map +1 -0
  324. package/dist/slash/loader.d.ts +10 -0
  325. package/dist/slash/loader.d.ts.map +1 -0
  326. package/dist/slash/loader.js +64 -0
  327. package/dist/slash/loader.js.map +1 -0
  328. package/dist/slash/types.d.ts +24 -0
  329. package/dist/slash/types.d.ts.map +1 -0
  330. package/dist/slash/types.js +11 -0
  331. package/dist/slash/types.js.map +1 -0
  332. package/dist/slash/write.d.ts +10 -0
  333. package/dist/slash/write.d.ts.map +1 -0
  334. package/dist/slash/write.js +26 -0
  335. package/dist/slash/write.js.map +1 -0
  336. package/dist/tui/fleet-view/index.d.ts.map +1 -1
  337. package/dist/tui/fleet-view/index.js +5 -1
  338. package/dist/tui/fleet-view/index.js.map +1 -1
  339. package/package.json +5 -1
@@ -0,0 +1,19 @@
1
+ /**
2
+ * rules command — manage and test workspace rules.
3
+ *
4
+ * oxagen rules list List rules and which are hard-enforced
5
+ * oxagen rules show <name> Show a rule's text + guard
6
+ * oxagen rules new <name> Scaffold .oxagen/rules/<name>.md
7
+ * oxagen rules check <tool> <subject> Dry-run a tool call against the guards
8
+ *
9
+ * Rules are injected into the agent's system prompt every turn and their guards
10
+ * are hard-enforced at the tool gate.
11
+ */
12
+ import { type LoadRulesOptions } from "../rules/index.js";
13
+ export type RulesCmdCtx = Pick<LoadRulesOptions, "cwd" | "userRulesDir">;
14
+ export declare function rulesList(ctx?: RulesCmdCtx): void;
15
+ export declare function rulesShow(name: string, ctx?: RulesCmdCtx): void;
16
+ export declare function rulesNew(name: string, ctx?: RulesCmdCtx): void;
17
+ /** Dry-run a proposed tool call against the rule guards (no model, no side effect). */
18
+ export declare function rulesCheck(tool: string, subject: string, ctx?: RulesCmdCtx): void;
19
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/commands/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAyC,KAAK,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAGjG,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,EAAE,KAAK,GAAG,cAAc,CAAC,CAAC;AAUzE,wBAAgB,SAAS,CAAC,GAAG,GAAE,WAAgB,GAAG,IAAI,CAWrD;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAuBnE;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAalE;AAED,uFAAuF;AACvF,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAkBrF"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * rules command — manage and test workspace rules.
3
+ *
4
+ * oxagen rules list List rules and which are hard-enforced
5
+ * oxagen rules show <name> Show a rule's text + guard
6
+ * oxagen rules new <name> Scaffold .oxagen/rules/<name>.md
7
+ * oxagen rules check <tool> <subject> Dry-run a tool call against the guards
8
+ *
9
+ * Rules are injected into the agent's system prompt every turn and their guards
10
+ * are hard-enforced at the tool gate.
11
+ */
12
+ import { loadRules, guardsToDeny, scaffoldRule } from "../rules/index.js";
13
+ import { evaluateLocalPermission } from "../settings/permissions-gate.js";
14
+ /** Map the friendly `check` tool arg to a CLI tool id + the input field. */
15
+ const TOOL_ALIAS = {
16
+ bash: { tool: "bash", field: "command" },
17
+ edit: { tool: "edit_file", field: "path" },
18
+ write: { tool: "write_file", field: "path" },
19
+ read: { tool: "read_file", field: "path" },
20
+ };
21
+ export function rulesList(ctx = {}) {
22
+ const rules = loadRules(ctx).sort((a, b) => a.id.localeCompare(b.id));
23
+ if (rules.length === 0) {
24
+ console.log("No rules defined. Create one with `oxagen rules new <name>`.");
25
+ return;
26
+ }
27
+ console.log("Workspace rules:\n");
28
+ for (const r of rules) {
29
+ console.log(` ${r.id}${r.guard ? " [enforced]" : ""}`);
30
+ if (r.description)
31
+ console.log(` ${r.description}`);
32
+ }
33
+ }
34
+ export function rulesShow(name, ctx = {}) {
35
+ const rule = loadRules(ctx).find((r) => r.id === name);
36
+ if (!rule) {
37
+ console.error(`Unknown rule "${name}". Run \`oxagen rules list\`.`);
38
+ process.exitCode = 1;
39
+ return;
40
+ }
41
+ console.log(`# ${rule.id}`);
42
+ if (rule.description)
43
+ console.log(rule.description);
44
+ console.log(`\nsource: ${rule.source}`);
45
+ if (rule.guard) {
46
+ const g = rule.guard;
47
+ const parts = [
48
+ g.tool ? `tool=${g.tool}` : "",
49
+ g.denyPathGlob ? `denyPath=${g.denyPathGlob}` : "",
50
+ g.denyCommandGlob ? `denyCommand=${g.denyCommandGlob}` : "",
51
+ ].filter(Boolean);
52
+ console.log(`guard: ${parts.join(" ")} (hard-enforced)`);
53
+ }
54
+ else {
55
+ console.log("guard: (none — prompt-only)");
56
+ }
57
+ console.log("\n--- rule ---\n");
58
+ console.log(rule.text);
59
+ }
60
+ export function rulesNew(name, ctx = {}) {
61
+ if (!/^[A-Za-z0-9][\w-]*$/.test(name)) {
62
+ console.error(`Invalid rule name "${name}". Use letters, digits, dashes, underscores.`);
63
+ process.exitCode = 1;
64
+ return;
65
+ }
66
+ const { path, created } = scaffoldRule({ name, cwd: ctx.cwd });
67
+ if (created) {
68
+ console.log(`✓ Created rule ${path}`);
69
+ console.log(" Add a guard (guard-tool / guard-deny-path / guard-deny-command) to hard-enforce it.");
70
+ }
71
+ else {
72
+ console.log(`${path} already exists — left untouched.`);
73
+ }
74
+ }
75
+ /** Dry-run a proposed tool call against the rule guards (no model, no side effect). */
76
+ export function rulesCheck(tool, subject, ctx = {}) {
77
+ const alias = TOOL_ALIAS[tool.toLowerCase()];
78
+ if (!alias) {
79
+ console.error(`Unknown tool "${tool}". Use one of: ${Object.keys(TOOL_ALIAS).join(", ")}`);
80
+ process.exitCode = 1;
81
+ return;
82
+ }
83
+ const { deny, reasons } = guardsToDeny(loadRules(ctx));
84
+ const input = { [alias.field]: subject };
85
+ const result = evaluateLocalPermission(alias.tool, input, { deny });
86
+ if (result.decision === "deny") {
87
+ const why = result.rule ? reasons[result.rule] ?? result.reason : result.reason;
88
+ console.log(`⛔ BLOCKED: ${tool} ${subject}`);
89
+ console.log(` ${why}`);
90
+ process.exitCode = 1;
91
+ }
92
+ else {
93
+ console.log(`✓ allowed: ${tool} ${subject} (no guard matched)`);
94
+ }
95
+ }
96
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/commands/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAyB,MAAM,mBAAmB,CAAC;AACjG,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAI1E,4EAA4E;AAC5E,MAAM,UAAU,GAAgE;IAC9E,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE;IACxC,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE;IAC1C,KAAK,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE;IAC5C,IAAI,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,EAAE;CAC3C,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,MAAmB,EAAE;IAC7C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAC5E,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,CAAC,WAAW;YAAE,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,MAAmB,EAAE;IAC3D,MAAM,IAAI,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,CAAC;IACvD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,KAAK,CAAC,iBAAiB,IAAI,+BAA+B,CAAC,CAAC;QACpE,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5B,IAAI,IAAI,CAAC,WAAW;QAAE,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC;QACrB,MAAM,KAAK,GAAG;YACZ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE;YAC9B,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE;YAClD,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE;SAC5D,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,WAAW,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC9D,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IAChC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,MAAmB,EAAE;IAC1D,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACtC,OAAO,CAAC,KAAK,CAAC,sBAAsB,IAAI,8CAA8C,CAAC,CAAC;QACxF,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;IAC/D,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC;QACtC,OAAO,CAAC,GAAG,CAAC,uFAAuF,CAAC,CAAC;IACvG,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,mCAAmC,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,uFAAuF;AACvF,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,OAAe,EAAE,MAAmB,EAAE;IAC7E,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,iBAAiB,IAAI,kBAAkB,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3F,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;QACrB,OAAO;IACT,CAAC;IACD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,YAAY,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;IACvD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC;IACzC,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;IACpE,IAAI,MAAM,CAAC,QAAQ,KAAK,MAAM,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC;QAChF,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,GAAG,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;QACzB,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,IAAI,OAAO,qBAAqB,CAAC,CAAC;IAClE,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type ResolveSettingsOptions } from "../settings/index.js";
2
+ /** Resolution context shared by every handler (paths come from here in tests). */
3
+ export type SettingsCtx = Pick<ResolveSettingsOptions, "cwd" | "userSettingsPath" | "projectDirName">;
4
+ export declare function settingsShow(ctx?: SettingsCtx): void;
5
+ export declare function settingsPath(ctx?: SettingsCtx): void;
6
+ export declare function settingsGet(key: string, ctx?: SettingsCtx): void;
7
+ export declare function settingsSet(key: string, value: string, scopeArg?: string, ctx?: SettingsCtx): void;
8
+ export declare function settingsValidate(ctx?: SettingsCtx): void;
9
+ export declare function settingsInit(scopeArg?: string, ctx?: SettingsCtx): void;
10
+ //# sourceMappingURL=settings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../src/commands/settings.ts"],"names":[],"mappings":"AAiBA,OAAO,EAOL,KAAK,sBAAsB,EAC5B,MAAM,sBAAsB,CAAC;AAI9B,kFAAkF;AAClF,MAAM,MAAM,WAAW,GAAG,IAAI,CAAC,sBAAsB,EAAE,KAAK,GAAG,kBAAkB,GAAG,gBAAgB,CAAC,CAAC;AAgBtG,wBAAgB,YAAY,CAAC,GAAG,GAAE,WAAgB,GAAG,IAAI,CAaxD;AAED,wBAAgB,YAAY,CAAC,GAAG,GAAE,WAAgB,GAAG,IAAI,CAOxD;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAQpE;AAED,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,QAAQ,CAAC,EAAE,MAAM,EACjB,GAAG,GAAE,WAAgB,GACpB,IAAI,CAcN;AAED,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,WAAgB,GAAG,IAAI,CAgB5D;AAED,wBAAgB,YAAY,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,GAAE,WAAgB,GAAG,IAAI,CAc3E"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * settings command — inspect and edit the unified `settings.json`.
3
+ *
4
+ * oxagen settings Show the merged settings + where each scope lives
5
+ * oxagen settings path List the three scope files and their status
6
+ * oxagen settings get <key> Print a value (dotted, e.g. permissions.defaultMode)
7
+ * oxagen settings set <key> <val> Write a value (model | apiUrl | env.NAME)
8
+ * oxagen settings validate Validate every scope file against the schema
9
+ * oxagen settings init Write a documented starter file (project scope)
10
+ *
11
+ * `set` / `init` target a single scope (default: project) so the user/project/
12
+ * local layering stays meaningful.
13
+ *
14
+ * Every handler accepts an optional resolution context (cwd / userSettingsPath)
15
+ * so the command is exercisable in tests without touching the real `~/.config`.
16
+ */
17
+ import { existsSync } from "node:fs";
18
+ import { loadSettings, getScopePaths, writeSettingsValue, writeStarterSettings, } from "../settings/index.js";
19
+ const SCOPES = ["user", "project", "local"];
20
+ function isScope(value) {
21
+ return SCOPES.includes(value);
22
+ }
23
+ /** Navigate a dotted path (e.g. "permissions.defaultMode") into the settings. */
24
+ function getByPath(settings, key) {
25
+ let cur = settings;
26
+ for (const part of key.split(".")) {
27
+ if (cur === null || typeof cur !== "object")
28
+ return undefined;
29
+ cur = cur[part];
30
+ }
31
+ return cur;
32
+ }
33
+ export function settingsShow(ctx = {}) {
34
+ const { settings, scopes } = loadSettings({ ...ctx, noCache: true });
35
+ console.log("Effective settings (merged user → project → local):\n");
36
+ console.log(JSON.stringify(settings, null, 2));
37
+ const present = scopes.filter((s) => s.settings || s.error);
38
+ console.log("\nScopes:");
39
+ if (present.length === 0) {
40
+ console.log(" (no settings files found — run `oxagen settings init`)");
41
+ }
42
+ for (const s of present) {
43
+ const status = s.error ? `⚠ ${s.error}` : "ok";
44
+ console.log(` ${s.scope.padEnd(8)} ${s.path} [${status}]`);
45
+ }
46
+ }
47
+ export function settingsPath(ctx = {}) {
48
+ const paths = getScopePaths(ctx);
49
+ console.log("Settings scope files (lowest → highest precedence):\n");
50
+ for (const scope of SCOPES) {
51
+ const path = paths[scope];
52
+ console.log(` ${scope.padEnd(8)} ${path} ${existsSync(path) ? "(exists)" : "(absent)"}`);
53
+ }
54
+ }
55
+ export function settingsGet(key, ctx = {}) {
56
+ const { settings } = loadSettings({ ...ctx, noCache: true });
57
+ const value = getByPath(settings, key);
58
+ if (value === undefined) {
59
+ console.log(`${key}: (not set)`);
60
+ return;
61
+ }
62
+ console.log(`${key}: ${typeof value === "string" ? value : JSON.stringify(value)}`);
63
+ }
64
+ export function settingsSet(key, value, scopeArg, ctx = {}) {
65
+ const scope = scopeArg ?? "project";
66
+ if (!isScope(scope)) {
67
+ console.error(`Unknown scope "${scope}". Use one of: ${SCOPES.join(", ")}`);
68
+ process.exitCode = 1;
69
+ return;
70
+ }
71
+ try {
72
+ const path = writeSettingsValue({ ...ctx, scope, key, value });
73
+ console.log(`✓ ${key} = ${value} (${scope}: ${path})`);
74
+ }
75
+ catch (err) {
76
+ console.error(`Error: ${err instanceof Error ? err.message : String(err)}`);
77
+ process.exitCode = 1;
78
+ }
79
+ }
80
+ export function settingsValidate(ctx = {}) {
81
+ const { scopes } = loadSettings({ ...ctx, noCache: true });
82
+ let ok = true;
83
+ let checked = 0;
84
+ for (const s of scopes) {
85
+ if (!s.settings && !s.error)
86
+ continue; // absent file — nothing to validate
87
+ checked++;
88
+ if (s.error) {
89
+ ok = false;
90
+ console.error(`✗ ${s.scope} (${s.path}): ${s.error}`);
91
+ }
92
+ else {
93
+ console.log(`✓ ${s.scope} (${s.path})`);
94
+ }
95
+ }
96
+ if (checked === 0)
97
+ console.log("No settings files found.");
98
+ if (!ok)
99
+ process.exitCode = 1;
100
+ }
101
+ export function settingsInit(scopeArg, ctx = {}) {
102
+ const scope = scopeArg ?? "project";
103
+ if (!isScope(scope)) {
104
+ console.error(`Unknown scope "${scope}". Use one of: ${SCOPES.join(", ")}`);
105
+ process.exitCode = 1;
106
+ return;
107
+ }
108
+ const { path, created } = writeStarterSettings({ ...ctx, scope });
109
+ if (created) {
110
+ console.log(`✓ Wrote starter settings to ${path}`);
111
+ console.log(" Edit it to add permissions, hooks, env, and MCP servers.");
112
+ }
113
+ else {
114
+ console.log(`${path} already exists — left untouched.`);
115
+ }
116
+ }
117
+ //# sourceMappingURL=settings.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../src/commands/settings.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@
13
13
  import { createRequire } from "node:module";
14
14
  import { Command } from "commander";
15
15
  import pkg from "../package.json" with { type: "json" };
16
+ import { parseModeArg } from "./agent/permissions.js";
16
17
  // The Oxagen context engine pulls in DuckDB, a native CommonJS dependency that
17
18
  // references a bare `require`. Under pure-ESM execution that global is absent, so
18
19
  // loading the store throws "require is not defined". Provide the shim before any
@@ -30,15 +31,40 @@ program
30
31
  .version(version)
31
32
  .argument("[prompt...]", "One-shot prompt (runs and exits)")
32
33
  .option("-m, --model <slug>", "Gateway model slug (overrides config/default)")
34
+ .option("--agent <name>", "Run the one-shot prompt as a named agent definition")
33
35
  .option("--readonly", "Read-only mode: read/search/explain only — no file edits or commands", false)
36
+ .option("--mode <mode>", "Permission mode: ask | accept-edits | bypass | readonly (REPL default: ask; one-shot ungated unless set)")
34
37
  .option("--no-pipeline", "Skip prompt evaluation, context injection, and completeness judging")
38
+ .option("--verbose", "Capture + emit full per-turn telemetry (per-phase timing, model+token+cost, tool results)", false)
35
39
  .action(async (promptWords, opts) => {
36
40
  const prompt = promptWords.join(" ").trim();
41
+ let mode;
42
+ if (opts.mode) {
43
+ mode = parseModeArg(opts.mode);
44
+ if (!mode) {
45
+ process.stderr.write(`Error: invalid --mode "${opts.mode}". Use ask, accept-edits, bypass, or readonly.\n`);
46
+ process.exitCode = 1;
47
+ return;
48
+ }
49
+ }
37
50
  const runOpts = {
38
51
  model: opts.model,
39
52
  readOnly: opts.readonly,
53
+ mode,
40
54
  bare: opts.pipeline === false,
55
+ verbose: opts.verbose,
41
56
  };
57
+ // --agent: run the prompt as a named agent (its prompt, tools, model).
58
+ if (opts.agent) {
59
+ if (!prompt) {
60
+ process.stderr.write("Error: --agent requires a prompt, e.g. `oxagen --agent reviewer \"…\"`.\n");
61
+ process.exitCode = 1;
62
+ return;
63
+ }
64
+ const { runAgentOneShot } = await import("./repl/one-shot.js");
65
+ await runAgentOneShot(prompt, opts.agent, runOpts);
66
+ return;
67
+ }
42
68
  if (prompt) {
43
69
  // One-shot mode: run prompt, stream response, exit
44
70
  const { runOneShot } = await import("./repl/one-shot.js");
@@ -117,7 +143,23 @@ program
117
143
  const { handleReplay } = await import("./commands/replay.js");
118
144
  await handleReplay(turn, opts);
119
145
  });
120
- // ── graph: knowledge-graph search ─────────────────────────────────────────────
146
+ // ── cost: project + report model cost from the baked-in rate card ─────────────
147
+ program
148
+ .command("cost")
149
+ // The root's global `-m, --model` is reused (commander binds it to the parent),
150
+ // so the action reads merged opts via optsWithGlobals() to see --model here.
151
+ .description("Project model cost from the baked-in rate card, or roll up this project's spend")
152
+ .option("--in <tokens>", "Input token count to price", (v) => parseInt(v, 10))
153
+ .option("--out <tokens>", "Output token count to price", (v) => parseInt(v, 10))
154
+ .option("--rates", "Print the baked-in rate card", false)
155
+ .option("--session", "Roll up what this project's recorded turns actually cost, by model", false)
156
+ .option("--json", "Output JSON", false)
157
+ .action(async (_opts, command) => {
158
+ const merged = command.optsWithGlobals();
159
+ const { handleCost } = await import("./commands/cost.js");
160
+ await handleCost(merged);
161
+ });
162
+ // ── graph: knowledge-graph search + pull + status ─────────────────────────────
121
163
  const graph = program.command("graph").description("Query the knowledge graph");
122
164
  graph
123
165
  .command("search")
@@ -132,6 +174,30 @@ graph
132
174
  const { handleGraphSearch } = await import("./commands/graph.search.js");
133
175
  await handleGraphSearch(opts);
134
176
  });
177
+ graph
178
+ .command("pull")
179
+ .description("Download an incremental snapshot of the workspace graph into a local DuckDB replica")
180
+ .option("--full", "Ignore the saved cursor and re-pull the entire graph", false)
181
+ .option("-l, --labels <csv>", "Comma-separated domain labels to filter (e.g. Person,SourceFile)")
182
+ .option("--no-system", "Exclude product-owned (system) nodes")
183
+ .option("--json", "Output summary as JSON")
184
+ .action(async (opts) => {
185
+ const { handleGraphPull } = await import("./commands/graph.pull.js");
186
+ await handleGraphPull({
187
+ full: opts.full,
188
+ labels: opts.labels,
189
+ noSystem: opts.system === false,
190
+ json: opts.json,
191
+ });
192
+ });
193
+ graph
194
+ .command("status")
195
+ .description("Show the state of the local workspace-graph replica")
196
+ .option("--json", "Output as JSON")
197
+ .action(async (opts) => {
198
+ const { handleGraphStatus } = await import("./commands/graph.status.js");
199
+ await handleGraphStatus(opts);
200
+ });
135
201
  // ── config: local configuration ───────────────────────────────────────────────
136
202
  program
137
203
  .command("config")
@@ -142,6 +208,232 @@ program
142
208
  const { handleConfig } = await import("./commands/config.js");
143
209
  await handleConfig(key, value);
144
210
  });
211
+ // ── settings: the unified settings.json driver ────────────────────────────────
212
+ const settings = program
213
+ .command("settings")
214
+ .description("Inspect and edit the unified settings.json (model, env, permissions, hooks, MCP)")
215
+ .action(async () => {
216
+ const { settingsShow } = await import("./commands/settings.js");
217
+ settingsShow();
218
+ });
219
+ settings
220
+ .command("show")
221
+ .description("Show the merged settings and which scope each file lives in")
222
+ .action(async () => {
223
+ const { settingsShow } = await import("./commands/settings.js");
224
+ settingsShow();
225
+ });
226
+ settings
227
+ .command("path")
228
+ .description("List the three scope files (user / project / local) and their status")
229
+ .action(async () => {
230
+ const { settingsPath } = await import("./commands/settings.js");
231
+ settingsPath();
232
+ });
233
+ settings
234
+ .command("get")
235
+ .description("Print a value by dotted key (e.g. permissions.defaultMode)")
236
+ .argument("<key>", "Dotted settings key")
237
+ .action(async (key) => {
238
+ const { settingsGet } = await import("./commands/settings.js");
239
+ settingsGet(key);
240
+ });
241
+ settings
242
+ .command("set")
243
+ .description("Set a value (model | apiUrl | env.NAME) in a scope")
244
+ .argument("<key>", "model, apiUrl, or env.NAME")
245
+ .argument("<value>", "Value to write")
246
+ .option("--scope <scope>", "user | project | local (default: project)")
247
+ .action(async (key, value, opts) => {
248
+ const { settingsSet } = await import("./commands/settings.js");
249
+ settingsSet(key, value, opts.scope);
250
+ });
251
+ settings
252
+ .command("validate")
253
+ .description("Validate every scope file against the settings schema")
254
+ .action(async () => {
255
+ const { settingsValidate } = await import("./commands/settings.js");
256
+ settingsValidate();
257
+ });
258
+ settings
259
+ .command("init")
260
+ .description("Write a documented starter settings.json (default: project scope)")
261
+ .option("--scope <scope>", "user | project | local (default: project)")
262
+ .action(async (opts) => {
263
+ const { settingsInit } = await import("./commands/settings.js");
264
+ settingsInit(opts.scope);
265
+ });
266
+ // ── agent: named agent definitions ────────────────────────────────────────────
267
+ const agent = program
268
+ .command("agent")
269
+ .description("Manage named agent definitions (run one with `oxagen --agent <name> \"…\"`)");
270
+ agent
271
+ .command("list")
272
+ .description("List available agents")
273
+ .action(async () => {
274
+ const { agentList } = await import("./commands/agent.js");
275
+ agentList();
276
+ });
277
+ agent
278
+ .command("show")
279
+ .description("Show an agent's definition and system prompt")
280
+ .argument("<name>", "Agent name")
281
+ .action(async (name) => {
282
+ const { agentShow } = await import("./commands/agent.js");
283
+ agentShow(name);
284
+ });
285
+ agent
286
+ .command("new")
287
+ .description("Scaffold a new agent at .oxagen/agents/<name>.md")
288
+ .argument("<name>", "Agent name")
289
+ .action(async (name) => {
290
+ const { agentNew } = await import("./commands/agent.js");
291
+ agentNew(name);
292
+ });
293
+ // ── command: user-defined slash commands ──────────────────────────────────────
294
+ const command = program
295
+ .command("command")
296
+ .description("Manage user-defined slash commands (invoke as `/name` in the REPL)");
297
+ command
298
+ .command("list")
299
+ .description("List available slash commands")
300
+ .action(async () => {
301
+ const { commandList } = await import("./commands/command.js");
302
+ commandList();
303
+ });
304
+ command
305
+ .command("show")
306
+ .description("Show a slash command's template")
307
+ .argument("<name>", "Command name")
308
+ .action(async (name) => {
309
+ const { commandShow } = await import("./commands/command.js");
310
+ commandShow(name);
311
+ });
312
+ command
313
+ .command("new")
314
+ .description("Scaffold a new slash command at .oxagen/commands/<name>.md")
315
+ .argument("<name>", "Command name")
316
+ .action(async (name) => {
317
+ const { commandNew } = await import("./commands/command.js");
318
+ commandNew(name);
319
+ });
320
+ command
321
+ .command("run")
322
+ .description("Expand a slash command's template with args and run it as a turn")
323
+ .argument("<name>", "Command name")
324
+ .argument("[args...]", "Arguments substituted into the template")
325
+ .action(async (name, args) => {
326
+ const { commandRun } = await import("./commands/command.js");
327
+ await commandRun(name, args ?? []);
328
+ });
329
+ // ── rules: workspace rules the agent must follow ──────────────────────────────
330
+ const rules = program
331
+ .command("rules")
332
+ .description("Manage workspace rules the agent is told about and hard-blocked from violating");
333
+ rules
334
+ .command("list")
335
+ .description("List rules (and which are hard-enforced)")
336
+ .action(async () => {
337
+ const { rulesList } = await import("./commands/rules.js");
338
+ rulesList();
339
+ });
340
+ rules
341
+ .command("show")
342
+ .description("Show a rule's text and guard")
343
+ .argument("<name>", "Rule name")
344
+ .action(async (name) => {
345
+ const { rulesShow } = await import("./commands/rules.js");
346
+ rulesShow(name);
347
+ });
348
+ rules
349
+ .command("new")
350
+ .description("Scaffold a new rule at .oxagen/rules/<name>.md")
351
+ .argument("<name>", "Rule name")
352
+ .action(async (name) => {
353
+ const { rulesNew } = await import("./commands/rules.js");
354
+ rulesNew(name);
355
+ });
356
+ rules
357
+ .command("check")
358
+ .description("Dry-run a proposed tool call against the guards (bash|edit|write|read)")
359
+ .argument("<tool>", "bash | edit | write | read")
360
+ .argument("<subject>", "The command (bash) or path (edit/write/read) to test")
361
+ .action(async (tool, subject) => {
362
+ const { rulesCheck } = await import("./commands/rules.js");
363
+ rulesCheck(tool, subject);
364
+ });
365
+ // ── mcp: external MCP servers ─────────────────────────────────────────────────
366
+ const collect = (val, prev) => prev.concat([val]);
367
+ const mcp = program
368
+ .command("mcp")
369
+ .description("Manage external MCP servers the agent loop connects to");
370
+ mcp
371
+ .command("add")
372
+ .description("Add an MCP server (stdio via --command, or http/sse/websocket via --url)")
373
+ .argument("<name>", "Server name (used in tool names: mcp__<name>__<tool>)")
374
+ .option("--command <command>", "stdio: the command to spawn (e.g. npx)")
375
+ .option("--arg <arg>", "stdio: a command argument (repeatable)", collect, [])
376
+ .option("--url <url>", "http/sse/websocket: the server URL")
377
+ .option("--transport <transport>", "streamable-http | sse | websocket (default streamable-http)")
378
+ .option("--auth <auth>", "none | bearer | header (default none)")
379
+ .option("--env-token <VAR>", "Env var holding the bearer token")
380
+ .option("--header <KEY=VALUE>", "Static header for header auth (repeatable)", collect, [])
381
+ .option("--scope <scope>", "user | project | local (default project)")
382
+ .action(async (name, opts) => {
383
+ const { mcpAdd } = await import("./commands/mcp.js");
384
+ mcpAdd(name, {
385
+ command: opts["command"],
386
+ arg: opts["arg"],
387
+ url: opts["url"],
388
+ transport: opts["transport"],
389
+ auth: opts["auth"],
390
+ envToken: opts["envToken"],
391
+ header: opts["header"],
392
+ scope: opts["scope"],
393
+ });
394
+ });
395
+ mcp
396
+ .command("list")
397
+ .description("List configured MCP servers")
398
+ .action(async () => {
399
+ const { mcpList } = await import("./commands/mcp.js");
400
+ mcpList();
401
+ });
402
+ mcp
403
+ .command("remove")
404
+ .description("Remove an MCP server")
405
+ .argument("<name>", "Server name")
406
+ .option("--scope <scope>", "Limit to a scope (default: auto-detect)")
407
+ .action(async (name, opts) => {
408
+ const { mcpRemove } = await import("./commands/mcp.js");
409
+ mcpRemove(name, opts.scope);
410
+ });
411
+ mcp
412
+ .command("enable")
413
+ .description("Enable a disabled MCP server")
414
+ .argument("<name>", "Server name")
415
+ .option("--scope <scope>", "Limit to a scope (default: auto-detect)")
416
+ .action(async (name, opts) => {
417
+ const { mcpSetEnabled } = await import("./commands/mcp.js");
418
+ mcpSetEnabled(name, true, opts.scope);
419
+ });
420
+ mcp
421
+ .command("disable")
422
+ .description("Disable an MCP server without removing it")
423
+ .argument("<name>", "Server name")
424
+ .option("--scope <scope>", "Limit to a scope (default: auto-detect)")
425
+ .action(async (name, opts) => {
426
+ const { mcpSetEnabled } = await import("./commands/mcp.js");
427
+ mcpSetEnabled(name, false, opts.scope);
428
+ });
429
+ mcp
430
+ .command("check")
431
+ .description("Connect to a server (or all enabled) and preview the tools it exposes")
432
+ .argument("[name]", "Server name (omit to check all enabled)")
433
+ .action(async (name) => {
434
+ const { mcpCheck } = await import("./commands/mcp.js");
435
+ await mcpCheck(name);
436
+ });
145
437
  // ── env: workspace environments ───────────────────────────────────────────────
146
438
  const env = program.command("env").description("Manage workspace environments");
147
439
  env
@@ -264,6 +556,10 @@ secret
264
556
  await handleSecretExport(opts);
265
557
  });
266
558
  async function main() {
559
+ // Project settings.json (env, apiUrl, model) into the environment before any
560
+ // command runs — filling only unset vars, so the shell always wins.
561
+ const { applySettingsToEnv } = await import("./settings/runtime.js");
562
+ applySettingsToEnv();
267
563
  await program.parseAsync(process.argv);
268
564
  }
269
565
  void main();