@oxagen/cli 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (442) 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 +135 -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 +44 -0
  29. package/dist/agent/__tests__/loop-errors.test.js.map +1 -0
  30. package/dist/agent/__tests__/model-router.test.d.ts +2 -0
  31. package/dist/agent/__tests__/model-router.test.d.ts.map +1 -0
  32. package/dist/agent/__tests__/model-router.test.js +122 -0
  33. package/dist/agent/__tests__/model-router.test.js.map +1 -0
  34. package/dist/agent/__tests__/orchestrator-isolation.test.d.ts +2 -0
  35. package/dist/agent/__tests__/orchestrator-isolation.test.d.ts.map +1 -0
  36. package/dist/agent/__tests__/orchestrator-isolation.test.js +134 -0
  37. package/dist/agent/__tests__/orchestrator-isolation.test.js.map +1 -0
  38. package/dist/agent/__tests__/orchestrator.test.d.ts +2 -0
  39. package/dist/agent/__tests__/orchestrator.test.d.ts.map +1 -0
  40. package/dist/agent/__tests__/orchestrator.test.js +201 -0
  41. package/dist/agent/__tests__/orchestrator.test.js.map +1 -0
  42. package/dist/agent/__tests__/pipeline.test.d.ts +2 -0
  43. package/dist/agent/__tests__/pipeline.test.d.ts.map +1 -0
  44. package/dist/agent/__tests__/pipeline.test.js +226 -0
  45. package/dist/agent/__tests__/pipeline.test.js.map +1 -0
  46. package/dist/agent/__tests__/planner.test.d.ts +2 -0
  47. package/dist/agent/__tests__/planner.test.d.ts.map +1 -0
  48. package/dist/agent/__tests__/planner.test.js +98 -0
  49. package/dist/agent/__tests__/planner.test.js.map +1 -0
  50. package/dist/agent/__tests__/prompt-enhancer.test.d.ts +2 -0
  51. package/dist/agent/__tests__/prompt-enhancer.test.d.ts.map +1 -0
  52. package/dist/agent/__tests__/prompt-enhancer.test.js +107 -0
  53. package/dist/agent/__tests__/prompt-enhancer.test.js.map +1 -0
  54. package/dist/agent/__tests__/trace-format.test.d.ts +2 -0
  55. package/dist/agent/__tests__/trace-format.test.d.ts.map +1 -0
  56. package/dist/agent/__tests__/trace-format.test.js +104 -0
  57. package/dist/agent/__tests__/trace-format.test.js.map +1 -0
  58. package/dist/agent/__tests__/trace-store.test.d.ts +2 -0
  59. package/dist/agent/__tests__/trace-store.test.d.ts.map +1 -0
  60. package/dist/agent/__tests__/trace-store.test.js +113 -0
  61. package/dist/agent/__tests__/trace-store.test.js.map +1 -0
  62. package/dist/agent/code-graph.d.ts +18 -0
  63. package/dist/agent/code-graph.d.ts.map +1 -0
  64. package/dist/agent/code-graph.js +119 -0
  65. package/dist/agent/code-graph.js.map +1 -0
  66. package/dist/agent/env.d.ts +11 -0
  67. package/dist/agent/env.d.ts.map +1 -0
  68. package/dist/agent/env.js +82 -0
  69. package/dist/agent/env.js.map +1 -0
  70. package/dist/agent/evaluator.d.ts +13 -0
  71. package/dist/agent/evaluator.d.ts.map +1 -0
  72. package/dist/agent/evaluator.js +146 -0
  73. package/dist/agent/evaluator.js.map +1 -0
  74. package/dist/agent/fleet/git-isolation.d.ts +142 -0
  75. package/dist/agent/fleet/git-isolation.d.ts.map +1 -0
  76. package/dist/agent/fleet/git-isolation.js +290 -0
  77. package/dist/agent/fleet/git-isolation.js.map +1 -0
  78. package/dist/agent/fleet/memory.d.ts +21 -0
  79. package/dist/agent/fleet/memory.d.ts.map +1 -0
  80. package/dist/agent/fleet/memory.js +129 -0
  81. package/dist/agent/fleet/memory.js.map +1 -0
  82. package/dist/agent/fleet/orchestrator.d.ts +103 -0
  83. package/dist/agent/fleet/orchestrator.d.ts.map +1 -0
  84. package/dist/agent/fleet/orchestrator.js +355 -0
  85. package/dist/agent/fleet/orchestrator.js.map +1 -0
  86. package/dist/agent/fleet/store.d.ts +13 -0
  87. package/dist/agent/fleet/store.d.ts.map +1 -0
  88. package/dist/agent/fleet/store.js +79 -0
  89. package/dist/agent/fleet/store.js.map +1 -0
  90. package/dist/agent/fleet/types.d.ts +105 -0
  91. package/dist/agent/fleet/types.d.ts.map +1 -0
  92. package/dist/agent/fleet/types.js +17 -0
  93. package/dist/agent/fleet/types.js.map +1 -0
  94. package/dist/agent/judge.d.ts +38 -0
  95. package/dist/agent/judge.d.ts.map +1 -0
  96. package/dist/agent/judge.js +170 -0
  97. package/dist/agent/judge.js.map +1 -0
  98. package/dist/agent/loop.d.ts +61 -0
  99. package/dist/agent/loop.d.ts.map +1 -0
  100. package/dist/agent/loop.js +134 -0
  101. package/dist/agent/loop.js.map +1 -0
  102. package/dist/agent/memory.d.ts +14 -0
  103. package/dist/agent/memory.d.ts.map +1 -0
  104. package/dist/agent/memory.js +118 -0
  105. package/dist/agent/memory.js.map +1 -0
  106. package/dist/agent/model-router.d.ts +79 -0
  107. package/dist/agent/model-router.d.ts.map +1 -0
  108. package/dist/agent/model-router.js +141 -0
  109. package/dist/agent/model-router.js.map +1 -0
  110. package/dist/agent/model.d.ts +9 -0
  111. package/dist/agent/model.d.ts.map +1 -0
  112. package/dist/agent/model.js +24 -0
  113. package/dist/agent/model.js.map +1 -0
  114. package/dist/agent/pipeline.d.ts +82 -0
  115. package/dist/agent/pipeline.d.ts.map +1 -0
  116. package/dist/agent/pipeline.js +320 -0
  117. package/dist/agent/pipeline.js.map +1 -0
  118. package/dist/agent/planner.d.ts +16 -0
  119. package/dist/agent/planner.d.ts.map +1 -0
  120. package/dist/agent/planner.js +126 -0
  121. package/dist/agent/planner.js.map +1 -0
  122. package/dist/agent/project-context.d.ts +13 -0
  123. package/dist/agent/project-context.d.ts.map +1 -0
  124. package/dist/agent/project-context.js +66 -0
  125. package/dist/agent/project-context.js.map +1 -0
  126. package/dist/agent/prompt-enhancer.d.ts +37 -0
  127. package/dist/agent/prompt-enhancer.d.ts.map +1 -0
  128. package/dist/agent/prompt-enhancer.js +115 -0
  129. package/dist/agent/prompt-enhancer.js.map +1 -0
  130. package/dist/agent/system-prompt.d.ts +9 -0
  131. package/dist/agent/system-prompt.d.ts.map +1 -0
  132. package/dist/agent/system-prompt.js +38 -0
  133. package/dist/agent/system-prompt.js.map +1 -0
  134. package/dist/agent/tools.d.ts +19 -0
  135. package/dist/agent/tools.d.ts.map +1 -0
  136. package/dist/agent/tools.js +323 -0
  137. package/dist/agent/tools.js.map +1 -0
  138. package/dist/agent/trace-format.d.ts +6 -0
  139. package/dist/agent/trace-format.d.ts.map +1 -0
  140. package/dist/agent/trace-format.js +74 -0
  141. package/dist/agent/trace-format.js.map +1 -0
  142. package/dist/agent/trace-store.d.ts +19 -0
  143. package/dist/agent/trace-store.d.ts.map +1 -0
  144. package/dist/agent/trace-store.js +82 -0
  145. package/dist/agent/trace-store.js.map +1 -0
  146. package/dist/agent/trace.d.ts +121 -0
  147. package/dist/agent/trace.d.ts.map +1 -0
  148. package/dist/agent/trace.js +2 -0
  149. package/dist/agent/trace.js.map +1 -0
  150. package/dist/commands/__tests__/replay.test.d.ts +2 -0
  151. package/dist/commands/__tests__/replay.test.d.ts.map +1 -0
  152. package/dist/commands/__tests__/replay.test.js +76 -0
  153. package/dist/commands/__tests__/replay.test.js.map +1 -0
  154. package/dist/commands/agent.skill.load.d.ts +3 -0
  155. package/dist/commands/agent.skill.load.d.ts.map +1 -0
  156. package/dist/commands/agent.skill.load.js +57 -0
  157. package/dist/commands/agent.skill.load.js.map +1 -0
  158. package/dist/commands/code.d.ts +14 -0
  159. package/dist/commands/code.d.ts.map +1 -0
  160. package/dist/commands/code.js +100 -0
  161. package/dist/commands/code.js.map +1 -0
  162. package/dist/commands/config.d.ts +2 -0
  163. package/dist/commands/config.d.ts.map +1 -0
  164. package/dist/commands/config.js +66 -0
  165. package/dist/commands/config.js.map +1 -0
  166. package/dist/commands/env.d.ts +19 -0
  167. package/dist/commands/env.d.ts.map +1 -0
  168. package/dist/commands/env.js +64 -0
  169. package/dist/commands/env.js.map +1 -0
  170. package/dist/commands/graph.search.d.ts +10 -0
  171. package/dist/commands/graph.search.d.ts.map +1 -0
  172. package/dist/commands/graph.search.js +25 -0
  173. package/dist/commands/graph.search.js.map +1 -0
  174. package/dist/commands/mcp.add.d.ts +13 -0
  175. package/dist/commands/mcp.add.d.ts.map +1 -0
  176. package/dist/commands/mcp.add.js +110 -0
  177. package/dist/commands/mcp.add.js.map +1 -0
  178. package/dist/commands/mcp.auth.d.ts +10 -0
  179. package/dist/commands/mcp.auth.d.ts.map +1 -0
  180. package/dist/commands/mcp.auth.js +132 -0
  181. package/dist/commands/mcp.auth.js.map +1 -0
  182. package/dist/commands/mcp.check.d.ts +10 -0
  183. package/dist/commands/mcp.check.d.ts.map +1 -0
  184. package/dist/commands/mcp.check.js +114 -0
  185. package/dist/commands/mcp.check.js.map +1 -0
  186. package/dist/commands/mcp.list.d.ts +9 -0
  187. package/dist/commands/mcp.list.d.ts.map +1 -0
  188. package/dist/commands/mcp.list.js +93 -0
  189. package/dist/commands/mcp.list.js.map +1 -0
  190. package/dist/commands/mcp.permit.d.ts +12 -0
  191. package/dist/commands/mcp.permit.d.ts.map +1 -0
  192. package/dist/commands/mcp.permit.js +117 -0
  193. package/dist/commands/mcp.permit.js.map +1 -0
  194. package/dist/commands/mcp.remove.d.ts +9 -0
  195. package/dist/commands/mcp.remove.d.ts.map +1 -0
  196. package/dist/commands/mcp.remove.js +65 -0
  197. package/dist/commands/mcp.remove.js.map +1 -0
  198. package/dist/commands/plugin.org.install_bulk.js +1 -1
  199. package/dist/commands/plugin.org.install_bulk.js.map +1 -1
  200. package/dist/commands/privacy.erase.test.js +7 -0
  201. package/dist/commands/privacy.erase.test.js.map +1 -1
  202. package/dist/commands/replay.d.ts +5 -0
  203. package/dist/commands/replay.d.ts.map +1 -0
  204. package/dist/commands/replay.js +28 -0
  205. package/dist/commands/replay.js.map +1 -0
  206. package/dist/commands/schema/schema.config.d.ts +3 -0
  207. package/dist/commands/schema/schema.config.d.ts.map +1 -0
  208. package/dist/commands/schema/schema.config.js +34 -0
  209. package/dist/commands/schema/schema.config.js.map +1 -0
  210. package/dist/commands/schema/schema.disable.d.ts +3 -0
  211. package/dist/commands/schema/schema.disable.d.ts.map +1 -0
  212. package/dist/commands/schema/schema.disable.js +22 -0
  213. package/dist/commands/schema/schema.disable.js.map +1 -0
  214. package/dist/commands/schema/schema.enable.d.ts +3 -0
  215. package/dist/commands/schema/schema.enable.d.ts.map +1 -0
  216. package/dist/commands/schema/schema.enable.js +22 -0
  217. package/dist/commands/schema/schema.enable.js.map +1 -0
  218. package/dist/commands/schema/schema.export.d.ts +3 -0
  219. package/dist/commands/schema/schema.export.d.ts.map +1 -0
  220. package/dist/commands/schema/schema.export.js +31 -0
  221. package/dist/commands/schema/schema.export.js.map +1 -0
  222. package/dist/commands/schema/schema.get.d.ts +3 -0
  223. package/dist/commands/schema/schema.get.d.ts.map +1 -0
  224. package/dist/commands/schema/schema.get.js +23 -0
  225. package/dist/commands/schema/schema.get.js.map +1 -0
  226. package/dist/commands/schema/schema.label.d.ts +5 -0
  227. package/dist/commands/schema/schema.label.d.ts.map +1 -0
  228. package/dist/commands/schema/schema.label.js +60 -0
  229. package/dist/commands/schema/schema.label.js.map +1 -0
  230. package/dist/commands/schema/schema.list.d.ts +3 -0
  231. package/dist/commands/schema/schema.list.d.ts.map +1 -0
  232. package/dist/commands/schema/schema.list.js +30 -0
  233. package/dist/commands/schema/schema.list.js.map +1 -0
  234. package/dist/commands/schema/schema.prop.d.ts +5 -0
  235. package/dist/commands/schema/schema.prop.d.ts.map +1 -0
  236. package/dist/commands/schema/schema.prop.js +72 -0
  237. package/dist/commands/schema/schema.prop.js.map +1 -0
  238. package/dist/commands/schema/schema.reconcile.d.ts +10 -0
  239. package/dist/commands/schema/schema.reconcile.d.ts.map +1 -0
  240. package/dist/commands/schema/schema.reconcile.js +65 -0
  241. package/dist/commands/schema/schema.reconcile.js.map +1 -0
  242. package/dist/commands/schema/schema.rel.d.ts +5 -0
  243. package/dist/commands/schema/schema.rel.d.ts.map +1 -0
  244. package/dist/commands/schema/schema.rel.js +65 -0
  245. package/dist/commands/schema/schema.rel.js.map +1 -0
  246. package/dist/commands/schema/schema.version.d.ts +7 -0
  247. package/dist/commands/schema/schema.version.d.ts.map +1 -0
  248. package/dist/commands/schema/schema.version.js +96 -0
  249. package/dist/commands/schema/schema.version.js.map +1 -0
  250. package/dist/commands/secret.d.ts +23 -0
  251. package/dist/commands/secret.d.ts.map +1 -0
  252. package/dist/commands/secret.js +90 -0
  253. package/dist/commands/secret.js.map +1 -0
  254. package/dist/commands/skill.create.d.ts +3 -0
  255. package/dist/commands/skill.create.d.ts.map +1 -0
  256. package/dist/commands/skill.create.js +52 -0
  257. package/dist/commands/skill.create.js.map +1 -0
  258. package/dist/commands/skill.enable.d.ts +3 -0
  259. package/dist/commands/skill.enable.d.ts.map +1 -0
  260. package/dist/commands/skill.enable.js +31 -0
  261. package/dist/commands/skill.enable.js.map +1 -0
  262. package/dist/commands.test.js +1291 -281
  263. package/dist/commands.test.js.map +1 -1
  264. package/dist/components/DevStatus.d.ts.map +1 -1
  265. package/dist/components/DevStatus.js +3 -2
  266. package/dist/components/DevStatus.js.map +1 -1
  267. package/dist/daemon/client.d.ts +30 -0
  268. package/dist/daemon/client.d.ts.map +1 -0
  269. package/dist/daemon/client.js +97 -0
  270. package/dist/daemon/client.js.map +1 -0
  271. package/dist/daemon/code-graph/builder.d.ts +6 -0
  272. package/dist/daemon/code-graph/builder.d.ts.map +1 -0
  273. package/dist/daemon/code-graph/builder.js +215 -0
  274. package/dist/daemon/code-graph/builder.js.map +1 -0
  275. package/dist/daemon/code-graph/query.d.ts +29 -0
  276. package/dist/daemon/code-graph/query.d.ts.map +1 -0
  277. package/dist/daemon/code-graph/query.js +98 -0
  278. package/dist/daemon/code-graph/query.js.map +1 -0
  279. package/dist/daemon/code-graph/types.d.ts +37 -0
  280. package/dist/daemon/code-graph/types.d.ts.map +1 -0
  281. package/dist/daemon/code-graph/types.js +5 -0
  282. package/dist/daemon/code-graph/types.js.map +1 -0
  283. package/dist/daemon/code-graph/watcher.d.ts +37 -0
  284. package/dist/daemon/code-graph/watcher.d.ts.map +1 -0
  285. package/dist/daemon/code-graph/watcher.js +79 -0
  286. package/dist/daemon/code-graph/watcher.js.map +1 -0
  287. package/dist/daemon/lifecycle.d.ts +6 -0
  288. package/dist/daemon/lifecycle.d.ts.map +1 -0
  289. package/dist/daemon/lifecycle.js +132 -0
  290. package/dist/daemon/lifecycle.js.map +1 -0
  291. package/dist/daemon/protocol.d.ts +113 -0
  292. package/dist/daemon/protocol.d.ts.map +1 -0
  293. package/dist/daemon/protocol.js +16 -0
  294. package/dist/daemon/protocol.js.map +1 -0
  295. package/dist/daemon/server.d.ts +26 -0
  296. package/dist/daemon/server.d.ts.map +1 -0
  297. package/dist/daemon/server.js +168 -0
  298. package/dist/daemon/server.js.map +1 -0
  299. package/dist/index.d.ts +1 -1
  300. package/dist/index.js +262 -356
  301. package/dist/index.js.map +1 -1
  302. package/dist/lib/api.d.ts +5 -0
  303. package/dist/lib/api.d.ts.map +1 -0
  304. package/dist/lib/api.js +52 -0
  305. package/dist/lib/api.js.map +1 -0
  306. package/dist/lib/config.d.ts +3 -0
  307. package/dist/lib/config.d.ts.map +1 -1
  308. package/dist/lib/config.js +8 -2
  309. package/dist/lib/config.js.map +1 -1
  310. package/dist/lib/differential-context.d.ts +46 -0
  311. package/dist/lib/differential-context.d.ts.map +1 -0
  312. package/dist/lib/differential-context.js +89 -0
  313. package/dist/lib/differential-context.js.map +1 -0
  314. package/dist/lib/resolve.d.ts +3 -0
  315. package/dist/lib/resolve.d.ts.map +1 -0
  316. package/dist/lib/resolve.js +29 -0
  317. package/dist/lib/resolve.js.map +1 -0
  318. package/dist/lib/structured-tool-io.d.ts +31 -0
  319. package/dist/lib/structured-tool-io.d.ts.map +1 -0
  320. package/dist/lib/structured-tool-io.js +56 -0
  321. package/dist/lib/structured-tool-io.js.map +1 -0
  322. package/dist/repl/__tests__/_queue_demo.test.d.ts +2 -0
  323. package/dist/repl/__tests__/_queue_demo.test.d.ts.map +1 -0
  324. package/dist/repl/__tests__/_queue_demo.test.js +40 -0
  325. package/dist/repl/__tests__/_queue_demo.test.js.map +1 -0
  326. package/dist/repl/__tests__/components.test.d.ts +2 -0
  327. package/dist/repl/__tests__/components.test.d.ts.map +1 -0
  328. package/dist/repl/__tests__/components.test.js +38 -0
  329. package/dist/repl/__tests__/components.test.js.map +1 -0
  330. package/dist/repl/__tests__/interactive.queue.test.d.ts +2 -0
  331. package/dist/repl/__tests__/interactive.queue.test.d.ts.map +1 -0
  332. package/dist/repl/__tests__/interactive.queue.test.js +124 -0
  333. package/dist/repl/__tests__/interactive.queue.test.js.map +1 -0
  334. package/dist/repl/components.d.ts +59 -0
  335. package/dist/repl/components.d.ts.map +1 -0
  336. package/dist/repl/components.js +152 -0
  337. package/dist/repl/components.js.map +1 -0
  338. package/dist/repl/interactive.d.ts +12 -0
  339. package/dist/repl/interactive.d.ts.map +1 -0
  340. package/dist/repl/interactive.js +326 -0
  341. package/dist/repl/interactive.js.map +1 -0
  342. package/dist/repl/one-shot.d.ts +9 -0
  343. package/dist/repl/one-shot.d.ts.map +1 -0
  344. package/dist/repl/one-shot.js +83 -0
  345. package/dist/repl/one-shot.js.map +1 -0
  346. package/dist/tui/__tests__/app.test.d.ts +2 -0
  347. package/dist/tui/__tests__/app.test.d.ts.map +1 -0
  348. package/dist/tui/__tests__/app.test.js +136 -0
  349. package/dist/tui/__tests__/app.test.js.map +1 -0
  350. package/dist/tui/__tests__/banner.test.d.ts +2 -0
  351. package/dist/tui/__tests__/banner.test.d.ts.map +1 -0
  352. package/dist/tui/__tests__/banner.test.js +15 -0
  353. package/dist/tui/__tests__/banner.test.js.map +1 -0
  354. package/dist/tui/__tests__/command-form.test.d.ts +2 -0
  355. package/dist/tui/__tests__/command-form.test.d.ts.map +1 -0
  356. package/dist/tui/__tests__/command-form.test.js +96 -0
  357. package/dist/tui/__tests__/command-form.test.js.map +1 -0
  358. package/dist/tui/__tests__/command-tree.test.d.ts +2 -0
  359. package/dist/tui/__tests__/command-tree.test.d.ts.map +1 -0
  360. package/dist/tui/__tests__/command-tree.test.js +55 -0
  361. package/dist/tui/__tests__/command-tree.test.js.map +1 -0
  362. package/dist/tui/__tests__/runner.test.d.ts +2 -0
  363. package/dist/tui/__tests__/runner.test.d.ts.map +1 -0
  364. package/dist/tui/__tests__/runner.test.js +38 -0
  365. package/dist/tui/__tests__/runner.test.js.map +1 -0
  366. package/dist/tui/__tests__/theme.test.d.ts +2 -0
  367. package/dist/tui/__tests__/theme.test.d.ts.map +1 -0
  368. package/dist/tui/__tests__/theme.test.js +11 -0
  369. package/dist/tui/__tests__/theme.test.js.map +1 -0
  370. package/dist/tui/agent-view/activity-feed.d.ts +3 -0
  371. package/dist/tui/agent-view/activity-feed.d.ts.map +1 -0
  372. package/dist/tui/agent-view/activity-feed.js +34 -0
  373. package/dist/tui/agent-view/activity-feed.js.map +1 -0
  374. package/dist/tui/agent-view/budget-bar.d.ts +3 -0
  375. package/dist/tui/agent-view/budget-bar.d.ts.map +1 -0
  376. package/dist/tui/agent-view/budget-bar.js +53 -0
  377. package/dist/tui/agent-view/budget-bar.js.map +1 -0
  378. package/dist/tui/agent-view/compile-panel.d.ts +3 -0
  379. package/dist/tui/agent-view/compile-panel.d.ts.map +1 -0
  380. package/dist/tui/agent-view/compile-panel.js +34 -0
  381. package/dist/tui/agent-view/compile-panel.js.map +1 -0
  382. package/dist/tui/agent-view/index.d.ts +4 -0
  383. package/dist/tui/agent-view/index.d.ts.map +1 -0
  384. package/dist/tui/agent-view/index.js +31 -0
  385. package/dist/tui/agent-view/index.js.map +1 -0
  386. package/dist/tui/agent-view/memory-panel.d.ts +3 -0
  387. package/dist/tui/agent-view/memory-panel.d.ts.map +1 -0
  388. package/dist/tui/agent-view/memory-panel.js +80 -0
  389. package/dist/tui/agent-view/memory-panel.js.map +1 -0
  390. package/dist/tui/agent-view/session-panel.d.ts +3 -0
  391. package/dist/tui/agent-view/session-panel.d.ts.map +1 -0
  392. package/dist/tui/agent-view/session-panel.js +44 -0
  393. package/dist/tui/agent-view/session-panel.js.map +1 -0
  394. package/dist/tui/agent-view/status-bar.d.ts +7 -0
  395. package/dist/tui/agent-view/status-bar.d.ts.map +1 -0
  396. package/dist/tui/agent-view/status-bar.js +22 -0
  397. package/dist/tui/agent-view/status-bar.js.map +1 -0
  398. package/dist/tui/app.d.ts +9 -0
  399. package/dist/tui/app.d.ts.map +1 -0
  400. package/dist/tui/app.js +115 -0
  401. package/dist/tui/app.js.map +1 -0
  402. package/dist/tui/banner.d.ts +5 -0
  403. package/dist/tui/banner.d.ts.map +1 -0
  404. package/dist/tui/banner.js +17 -0
  405. package/dist/tui/banner.js.map +1 -0
  406. package/dist/tui/command-form.d.ts +9 -0
  407. package/dist/tui/command-form.d.ts.map +1 -0
  408. package/dist/tui/command-form.js +76 -0
  409. package/dist/tui/command-form.js.map +1 -0
  410. package/dist/tui/command-tree.d.ts +30 -0
  411. package/dist/tui/command-tree.d.ts.map +1 -0
  412. package/dist/tui/command-tree.js +43 -0
  413. package/dist/tui/command-tree.js.map +1 -0
  414. package/dist/tui/fleet-view/agent-row.d.ts +10 -0
  415. package/dist/tui/fleet-view/agent-row.d.ts.map +1 -0
  416. package/dist/tui/fleet-view/agent-row.js +80 -0
  417. package/dist/tui/fleet-view/agent-row.js.map +1 -0
  418. package/dist/tui/fleet-view/dispatch-input.d.ts +5 -0
  419. package/dist/tui/fleet-view/dispatch-input.d.ts.map +1 -0
  420. package/dist/tui/fleet-view/dispatch-input.js +36 -0
  421. package/dist/tui/fleet-view/dispatch-input.js.map +1 -0
  422. package/dist/tui/fleet-view/fleet-app.d.ts +11 -0
  423. package/dist/tui/fleet-view/fleet-app.d.ts.map +1 -0
  424. package/dist/tui/fleet-view/fleet-app.js +95 -0
  425. package/dist/tui/fleet-view/fleet-app.js.map +1 -0
  426. package/dist/tui/fleet-view/fleet-summary.d.ts +6 -0
  427. package/dist/tui/fleet-view/fleet-summary.d.ts.map +1 -0
  428. package/dist/tui/fleet-view/fleet-summary.js +19 -0
  429. package/dist/tui/fleet-view/fleet-summary.js.map +1 -0
  430. package/dist/tui/fleet-view/index.d.ts +16 -0
  431. package/dist/tui/fleet-view/index.d.ts.map +1 -0
  432. package/dist/tui/fleet-view/index.js +61 -0
  433. package/dist/tui/fleet-view/index.js.map +1 -0
  434. package/dist/tui/runner.d.ts +7 -0
  435. package/dist/tui/runner.d.ts.map +1 -0
  436. package/dist/tui/runner.js +36 -0
  437. package/dist/tui/runner.js.map +1 -0
  438. package/dist/tui/theme.d.ts +8 -0
  439. package/dist/tui/theme.d.ts.map +1 -0
  440. package/dist/tui/theme.js +10 -0
  441. package/dist/tui/theme.js.map +1 -0
  442. package/package.json +12 -7
@@ -3,7 +3,11 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
3
3
  vi.mock("./lib/config.js", () => ({
4
4
  getToken: vi.fn(() => "test-token"),
5
5
  getApiUrl: vi.fn(() => "http://localhost:4000"),
6
- readConfig: vi.fn(() => ({ token: "test-token", orgSlug: "my-org", workspaceSlug: "default" })),
6
+ readConfig: vi.fn(() => ({
7
+ token: "test-token",
8
+ orgSlug: "my-org",
9
+ workspaceSlug: "default",
10
+ })),
7
11
  writeConfig: vi.fn(),
8
12
  clearConfig: vi.fn(),
9
13
  getOrgId: vi.fn(() => "my-org"),
@@ -67,8 +71,6 @@ import { imageListCommand } from "./commands/image.list.js";
67
71
  import { imageAnalyzeCommand } from "./commands/image.analyze.js";
68
72
  import { documentListCommand } from "./commands/document.list.js";
69
73
  import { documentReadCommand } from "./commands/document.read.js";
70
- import { formCreateCommand } from "./commands/form.create.js";
71
- import { formSubmitCommand } from "./commands/form.submit.js";
72
74
  import { automationCreateCommand } from "./commands/automation.create.js";
73
75
  import { automationEnableCommand } from "./commands/automation.enable.js";
74
76
  import { automationDisableCommand } from "./commands/automation.disable.js";
@@ -94,7 +96,6 @@ import { agentTaskBackgroundReadCommand } from "./commands/agent.task.background
94
96
  import { agentTaskBackgroundCancelCommand } from "./commands/agent.task.background.cancel.js";
95
97
  import { assetUploadCommand } from "./commands/asset.upload.js";
96
98
  import { billingSubscriptionUpgradeStartCommand } from "./commands/billing.subscription.upgrade.start.js";
97
- import { brandkitApplyCommand } from "./commands/brandkit.apply.js";
98
99
  import { conversationPurgeCommand } from "./commands/conversation.purge.js";
99
100
  import { documentsPdfCreateCommand } from "./commands/documents.pdf.create.js";
100
101
  import { formFillCommand } from "./commands/form.fill.js";
@@ -139,7 +140,9 @@ afterEach(() => {
139
140
  describe("auth login", () => {
140
141
  it("exits 1 if email or password is missing", async () => {
141
142
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
142
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
143
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
144
+ throw new Error("exit");
145
+ });
143
146
  await expect(() => authLoginCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
144
147
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("email and password are required"));
145
148
  consoleSpy.mockRestore();
@@ -147,8 +150,18 @@ describe("auth login", () => {
147
150
  });
148
151
  it("calls API with credentials and stores token", async () => {
149
152
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
150
- mockApiRequest.mockResolvedValueOnce({ token: "new-token", user: { email: "user@example.com" } });
151
- await authLoginCommand.parseAsync(["node", "cli", "--email", "user@example.com", "--password", "secret"]);
153
+ mockApiRequest.mockResolvedValueOnce({
154
+ token: "new-token",
155
+ user: { email: "user@example.com" },
156
+ });
157
+ await authLoginCommand.parseAsync([
158
+ "node",
159
+ "cli",
160
+ "--email",
161
+ "user@example.com",
162
+ "--password",
163
+ "secret",
164
+ ]);
152
165
  expect(mockApiRequest).toHaveBeenCalledWith("/auth/sign-in/email", expect.objectContaining({ method: "POST" }));
153
166
  expect(mockWriteConfig).toHaveBeenCalledWith(expect.objectContaining({ token: "new-token" }));
154
167
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Authenticated"));
@@ -156,9 +169,18 @@ describe("auth login", () => {
156
169
  });
157
170
  it("exits 1 on API error during login", async () => {
158
171
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
159
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
172
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
173
+ throw new Error("exit");
174
+ });
160
175
  mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
161
- await expect(() => authLoginCommand.parseAsync(["node", "cli", "--email", "a@b.com", "--password", "pw"])).rejects.toThrow("exit");
176
+ await expect(() => authLoginCommand.parseAsync([
177
+ "node",
178
+ "cli",
179
+ "--email",
180
+ "a@b.com",
181
+ "--password",
182
+ "pw",
183
+ ])).rejects.toThrow("exit");
162
184
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
163
185
  consoleSpy.mockRestore();
164
186
  exitSpy.mockRestore();
@@ -166,7 +188,14 @@ describe("auth login", () => {
166
188
  it("handles response with session.token shape", async () => {
167
189
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
168
190
  mockApiRequest.mockResolvedValueOnce({ session: { token: "session-tok" } });
169
- await authLoginCommand.parseAsync(["node", "cli", "-e", "a@b.com", "-p", "pw"]);
191
+ await authLoginCommand.parseAsync([
192
+ "node",
193
+ "cli",
194
+ "-e",
195
+ "a@b.com",
196
+ "-p",
197
+ "pw",
198
+ ]);
170
199
  expect(mockWriteConfig).toHaveBeenCalledWith(expect.objectContaining({ token: "session-tok" }));
171
200
  consoleSpy.mockRestore();
172
201
  });
@@ -221,15 +250,22 @@ describe("auth whoami", () => {
221
250
  });
222
251
  it("falls back to config values for org/workspace", async () => {
223
252
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
224
- mockApiRequest.mockResolvedValueOnce({ user: { email: "mac@example.com" } });
225
- vi.mocked(config.readConfig).mockReturnValue({ orgSlug: "cfg-org", workspaceSlug: "cfg-ws" });
253
+ mockApiRequest.mockResolvedValueOnce({
254
+ user: { email: "mac@example.com" },
255
+ });
256
+ vi.mocked(config.readConfig).mockReturnValue({
257
+ orgSlug: "cfg-org",
258
+ workspaceSlug: "cfg-ws",
259
+ });
226
260
  await authWhoamiCommand.parseAsync(["node", "cli"]);
227
261
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cfg-org"));
228
262
  consoleSpy.mockRestore();
229
263
  });
230
264
  it("exits 1 on API error", async () => {
231
265
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
232
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
266
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
267
+ throw new Error("exit");
268
+ });
233
269
  mockApiRequest.mockRejectedValueOnce(new Error("Forbidden"));
234
270
  await expect(() => authWhoamiCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
235
271
  consoleSpy.mockRestore();
@@ -259,7 +295,9 @@ describe("org list", () => {
259
295
  });
260
296
  it("handles data array shape from API", async () => {
261
297
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
262
- mockApiRequest.mockResolvedValueOnce({ data: [{ id: "id1", slug: "org-1", name: "Org 1" }] });
298
+ mockApiRequest.mockResolvedValueOnce({
299
+ data: [{ id: "id1", slug: "org-1", name: "Org 1" }],
300
+ });
263
301
  await orgListCommand.parseAsync(["node", "cli"]);
264
302
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("org-1"));
265
303
  consoleSpy.mockRestore();
@@ -271,7 +309,9 @@ describe("org list", () => {
271
309
  describe("org create", () => {
272
310
  it("creates org and prints slug", async () => {
273
311
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
274
- mockApiRequest.mockResolvedValueOnce({ organization: { slug: "new-org", name: "New Org" } });
312
+ mockApiRequest.mockResolvedValueOnce({
313
+ organization: { slug: "new-org", name: "New Org" },
314
+ });
275
315
  await orgCreateCommand.parseAsync(["node", "cli", "New Org"]);
276
316
  expect(mockApiRequest).toHaveBeenCalledWith("/organizations", expect.objectContaining({ method: "POST" }));
277
317
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("new-org"));
@@ -279,7 +319,9 @@ describe("org create", () => {
279
319
  });
280
320
  it("exits 1 on API error", async () => {
281
321
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
282
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
322
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
323
+ throw new Error("exit");
324
+ });
283
325
  mockApiRequest.mockRejectedValueOnce(new Error("Conflict"));
284
326
  await expect(() => orgCreateCommand.parseAsync(["node", "cli", "Dup"])).rejects.toThrow("exit");
285
327
  consoleSpy.mockRestore();
@@ -293,7 +335,13 @@ describe("org member add", () => {
293
335
  it("adds member and confirms", async () => {
294
336
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
295
337
  mockApiRequest.mockResolvedValueOnce({});
296
- await orgMemberAddCommand.parseAsync(["node", "cli", "new@example.com", "--role", "admin"]);
338
+ await orgMemberAddCommand.parseAsync([
339
+ "node",
340
+ "cli",
341
+ "new@example.com",
342
+ "--role",
343
+ "admin",
344
+ ]);
297
345
  expect(mockApiRequest).toHaveBeenCalledWith("/org/members", expect.objectContaining({ method: "POST" }));
298
346
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("new@example.com"));
299
347
  consoleSpy.mockRestore();
@@ -301,7 +349,13 @@ describe("org member add", () => {
301
349
  it("defaults role to member when no --role flag given", async () => {
302
350
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
303
351
  mockApiRequest.mockResolvedValueOnce({});
304
- await orgMemberAddCommand.parseAsync(["node", "cli", "x@example.com", "--role", "member"]);
352
+ await orgMemberAddCommand.parseAsync([
353
+ "node",
354
+ "cli",
355
+ "x@example.com",
356
+ "--role",
357
+ "member",
358
+ ]);
305
359
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("member"));
306
360
  consoleSpy.mockRestore();
307
361
  });
@@ -348,7 +402,9 @@ describe("workspace list", () => {
348
402
  describe("workspace create", () => {
349
403
  it("creates workspace and prints slug", async () => {
350
404
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
351
- mockApiRequest.mockResolvedValueOnce({ workspace: { slug: "my-ws", name: "My WS" } });
405
+ mockApiRequest.mockResolvedValueOnce({
406
+ workspace: { slug: "my-ws", name: "My WS" },
407
+ });
352
408
  await workspaceCreateCommand.parseAsync(["node", "cli", "My WS"]);
353
409
  expect(mockApiRequest).toHaveBeenCalledWith("/workspaces", expect.objectContaining({ method: "POST" }));
354
410
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("my-ws"));
@@ -364,7 +420,10 @@ function makeSseResponse(text) {
364
420
  const line = `data: ${JSON.stringify({ type: "text", text })}\n\nevent: done\ndata: [DONE]\n\n`;
365
421
  const encoder = new TextEncoder();
366
422
  const stream = new ReadableStream({
367
- start(c) { c.enqueue(encoder.encode(line)); c.close(); },
423
+ start(c) {
424
+ c.enqueue(encoder.encode(line));
425
+ c.close();
426
+ },
368
427
  });
369
428
  return new Response(stream, {
370
429
  status: 200,
@@ -378,9 +437,13 @@ function makeErrorResponse(status, message) {
378
437
  });
379
438
  }
380
439
  describe("chat send", () => {
381
- afterEach(() => { vi.restoreAllMocks(); });
440
+ afterEach(() => {
441
+ vi.restoreAllMocks();
442
+ });
382
443
  it("sends message and streams response to stdout", async () => {
383
- const stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
444
+ const stdoutSpy = vi
445
+ .spyOn(process.stdout, "write")
446
+ .mockImplementation(() => true);
384
447
  vi.spyOn(global, "fetch").mockResolvedValueOnce(makeSseResponse("Hello back!"));
385
448
  await chatSendCommand.parseAsync(["node", "cli", "hello"]);
386
449
  const written = stdoutSpy.mock.calls.map((c) => String(c[0])).join("");
@@ -388,19 +451,29 @@ describe("chat send", () => {
388
451
  stdoutSpy.mockRestore();
389
452
  });
390
453
  it("passes conversationId when --conversation is provided", async () => {
391
- const stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
454
+ const stdoutSpy = vi
455
+ .spyOn(process.stdout, "write")
456
+ .mockImplementation(() => true);
392
457
  let capturedBody = null;
393
458
  vi.spyOn(global, "fetch").mockImplementationOnce(async (_url, init) => {
394
459
  capturedBody = JSON.parse(init.body);
395
460
  return makeSseResponse("ok");
396
461
  });
397
- await chatSendCommand.parseAsync(["node", "cli", "hi", "--conversation", "cnv_abc"]);
462
+ await chatSendCommand.parseAsync([
463
+ "node",
464
+ "cli",
465
+ "hi",
466
+ "--conversation",
467
+ "cnv_abc",
468
+ ]);
398
469
  expect(capturedBody["conversationId"]).toBe("cnv_abc");
399
470
  stdoutSpy.mockRestore();
400
471
  });
401
472
  it("exits 1 when fetch throws a network error", async () => {
402
473
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
403
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
474
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
475
+ throw new Error("exit");
476
+ });
404
477
  vi.spyOn(global, "fetch").mockRejectedValueOnce(new Error("ECONNREFUSED"));
405
478
  await expect(() => chatSendCommand.parseAsync(["node", "cli", "msg"])).rejects.toThrow("exit");
406
479
  consoleSpy.mockRestore();
@@ -408,7 +481,9 @@ describe("chat send", () => {
408
481
  });
409
482
  it("exits 1 on non-ok HTTP response", async () => {
410
483
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
411
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
484
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
485
+ throw new Error("exit");
486
+ });
412
487
  vi.spyOn(global, "fetch").mockResolvedValueOnce(makeErrorResponse(503, "Service unavailable"));
413
488
  await expect(() => chatSendCommand.parseAsync(["node", "cli", "test"])).rejects.toThrow();
414
489
  consoleSpy.mockRestore();
@@ -439,7 +514,14 @@ describe("conversation list", () => {
439
514
  it("passes filter and limit params", async () => {
440
515
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
441
516
  mockApiRequest.mockResolvedValueOnce({ conversations: [] });
442
- await conversationListCommand.parseAsync(["node", "cli", "--filter", "archived", "--limit", "5"]);
517
+ await conversationListCommand.parseAsync([
518
+ "node",
519
+ "cli",
520
+ "--filter",
521
+ "archived",
522
+ "--limit",
523
+ "5",
524
+ ]);
443
525
  expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("archived"));
444
526
  consoleSpy.mockRestore();
445
527
  });
@@ -455,7 +537,9 @@ describe("conversation delete", () => {
455
537
  });
456
538
  it("exits 1 on not found", async () => {
457
539
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
458
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
540
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
541
+ throw new Error("exit");
542
+ });
459
543
  mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
460
544
  await expect(() => conversationDeleteCommand.parseAsync(["node", "cli", "bad"])).rejects.toThrow("exit");
461
545
  consoleSpy.mockRestore();
@@ -474,7 +558,12 @@ describe("conversation archive", () => {
474
558
  it("unarchives when --unarchive flag is set", async () => {
475
559
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
476
560
  mockApiRequest.mockResolvedValueOnce({});
477
- await conversationArchiveCommand.parseAsync(["node", "cli", "cnv_abc", "--unarchive"]);
561
+ await conversationArchiveCommand.parseAsync([
562
+ "node",
563
+ "cli",
564
+ "cnv_abc",
565
+ "--unarchive",
566
+ ]);
478
567
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("unarchived"));
479
568
  consoleSpy.mockRestore();
480
569
  });
@@ -483,7 +572,12 @@ describe("conversation rename", () => {
483
572
  it("renames conversation", async () => {
484
573
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
485
574
  mockApiRequest.mockResolvedValueOnce({});
486
- await conversationRenameCommand.parseAsync(["node", "cli", "cnv_abc", "New Title"]);
575
+ await conversationRenameCommand.parseAsync([
576
+ "node",
577
+ "cli",
578
+ "cnv_abc",
579
+ "New Title",
580
+ ]);
487
581
  expect(mockApiRequest).toHaveBeenCalledWith("/conversations/cnv_abc/rename", expect.objectContaining({ method: "POST" }));
488
582
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("New Title"));
489
583
  consoleSpy.mockRestore();
@@ -495,7 +589,10 @@ describe("conversation rename", () => {
495
589
  describe("api-key create", () => {
496
590
  it("creates API key and displays secret", async () => {
497
591
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
498
- mockApiRequest.mockResolvedValueOnce({ id: "key_123", key: "oxk_abc123secret" });
592
+ mockApiRequest.mockResolvedValueOnce({
593
+ id: "key_123",
594
+ key: "oxk_abc123secret",
595
+ });
499
596
  const origIsTTY = process.stdout.isTTY;
500
597
  process.stdout.isTTY = true; // Simulate interactive TTY to show full secret
501
598
  await apiKeyCreateCommand.parseAsync(["node", "cli", "my-key"]);
@@ -507,7 +604,9 @@ describe("api-key create", () => {
507
604
  });
508
605
  it("exits 1 on API error", async () => {
509
606
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
510
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
607
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
608
+ throw new Error("exit");
609
+ });
511
610
  mockApiRequest.mockRejectedValueOnce(new Error("Quota exceeded"));
512
611
  await expect(() => apiKeyCreateCommand.parseAsync(["node", "cli", "key"])).rejects.toThrow("exit");
513
612
  consoleSpy.mockRestore();
@@ -533,7 +632,11 @@ describe("notifications list", () => {
533
632
  mockApiRequest.mockResolvedValueOnce({
534
633
  notifications: [
535
634
  { publicId: "ntf_1", title: "New member joined", readAt: null },
536
- { publicId: "ntf_2", title: "Subscription renewed", readAt: "2026-06-01" },
635
+ {
636
+ publicId: "ntf_2",
637
+ title: "Subscription renewed",
638
+ readAt: "2026-06-01",
639
+ },
537
640
  ],
538
641
  });
539
642
  await notificationsListCommand.parseAsync(["node", "cli"]);
@@ -568,7 +671,12 @@ describe("notifications mark", () => {
568
671
  it("marks notification as unread with --unread flag", async () => {
569
672
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
570
673
  mockApiRequest.mockResolvedValueOnce({});
571
- await notificationsMarkCommand.parseAsync(["node", "cli", "ntf_1", "--unread"]);
674
+ await notificationsMarkCommand.parseAsync([
675
+ "node",
676
+ "cli",
677
+ "ntf_1",
678
+ "--unread",
679
+ ]);
572
680
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("unread"));
573
681
  consoleSpy.mockRestore();
574
682
  });
@@ -580,7 +688,10 @@ describe("plugin list", () => {
580
688
  it("lists installed plugins", async () => {
581
689
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
582
690
  mockApiRequest.mockResolvedValueOnce({
583
- plugins: [{ pluginId: "github", enabled: true }, { pluginId: "slack", enabled: false }],
691
+ plugins: [
692
+ { pluginId: "github", enabled: true },
693
+ { pluginId: "slack", enabled: false },
694
+ ],
584
695
  });
585
696
  await pluginListCommand.parseAsync(["node", "cli"]);
586
697
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("github"));
@@ -606,7 +717,9 @@ describe("plugin install", () => {
606
717
  });
607
718
  it("exits 1 on install failure", async () => {
608
719
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
609
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
720
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
721
+ throw new Error("exit");
722
+ });
610
723
  mockApiRequest.mockRejectedValueOnce(new Error("Not found in catalog"));
611
724
  await expect(() => pluginInstallCommand.parseAsync(["node", "cli", "bad-plugin"])).rejects.toThrow("exit");
612
725
  consoleSpy.mockRestore();
@@ -652,7 +765,9 @@ describe("billing status", () => {
652
765
  });
653
766
  it("exits 1 on API error", async () => {
654
767
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
655
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
768
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
769
+ throw new Error("exit");
770
+ });
656
771
  mockApiRequest.mockRejectedValueOnce(new Error("Forbidden"));
657
772
  await expect(() => billingStatusCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
658
773
  consoleSpy.mockRestore();
@@ -681,7 +796,9 @@ describe("agent skill list", () => {
681
796
  it("lists agent skills successfully", async () => {
682
797
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
683
798
  mockApiRequest.mockResolvedValueOnce({
684
- skills: [{ id: "skill1", name: "memory", description: "Memory management" }],
799
+ skills: [
800
+ { id: "skill1", name: "memory", description: "Memory management" },
801
+ ],
685
802
  });
686
803
  await agentSkillListCommand.parseAsync(["node", "cli"]);
687
804
  expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/skill/list"), expect.objectContaining({ method: "GET" }));
@@ -696,7 +813,9 @@ describe("agent tool list", () => {
696
813
  it("lists agent tools successfully", async () => {
697
814
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
698
815
  mockApiRequest.mockResolvedValueOnce({
699
- tools: [{ id: "tool1", name: "search", description: "Search capability" }],
816
+ tools: [
817
+ { id: "tool1", name: "search", description: "Search capability" },
818
+ ],
700
819
  });
701
820
  await agentToolListCommand.parseAsync(["node", "cli"]);
702
821
  expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/tool/list"), expect.objectContaining({ method: "GET" }));
@@ -714,7 +833,12 @@ describe("billing credits purchase", () => {
714
833
  credits: 100,
715
834
  totalCost: 10,
716
835
  });
717
- await billingCreditsPurchaseCommand.parseAsync(["node", "cli", "-a", "100"]);
836
+ await billingCreditsPurchaseCommand.parseAsync([
837
+ "node",
838
+ "cli",
839
+ "-a",
840
+ "100",
841
+ ]);
718
842
  expect(mockApiRequest).toHaveBeenCalledWith("/billing/credits/purchase", expect.objectContaining({ method: "POST" }));
719
843
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Purchase initiated"));
720
844
  consoleSpy.mockRestore();
@@ -762,7 +886,12 @@ describe("plugin org uninstall", () => {
762
886
  id: "plugin1",
763
887
  status: "uninstalled",
764
888
  });
765
- await pluginOrgUninstallCommand.parseAsync(["node", "cli", "-p", "plugin1"]);
889
+ await pluginOrgUninstallCommand.parseAsync([
890
+ "node",
891
+ "cli",
892
+ "-p",
893
+ "plugin1",
894
+ ]);
766
895
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/uninstall", expect.objectContaining({ method: "POST" }));
767
896
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Plugin uninstalled"));
768
897
  consoleSpy.mockRestore();
@@ -775,7 +904,14 @@ describe("plugin catalog get", () => {
775
904
  it("browses plugin catalog", async () => {
776
905
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
777
906
  mockApiRequest.mockResolvedValueOnce({
778
- plugins: [{ id: "p1", name: "github", description: "GitHub integration", category: "vcs" }],
907
+ plugins: [
908
+ {
909
+ id: "p1",
910
+ name: "github",
911
+ description: "GitHub integration",
912
+ category: "vcs",
913
+ },
914
+ ],
779
915
  });
780
916
  await pluginCatalogGetCommand.parseAsync(["node", "cli"]);
781
917
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/catalog/get?", expect.objectContaining({ method: "GET" }));
@@ -794,7 +930,14 @@ describe("org member role change", () => {
794
930
  role: "admin",
795
931
  updated: true,
796
932
  });
797
- await orgMemberRoleChangeCommand.parseAsync(["node", "cli", "-u", "user1", "-r", "admin"]);
933
+ await orgMemberRoleChangeCommand.parseAsync([
934
+ "node",
935
+ "cli",
936
+ "-u",
937
+ "user1",
938
+ "-r",
939
+ "admin",
940
+ ]);
798
941
  expect(mockApiRequest).toHaveBeenCalledWith("/org/member/role-change", expect.objectContaining({ method: "POST" }));
799
942
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Role updated"));
800
943
  consoleSpy.mockRestore();
@@ -807,14 +950,30 @@ describe("agent approval resolve", () => {
807
950
  it("resolves approval with approve decision", async () => {
808
951
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
809
952
  mockApiRequest.mockResolvedValueOnce({ id: "apr1", status: "approved" });
810
- await agentApprovalResolveCommand.parseAsync(["node", "cli", "-a", "apr1", "-d", "approve"]);
953
+ await agentApprovalResolveCommand.parseAsync([
954
+ "node",
955
+ "cli",
956
+ "-a",
957
+ "apr1",
958
+ "-d",
959
+ "approve",
960
+ ]);
811
961
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/approval/resolve", expect.objectContaining({ method: "POST" }));
812
962
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("approved"));
813
963
  consoleSpy.mockRestore();
814
964
  });
815
965
  it("rejects invalid decision", async () => {
816
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
817
- await expect(() => agentApprovalResolveCommand.parseAsync(["node", "cli", "-a", "apr1", "-d", "invalid"])).rejects.toThrow();
966
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
967
+ throw new Error("exit");
968
+ });
969
+ await expect(() => agentApprovalResolveCommand.parseAsync([
970
+ "node",
971
+ "cli",
972
+ "-a",
973
+ "apr1",
974
+ "-d",
975
+ "invalid",
976
+ ])).rejects.toThrow();
818
977
  exitSpy.mockRestore();
819
978
  });
820
979
  });
@@ -824,8 +983,19 @@ describe("agent approval resolve", () => {
824
983
  describe("archive create", () => {
825
984
  it("creates archive from conversation", async () => {
826
985
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
827
- mockApiRequest.mockResolvedValueOnce({ id: "arc1", name: "Archive 1", status: "created" });
828
- await archiveCreateCommand.parseAsync(["node", "cli", "-c", "conv1", "-n", "My Archive"]);
986
+ mockApiRequest.mockResolvedValueOnce({
987
+ id: "arc1",
988
+ name: "Archive 1",
989
+ status: "created",
990
+ });
991
+ await archiveCreateCommand.parseAsync([
992
+ "node",
993
+ "cli",
994
+ "-c",
995
+ "conv1",
996
+ "-n",
997
+ "My Archive",
998
+ ]);
829
999
  expect(mockApiRequest).toHaveBeenCalledWith("/archive/create", expect.objectContaining({ method: "POST" }));
830
1000
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Archive created"));
831
1001
  consoleSpy.mockRestore();
@@ -838,7 +1008,14 @@ describe("workflow run", () => {
838
1008
  it("runs workflow with input", async () => {
839
1009
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
840
1010
  mockApiRequest.mockResolvedValueOnce({ id: "run1", status: "started" });
841
- await workflowRunCommand.parseAsync(["node", "cli", "-w", "wf1", "--input", '{"key":"value"}']);
1011
+ await workflowRunCommand.parseAsync([
1012
+ "node",
1013
+ "cli",
1014
+ "-w",
1015
+ "wf1",
1016
+ "--input",
1017
+ '{"key":"value"}',
1018
+ ]);
842
1019
  expect(mockApiRequest).toHaveBeenCalledWith("/workflow/run", expect.objectContaining({ method: "POST" }));
843
1020
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("started"));
844
1021
  consoleSpy.mockRestore();
@@ -861,7 +1038,12 @@ describe("user preferences update", () => {
861
1038
  it("updates user preferences", async () => {
862
1039
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
863
1040
  mockApiRequest.mockResolvedValueOnce({ theme: "light" });
864
- await userPreferencesUpdateCommand.parseAsync(["node", "cli", "-t", "light"]);
1041
+ await userPreferencesUpdateCommand.parseAsync([
1042
+ "node",
1043
+ "cli",
1044
+ "-t",
1045
+ "light",
1046
+ ]);
865
1047
  expect(mockApiRequest).toHaveBeenCalledWith("/user/preferences/update", expect.objectContaining({ method: "POST" }));
866
1048
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("light"));
867
1049
  consoleSpy.mockRestore();
@@ -873,7 +1055,14 @@ describe("user preferences update", () => {
873
1055
  describe("workspace member list", () => {
874
1056
  it("lists workspace members", async () => {
875
1057
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
876
- mockApiRequest.mockResolvedValueOnce([{ id: "m1", email: "user@example.com", role: "member", joined_at: "2026-06-08" }]);
1058
+ mockApiRequest.mockResolvedValueOnce([
1059
+ {
1060
+ id: "m1",
1061
+ email: "user@example.com",
1062
+ role: "member",
1063
+ joined_at: "2026-06-08",
1064
+ },
1065
+ ]);
877
1066
  await workspaceMemberListCommand.parseAsync(["node", "cli"]);
878
1067
  expect(mockApiRequest).toHaveBeenCalled();
879
1068
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("member(s)"));
@@ -884,7 +1073,12 @@ describe("workspace invite send", () => {
884
1073
  it("sends workspace invitation", async () => {
885
1074
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
886
1075
  mockApiRequest.mockResolvedValueOnce({ id: "inv1", status: "sent" });
887
- await workspaceInviteSendCommand.parseAsync(["node", "cli", "-e", "user@example.com"]);
1076
+ await workspaceInviteSendCommand.parseAsync([
1077
+ "node",
1078
+ "cli",
1079
+ "-e",
1080
+ "user@example.com",
1081
+ ]);
888
1082
  expect(mockApiRequest).toHaveBeenCalledWith("/workspace/invite/send", expect.objectContaining({ method: "POST" }));
889
1083
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Invitation sent"));
890
1084
  consoleSpy.mockRestore();
@@ -896,8 +1090,18 @@ describe("workspace invite send", () => {
896
1090
  describe("conversation chat", () => {
897
1091
  it("sends chat message", async () => {
898
1092
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
899
- mockApiRequest.mockResolvedValueOnce({ id: "msg1", created_at: "2026-06-08T00:00:00Z" });
900
- await conversationChatCommand.parseAsync(["node", "cli", "-c", "conv1", "-m", "Hello"]);
1093
+ mockApiRequest.mockResolvedValueOnce({
1094
+ id: "msg1",
1095
+ created_at: "2026-06-08T00:00:00Z",
1096
+ });
1097
+ await conversationChatCommand.parseAsync([
1098
+ "node",
1099
+ "cli",
1100
+ "-c",
1101
+ "conv1",
1102
+ "-m",
1103
+ "Hello",
1104
+ ]);
901
1105
  expect(mockApiRequest).toHaveBeenCalledWith("/conversation/chat", expect.objectContaining({ method: "POST" }));
902
1106
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Message sent"));
903
1107
  consoleSpy.mockRestore();
@@ -909,7 +1113,10 @@ describe("conversation chat", () => {
909
1113
  describe("image create", () => {
910
1114
  it("creates image from prompt", async () => {
911
1115
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
912
- mockApiRequest.mockResolvedValueOnce({ id: "img1", url: "https://example.com/img1.jpg" });
1116
+ mockApiRequest.mockResolvedValueOnce({
1117
+ id: "img1",
1118
+ url: "https://example.com/img1.jpg",
1119
+ });
913
1120
  await imageCreateCommand.parseAsync(["node", "cli", "-p", "A blue sky"]);
914
1121
  expect(mockApiRequest).toHaveBeenCalledWith("/image/create", expect.objectContaining({ method: "POST" }));
915
1122
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Image created"));
@@ -919,7 +1126,16 @@ describe("image create", () => {
919
1126
  describe("image list", () => {
920
1127
  it("lists images", async () => {
921
1128
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
922
- mockApiRequest.mockResolvedValueOnce({ images: [{ id: "img1", url: "https://example.com/img1.jpg", prompt: "Blue sky", created_at: "2026-06-08" }] });
1129
+ mockApiRequest.mockResolvedValueOnce({
1130
+ images: [
1131
+ {
1132
+ id: "img1",
1133
+ url: "https://example.com/img1.jpg",
1134
+ prompt: "Blue sky",
1135
+ created_at: "2026-06-08",
1136
+ },
1137
+ ],
1138
+ });
923
1139
  await imageListCommand.parseAsync(["node", "cli"]);
924
1140
  expect(mockApiRequest).toHaveBeenCalled();
925
1141
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Images"));
@@ -929,7 +1145,10 @@ describe("image list", () => {
929
1145
  describe("image analyze", () => {
930
1146
  it("analyzes image", async () => {
931
1147
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
932
- mockApiRequest.mockResolvedValueOnce({ analysis: "sky", tags: ["nature", "outdoor"] });
1148
+ mockApiRequest.mockResolvedValueOnce({
1149
+ analysis: "sky",
1150
+ tags: ["nature", "outdoor"],
1151
+ });
933
1152
  await imageAnalyzeCommand.parseAsync(["node", "cli", "-i", "img1"]);
934
1153
  expect(mockApiRequest).toHaveBeenCalledWith("/image/analyze", expect.objectContaining({ method: "POST" }));
935
1154
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Analysis"));
@@ -952,7 +1171,17 @@ describe("document create", () => {
952
1171
  describe("document list", () => {
953
1172
  it("lists documents", async () => {
954
1173
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
955
- mockApiRequest.mockResolvedValueOnce({ documents: [{ id: "doc1", title: "Doc 1", created_at: "2026-06-08", updated_at: "2026-06-08", author: "user" }] });
1174
+ mockApiRequest.mockResolvedValueOnce({
1175
+ documents: [
1176
+ {
1177
+ id: "doc1",
1178
+ title: "Doc 1",
1179
+ created_at: "2026-06-08",
1180
+ updated_at: "2026-06-08",
1181
+ author: "user",
1182
+ },
1183
+ ],
1184
+ });
956
1185
  await documentListCommand.parseAsync(["node", "cli"]);
957
1186
  expect(mockApiRequest).toHaveBeenCalled();
958
1187
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Documents"));
@@ -962,7 +1191,12 @@ describe("document list", () => {
962
1191
  describe("document read", () => {
963
1192
  it("reads document", async () => {
964
1193
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
965
- mockApiRequest.mockResolvedValueOnce({ title: "Doc 1", content: "Content...", metadata: {}, created_at: "2026-06-08" });
1194
+ mockApiRequest.mockResolvedValueOnce({
1195
+ title: "Doc 1",
1196
+ content: "Content...",
1197
+ metadata: {},
1198
+ created_at: "2026-06-08",
1199
+ });
966
1200
  await documentReadCommand.parseAsync(["node", "cli", "-d", "doc1"]);
967
1201
  expect(mockApiRequest).toHaveBeenCalled();
968
1202
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Title:"));
@@ -970,35 +1204,14 @@ describe("document read", () => {
970
1204
  });
971
1205
  });
972
1206
  // ---------------------------------------------------------------------------
973
- // form management
974
- // ---------------------------------------------------------------------------
975
- describe("form create", () => {
976
- it("creates form", async () => {
977
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
978
- mockApiRequest.mockResolvedValueOnce({ id: "form1", title: "Survey" });
979
- await formCreateCommand.parseAsync(["node", "cli", "-t", "Survey"]);
980
- expect(mockApiRequest).toHaveBeenCalledWith("/form/create", expect.objectContaining({ method: "POST" }));
981
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Form created"));
982
- consoleSpy.mockRestore();
983
- });
984
- });
985
- describe("form submit", () => {
986
- it("submits form", async () => {
987
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
988
- mockApiRequest.mockResolvedValueOnce({ id: "sub1", status: "submitted" });
989
- await formSubmitCommand.parseAsync(["node", "cli", "-f", "form1"]);
990
- expect(mockApiRequest).toHaveBeenCalledWith("/form/submit", expect.objectContaining({ method: "POST" }));
991
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("submitted"));
992
- consoleSpy.mockRestore();
993
- });
994
- });
995
- // ---------------------------------------------------------------------------
996
1207
  // automation management
997
1208
  // ---------------------------------------------------------------------------
998
1209
  describe("automation list", () => {
999
1210
  it("lists automations", async () => {
1000
1211
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1001
- mockApiRequest.mockResolvedValueOnce([{ id: "auto1", name: "Auto 1", status: "active", triggers: ["event1"] }]);
1212
+ mockApiRequest.mockResolvedValueOnce([
1213
+ { id: "auto1", name: "Auto 1", status: "active", triggers: ["event1"] },
1214
+ ]);
1002
1215
  await automationListCommand.parseAsync(["node", "cli"]);
1003
1216
  expect(mockApiRequest).toHaveBeenCalled();
1004
1217
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("automation(s)"));
@@ -1016,7 +1229,12 @@ describe("automation create", () => {
1016
1229
  triggerType: "api",
1017
1230
  enabled: false,
1018
1231
  });
1019
- await automationCreateCommand.parseAsync(["node", "cli", "-n", "My Automation"]);
1232
+ await automationCreateCommand.parseAsync([
1233
+ "node",
1234
+ "cli",
1235
+ "-n",
1236
+ "My Automation",
1237
+ ]);
1020
1238
  expect(mockApiRequest).toHaveBeenCalledWith("/automation/create", expect.objectContaining({ method: "POST" }));
1021
1239
  const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1022
1240
  expect(body).toMatchObject({
@@ -1040,12 +1258,18 @@ describe("automation create", () => {
1040
1258
  enabled: true,
1041
1259
  });
1042
1260
  await automationCreateCommand.parseAsync([
1043
- "node", "cli",
1044
- "-n", "Watcher",
1045
- "--trigger-type", "event",
1046
- "--entity-type", "Contact",
1047
- "--event-type", "node.updated",
1048
- "--conditions", '[{"property":"status","toValue":"customer","operator":"eq"}]',
1261
+ "node",
1262
+ "cli",
1263
+ "-n",
1264
+ "Watcher",
1265
+ "--trigger-type",
1266
+ "event",
1267
+ "--entity-type",
1268
+ "Contact",
1269
+ "--event-type",
1270
+ "node.updated",
1271
+ "--conditions",
1272
+ '[{"property":"status","toValue":"customer","operator":"eq"}]',
1049
1273
  "--enabled",
1050
1274
  ]);
1051
1275
  const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
@@ -1055,7 +1279,9 @@ describe("automation create", () => {
1055
1279
  triggerConfig: {
1056
1280
  entityType: "Contact",
1057
1281
  eventType: "node.updated",
1058
- propertyConditions: [{ property: "status", toValue: "customer", operator: "eq" }],
1282
+ propertyConditions: [
1283
+ { property: "status", toValue: "customer", operator: "eq" },
1284
+ ],
1059
1285
  },
1060
1286
  enabled: true,
1061
1287
  });
@@ -1072,16 +1298,24 @@ describe("automation create", () => {
1072
1298
  enabled: false,
1073
1299
  });
1074
1300
  await automationCreateCommand.parseAsync([
1075
- "node", "cli",
1076
- "-n", "Report",
1077
- "--trigger-type", "schedule",
1078
- "--cron", "0 9 * * 1",
1079
- "--timezone", "America/New_York",
1301
+ "node",
1302
+ "cli",
1303
+ "-n",
1304
+ "Report",
1305
+ "--trigger-type",
1306
+ "schedule",
1307
+ "--cron",
1308
+ "0 9 * * 1",
1309
+ "--timezone",
1310
+ "America/New_York",
1080
1311
  ]);
1081
1312
  const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1082
1313
  expect(body).toMatchObject({
1083
1314
  triggerType: "schedule",
1084
- triggerConfig: { cronExpression: "0 9 * * 1", timezone: "America/New_York" },
1315
+ triggerConfig: {
1316
+ cronExpression: "0 9 * * 1",
1317
+ timezone: "America/New_York",
1318
+ },
1085
1319
  });
1086
1320
  consoleSpy.mockRestore();
1087
1321
  });
@@ -1089,7 +1323,11 @@ describe("automation create", () => {
1089
1323
  describe("automation enable", () => {
1090
1324
  it("enables automation", async () => {
1091
1325
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1092
- mockApiRequest.mockResolvedValueOnce({ automation_id: "plt_1", enabled: true, status: "active" });
1326
+ mockApiRequest.mockResolvedValueOnce({
1327
+ automation_id: "plt_1",
1328
+ enabled: true,
1329
+ status: "active",
1330
+ });
1093
1331
  await automationEnableCommand.parseAsync(["node", "cli", "plt_1"]);
1094
1332
  expect(mockApiRequest).toHaveBeenCalledWith("/automation/enable", expect.objectContaining({ method: "POST" }));
1095
1333
  const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
@@ -1101,7 +1339,11 @@ describe("automation enable", () => {
1101
1339
  describe("automation disable", () => {
1102
1340
  it("disables automation", async () => {
1103
1341
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1104
- mockApiRequest.mockResolvedValueOnce({ automation_id: "plt_1", enabled: false, status: "paused" });
1342
+ mockApiRequest.mockResolvedValueOnce({
1343
+ automation_id: "plt_1",
1344
+ enabled: false,
1345
+ status: "paused",
1346
+ });
1105
1347
  await automationDisableCommand.parseAsync(["node", "cli", "plt_1"]);
1106
1348
  expect(mockApiRequest).toHaveBeenCalledWith("/automation/disable", expect.objectContaining({ method: "POST" }));
1107
1349
  const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
@@ -1126,7 +1368,16 @@ describe("automation trigger", () => {
1126
1368
  describe("skill workspace list", () => {
1127
1369
  it("lists workspace skills", async () => {
1128
1370
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1129
- mockApiRequest.mockResolvedValueOnce({ skills: [{ id: "skill1", name: "Research", enabled: true, description: "Research skill" }] });
1371
+ mockApiRequest.mockResolvedValueOnce({
1372
+ skills: [
1373
+ {
1374
+ id: "skill1",
1375
+ name: "Research",
1376
+ enabled: true,
1377
+ description: "Research skill",
1378
+ },
1379
+ ],
1380
+ });
1130
1381
  await skillWorkspaceListCommand.parseAsync(["node", "cli"]);
1131
1382
  expect(mockApiRequest).toHaveBeenCalled();
1132
1383
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Workspace skills"));
@@ -1139,18 +1390,40 @@ describe("skill workspace list", () => {
1139
1390
  describe("agent memory recall", () => {
1140
1391
  it("recalls memory observations", async () => {
1141
1392
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1142
- const mockResult = { observations: [{ id: "obs1", text: "User prefers dark mode", score: 0.9 }] };
1393
+ const mockResult = {
1394
+ observations: [
1395
+ { id: "obs1", text: "User prefers dark mode", score: 0.9 },
1396
+ ],
1397
+ };
1143
1398
  mockApiRequest.mockResolvedValueOnce(mockResult);
1144
- await agentMemoryRecallCommand.parseAsync(["node", "cli", "-a", "agent1", "-q", "user preferences"]);
1399
+ await agentMemoryRecallCommand.parseAsync([
1400
+ "node",
1401
+ "cli",
1402
+ "-a",
1403
+ "agent1",
1404
+ "-q",
1405
+ "user preferences",
1406
+ ]);
1145
1407
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/memory/recall", expect.objectContaining({ method: "POST" }));
1146
1408
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("obs1"));
1147
1409
  consoleSpy.mockRestore();
1148
1410
  });
1149
1411
  it("handles recall failure", async () => {
1150
1412
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1151
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1413
+ const exitSpy = vi
1414
+ .spyOn(process, "exit")
1415
+ .mockImplementation((_code) => {
1416
+ throw new Error("process.exit");
1417
+ });
1152
1418
  mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1153
- await expect(agentMemoryRecallCommand.parseAsync(["node", "cli", "-a", "agent1", "-q", "query"])).rejects.toThrow();
1419
+ await expect(agentMemoryRecallCommand.parseAsync([
1420
+ "node",
1421
+ "cli",
1422
+ "-a",
1423
+ "agent1",
1424
+ "-q",
1425
+ "query",
1426
+ ])).rejects.toThrow();
1154
1427
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to recall"), expect.any(Error));
1155
1428
  consoleSpy.mockRestore();
1156
1429
  exitSpy.mockRestore();
@@ -1161,7 +1434,14 @@ describe("agent memory write", () => {
1161
1434
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1162
1435
  const mockResult = { id: "obs2", status: "stored" };
1163
1436
  mockApiRequest.mockResolvedValueOnce(mockResult);
1164
- await agentMemoryWriteCommand.parseAsync(["node", "cli", "-a", "agent1", "-t", "User prefers TypeScript"]);
1437
+ await agentMemoryWriteCommand.parseAsync([
1438
+ "node",
1439
+ "cli",
1440
+ "-a",
1441
+ "agent1",
1442
+ "-t",
1443
+ "User prefers TypeScript",
1444
+ ]);
1165
1445
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/memory/write", expect.objectContaining({ method: "POST" }));
1166
1446
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("obs2"));
1167
1447
  consoleSpy.mockRestore();
@@ -1169,16 +1449,36 @@ describe("agent memory write", () => {
1169
1449
  it("writes a memory observation with tags", async () => {
1170
1450
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1171
1451
  mockApiRequest.mockResolvedValueOnce({ id: "obs3", status: "stored" });
1172
- await agentMemoryWriteCommand.parseAsync(["node", "cli", "-a", "agent1", "-t", "Uses dark mode", "--tags", "ui,preferences"]);
1452
+ await agentMemoryWriteCommand.parseAsync([
1453
+ "node",
1454
+ "cli",
1455
+ "-a",
1456
+ "agent1",
1457
+ "-t",
1458
+ "Uses dark mode",
1459
+ "--tags",
1460
+ "ui,preferences",
1461
+ ]);
1173
1462
  const callBody = JSON.parse(mockApiRequest.mock.calls[0][1].body);
1174
1463
  expect(callBody.tags).toEqual(["ui", "preferences"]);
1175
1464
  consoleSpy.mockRestore();
1176
1465
  });
1177
1466
  it("handles write failure", async () => {
1178
1467
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1179
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1468
+ const exitSpy = vi
1469
+ .spyOn(process, "exit")
1470
+ .mockImplementation((_code) => {
1471
+ throw new Error("process.exit");
1472
+ });
1180
1473
  mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1181
- await expect(agentMemoryWriteCommand.parseAsync(["node", "cli", "-a", "agent1", "-t", "text"])).rejects.toThrow();
1474
+ await expect(agentMemoryWriteCommand.parseAsync([
1475
+ "node",
1476
+ "cli",
1477
+ "-a",
1478
+ "agent1",
1479
+ "-t",
1480
+ "text",
1481
+ ])).rejects.toThrow();
1182
1482
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to write"), expect.any(Error));
1183
1483
  consoleSpy.mockRestore();
1184
1484
  exitSpy.mockRestore();
@@ -1190,26 +1490,59 @@ describe("agent memory write", () => {
1190
1490
  describe("documents generate", () => {
1191
1491
  it("generates a document from template", async () => {
1192
1492
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1193
- const mockResult = { id: "doc1", status: "complete", url: "https://example.com/doc.pdf" };
1493
+ const mockResult = {
1494
+ id: "doc1",
1495
+ status: "complete",
1496
+ url: "https://example.com/doc.pdf",
1497
+ };
1194
1498
  mockApiRequest.mockResolvedValueOnce(mockResult);
1195
- await documentsGenerateCommand.parseAsync(["node", "cli", "-t", "report", "-c", '{"title":"Q1 Report"}']);
1499
+ await documentsGenerateCommand.parseAsync([
1500
+ "node",
1501
+ "cli",
1502
+ "-t",
1503
+ "report",
1504
+ "-c",
1505
+ '{"title":"Q1 Report"}',
1506
+ ]);
1196
1507
  expect(mockApiRequest).toHaveBeenCalledWith("/documents/generate", expect.objectContaining({ method: "POST" }));
1197
1508
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("doc1"));
1198
1509
  consoleSpy.mockRestore();
1199
1510
  });
1200
1511
  it("fails on invalid JSON context", async () => {
1201
1512
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1202
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1203
- await expect(documentsGenerateCommand.parseAsync(["node", "cli", "-t", "report", "-c", "not-json"])).rejects.toThrow();
1513
+ const exitSpy = vi
1514
+ .spyOn(process, "exit")
1515
+ .mockImplementation((_code) => {
1516
+ throw new Error("process.exit");
1517
+ });
1518
+ await expect(documentsGenerateCommand.parseAsync([
1519
+ "node",
1520
+ "cli",
1521
+ "-t",
1522
+ "report",
1523
+ "-c",
1524
+ "not-json",
1525
+ ])).rejects.toThrow();
1204
1526
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Invalid JSON"), expect.anything());
1205
1527
  consoleSpy.mockRestore();
1206
1528
  exitSpy.mockRestore();
1207
1529
  });
1208
1530
  it("handles generate failure", async () => {
1209
1531
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1210
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1532
+ const exitSpy = vi
1533
+ .spyOn(process, "exit")
1534
+ .mockImplementation((_code) => {
1535
+ throw new Error("process.exit");
1536
+ });
1211
1537
  mockApiRequest.mockRejectedValueOnce(new Error("Template not found"));
1212
- await expect(documentsGenerateCommand.parseAsync(["node", "cli", "-t", "report", "-c", '{}'])).rejects.toThrow();
1538
+ await expect(documentsGenerateCommand.parseAsync([
1539
+ "node",
1540
+ "cli",
1541
+ "-t",
1542
+ "report",
1543
+ "-c",
1544
+ "{}",
1545
+ ])).rejects.toThrow();
1213
1546
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
1214
1547
  consoleSpy.mockRestore();
1215
1548
  exitSpy.mockRestore();
@@ -1223,14 +1556,23 @@ describe("image generate", () => {
1223
1556
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1224
1557
  const mockResult = { url: "https://example.com/img.png", id: "img1" };
1225
1558
  mockApiRequest.mockResolvedValueOnce(mockResult);
1226
- await imageGenerateCommand.parseAsync(["node", "cli", "-p", "A sunset over the ocean"]);
1559
+ await imageGenerateCommand.parseAsync([
1560
+ "node",
1561
+ "cli",
1562
+ "-p",
1563
+ "A sunset over the ocean",
1564
+ ]);
1227
1565
  expect(mockApiRequest).toHaveBeenCalledWith("/image/generate", expect.objectContaining({ method: "POST" }));
1228
1566
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("img1"));
1229
1567
  consoleSpy.mockRestore();
1230
1568
  });
1231
1569
  it("handles generate failure", async () => {
1232
1570
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1233
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1571
+ const exitSpy = vi
1572
+ .spyOn(process, "exit")
1573
+ .mockImplementation((_code) => {
1574
+ throw new Error("process.exit");
1575
+ });
1234
1576
  mockApiRequest.mockRejectedValueOnce(new Error("Model not found"));
1235
1577
  await expect(imageGenerateCommand.parseAsync(["node", "cli", "-p", "a cat"])).rejects.toThrow();
1236
1578
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
@@ -1244,15 +1586,27 @@ describe("image generate", () => {
1244
1586
  describe("org member invite accept", () => {
1245
1587
  it("accepts an invitation", async () => {
1246
1588
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1247
- mockApiRequest.mockResolvedValueOnce({ status: "accepted", orgSlug: "my-org" });
1248
- await orgMemberInviteAcceptCommand.parseAsync(["node", "cli", "-i", "invite123"]);
1589
+ mockApiRequest.mockResolvedValueOnce({
1590
+ status: "accepted",
1591
+ orgSlug: "my-org",
1592
+ });
1593
+ await orgMemberInviteAcceptCommand.parseAsync([
1594
+ "node",
1595
+ "cli",
1596
+ "-i",
1597
+ "invite123",
1598
+ ]);
1249
1599
  expect(mockApiRequest).toHaveBeenCalledWith("/org/member/invite/accept", expect.objectContaining({ method: "POST" }));
1250
1600
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("accepted"));
1251
1601
  consoleSpy.mockRestore();
1252
1602
  });
1253
1603
  it("handles accept failure", async () => {
1254
1604
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1255
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1605
+ const exitSpy = vi
1606
+ .spyOn(process, "exit")
1607
+ .mockImplementation((_code) => {
1608
+ throw new Error("process.exit");
1609
+ });
1256
1610
  mockApiRequest.mockRejectedValueOnce(new Error("Invitation expired"));
1257
1611
  await expect(orgMemberInviteAcceptCommand.parseAsync(["node", "cli", "-i", "inv1"])).rejects.toThrow();
1258
1612
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to accept"), expect.any(Error));
@@ -1266,7 +1620,10 @@ describe("org member invite accept", () => {
1266
1620
  describe("plugin catalog browse", () => {
1267
1621
  it("browses the plugin catalog", async () => {
1268
1622
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1269
- const mockResult = { plugins: [{ id: "p1", name: "Slack", category: "messaging" }], total: 1 };
1623
+ const mockResult = {
1624
+ plugins: [{ id: "p1", name: "Slack", category: "messaging" }],
1625
+ total: 1,
1626
+ };
1270
1627
  mockApiRequest.mockResolvedValueOnce(mockResult);
1271
1628
  await pluginCatalogBrowseCommand.parseAsync(["node", "cli"]);
1272
1629
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/catalog/browse", expect.objectContaining({ method: "GET" }));
@@ -1275,7 +1632,11 @@ describe("plugin catalog browse", () => {
1275
1632
  });
1276
1633
  it("handles browse failure", async () => {
1277
1634
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1278
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1635
+ const exitSpy = vi
1636
+ .spyOn(process, "exit")
1637
+ .mockImplementation((_code) => {
1638
+ throw new Error("process.exit");
1639
+ });
1279
1640
  mockApiRequest.mockRejectedValueOnce(new Error("Service unavailable"));
1280
1641
  await expect(pluginCatalogBrowseCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1281
1642
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to browse"), expect.any(Error));
@@ -1289,15 +1650,27 @@ describe("plugin catalog browse", () => {
1289
1650
  describe("plugin credential reauth", () => {
1290
1651
  it("re-authenticates plugin credentials", async () => {
1291
1652
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1292
- mockApiRequest.mockResolvedValueOnce({ status: "reauthenticated", pluginId: "slack" });
1293
- await pluginCredentialReauthCommand.parseAsync(["node", "cli", "-p", "slack"]);
1653
+ mockApiRequest.mockResolvedValueOnce({
1654
+ status: "reauthenticated",
1655
+ pluginId: "slack",
1656
+ });
1657
+ await pluginCredentialReauthCommand.parseAsync([
1658
+ "node",
1659
+ "cli",
1660
+ "-p",
1661
+ "slack",
1662
+ ]);
1294
1663
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/credential/reauth", expect.objectContaining({ method: "POST" }));
1295
1664
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("reauthenticated"));
1296
1665
  consoleSpy.mockRestore();
1297
1666
  });
1298
1667
  it("handles reauth failure", async () => {
1299
1668
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1300
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1669
+ const exitSpy = vi
1670
+ .spyOn(process, "exit")
1671
+ .mockImplementation((_code) => {
1672
+ throw new Error("process.exit");
1673
+ });
1301
1674
  mockApiRequest.mockRejectedValueOnce(new Error("OAuth error"));
1302
1675
  await expect(pluginCredentialReauthCommand.parseAsync(["node", "cli", "-p", "slack"])).rejects.toThrow();
1303
1676
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to re-authenticate"), expect.any(Error));
@@ -1311,7 +1684,11 @@ describe("plugin credential reauth", () => {
1311
1684
  describe("plugin registry list", () => {
1312
1685
  it("lists plugin registries", async () => {
1313
1686
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1314
- mockApiRequest.mockResolvedValueOnce({ registries: [{ id: "reg1", name: "Official", url: "https://registry.oxagen.ai" }] });
1687
+ mockApiRequest.mockResolvedValueOnce({
1688
+ registries: [
1689
+ { id: "reg1", name: "Official", url: "https://registry.oxagen.ai" },
1690
+ ],
1691
+ });
1315
1692
  await pluginRegistryListCommand.parseAsync(["node", "cli"]);
1316
1693
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/list", expect.objectContaining({ method: "GET" }));
1317
1694
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Official"));
@@ -1319,7 +1696,11 @@ describe("plugin registry list", () => {
1319
1696
  });
1320
1697
  it("handles list failure", async () => {
1321
1698
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1322
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1699
+ const exitSpy = vi
1700
+ .spyOn(process, "exit")
1701
+ .mockImplementation((_code) => {
1702
+ throw new Error("process.exit");
1703
+ });
1323
1704
  mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1324
1705
  await expect(pluginRegistryListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1325
1706
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to list"), expect.any(Error));
@@ -1330,17 +1711,39 @@ describe("plugin registry list", () => {
1330
1711
  describe("plugin registry add", () => {
1331
1712
  it("adds a plugin registry", async () => {
1332
1713
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1333
- mockApiRequest.mockResolvedValueOnce({ id: "reg2", name: "Private", url: "https://private.example.com" });
1334
- await pluginRegistryAddCommand.parseAsync(["node", "cli", "-n", "Private", "-u", "https://private.example.com"]);
1714
+ mockApiRequest.mockResolvedValueOnce({
1715
+ id: "reg2",
1716
+ name: "Private",
1717
+ url: "https://private.example.com",
1718
+ });
1719
+ await pluginRegistryAddCommand.parseAsync([
1720
+ "node",
1721
+ "cli",
1722
+ "-n",
1723
+ "Private",
1724
+ "-u",
1725
+ "https://private.example.com",
1726
+ ]);
1335
1727
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/add", expect.objectContaining({ method: "POST" }));
1336
1728
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("reg2"));
1337
1729
  consoleSpy.mockRestore();
1338
1730
  });
1339
1731
  it("handles add failure", async () => {
1340
1732
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1341
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1733
+ const exitSpy = vi
1734
+ .spyOn(process, "exit")
1735
+ .mockImplementation((_code) => {
1736
+ throw new Error("process.exit");
1737
+ });
1342
1738
  mockApiRequest.mockRejectedValueOnce(new Error("Registry already exists"));
1343
- await expect(pluginRegistryAddCommand.parseAsync(["node", "cli", "-n", "Private", "-u", "https://x.com"])).rejects.toThrow();
1739
+ await expect(pluginRegistryAddCommand.parseAsync([
1740
+ "node",
1741
+ "cli",
1742
+ "-n",
1743
+ "Private",
1744
+ "-u",
1745
+ "https://x.com",
1746
+ ])).rejects.toThrow();
1344
1747
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to add"), expect.any(Error));
1345
1748
  consoleSpy.mockRestore();
1346
1749
  exitSpy.mockRestore();
@@ -1360,7 +1763,11 @@ describe("svg generate", () => {
1360
1763
  });
1361
1764
  it("handles generate failure", async () => {
1362
1765
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1363
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1766
+ const exitSpy = vi
1767
+ .spyOn(process, "exit")
1768
+ .mockImplementation((_code) => {
1769
+ throw new Error("process.exit");
1770
+ });
1364
1771
  mockApiRequest.mockRejectedValueOnce(new Error("Generation failed"));
1365
1772
  await expect(svgGenerateCommand.parseAsync(["node", "cli", "-d", "circle"])).rejects.toThrow();
1366
1773
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
@@ -1374,15 +1781,28 @@ describe("svg generate", () => {
1374
1781
  describe("video generate", () => {
1375
1782
  it("generates a video", async () => {
1376
1783
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1377
- mockApiRequest.mockResolvedValueOnce({ id: "vid1", status: "processing", url: null });
1378
- await videoGenerateCommand.parseAsync(["node", "cli", "-p", "A flying eagle"]);
1784
+ mockApiRequest.mockResolvedValueOnce({
1785
+ id: "vid1",
1786
+ status: "processing",
1787
+ url: null,
1788
+ });
1789
+ await videoGenerateCommand.parseAsync([
1790
+ "node",
1791
+ "cli",
1792
+ "-p",
1793
+ "A flying eagle",
1794
+ ]);
1379
1795
  expect(mockApiRequest).toHaveBeenCalledWith("/video/generate", expect.objectContaining({ method: "POST" }));
1380
1796
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("vid1"));
1381
1797
  consoleSpy.mockRestore();
1382
1798
  });
1383
1799
  it("handles generate failure", async () => {
1384
1800
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1385
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1801
+ const exitSpy = vi
1802
+ .spyOn(process, "exit")
1803
+ .mockImplementation((_code) => {
1804
+ throw new Error("process.exit");
1805
+ });
1386
1806
  mockApiRequest.mockRejectedValueOnce(new Error("Model not available"));
1387
1807
  await expect(videoGenerateCommand.parseAsync(["node", "cli", "-p", "a cat"])).rejects.toThrow();
1388
1808
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
@@ -1396,7 +1816,10 @@ describe("video generate", () => {
1396
1816
  describe("workspace model settings read", () => {
1397
1817
  it("reads workspace model settings", async () => {
1398
1818
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1399
- mockApiRequest.mockResolvedValueOnce({ defaultModel: "claude-haiku-4-5-20251001", maxTokens: 4096 });
1819
+ mockApiRequest.mockResolvedValueOnce({
1820
+ defaultModel: "claude-haiku-4-5-20251001",
1821
+ maxTokens: 4096,
1822
+ });
1400
1823
  await workspaceModelSettingsReadCommand.parseAsync(["node", "cli"]);
1401
1824
  expect(mockApiRequest).toHaveBeenCalledWith("/workspace/model-settings/read", expect.objectContaining({ method: "POST" }));
1402
1825
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("defaultModel"));
@@ -1404,7 +1827,11 @@ describe("workspace model settings read", () => {
1404
1827
  });
1405
1828
  it("handles read failure", async () => {
1406
1829
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1407
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1830
+ const exitSpy = vi
1831
+ .spyOn(process, "exit")
1832
+ .mockImplementation((_code) => {
1833
+ throw new Error("process.exit");
1834
+ });
1408
1835
  mockApiRequest.mockRejectedValueOnce(new Error("Workspace not found"));
1409
1836
  await expect(workspaceModelSettingsReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1410
1837
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to read"), expect.any(Error));
@@ -1415,17 +1842,39 @@ describe("workspace model settings read", () => {
1415
1842
  describe("workspace model settings write", () => {
1416
1843
  it("writes workspace model settings", async () => {
1417
1844
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1418
- mockApiRequest.mockResolvedValueOnce({ success: true, key: "defaultModel", value: "claude-sonnet-4-6" });
1419
- await workspaceModelSettingsWriteCommand.parseAsync(["node", "cli", "-k", "defaultModel", "-v", "claude-sonnet-4-6"]);
1845
+ mockApiRequest.mockResolvedValueOnce({
1846
+ success: true,
1847
+ key: "defaultModel",
1848
+ value: "claude-sonnet-4-6",
1849
+ });
1850
+ await workspaceModelSettingsWriteCommand.parseAsync([
1851
+ "node",
1852
+ "cli",
1853
+ "-k",
1854
+ "defaultModel",
1855
+ "-v",
1856
+ "claude-sonnet-4-6",
1857
+ ]);
1420
1858
  expect(mockApiRequest).toHaveBeenCalledWith("/workspace/model-settings/write", expect.objectContaining({ method: "POST" }));
1421
1859
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("defaultModel"));
1422
1860
  consoleSpy.mockRestore();
1423
1861
  });
1424
1862
  it("handles write failure", async () => {
1425
1863
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1426
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1864
+ const exitSpy = vi
1865
+ .spyOn(process, "exit")
1866
+ .mockImplementation((_code) => {
1867
+ throw new Error("process.exit");
1868
+ });
1427
1869
  mockApiRequest.mockRejectedValueOnce(new Error("Invalid setting key"));
1428
- await expect(workspaceModelSettingsWriteCommand.parseAsync(["node", "cli", "-k", "badKey", "-v", "value"])).rejects.toThrow();
1870
+ await expect(workspaceModelSettingsWriteCommand.parseAsync([
1871
+ "node",
1872
+ "cli",
1873
+ "-k",
1874
+ "badKey",
1875
+ "-v",
1876
+ "value",
1877
+ ])).rejects.toThrow();
1429
1878
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to write"), expect.any(Error));
1430
1879
  consoleSpy.mockRestore();
1431
1880
  exitSpy.mockRestore();
@@ -1437,17 +1886,43 @@ describe("workspace model settings write", () => {
1437
1886
  describe("agent mcp register", () => {
1438
1887
  it("registers an MCP server", async () => {
1439
1888
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1440
- mockApiRequest.mockResolvedValueOnce({ mcpServerId: "mcp1", healthStatus: "healthy", discoveredTools: ["tool1", "tool2"] });
1441
- await agentMcpRegisterCommand.parseAsync(["node", "cli", "-n", "My MCP", "-u", "https://mcp.example.com", "-t", "streamable-http"]);
1889
+ mockApiRequest.mockResolvedValueOnce({
1890
+ mcpServerId: "mcp1",
1891
+ healthStatus: "healthy",
1892
+ discoveredTools: ["tool1", "tool2"],
1893
+ });
1894
+ await agentMcpRegisterCommand.parseAsync([
1895
+ "node",
1896
+ "cli",
1897
+ "-n",
1898
+ "My MCP",
1899
+ "-u",
1900
+ "https://mcp.example.com",
1901
+ "-t",
1902
+ "streamable-http",
1903
+ ]);
1442
1904
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/mcp/register", expect.objectContaining({ method: "POST" }));
1443
1905
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("mcp1"));
1444
1906
  consoleSpy.mockRestore();
1445
1907
  });
1446
1908
  it("handles registration failure", async () => {
1447
1909
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1448
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1910
+ const exitSpy = vi
1911
+ .spyOn(process, "exit")
1912
+ .mockImplementation((_code) => {
1913
+ throw new Error("process.exit");
1914
+ });
1449
1915
  mockApiRequest.mockRejectedValueOnce(new Error("Bad URL"));
1450
- await expect(agentMcpRegisterCommand.parseAsync(["node", "cli", "-n", "M", "-u", "http://x", "-t", "stdio"])).rejects.toThrow();
1916
+ await expect(agentMcpRegisterCommand.parseAsync([
1917
+ "node",
1918
+ "cli",
1919
+ "-n",
1920
+ "M",
1921
+ "-u",
1922
+ "http://x",
1923
+ "-t",
1924
+ "stdio",
1925
+ ])).rejects.toThrow();
1451
1926
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
1452
1927
  consoleSpy.mockRestore();
1453
1928
  exitSpy.mockRestore();
@@ -1459,17 +1934,38 @@ describe("agent mcp register", () => {
1459
1934
  describe("agent plan approve", () => {
1460
1935
  it("approves a plan", async () => {
1461
1936
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1462
- mockApiRequest.mockResolvedValueOnce({ planId: "plan1", status: "approved" });
1463
- await agentPlanApproveCommand.parseAsync(["node", "cli", "-p", "plan1", "-d", "approve"]);
1937
+ mockApiRequest.mockResolvedValueOnce({
1938
+ planId: "plan1",
1939
+ status: "approved",
1940
+ });
1941
+ await agentPlanApproveCommand.parseAsync([
1942
+ "node",
1943
+ "cli",
1944
+ "-p",
1945
+ "plan1",
1946
+ "-d",
1947
+ "approve",
1948
+ ]);
1464
1949
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/plan/approve", expect.objectContaining({ method: "POST" }));
1465
1950
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("approved"));
1466
1951
  consoleSpy.mockRestore();
1467
1952
  });
1468
1953
  it("handles approval failure", async () => {
1469
1954
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1470
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1955
+ const exitSpy = vi
1956
+ .spyOn(process, "exit")
1957
+ .mockImplementation((_code) => {
1958
+ throw new Error("process.exit");
1959
+ });
1471
1960
  mockApiRequest.mockRejectedValueOnce(new Error("Plan not found"));
1472
- await expect(agentPlanApproveCommand.parseAsync(["node", "cli", "-p", "p1", "-d", "deny"])).rejects.toThrow();
1961
+ await expect(agentPlanApproveCommand.parseAsync([
1962
+ "node",
1963
+ "cli",
1964
+ "-p",
1965
+ "p1",
1966
+ "-d",
1967
+ "deny",
1968
+ ])).rejects.toThrow();
1473
1969
  consoleSpy.mockRestore();
1474
1970
  exitSpy.mockRestore();
1475
1971
  });
@@ -1480,17 +1976,38 @@ describe("agent plan approve", () => {
1480
1976
  describe("agent task background start", () => {
1481
1977
  it("starts a background task", async () => {
1482
1978
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1483
- mockApiRequest.mockResolvedValueOnce({ taskId: "task1", inngestRunId: "run1" });
1484
- await agentTaskBackgroundStartCommand.parseAsync(["node", "cli", "-k", "research", "--payload", '{"query":"test"}']);
1979
+ mockApiRequest.mockResolvedValueOnce({
1980
+ taskId: "task1",
1981
+ inngestRunId: "run1",
1982
+ });
1983
+ await agentTaskBackgroundStartCommand.parseAsync([
1984
+ "node",
1985
+ "cli",
1986
+ "-k",
1987
+ "research",
1988
+ "--payload",
1989
+ '{"query":"test"}',
1990
+ ]);
1485
1991
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/task/background/start", expect.objectContaining({ method: "POST" }));
1486
1992
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("task1"));
1487
1993
  consoleSpy.mockRestore();
1488
1994
  });
1489
1995
  it("handles start failure", async () => {
1490
1996
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1491
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1997
+ const exitSpy = vi
1998
+ .spyOn(process, "exit")
1999
+ .mockImplementation((_code) => {
2000
+ throw new Error("process.exit");
2001
+ });
1492
2002
  mockApiRequest.mockRejectedValueOnce(new Error("Queue full"));
1493
- await expect(agentTaskBackgroundStartCommand.parseAsync(["node", "cli", "-k", "kind", "--payload", "{}"])).rejects.toThrow();
2003
+ await expect(agentTaskBackgroundStartCommand.parseAsync([
2004
+ "node",
2005
+ "cli",
2006
+ "-k",
2007
+ "kind",
2008
+ "--payload",
2009
+ "{}",
2010
+ ])).rejects.toThrow();
1494
2011
  consoleSpy.mockRestore();
1495
2012
  exitSpy.mockRestore();
1496
2013
  });
@@ -1498,15 +2015,34 @@ describe("agent task background start", () => {
1498
2015
  describe("agent task background read", () => {
1499
2016
  it("reads task status", async () => {
1500
2017
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1501
- mockApiRequest.mockResolvedValueOnce({ taskId: "task1", kind: "research", status: "completed", label: "My task", resultPayload: { answer: "42" }, failureReason: null, createdAt: "2026-06-08", startedAt: "2026-06-08", completedAt: "2026-06-08" });
1502
- await agentTaskBackgroundReadCommand.parseAsync(["node", "cli", "-t", "task1"]);
2018
+ mockApiRequest.mockResolvedValueOnce({
2019
+ taskId: "task1",
2020
+ kind: "research",
2021
+ status: "completed",
2022
+ label: "My task",
2023
+ resultPayload: { answer: "42" },
2024
+ failureReason: null,
2025
+ createdAt: "2026-06-08",
2026
+ startedAt: "2026-06-08",
2027
+ completedAt: "2026-06-08",
2028
+ });
2029
+ await agentTaskBackgroundReadCommand.parseAsync([
2030
+ "node",
2031
+ "cli",
2032
+ "-t",
2033
+ "task1",
2034
+ ]);
1503
2035
  expect(mockApiRequest).toHaveBeenCalled();
1504
2036
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("completed"));
1505
2037
  consoleSpy.mockRestore();
1506
2038
  });
1507
2039
  it("handles read failure", async () => {
1508
2040
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1509
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2041
+ const exitSpy = vi
2042
+ .spyOn(process, "exit")
2043
+ .mockImplementation((_code) => {
2044
+ throw new Error("process.exit");
2045
+ });
1510
2046
  mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
1511
2047
  await expect(agentTaskBackgroundReadCommand.parseAsync(["node", "cli", "-t", "t1"])).rejects.toThrow();
1512
2048
  consoleSpy.mockRestore();
@@ -1517,7 +2053,12 @@ describe("agent task background cancel", () => {
1517
2053
  it("cancels a background task", async () => {
1518
2054
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1519
2055
  mockApiRequest.mockResolvedValueOnce({ cancelled: true });
1520
- await agentTaskBackgroundCancelCommand.parseAsync(["node", "cli", "-t", "task1"]);
2056
+ await agentTaskBackgroundCancelCommand.parseAsync([
2057
+ "node",
2058
+ "cli",
2059
+ "-t",
2060
+ "task1",
2061
+ ]);
1521
2062
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/task/background/cancel", expect.objectContaining({ method: "POST" }));
1522
2063
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cancelled"));
1523
2064
  consoleSpy.mockRestore();
@@ -1525,13 +2066,22 @@ describe("agent task background cancel", () => {
1525
2066
  it("reports task could not be cancelled", async () => {
1526
2067
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1527
2068
  mockApiRequest.mockResolvedValueOnce({ cancelled: false });
1528
- await agentTaskBackgroundCancelCommand.parseAsync(["node", "cli", "-t", "task1"]);
2069
+ await agentTaskBackgroundCancelCommand.parseAsync([
2070
+ "node",
2071
+ "cli",
2072
+ "-t",
2073
+ "task1",
2074
+ ]);
1529
2075
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("could not be cancelled"));
1530
2076
  consoleSpy.mockRestore();
1531
2077
  });
1532
2078
  it("handles cancel failure", async () => {
1533
2079
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1534
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2080
+ const exitSpy = vi
2081
+ .spyOn(process, "exit")
2082
+ .mockImplementation((_code) => {
2083
+ throw new Error("process.exit");
2084
+ });
1535
2085
  mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
1536
2086
  await expect(agentTaskBackgroundCancelCommand.parseAsync(["node", "cli", "-t", "t1"])).rejects.toThrow();
1537
2087
  consoleSpy.mockRestore();
@@ -1544,17 +2094,40 @@ describe("agent task background cancel", () => {
1544
2094
  describe("asset upload", () => {
1545
2095
  it("uploads an asset", async () => {
1546
2096
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1547
- mockApiRequest.mockResolvedValueOnce({ url: "https://cdn.example.com/img.png", key: "img/abc.png", contentType: "image/png", bytes: 12345 });
1548
- await assetUploadCommand.parseAsync(["node", "cli", "-s", "https://example.com/img.png", "-k", "image"]);
2097
+ mockApiRequest.mockResolvedValueOnce({
2098
+ url: "https://cdn.example.com/img.png",
2099
+ key: "img/abc.png",
2100
+ contentType: "image/png",
2101
+ bytes: 12345,
2102
+ });
2103
+ await assetUploadCommand.parseAsync([
2104
+ "node",
2105
+ "cli",
2106
+ "-s",
2107
+ "https://example.com/img.png",
2108
+ "-k",
2109
+ "image",
2110
+ ]);
1549
2111
  expect(mockApiRequest).toHaveBeenCalledWith("/asset/upload", expect.objectContaining({ method: "POST" }));
1550
2112
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Asset uploaded"));
1551
2113
  consoleSpy.mockRestore();
1552
2114
  });
1553
2115
  it("handles upload failure", async () => {
1554
2116
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1555
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2117
+ const exitSpy = vi
2118
+ .spyOn(process, "exit")
2119
+ .mockImplementation((_code) => {
2120
+ throw new Error("process.exit");
2121
+ });
1556
2122
  mockApiRequest.mockRejectedValueOnce(new Error("Source URL unreachable"));
1557
- await expect(assetUploadCommand.parseAsync(["node", "cli", "-s", "https://bad.url", "-k", "image"])).rejects.toThrow();
2123
+ await expect(assetUploadCommand.parseAsync([
2124
+ "node",
2125
+ "cli",
2126
+ "-s",
2127
+ "https://bad.url",
2128
+ "-k",
2129
+ "image",
2130
+ ])).rejects.toThrow();
1558
2131
  consoleSpy.mockRestore();
1559
2132
  exitSpy.mockRestore();
1560
2133
  });
@@ -1565,38 +2138,47 @@ describe("asset upload", () => {
1565
2138
  describe("billing subscription upgrade start", () => {
1566
2139
  it("starts a checkout session", async () => {
1567
2140
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1568
- mockApiRequest.mockResolvedValueOnce({ checkoutUrl: "https://checkout.stripe.com/pay/cs_test_123", planSlug: "scale", interval: "month" });
1569
- await billingSubscriptionUpgradeStartCommand.parseAsync(["node", "cli", "-p", "scale", "-i", "month", "--success-url", "https://app.oxagen.ai/success", "--cancel-url", "https://app.oxagen.ai/cancel"]);
2141
+ mockApiRequest.mockResolvedValueOnce({
2142
+ checkoutUrl: "https://checkout.stripe.com/pay/cs_test_123",
2143
+ planSlug: "scale",
2144
+ interval: "month",
2145
+ });
2146
+ await billingSubscriptionUpgradeStartCommand.parseAsync([
2147
+ "node",
2148
+ "cli",
2149
+ "-p",
2150
+ "scale",
2151
+ "-i",
2152
+ "month",
2153
+ "--success-url",
2154
+ "https://app.oxagen.ai/success",
2155
+ "--cancel-url",
2156
+ "https://app.oxagen.ai/cancel",
2157
+ ]);
1570
2158
  expect(mockApiRequest).toHaveBeenCalledWith("/billing/subscription/upgrade/start", expect.objectContaining({ method: "POST" }));
1571
2159
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Checkout session created"));
1572
2160
  consoleSpy.mockRestore();
1573
2161
  });
1574
2162
  it("handles upgrade failure", async () => {
1575
2163
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1576
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2164
+ const exitSpy = vi
2165
+ .spyOn(process, "exit")
2166
+ .mockImplementation((_code) => {
2167
+ throw new Error("process.exit");
2168
+ });
1577
2169
  mockApiRequest.mockRejectedValueOnce(new Error("Stripe error"));
1578
- await expect(billingSubscriptionUpgradeStartCommand.parseAsync(["node", "cli", "-p", "scale", "-i", "month", "--success-url", "https://a.com/ok", "--cancel-url", "https://a.com/cancel"])).rejects.toThrow();
1579
- consoleSpy.mockRestore();
1580
- exitSpy.mockRestore();
1581
- });
1582
- });
1583
- // ---------------------------------------------------------------------------
1584
- // brandkit apply
1585
- // ---------------------------------------------------------------------------
1586
- describe("brandkit apply", () => {
1587
- it("applies a brand kit", async () => {
1588
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1589
- mockApiRequest.mockResolvedValueOnce({ stub: true, applied: false, brandKitId: "bk1", targetFileId: "file1" });
1590
- await brandkitApplyCommand.parseAsync(["node", "cli", "-b", "bk1", "-f", "file1", "-w", "ws1"]);
1591
- expect(mockApiRequest).toHaveBeenCalledWith("/brandkit/apply", expect.objectContaining({ method: "POST" }));
1592
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("stub"));
1593
- consoleSpy.mockRestore();
1594
- });
1595
- it("handles apply failure", async () => {
1596
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1597
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1598
- mockApiRequest.mockRejectedValueOnce(new Error("Brand kit not found"));
1599
- await expect(brandkitApplyCommand.parseAsync(["node", "cli", "-b", "bk1", "-f", "f1", "-w", "ws1"])).rejects.toThrow();
2170
+ await expect(billingSubscriptionUpgradeStartCommand.parseAsync([
2171
+ "node",
2172
+ "cli",
2173
+ "-p",
2174
+ "scale",
2175
+ "-i",
2176
+ "month",
2177
+ "--success-url",
2178
+ "https://a.com/ok",
2179
+ "--cancel-url",
2180
+ "https://a.com/cancel",
2181
+ ])).rejects.toThrow();
1600
2182
  consoleSpy.mockRestore();
1601
2183
  exitSpy.mockRestore();
1602
2184
  });
@@ -1608,14 +2190,24 @@ describe("conversation purge", () => {
1608
2190
  it("purges archived conversations with --yes", async () => {
1609
2191
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1610
2192
  mockApiRequest.mockResolvedValueOnce({ deleted: 5 });
1611
- await conversationPurgeCommand.parseAsync(["node", "cli", "-w", "ws1", "--yes"]);
2193
+ await conversationPurgeCommand.parseAsync([
2194
+ "node",
2195
+ "cli",
2196
+ "-w",
2197
+ "ws1",
2198
+ "--yes",
2199
+ ]);
1612
2200
  expect(mockApiRequest).toHaveBeenCalledWith("/conversation/purge", expect.objectContaining({ method: "POST" }));
1613
2201
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Purged 5"));
1614
2202
  consoleSpy.mockRestore();
1615
2203
  });
1616
2204
  it("exits without --yes", async () => {
1617
2205
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1618
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2206
+ const exitSpy = vi
2207
+ .spyOn(process, "exit")
2208
+ .mockImplementation((_code) => {
2209
+ throw new Error("process.exit");
2210
+ });
1619
2211
  await expect(conversationPurgeCommand.parseAsync(["node", "cli", "-w", "ws1"])).rejects.toThrow();
1620
2212
  expect(consoleSpy).toHaveBeenCalled();
1621
2213
  consoleSpy.mockRestore();
@@ -1623,9 +2215,19 @@ describe("conversation purge", () => {
1623
2215
  });
1624
2216
  it("handles purge failure", async () => {
1625
2217
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1626
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2218
+ const exitSpy = vi
2219
+ .spyOn(process, "exit")
2220
+ .mockImplementation((_code) => {
2221
+ throw new Error("process.exit");
2222
+ });
1627
2223
  mockApiRequest.mockRejectedValueOnce(new Error("Workspace not found"));
1628
- await expect(conversationPurgeCommand.parseAsync(["node", "cli", "-w", "ws1", "--yes"])).rejects.toThrow();
2224
+ await expect(conversationPurgeCommand.parseAsync([
2225
+ "node",
2226
+ "cli",
2227
+ "-w",
2228
+ "ws1",
2229
+ "--yes",
2230
+ ])).rejects.toThrow();
1629
2231
  consoleSpy.mockRestore();
1630
2232
  exitSpy.mockRestore();
1631
2233
  });
@@ -1636,15 +2238,32 @@ describe("conversation purge", () => {
1636
2238
  describe("documents pdf create", () => {
1637
2239
  it("creates a PDF document", async () => {
1638
2240
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1639
- mockApiRequest.mockResolvedValueOnce({ assetId: "asset1", publicId: "pub1", kind: "pdf", mimeType: "application/pdf", sizeBytes: 50000, url: "https://blob.example.com/doc.pdf", serveUrl: "https://api.example.com/assets/asset1" });
1640
- await documentsPdfCreateCommand.parseAsync(["node", "cli", "-t", "Q1 Report"]);
2241
+ mockApiRequest.mockResolvedValueOnce({
2242
+ assetId: "asset1",
2243
+ publicId: "pub1",
2244
+ kind: "pdf",
2245
+ mimeType: "application/pdf",
2246
+ sizeBytes: 50000,
2247
+ url: "https://blob.example.com/doc.pdf",
2248
+ serveUrl: "https://api.example.com/assets/asset1",
2249
+ });
2250
+ await documentsPdfCreateCommand.parseAsync([
2251
+ "node",
2252
+ "cli",
2253
+ "-t",
2254
+ "Q1 Report",
2255
+ ]);
1641
2256
  expect(mockApiRequest).toHaveBeenCalledWith("/documents/pdf/create", expect.objectContaining({ method: "POST" }));
1642
2257
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("PDF created"));
1643
2258
  consoleSpy.mockRestore();
1644
2259
  });
1645
2260
  it("handles pdf create failure", async () => {
1646
2261
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1647
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2262
+ const exitSpy = vi
2263
+ .spyOn(process, "exit")
2264
+ .mockImplementation((_code) => {
2265
+ throw new Error("process.exit");
2266
+ });
1648
2267
  mockApiRequest.mockRejectedValueOnce(new Error("Generation failed"));
1649
2268
  await expect(documentsPdfCreateCommand.parseAsync(["node", "cli", "-t", "Report"])).rejects.toThrow();
1650
2269
  consoleSpy.mockRestore();
@@ -1657,18 +2276,50 @@ describe("documents pdf create", () => {
1657
2276
  describe("form fill", () => {
1658
2277
  it("fills form fields", async () => {
1659
2278
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1660
- const fields = [{ name: "firstName", label: "First Name", type: "text", current: "", changed: false, proposed: "Alice", reason: "Inferred from instruction" }];
2279
+ const fields = [
2280
+ {
2281
+ name: "firstName",
2282
+ label: "First Name",
2283
+ type: "text",
2284
+ current: "",
2285
+ changed: false,
2286
+ proposed: "Alice",
2287
+ reason: "Inferred from instruction",
2288
+ },
2289
+ ];
1661
2290
  mockApiRequest.mockResolvedValueOnce({ fields });
1662
- await formFillCommand.parseAsync(["node", "cli", "-r", "/profile", "-i", "Fill with Alice's info", "--fields", '[{"name":"firstName","label":"First Name","type":"text","current":""}]']);
2291
+ await formFillCommand.parseAsync([
2292
+ "node",
2293
+ "cli",
2294
+ "-r",
2295
+ "/profile",
2296
+ "-i",
2297
+ "Fill with Alice's info",
2298
+ "--fields",
2299
+ '[{"name":"firstName","label":"First Name","type":"text","current":""}]',
2300
+ ]);
1663
2301
  expect(mockApiRequest).toHaveBeenCalledWith("/form/fill", expect.objectContaining({ method: "POST" }));
1664
2302
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Form fill suggestion"));
1665
2303
  consoleSpy.mockRestore();
1666
2304
  });
1667
2305
  it("handles form fill failure", async () => {
1668
2306
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1669
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2307
+ const exitSpy = vi
2308
+ .spyOn(process, "exit")
2309
+ .mockImplementation((_code) => {
2310
+ throw new Error("process.exit");
2311
+ });
1670
2312
  mockApiRequest.mockRejectedValueOnce(new Error("LLM error"));
1671
- await expect(formFillCommand.parseAsync(["node", "cli", "-r", "/p", "-i", "fill", "--fields", "[]"])).rejects.toThrow();
2313
+ await expect(formFillCommand.parseAsync([
2314
+ "node",
2315
+ "cli",
2316
+ "-r",
2317
+ "/p",
2318
+ "-i",
2319
+ "fill",
2320
+ "--fields",
2321
+ "[]",
2322
+ ])).rejects.toThrow();
1672
2323
  consoleSpy.mockRestore();
1673
2324
  exitSpy.mockRestore();
1674
2325
  });
@@ -1679,15 +2330,27 @@ describe("form fill", () => {
1679
2330
  describe("org member invite decline", () => {
1680
2331
  it("declines an invitation", async () => {
1681
2332
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1682
- mockApiRequest.mockResolvedValueOnce({ invitationPublicId: "inv1", status: "declined" });
1683
- await orgMemberInviteDeclineCommand.parseAsync(["node", "cli", "-i", "inv1"]);
2333
+ mockApiRequest.mockResolvedValueOnce({
2334
+ invitationPublicId: "inv1",
2335
+ status: "declined",
2336
+ });
2337
+ await orgMemberInviteDeclineCommand.parseAsync([
2338
+ "node",
2339
+ "cli",
2340
+ "-i",
2341
+ "inv1",
2342
+ ]);
1684
2343
  expect(mockApiRequest).toHaveBeenCalledWith("/org/member/invite/decline", expect.objectContaining({ method: "POST" }));
1685
2344
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("declined"));
1686
2345
  consoleSpy.mockRestore();
1687
2346
  });
1688
2347
  it("handles decline failure", async () => {
1689
2348
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1690
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2349
+ const exitSpy = vi
2350
+ .spyOn(process, "exit")
2351
+ .mockImplementation((_code) => {
2352
+ throw new Error("process.exit");
2353
+ });
1691
2354
  mockApiRequest.mockRejectedValueOnce(new Error("Invitation not found"));
1692
2355
  await expect(orgMemberInviteDeclineCommand.parseAsync(["node", "cli", "-i", "inv1"])).rejects.toThrow();
1693
2356
  consoleSpy.mockRestore();
@@ -1700,17 +2363,41 @@ describe("org member invite decline", () => {
1700
2363
  describe("organization create", () => {
1701
2364
  it("creates an organization", async () => {
1702
2365
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1703
- mockApiRequest.mockResolvedValueOnce({ publicId: "org1", name: "Acme Corp", slug: "acme-corp", type: "business", createdAt: "2026-06-08" });
1704
- await organizationCreateCommand.parseAsync(["node", "cli", "-n", "Acme Corp", "-s", "acme-corp"]);
2366
+ mockApiRequest.mockResolvedValueOnce({
2367
+ publicId: "org1",
2368
+ name: "Acme Corp",
2369
+ slug: "acme-corp",
2370
+ type: "business",
2371
+ createdAt: "2026-06-08",
2372
+ });
2373
+ await organizationCreateCommand.parseAsync([
2374
+ "node",
2375
+ "cli",
2376
+ "-n",
2377
+ "Acme Corp",
2378
+ "-s",
2379
+ "acme-corp",
2380
+ ]);
1705
2381
  expect(mockApiRequest).toHaveBeenCalledWith("/organization/create", expect.objectContaining({ method: "POST" }));
1706
2382
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Organization created"));
1707
2383
  consoleSpy.mockRestore();
1708
2384
  });
1709
2385
  it("handles create failure", async () => {
1710
2386
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1711
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2387
+ const exitSpy = vi
2388
+ .spyOn(process, "exit")
2389
+ .mockImplementation((_code) => {
2390
+ throw new Error("process.exit");
2391
+ });
1712
2392
  mockApiRequest.mockRejectedValueOnce(new Error("Slug already taken"));
1713
- await expect(organizationCreateCommand.parseAsync(["node", "cli", "-n", "Acme", "-s", "acme"])).rejects.toThrow();
2393
+ await expect(organizationCreateCommand.parseAsync([
2394
+ "node",
2395
+ "cli",
2396
+ "-n",
2397
+ "Acme",
2398
+ "-s",
2399
+ "acme",
2400
+ ])).rejects.toThrow();
1714
2401
  consoleSpy.mockRestore();
1715
2402
  exitSpy.mockRestore();
1716
2403
  });
@@ -1722,16 +2409,36 @@ describe("plugin credential set_secret", () => {
1722
2409
  it("stores a credential", async () => {
1723
2410
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1724
2411
  mockApiRequest.mockResolvedValueOnce({ ok: true });
1725
- await pluginCredentialSetSecretCommand.parseAsync(["node", "cli", "-l", "listing1", "-a", "secret", "--secret", "my-secret"]);
2412
+ await pluginCredentialSetSecretCommand.parseAsync([
2413
+ "node",
2414
+ "cli",
2415
+ "-l",
2416
+ "listing1",
2417
+ "-a",
2418
+ "secret",
2419
+ "--secret",
2420
+ "my-secret",
2421
+ ]);
1726
2422
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/credential/set_secret", expect.objectContaining({ method: "POST" }));
1727
2423
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Credential stored"));
1728
2424
  consoleSpy.mockRestore();
1729
2425
  });
1730
2426
  it("handles credential failure", async () => {
1731
2427
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1732
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2428
+ const exitSpy = vi
2429
+ .spyOn(process, "exit")
2430
+ .mockImplementation((_code) => {
2431
+ throw new Error("process.exit");
2432
+ });
1733
2433
  mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
1734
- await expect(pluginCredentialSetSecretCommand.parseAsync(["node", "cli", "-l", "l1", "-a", "secret"])).rejects.toThrow();
2434
+ await expect(pluginCredentialSetSecretCommand.parseAsync([
2435
+ "node",
2436
+ "cli",
2437
+ "-l",
2438
+ "l1",
2439
+ "-a",
2440
+ "secret",
2441
+ ])).rejects.toThrow();
1735
2442
  consoleSpy.mockRestore();
1736
2443
  exitSpy.mockRestore();
1737
2444
  });
@@ -1742,22 +2449,41 @@ describe("plugin credential set_secret", () => {
1742
2449
  describe("plugin org install bulk", () => {
1743
2450
  it("bulk installs plugins", async () => {
1744
2451
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1745
- mockApiRequest.mockResolvedValueOnce({ installed: [{ catalogServerId: "srv1", orgListingId: "listing1", error: null }] });
1746
- await pluginOrgInstallBulkCommand.parseAsync(["node", "cli", "--items", '[{"catalogServerId":"srv1"}]']);
2452
+ mockApiRequest.mockResolvedValueOnce({
2453
+ installed: [{ pluginId: "srv1", orgListingId: "listing1", error: null }],
2454
+ });
2455
+ await pluginOrgInstallBulkCommand.parseAsync([
2456
+ "node",
2457
+ "cli",
2458
+ "--items",
2459
+ '[{"catalogServerId":"srv1"}]',
2460
+ ]);
1747
2461
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/install_bulk", expect.objectContaining({ method: "POST" }));
1748
2462
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("1 succeeded"));
1749
2463
  consoleSpy.mockRestore();
1750
2464
  });
1751
2465
  it("reports partial failures", async () => {
1752
2466
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1753
- mockApiRequest.mockResolvedValueOnce({ installed: [{ catalogServerId: "srv1", orgListingId: null, error: "Not found" }] });
1754
- await pluginOrgInstallBulkCommand.parseAsync(["node", "cli", "--items", '[{"catalogServerId":"srv1"}]']);
2467
+ mockApiRequest.mockResolvedValueOnce({
2468
+ installed: [{ pluginId: "srv1", orgListingId: null, error: "Not found" }],
2469
+ });
2470
+ await pluginOrgInstallBulkCommand.parseAsync([
2471
+ "node",
2472
+ "cli",
2473
+ "--items",
2474
+ '[{"catalogServerId":"srv1"}]',
2475
+ ]);
1755
2476
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("0 succeeded, 1 failed"));
2477
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("srv1: Not found"));
1756
2478
  consoleSpy.mockRestore();
1757
2479
  });
1758
2480
  it("handles bulk install failure", async () => {
1759
2481
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1760
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2482
+ const exitSpy = vi
2483
+ .spyOn(process, "exit")
2484
+ .mockImplementation((_code) => {
2485
+ throw new Error("process.exit");
2486
+ });
1761
2487
  mockApiRequest.mockRejectedValueOnce(new Error("Bad request"));
1762
2488
  await expect(pluginOrgInstallBulkCommand.parseAsync(["node", "cli", "--items", "[]"])).rejects.toThrow();
1763
2489
  consoleSpy.mockRestore();
@@ -1771,7 +2497,15 @@ describe("plugin org list", () => {
1771
2497
  it("lists org plugins", async () => {
1772
2498
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1773
2499
  mockApiRequest.mockResolvedValueOnce({
1774
- listings: [{ id: "l1", publicId: "pub1", name: "Slack", pluginType: "mcp_server", enabled: true }],
2500
+ listings: [
2501
+ {
2502
+ id: "l1",
2503
+ publicId: "pub1",
2504
+ name: "Slack",
2505
+ pluginType: "mcp_server",
2506
+ enabled: true,
2507
+ },
2508
+ ],
1775
2509
  denylist: [],
1776
2510
  });
1777
2511
  await pluginOrgListCommand.parseAsync(["node", "cli"]);
@@ -1783,7 +2517,14 @@ describe("plugin org list", () => {
1783
2517
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1784
2518
  mockApiRequest.mockResolvedValueOnce({
1785
2519
  listings: [],
1786
- denylist: [{ id: "d1", serverName: "bad-server", pluginType: "mcp_server", reason: "Security risk" }],
2520
+ denylist: [
2521
+ {
2522
+ id: "d1",
2523
+ serverName: "bad-server",
2524
+ pluginType: "mcp_server",
2525
+ reason: "Security risk",
2526
+ },
2527
+ ],
1787
2528
  });
1788
2529
  await pluginOrgListCommand.parseAsync(["node", "cli"]);
1789
2530
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Denylist"));
@@ -1791,7 +2532,11 @@ describe("plugin org list", () => {
1791
2532
  });
1792
2533
  it("handles list failure", async () => {
1793
2534
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1794
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2535
+ const exitSpy = vi
2536
+ .spyOn(process, "exit")
2537
+ .mockImplementation((_code) => {
2538
+ throw new Error("process.exit");
2539
+ });
1795
2540
  mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
1796
2541
  await expect(pluginOrgListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1797
2542
  consoleSpy.mockRestore();
@@ -1805,7 +2550,14 @@ describe("plugin org set_enabled", () => {
1805
2550
  it("enables a plugin listing", async () => {
1806
2551
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1807
2552
  mockApiRequest.mockResolvedValueOnce({ ok: true });
1808
- await pluginOrgSetEnabledCommand.parseAsync(["node", "cli", "-l", "listing1", "--enabled", "true"]);
2553
+ await pluginOrgSetEnabledCommand.parseAsync([
2554
+ "node",
2555
+ "cli",
2556
+ "-l",
2557
+ "listing1",
2558
+ "--enabled",
2559
+ "true",
2560
+ ]);
1809
2561
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/set_enabled", expect.objectContaining({ method: "POST" }));
1810
2562
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("enabled"));
1811
2563
  consoleSpy.mockRestore();
@@ -1813,15 +2565,33 @@ describe("plugin org set_enabled", () => {
1813
2565
  it("disables a plugin listing", async () => {
1814
2566
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1815
2567
  mockApiRequest.mockResolvedValueOnce({ ok: true });
1816
- await pluginOrgSetEnabledCommand.parseAsync(["node", "cli", "-l", "listing1", "--enabled", "false"]);
2568
+ await pluginOrgSetEnabledCommand.parseAsync([
2569
+ "node",
2570
+ "cli",
2571
+ "-l",
2572
+ "listing1",
2573
+ "--enabled",
2574
+ "false",
2575
+ ]);
1817
2576
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("disabled"));
1818
2577
  consoleSpy.mockRestore();
1819
2578
  });
1820
2579
  it("handles set_enabled failure", async () => {
1821
2580
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1822
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2581
+ const exitSpy = vi
2582
+ .spyOn(process, "exit")
2583
+ .mockImplementation((_code) => {
2584
+ throw new Error("process.exit");
2585
+ });
1823
2586
  mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
1824
- await expect(pluginOrgSetEnabledCommand.parseAsync(["node", "cli", "-l", "l1", "--enabled", "true"])).rejects.toThrow();
2587
+ await expect(pluginOrgSetEnabledCommand.parseAsync([
2588
+ "node",
2589
+ "cli",
2590
+ "-l",
2591
+ "l1",
2592
+ "--enabled",
2593
+ "true",
2594
+ ])).rejects.toThrow();
1825
2595
  consoleSpy.mockRestore();
1826
2596
  exitSpy.mockRestore();
1827
2597
  });
@@ -1840,7 +2610,11 @@ describe("plugin registry remove", () => {
1840
2610
  });
1841
2611
  it("handles remove failure", async () => {
1842
2612
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1843
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2613
+ const exitSpy = vi
2614
+ .spyOn(process, "exit")
2615
+ .mockImplementation((_code) => {
2616
+ throw new Error("process.exit");
2617
+ });
1844
2618
  mockApiRequest.mockRejectedValueOnce(new Error("Registry is global default"));
1845
2619
  await expect(pluginRegistryRemoveCommand.parseAsync(["node", "cli", "-r", "r1"])).rejects.toThrow();
1846
2620
  consoleSpy.mockRestore();
@@ -1854,7 +2628,12 @@ describe("plugin settings set_auth_alerts", () => {
1854
2628
  it("updates auth alert settings", async () => {
1855
2629
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1856
2630
  mockApiRequest.mockResolvedValueOnce({ ok: true });
1857
- await pluginSettingsSetAuthAlertsCommand.parseAsync(["node", "cli", "--roles", "Owner,Admin"]);
2631
+ await pluginSettingsSetAuthAlertsCommand.parseAsync([
2632
+ "node",
2633
+ "cli",
2634
+ "--roles",
2635
+ "Owner,Admin",
2636
+ ]);
1858
2637
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/settings/set_auth_alerts", expect.objectContaining({ method: "POST" }));
1859
2638
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("updated"));
1860
2639
  consoleSpy.mockRestore();
@@ -1862,15 +2641,29 @@ describe("plugin settings set_auth_alerts", () => {
1862
2641
  it("reports update failed when ok=false", async () => {
1863
2642
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1864
2643
  mockApiRequest.mockResolvedValueOnce({ ok: false });
1865
- await pluginSettingsSetAuthAlertsCommand.parseAsync(["node", "cli", "--roles", "Owner"]);
2644
+ await pluginSettingsSetAuthAlertsCommand.parseAsync([
2645
+ "node",
2646
+ "cli",
2647
+ "--roles",
2648
+ "Owner",
2649
+ ]);
1866
2650
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Update failed"));
1867
2651
  consoleSpy.mockRestore();
1868
2652
  });
1869
2653
  it("handles failure", async () => {
1870
2654
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1871
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2655
+ const exitSpy = vi
2656
+ .spyOn(process, "exit")
2657
+ .mockImplementation((_code) => {
2658
+ throw new Error("process.exit");
2659
+ });
1872
2660
  mockApiRequest.mockRejectedValueOnce(new Error("Permission denied"));
1873
- await expect(pluginSettingsSetAuthAlertsCommand.parseAsync(["node", "cli", "--roles", "Owner"])).rejects.toThrow();
2661
+ await expect(pluginSettingsSetAuthAlertsCommand.parseAsync([
2662
+ "node",
2663
+ "cli",
2664
+ "--roles",
2665
+ "Owner",
2666
+ ])).rejects.toThrow();
1874
2667
  consoleSpy.mockRestore();
1875
2668
  exitSpy.mockRestore();
1876
2669
  });
@@ -1882,7 +2675,14 @@ describe("plugin workspace set_enabled", () => {
1882
2675
  it("enables a plugin for workspace", async () => {
1883
2676
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1884
2677
  mockApiRequest.mockResolvedValueOnce({ workspaceServerId: "wsrv1" });
1885
- await pluginWorkspaceSetEnabledCommand.parseAsync(["node", "cli", "-l", "listing1", "--enabled", "true"]);
2678
+ await pluginWorkspaceSetEnabledCommand.parseAsync([
2679
+ "node",
2680
+ "cli",
2681
+ "-l",
2682
+ "listing1",
2683
+ "--enabled",
2684
+ "true",
2685
+ ]);
1886
2686
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/workspace/set_enabled", expect.objectContaining({ method: "POST" }));
1887
2687
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("enabled"));
1888
2688
  consoleSpy.mockRestore();
@@ -1890,15 +2690,33 @@ describe("plugin workspace set_enabled", () => {
1890
2690
  it("disables a plugin for workspace (no server ID)", async () => {
1891
2691
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1892
2692
  mockApiRequest.mockResolvedValueOnce({ workspaceServerId: null });
1893
- await pluginWorkspaceSetEnabledCommand.parseAsync(["node", "cli", "-l", "listing1", "--enabled", "false"]);
2693
+ await pluginWorkspaceSetEnabledCommand.parseAsync([
2694
+ "node",
2695
+ "cli",
2696
+ "-l",
2697
+ "listing1",
2698
+ "--enabled",
2699
+ "false",
2700
+ ]);
1894
2701
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("disabled"));
1895
2702
  consoleSpy.mockRestore();
1896
2703
  });
1897
2704
  it("handles failure", async () => {
1898
2705
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1899
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2706
+ const exitSpy = vi
2707
+ .spyOn(process, "exit")
2708
+ .mockImplementation((_code) => {
2709
+ throw new Error("process.exit");
2710
+ });
1900
2711
  mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
1901
- await expect(pluginWorkspaceSetEnabledCommand.parseAsync(["node", "cli", "-l", "l1", "--enabled", "true"])).rejects.toThrow();
2712
+ await expect(pluginWorkspaceSetEnabledCommand.parseAsync([
2713
+ "node",
2714
+ "cli",
2715
+ "-l",
2716
+ "l1",
2717
+ "--enabled",
2718
+ "true",
2719
+ ])).rejects.toThrow();
1902
2720
  consoleSpy.mockRestore();
1903
2721
  exitSpy.mockRestore();
1904
2722
  });
@@ -1916,16 +2734,30 @@ describe("system install instructions", () => {
1916
2734
  { label: "Authenticate", command: "oxagen auth login" },
1917
2735
  ],
1918
2736
  });
1919
- await systemInstallInstructionsCommand.parseAsync(["node", "cli", "-c", "claude-code"]);
2737
+ await systemInstallInstructionsCommand.parseAsync([
2738
+ "node",
2739
+ "cli",
2740
+ "-c",
2741
+ "claude-code",
2742
+ ]);
1920
2743
  expect(mockApiRequest).toHaveBeenCalled();
1921
2744
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("claude-code"));
1922
2745
  consoleSpy.mockRestore();
1923
2746
  });
1924
2747
  it("handles fetch failure", async () => {
1925
2748
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1926
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2749
+ const exitSpy = vi
2750
+ .spyOn(process, "exit")
2751
+ .mockImplementation((_code) => {
2752
+ throw new Error("process.exit");
2753
+ });
1927
2754
  mockApiRequest.mockRejectedValueOnce(new Error("Unknown client"));
1928
- await expect(systemInstallInstructionsCommand.parseAsync(["node", "cli", "-c", "unknown"])).rejects.toThrow();
2755
+ await expect(systemInstallInstructionsCommand.parseAsync([
2756
+ "node",
2757
+ "cli",
2758
+ "-c",
2759
+ "unknown",
2760
+ ])).rejects.toThrow();
1929
2761
  consoleSpy.mockRestore();
1930
2762
  exitSpy.mockRestore();
1931
2763
  });
@@ -1969,7 +2801,11 @@ describe("user preferences read", () => {
1969
2801
  });
1970
2802
  it("handles read failure", async () => {
1971
2803
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1972
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2804
+ const exitSpy = vi
2805
+ .spyOn(process, "exit")
2806
+ .mockImplementation((_code) => {
2807
+ throw new Error("process.exit");
2808
+ });
1973
2809
  mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
1974
2810
  await expect(userPreferencesReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1975
2811
  consoleSpy.mockRestore();
@@ -1989,16 +2825,30 @@ describe("user preferences write", () => {
1989
2825
  defaultImageModel: null,
1990
2826
  defaultVideoModel: null,
1991
2827
  });
1992
- await userPreferencesWriteCommand.parseAsync(["node", "cli", "--font-size", "large"]);
2828
+ await userPreferencesWriteCommand.parseAsync([
2829
+ "node",
2830
+ "cli",
2831
+ "--font-size",
2832
+ "large",
2833
+ ]);
1993
2834
  expect(mockApiRequest).toHaveBeenCalledWith("/user/preferences/write", expect.objectContaining({ method: "POST" }));
1994
2835
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("updated"));
1995
2836
  consoleSpy.mockRestore();
1996
2837
  });
1997
2838
  it("handles write failure", async () => {
1998
2839
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1999
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2840
+ const exitSpy = vi
2841
+ .spyOn(process, "exit")
2842
+ .mockImplementation((_code) => {
2843
+ throw new Error("process.exit");
2844
+ });
2000
2845
  mockApiRequest.mockRejectedValueOnce(new Error("Validation failed"));
2001
- await expect(userPreferencesWriteCommand.parseAsync(["node", "cli", "--density", "bad"])).rejects.toThrow();
2846
+ await expect(userPreferencesWriteCommand.parseAsync([
2847
+ "node",
2848
+ "cli",
2849
+ "--density",
2850
+ "bad",
2851
+ ])).rejects.toThrow();
2002
2852
  consoleSpy.mockRestore();
2003
2853
  exitSpy.mockRestore();
2004
2854
  });
@@ -2024,7 +2874,11 @@ describe("workflow cancel", () => {
2024
2874
  });
2025
2875
  it("handles cancel failure", async () => {
2026
2876
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2027
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2877
+ const exitSpy = vi
2878
+ .spyOn(process, "exit")
2879
+ .mockImplementation((_code) => {
2880
+ throw new Error("process.exit");
2881
+ });
2028
2882
  mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
2029
2883
  await expect(workflowCancelCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
2030
2884
  consoleSpy.mockRestore();
@@ -2035,7 +2889,15 @@ describe("workflow status", () => {
2035
2889
  it("shows workflow status and tasks", async () => {
2036
2890
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2037
2891
  mockApiRequest.mockResolvedValueOnce({
2038
- workflow: { id: "wf1", publicId: "wfr_abc", title: "Research task", status: "running", totalTasks: 5, completedTasks: 3, failedTasks: 0 },
2892
+ workflow: {
2893
+ id: "wf1",
2894
+ publicId: "wfr_abc",
2895
+ title: "Research task",
2896
+ status: "running",
2897
+ totalTasks: 5,
2898
+ completedTasks: 3,
2899
+ failedTasks: 0,
2900
+ },
2039
2901
  tasks: [
2040
2902
  { id: "t1", title: "Gather data", status: "completed" },
2041
2903
  { id: "t2", title: "Analyze data", status: "running" },
@@ -2048,7 +2910,11 @@ describe("workflow status", () => {
2048
2910
  });
2049
2911
  it("handles status fetch failure", async () => {
2050
2912
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2051
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
2913
+ const exitSpy = vi
2914
+ .spyOn(process, "exit")
2915
+ .mockImplementation((_code) => {
2916
+ throw new Error("process.exit");
2917
+ });
2052
2918
  mockApiRequest.mockRejectedValueOnce(new Error("Workflow not found"));
2053
2919
  await expect(workflowStatusCommand.parseAsync(["node", "cli", "-w", "wfr_xyz"])).rejects.toThrow();
2054
2920
  consoleSpy.mockRestore();
@@ -2063,7 +2929,11 @@ describe("workflow status", () => {
2063
2929
  describe("branch coverage: ApiError error paths", () => {
2064
2930
  it("automation list returns ApiError message", async () => {
2065
2931
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2066
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2932
+ const exitSpy = vi
2933
+ .spyOn(process, "exit")
2934
+ .mockImplementation((_code) => {
2935
+ throw new Error("exit");
2936
+ });
2067
2937
  mockApiError(403, "Forbidden");
2068
2938
  await expect(automationListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2069
2939
  expect(consoleSpy).toHaveBeenCalledWith("Error: Forbidden");
@@ -2072,7 +2942,11 @@ describe("branch coverage: ApiError error paths", () => {
2072
2942
  });
2073
2943
  it("automation create returns ApiError message", async () => {
2074
2944
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2075
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2945
+ const exitSpy = vi
2946
+ .spyOn(process, "exit")
2947
+ .mockImplementation((_code) => {
2948
+ throw new Error("exit");
2949
+ });
2076
2950
  mockApiError(400, "Name required");
2077
2951
  await expect(automationCreateCommand.parseAsync(["node", "cli", "-n", "A"])).rejects.toThrow();
2078
2952
  expect(consoleSpy).toHaveBeenCalledWith("Error: Name required");
@@ -2081,7 +2955,11 @@ describe("branch coverage: ApiError error paths", () => {
2081
2955
  });
2082
2956
  it("automation enable returns ApiError message", async () => {
2083
2957
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2084
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2958
+ const exitSpy = vi
2959
+ .spyOn(process, "exit")
2960
+ .mockImplementation((_code) => {
2961
+ throw new Error("exit");
2962
+ });
2085
2963
  mockApiError(404, "Automation not found");
2086
2964
  await expect(automationEnableCommand.parseAsync(["node", "cli", "plt_missing"])).rejects.toThrow();
2087
2965
  expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
@@ -2090,7 +2968,11 @@ describe("branch coverage: ApiError error paths", () => {
2090
2968
  });
2091
2969
  it("automation disable returns ApiError message", async () => {
2092
2970
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2093
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2971
+ const exitSpy = vi
2972
+ .spyOn(process, "exit")
2973
+ .mockImplementation((_code) => {
2974
+ throw new Error("exit");
2975
+ });
2094
2976
  mockApiError(404, "Automation not found");
2095
2977
  await expect(automationDisableCommand.parseAsync(["node", "cli", "plt_missing"])).rejects.toThrow();
2096
2978
  expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
@@ -2099,7 +2981,11 @@ describe("branch coverage: ApiError error paths", () => {
2099
2981
  });
2100
2982
  it("automation trigger returns ApiError message", async () => {
2101
2983
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2102
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2984
+ const exitSpy = vi
2985
+ .spyOn(process, "exit")
2986
+ .mockImplementation((_code) => {
2987
+ throw new Error("exit");
2988
+ });
2103
2989
  mockApiError(404, "Automation not found");
2104
2990
  await expect(automationTriggerCommand.parseAsync(["node", "cli", "-a", "a1"])).rejects.toThrow();
2105
2991
  expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
@@ -2108,7 +2994,11 @@ describe("branch coverage: ApiError error paths", () => {
2108
2994
  });
2109
2995
  it("billing credits purchase returns ApiError message", async () => {
2110
2996
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2111
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2997
+ const exitSpy = vi
2998
+ .spyOn(process, "exit")
2999
+ .mockImplementation((_code) => {
3000
+ throw new Error("exit");
3001
+ });
2112
3002
  mockApiError(402, "Payment failed");
2113
3003
  await expect(billingCreditsPurchaseCommand.parseAsync(["node", "cli", "-a", "10"])).rejects.toThrow();
2114
3004
  expect(consoleSpy).toHaveBeenCalledWith("Error: Payment failed");
@@ -2117,7 +3007,11 @@ describe("branch coverage: ApiError error paths", () => {
2117
3007
  });
2118
3008
  it("billing subscription read returns ApiError message", async () => {
2119
3009
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2120
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3010
+ const exitSpy = vi
3011
+ .spyOn(process, "exit")
3012
+ .mockImplementation((_code) => {
3013
+ throw new Error("exit");
3014
+ });
2121
3015
  mockApiError(404, "Subscription not found");
2122
3016
  await expect(billingSubscriptionReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2123
3017
  expect(consoleSpy).toHaveBeenCalledWith("Error: Subscription not found");
@@ -2126,7 +3020,11 @@ describe("branch coverage: ApiError error paths", () => {
2126
3020
  });
2127
3021
  it("document list returns ApiError message", async () => {
2128
3022
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2129
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3023
+ const exitSpy = vi
3024
+ .spyOn(process, "exit")
3025
+ .mockImplementation((_code) => {
3026
+ throw new Error("exit");
3027
+ });
2130
3028
  mockApiError(403, "Access denied");
2131
3029
  await expect(documentListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2132
3030
  expect(consoleSpy).toHaveBeenCalledWith("Error: Access denied");
@@ -2135,7 +3033,11 @@ describe("branch coverage: ApiError error paths", () => {
2135
3033
  });
2136
3034
  it("workspace member list returns ApiError message", async () => {
2137
3035
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2138
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3036
+ const exitSpy = vi
3037
+ .spyOn(process, "exit")
3038
+ .mockImplementation((_code) => {
3039
+ throw new Error("exit");
3040
+ });
2139
3041
  mockApiError(403, "Not a member");
2140
3042
  await expect(workspaceMemberListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2141
3043
  expect(consoleSpy).toHaveBeenCalledWith("Error: Not a member");
@@ -2144,7 +3046,11 @@ describe("branch coverage: ApiError error paths", () => {
2144
3046
  });
2145
3047
  it("workflow cancel returns ApiError message", async () => {
2146
3048
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2147
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3049
+ const exitSpy = vi
3050
+ .spyOn(process, "exit")
3051
+ .mockImplementation((_code) => {
3052
+ throw new Error("exit");
3053
+ });
2148
3054
  mockApiError(404, "Workflow not found");
2149
3055
  await expect(workflowCancelCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
2150
3056
  expect(consoleSpy).toHaveBeenCalledWith("Error: Workflow not found");
@@ -2153,7 +3059,11 @@ describe("branch coverage: ApiError error paths", () => {
2153
3059
  });
2154
3060
  it("workflow status returns ApiError message", async () => {
2155
3061
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2156
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3062
+ const exitSpy = vi
3063
+ .spyOn(process, "exit")
3064
+ .mockImplementation((_code) => {
3065
+ throw new Error("exit");
3066
+ });
2157
3067
  mockApiError(404, "Run expired");
2158
3068
  await expect(workflowStatusCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
2159
3069
  expect(consoleSpy).toHaveBeenCalledWith("Error: Run expired");
@@ -2162,7 +3072,11 @@ describe("branch coverage: ApiError error paths", () => {
2162
3072
  });
2163
3073
  it("user preferences read returns ApiError message", async () => {
2164
3074
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2165
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3075
+ const exitSpy = vi
3076
+ .spyOn(process, "exit")
3077
+ .mockImplementation((_code) => {
3078
+ throw new Error("exit");
3079
+ });
2166
3080
  mockApiError(401, "Unauthorized");
2167
3081
  await expect(userPreferencesReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2168
3082
  expect(consoleSpy).toHaveBeenCalledWith("Error: Unauthorized");
@@ -2171,9 +3085,18 @@ describe("branch coverage: ApiError error paths", () => {
2171
3085
  });
2172
3086
  it("user preferences write returns ApiError message", async () => {
2173
3087
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2174
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3088
+ const exitSpy = vi
3089
+ .spyOn(process, "exit")
3090
+ .mockImplementation((_code) => {
3091
+ throw new Error("exit");
3092
+ });
2175
3093
  mockApiError(400, "Invalid font size");
2176
- await expect(userPreferencesWriteCommand.parseAsync(["node", "cli", "--font-size", "xxx"])).rejects.toThrow();
3094
+ await expect(userPreferencesWriteCommand.parseAsync([
3095
+ "node",
3096
+ "cli",
3097
+ "--font-size",
3098
+ "xxx",
3099
+ ])).rejects.toThrow();
2177
3100
  expect(consoleSpy).toHaveBeenCalledWith("Error: Invalid font size");
2178
3101
  consoleSpy.mockRestore();
2179
3102
  exitSpy.mockRestore();
@@ -2189,27 +3112,40 @@ describe("branch coverage: empty/optional data branches", () => {
2189
3112
  });
2190
3113
  it("automation list with workspace option", async () => {
2191
3114
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2192
- mockApiRequest.mockResolvedValueOnce([{ id: "a1", name: "Test", status: "active", triggers: [] }]);
3115
+ mockApiRequest.mockResolvedValueOnce([
3116
+ { id: "a1", name: "Test", status: "active", triggers: [] },
3117
+ ]);
2193
3118
  await automationListCommand.parseAsync(["node", "cli", "-w", "ws1"]);
2194
3119
  expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("workspace_id=ws1"), expect.anything());
2195
3120
  consoleSpy.mockRestore();
2196
3121
  });
2197
3122
  it("automation list shows 'none' when triggers are empty", async () => {
2198
3123
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2199
- mockApiRequest.mockResolvedValueOnce([{ id: "a1", name: "Untriggered", status: "active", triggers: [] }]);
3124
+ mockApiRequest.mockResolvedValueOnce([
3125
+ { id: "a1", name: "Untriggered", status: "active", triggers: [] },
3126
+ ]);
2200
3127
  await automationListCommand.parseAsync(["node", "cli"]);
2201
3128
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("triggers=none"));
2202
3129
  consoleSpy.mockRestore();
2203
3130
  });
2204
3131
  it("image create with save-to option", async () => {
2205
3132
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2206
- mockApiRequest.mockResolvedValueOnce({ id: "img1", url: "https://cdn.example.com/img.png", created_at: "2026-06-08", workspace_id: "ws1" });
3133
+ mockApiRequest.mockResolvedValueOnce({
3134
+ id: "img1",
3135
+ url: "https://cdn.example.com/img.png",
3136
+ created_at: "2026-06-08",
3137
+ workspace_id: "ws1",
3138
+ });
2207
3139
  await imageCreateCommand.parseAsync(["node", "cli", "-p", "A cat"]);
2208
3140
  consoleSpy.mockRestore();
2209
3141
  });
2210
3142
  it("conversation chat ApiError path", async () => {
2211
3143
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2212
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3144
+ const exitSpy = vi
3145
+ .spyOn(process, "exit")
3146
+ .mockImplementation((_code) => {
3147
+ throw new Error("exit");
3148
+ });
2213
3149
  mockApiError(401, "Not authenticated");
2214
3150
  await expect(conversationChatCommand.parseAsync(["node", "cli", "-m", "Hello"])).rejects.toThrow();
2215
3151
  expect(consoleSpy).toHaveBeenCalledWith("Error: Not authenticated");
@@ -2218,7 +3154,11 @@ describe("branch coverage: empty/optional data branches", () => {
2218
3154
  });
2219
3155
  it("workspace list ApiError path", async () => {
2220
3156
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2221
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3157
+ const exitSpy = vi
3158
+ .spyOn(process, "exit")
3159
+ .mockImplementation((_code) => {
3160
+ throw new Error("exit");
3161
+ });
2222
3162
  mockApiError(403, "Org not found");
2223
3163
  await expect(workspaceListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2224
3164
  expect(consoleSpy).toHaveBeenCalledWith("Error: Org not found");
@@ -2227,7 +3167,11 @@ describe("branch coverage: empty/optional data branches", () => {
2227
3167
  });
2228
3168
  it("org list ApiError path", async () => {
2229
3169
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2230
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3170
+ const exitSpy = vi
3171
+ .spyOn(process, "exit")
3172
+ .mockImplementation((_code) => {
3173
+ throw new Error("exit");
3174
+ });
2231
3175
  mockApiError(401, "Token expired");
2232
3176
  await expect(orgListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2233
3177
  expect(consoleSpy).toHaveBeenCalledWith("Error: Token expired");
@@ -2236,7 +3180,11 @@ describe("branch coverage: empty/optional data branches", () => {
2236
3180
  });
2237
3181
  it("api-key create ApiError path", async () => {
2238
3182
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2239
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3183
+ const exitSpy = vi
3184
+ .spyOn(process, "exit")
3185
+ .mockImplementation((_code) => {
3186
+ throw new Error("exit");
3187
+ });
2240
3188
  mockApiError(429, "Rate limit exceeded");
2241
3189
  await expect(apiKeyCreateCommand.parseAsync(["node", "cli", "mykey"])).rejects.toThrow();
2242
3190
  expect(consoleSpy).toHaveBeenCalledWith("Error: Rate limit exceeded");
@@ -2245,7 +3193,11 @@ describe("branch coverage: empty/optional data branches", () => {
2245
3193
  });
2246
3194
  it("plugin list ApiError path", async () => {
2247
3195
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2248
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3196
+ const exitSpy = vi
3197
+ .spyOn(process, "exit")
3198
+ .mockImplementation((_code) => {
3199
+ throw new Error("exit");
3200
+ });
2249
3201
  mockApiError(403, "Permission denied");
2250
3202
  await expect(pluginListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2251
3203
  expect(consoleSpy).toHaveBeenCalledWith("Error: Permission denied");
@@ -2254,7 +3206,11 @@ describe("branch coverage: empty/optional data branches", () => {
2254
3206
  });
2255
3207
  it("billing status ApiError path", async () => {
2256
3208
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2257
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3209
+ const exitSpy = vi
3210
+ .spyOn(process, "exit")
3211
+ .mockImplementation((_code) => {
3212
+ throw new Error("exit");
3213
+ });
2258
3214
  mockApiError(402, "Billing error");
2259
3215
  await expect(billingStatusCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2260
3216
  expect(consoleSpy).toHaveBeenCalledWith("Error: Billing error");
@@ -2263,7 +3219,11 @@ describe("branch coverage: empty/optional data branches", () => {
2263
3219
  });
2264
3220
  it("chat send ApiError path", async () => {
2265
3221
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2266
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3222
+ const exitSpy = vi
3223
+ .spyOn(process, "exit")
3224
+ .mockImplementation((_code) => {
3225
+ throw new Error("exit");
3226
+ });
2267
3227
  // chat.send uses native fetch (not apiRequest); mock fetch directly.
2268
3228
  vi.spyOn(global, "fetch").mockResolvedValueOnce(new Response(JSON.stringify({ error: "Service unavailable" }), {
2269
3229
  status: 503,
@@ -2275,7 +3235,11 @@ describe("branch coverage: empty/optional data branches", () => {
2275
3235
  });
2276
3236
  it("document read ApiError path", async () => {
2277
3237
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2278
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3238
+ const exitSpy = vi
3239
+ .spyOn(process, "exit")
3240
+ .mockImplementation((_code) => {
3241
+ throw new Error("exit");
3242
+ });
2279
3243
  mockApiError(404, "Document not found");
2280
3244
  await expect(documentReadCommand.parseAsync(["node", "cli", "-d", "doc1"])).rejects.toThrow();
2281
3245
  expect(consoleSpy).toHaveBeenCalledWith("Error: Document not found");
@@ -2290,7 +3254,11 @@ describe("branch coverage: empty/optional data branches", () => {
2290
3254
  });
2291
3255
  it("workflow run ApiError path", async () => {
2292
3256
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2293
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
3257
+ const exitSpy = vi
3258
+ .spyOn(process, "exit")
3259
+ .mockImplementation((_code) => {
3260
+ throw new Error("exit");
3261
+ });
2294
3262
  mockApiError(400, "Invalid workflow spec");
2295
3263
  await expect(workflowRunCommand.parseAsync(["node", "cli", "-w", "wf1"])).rejects.toThrow();
2296
3264
  expect(consoleSpy).toHaveBeenCalledWith("Error: Invalid workflow spec");
@@ -2315,7 +3283,13 @@ describe("Environment Variable Defaults", () => {
2315
3283
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2316
3284
  mockGetOrgId.mockReturnValue("env-org-123");
2317
3285
  mockApiRequest.mockResolvedValueOnce({ members: [] });
2318
- await orgMemberAddCommand.parseAsync(["node", "cli", "user@example.com", "--role", "admin"]);
3286
+ await orgMemberAddCommand.parseAsync([
3287
+ "node",
3288
+ "cli",
3289
+ "user@example.com",
3290
+ "--role",
3291
+ "admin",
3292
+ ]);
2319
3293
  expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2320
3294
  body: expect.stringContaining("env-org-123"),
2321
3295
  }));
@@ -2325,7 +3299,15 @@ describe("Environment Variable Defaults", () => {
2325
3299
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2326
3300
  mockGetOrgId.mockReturnValue("env-org-123");
2327
3301
  mockApiRequest.mockResolvedValueOnce({ members: [] });
2328
- await orgMemberAddCommand.parseAsync(["node", "cli", "user@example.com", "--role", "admin", "--org", "cli-org-456"]);
3302
+ await orgMemberAddCommand.parseAsync([
3303
+ "node",
3304
+ "cli",
3305
+ "user@example.com",
3306
+ "--role",
3307
+ "admin",
3308
+ "--org",
3309
+ "cli-org-456",
3310
+ ]);
2329
3311
  expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2330
3312
  body: expect.stringContaining("cli-org-456"),
2331
3313
  }));
@@ -2350,7 +3332,12 @@ describe("Environment Variable Defaults", () => {
2350
3332
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2351
3333
  mockGetWorkspaceId.mockReturnValue("env-workspace-789");
2352
3334
  mockApiRequest.mockResolvedValueOnce([]);
2353
- await workspaceMemberListCommand.parseAsync(["node", "cli", "-w", "cli-workspace-xyz"]);
3335
+ await workspaceMemberListCommand.parseAsync([
3336
+ "node",
3337
+ "cli",
3338
+ "-w",
3339
+ "cli-workspace-xyz",
3340
+ ]);
2354
3341
  const calls = mockApiRequest.mock.calls;
2355
3342
  expect(calls.length).toBeGreaterThan(0);
2356
3343
  expect(calls[0]?.[0]).toContain("workspace_id=cli-workspace-xyz");
@@ -2375,11 +3362,17 @@ describe("Environment Variable Defaults", () => {
2375
3362
  discoveredTools: ["tool1"],
2376
3363
  });
2377
3364
  await agentMcpRegisterCommand.parseAsync([
2378
- "node", "cli", "register",
2379
- "-n", "my-mcp",
2380
- "-u", "http://localhost:9000",
2381
- "-t", "streamable-http",
2382
- "-w", "explicit-workspace-888"
3365
+ "node",
3366
+ "cli",
3367
+ "register",
3368
+ "-n",
3369
+ "my-mcp",
3370
+ "-u",
3371
+ "http://localhost:9000",
3372
+ "-t",
3373
+ "streamable-http",
3374
+ "-w",
3375
+ "explicit-workspace-888",
2383
3376
  ]);
2384
3377
  expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2385
3378
  body: expect.stringContaining("explicit-workspace-888"),
@@ -2396,10 +3389,15 @@ describe("Environment Variable Defaults", () => {
2396
3389
  discoveredTools: [],
2397
3390
  });
2398
3391
  await agentMcpRegisterCommand.parseAsync([
2399
- "node", "cli", "register",
2400
- "-n", "my-mcp",
2401
- "-u", "http://localhost:9000",
2402
- "-t", "streamable-http"
3392
+ "node",
3393
+ "cli",
3394
+ "register",
3395
+ "-n",
3396
+ "my-mcp",
3397
+ "-u",
3398
+ "http://localhost:9000",
3399
+ "-t",
3400
+ "streamable-http",
2403
3401
  ]);
2404
3402
  expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2405
3403
  body: expect.stringContaining("fallback-org-111"),
@@ -2417,7 +3415,12 @@ describe("Environment Variable Defaults", () => {
2417
3415
  it("workspace member list uses OXAGEN_WORKSPACE_ID as default when no --workspace flag", async () => {
2418
3416
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2419
3417
  mockApiRequest.mockResolvedValueOnce([
2420
- { id: "user1", email: "user@test.com", role: "member", joined_at: "2024-01-01" }
3418
+ {
3419
+ id: "user1",
3420
+ email: "user@test.com",
3421
+ role: "member",
3422
+ joined_at: "2024-01-01",
3423
+ },
2421
3424
  ]);
2422
3425
  await workspaceMemberListCommand.parseAsync(["node", "cli"]);
2423
3426
  const calls = mockApiRequest.mock.calls;
@@ -2428,11 +3431,18 @@ describe("Environment Variable Defaults", () => {
2428
3431
  it("workspace member list uses explicit --workspace to override OXAGEN_WORKSPACE_ID", async () => {
2429
3432
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2430
3433
  mockApiRequest.mockResolvedValueOnce([
2431
- { id: "user1", email: "user@test.com", role: "member", joined_at: "2024-01-01" }
3434
+ {
3435
+ id: "user1",
3436
+ email: "user@test.com",
3437
+ role: "member",
3438
+ joined_at: "2024-01-01",
3439
+ },
2432
3440
  ]);
2433
3441
  await workspaceMemberListCommand.parseAsync([
2434
- "node", "cli",
2435
- "-w", "explicit-ws"
3442
+ "node",
3443
+ "cli",
3444
+ "-w",
3445
+ "explicit-ws",
2436
3446
  ]);
2437
3447
  const calls = mockApiRequest.mock.calls;
2438
3448
  expect(calls.length).toBeGreaterThan(0);