@oxagen/cli 0.4.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 (537) hide show
  1. package/README.md +68 -5
  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.mcp.consent.list.d.ts +3 -0
  155. package/dist/commands/agent.mcp.consent.list.d.ts.map +1 -0
  156. package/dist/commands/agent.mcp.consent.list.js +30 -0
  157. package/dist/commands/agent.mcp.consent.list.js.map +1 -0
  158. package/dist/commands/agent.mcp.consent.resolve.d.ts +3 -0
  159. package/dist/commands/agent.mcp.consent.resolve.d.ts.map +1 -0
  160. package/dist/commands/agent.mcp.consent.resolve.js +34 -0
  161. package/dist/commands/agent.mcp.consent.resolve.js.map +1 -0
  162. package/dist/commands/agent.mcp.delete.d.ts +3 -0
  163. package/dist/commands/agent.mcp.delete.d.ts.map +1 -0
  164. package/dist/commands/agent.mcp.delete.js +27 -0
  165. package/dist/commands/agent.mcp.delete.js.map +1 -0
  166. package/dist/commands/agent.mcp.set_enabled.d.ts +3 -0
  167. package/dist/commands/agent.mcp.set_enabled.d.ts.map +1 -0
  168. package/dist/commands/agent.mcp.set_enabled.js +33 -0
  169. package/dist/commands/agent.mcp.set_enabled.js.map +1 -0
  170. package/dist/commands/agent.skill.load.d.ts +3 -0
  171. package/dist/commands/agent.skill.load.d.ts.map +1 -0
  172. package/dist/commands/agent.skill.load.js +57 -0
  173. package/dist/commands/agent.skill.load.js.map +1 -0
  174. package/dist/commands/audit.log.query.d.ts +3 -0
  175. package/dist/commands/audit.log.query.d.ts.map +1 -0
  176. package/dist/commands/audit.log.query.js +42 -0
  177. package/dist/commands/audit.log.query.js.map +1 -0
  178. package/dist/commands/automation.create.d.ts.map +1 -1
  179. package/dist/commands/automation.create.js +43 -4
  180. package/dist/commands/automation.create.js.map +1 -1
  181. package/dist/commands/automation.disable.d.ts +3 -0
  182. package/dist/commands/automation.disable.d.ts.map +1 -0
  183. package/dist/commands/automation.disable.js +24 -0
  184. package/dist/commands/automation.disable.js.map +1 -0
  185. package/dist/commands/automation.enable.d.ts +3 -0
  186. package/dist/commands/automation.enable.d.ts.map +1 -0
  187. package/dist/commands/automation.enable.js +24 -0
  188. package/dist/commands/automation.enable.js.map +1 -0
  189. package/dist/commands/automation.update.d.ts +3 -0
  190. package/dist/commands/automation.update.d.ts.map +1 -0
  191. package/dist/commands/automation.update.js +42 -0
  192. package/dist/commands/automation.update.js.map +1 -0
  193. package/dist/commands/code.d.ts +14 -0
  194. package/dist/commands/code.d.ts.map +1 -0
  195. package/dist/commands/code.js +100 -0
  196. package/dist/commands/code.js.map +1 -0
  197. package/dist/commands/config.d.ts +2 -0
  198. package/dist/commands/config.d.ts.map +1 -0
  199. package/dist/commands/config.js +66 -0
  200. package/dist/commands/config.js.map +1 -0
  201. package/dist/commands/conversation.files.list.d.ts +3 -0
  202. package/dist/commands/conversation.files.list.d.ts.map +1 -0
  203. package/dist/commands/conversation.files.list.js +39 -0
  204. package/dist/commands/conversation.files.list.js.map +1 -0
  205. package/dist/commands/env.d.ts +19 -0
  206. package/dist/commands/env.d.ts.map +1 -0
  207. package/dist/commands/env.js +64 -0
  208. package/dist/commands/env.js.map +1 -0
  209. package/dist/commands/graph.search.d.ts +10 -0
  210. package/dist/commands/graph.search.d.ts.map +1 -0
  211. package/dist/commands/graph.search.js +25 -0
  212. package/dist/commands/graph.search.js.map +1 -0
  213. package/dist/commands/markdown.generate.d.ts +3 -0
  214. package/dist/commands/markdown.generate.d.ts.map +1 -0
  215. package/dist/commands/markdown.generate.js +37 -0
  216. package/dist/commands/markdown.generate.js.map +1 -0
  217. package/dist/commands/mcp.add.d.ts +13 -0
  218. package/dist/commands/mcp.add.d.ts.map +1 -0
  219. package/dist/commands/mcp.add.js +110 -0
  220. package/dist/commands/mcp.add.js.map +1 -0
  221. package/dist/commands/mcp.auth.d.ts +10 -0
  222. package/dist/commands/mcp.auth.d.ts.map +1 -0
  223. package/dist/commands/mcp.auth.js +132 -0
  224. package/dist/commands/mcp.auth.js.map +1 -0
  225. package/dist/commands/mcp.check.d.ts +10 -0
  226. package/dist/commands/mcp.check.d.ts.map +1 -0
  227. package/dist/commands/mcp.check.js +114 -0
  228. package/dist/commands/mcp.check.js.map +1 -0
  229. package/dist/commands/mcp.list.d.ts +9 -0
  230. package/dist/commands/mcp.list.d.ts.map +1 -0
  231. package/dist/commands/mcp.list.js +93 -0
  232. package/dist/commands/mcp.list.js.map +1 -0
  233. package/dist/commands/mcp.permit.d.ts +12 -0
  234. package/dist/commands/mcp.permit.d.ts.map +1 -0
  235. package/dist/commands/mcp.permit.js +117 -0
  236. package/dist/commands/mcp.permit.js.map +1 -0
  237. package/dist/commands/mcp.remove.d.ts +9 -0
  238. package/dist/commands/mcp.remove.d.ts.map +1 -0
  239. package/dist/commands/mcp.remove.js +65 -0
  240. package/dist/commands/mcp.remove.js.map +1 -0
  241. package/dist/commands/mermaid.generate.d.ts +3 -0
  242. package/dist/commands/mermaid.generate.d.ts.map +1 -0
  243. package/dist/commands/mermaid.generate.js +33 -0
  244. package/dist/commands/mermaid.generate.js.map +1 -0
  245. package/dist/commands/ontology.neighbors.d.ts +3 -0
  246. package/dist/commands/ontology.neighbors.d.ts.map +1 -0
  247. package/dist/commands/ontology.neighbors.js +34 -0
  248. package/dist/commands/ontology.neighbors.js.map +1 -0
  249. package/dist/commands/ontology.query.d.ts +3 -0
  250. package/dist/commands/ontology.query.d.ts.map +1 -0
  251. package/dist/commands/ontology.query.js +36 -0
  252. package/dist/commands/ontology.query.js.map +1 -0
  253. package/dist/commands/plugin.org.install_bulk.js +1 -1
  254. package/dist/commands/plugin.org.install_bulk.js.map +1 -1
  255. package/dist/commands/privacy.erase.d.ts.map +1 -1
  256. package/dist/commands/privacy.erase.js +2 -1
  257. package/dist/commands/privacy.erase.js.map +1 -1
  258. package/dist/commands/privacy.erase.test.d.ts +2 -0
  259. package/dist/commands/privacy.erase.test.d.ts.map +1 -0
  260. package/dist/commands/privacy.erase.test.js +132 -0
  261. package/dist/commands/privacy.erase.test.js.map +1 -0
  262. package/dist/commands/replay.d.ts +5 -0
  263. package/dist/commands/replay.d.ts.map +1 -0
  264. package/dist/commands/replay.js +28 -0
  265. package/dist/commands/replay.js.map +1 -0
  266. package/dist/commands/schema/schema.config.d.ts +3 -0
  267. package/dist/commands/schema/schema.config.d.ts.map +1 -0
  268. package/dist/commands/schema/schema.config.js +34 -0
  269. package/dist/commands/schema/schema.config.js.map +1 -0
  270. package/dist/commands/schema/schema.disable.d.ts +3 -0
  271. package/dist/commands/schema/schema.disable.d.ts.map +1 -0
  272. package/dist/commands/schema/schema.disable.js +22 -0
  273. package/dist/commands/schema/schema.disable.js.map +1 -0
  274. package/dist/commands/schema/schema.enable.d.ts +3 -0
  275. package/dist/commands/schema/schema.enable.d.ts.map +1 -0
  276. package/dist/commands/schema/schema.enable.js +22 -0
  277. package/dist/commands/schema/schema.enable.js.map +1 -0
  278. package/dist/commands/schema/schema.export.d.ts +3 -0
  279. package/dist/commands/schema/schema.export.d.ts.map +1 -0
  280. package/dist/commands/schema/schema.export.js +31 -0
  281. package/dist/commands/schema/schema.export.js.map +1 -0
  282. package/dist/commands/schema/schema.get.d.ts +3 -0
  283. package/dist/commands/schema/schema.get.d.ts.map +1 -0
  284. package/dist/commands/schema/schema.get.js +23 -0
  285. package/dist/commands/schema/schema.get.js.map +1 -0
  286. package/dist/commands/schema/schema.label.d.ts +5 -0
  287. package/dist/commands/schema/schema.label.d.ts.map +1 -0
  288. package/dist/commands/schema/schema.label.js +60 -0
  289. package/dist/commands/schema/schema.label.js.map +1 -0
  290. package/dist/commands/schema/schema.list.d.ts +3 -0
  291. package/dist/commands/schema/schema.list.d.ts.map +1 -0
  292. package/dist/commands/schema/schema.list.js +30 -0
  293. package/dist/commands/schema/schema.list.js.map +1 -0
  294. package/dist/commands/schema/schema.prop.d.ts +5 -0
  295. package/dist/commands/schema/schema.prop.d.ts.map +1 -0
  296. package/dist/commands/schema/schema.prop.js +72 -0
  297. package/dist/commands/schema/schema.prop.js.map +1 -0
  298. package/dist/commands/schema/schema.reconcile.d.ts +10 -0
  299. package/dist/commands/schema/schema.reconcile.d.ts.map +1 -0
  300. package/dist/commands/schema/schema.reconcile.js +65 -0
  301. package/dist/commands/schema/schema.reconcile.js.map +1 -0
  302. package/dist/commands/schema/schema.rel.d.ts +5 -0
  303. package/dist/commands/schema/schema.rel.d.ts.map +1 -0
  304. package/dist/commands/schema/schema.rel.js +65 -0
  305. package/dist/commands/schema/schema.rel.js.map +1 -0
  306. package/dist/commands/schema/schema.version.d.ts +7 -0
  307. package/dist/commands/schema/schema.version.d.ts.map +1 -0
  308. package/dist/commands/schema/schema.version.js +96 -0
  309. package/dist/commands/schema/schema.version.js.map +1 -0
  310. package/dist/commands/secret.d.ts +23 -0
  311. package/dist/commands/secret.d.ts.map +1 -0
  312. package/dist/commands/secret.js +90 -0
  313. package/dist/commands/secret.js.map +1 -0
  314. package/dist/commands/skill.create.d.ts +3 -0
  315. package/dist/commands/skill.create.d.ts.map +1 -0
  316. package/dist/commands/skill.create.js +52 -0
  317. package/dist/commands/skill.create.js.map +1 -0
  318. package/dist/commands/skill.edit.d.ts +3 -0
  319. package/dist/commands/skill.edit.d.ts.map +1 -0
  320. package/dist/commands/skill.edit.js +28 -0
  321. package/dist/commands/skill.edit.js.map +1 -0
  322. package/dist/commands/skill.enable.d.ts +3 -0
  323. package/dist/commands/skill.enable.d.ts.map +1 -0
  324. package/dist/commands/skill.enable.js +31 -0
  325. package/dist/commands/skill.enable.js.map +1 -0
  326. package/dist/commands/skill.export.d.ts +3 -0
  327. package/dist/commands/skill.export.d.ts.map +1 -0
  328. package/dist/commands/skill.export.js +25 -0
  329. package/dist/commands/skill.export.js.map +1 -0
  330. package/dist/commands/skill.metrics.read.d.ts +3 -0
  331. package/dist/commands/skill.metrics.read.d.ts.map +1 -0
  332. package/dist/commands/skill.metrics.read.js +56 -0
  333. package/dist/commands/skill.metrics.read.js.map +1 -0
  334. package/dist/commands/skill.version.activate.d.ts +3 -0
  335. package/dist/commands/skill.version.activate.d.ts.map +1 -0
  336. package/dist/commands/skill.version.activate.js +24 -0
  337. package/dist/commands/skill.version.activate.js.map +1 -0
  338. package/dist/commands/skill.version.get.d.ts +3 -0
  339. package/dist/commands/skill.version.get.d.ts.map +1 -0
  340. package/dist/commands/skill.version.get.js +43 -0
  341. package/dist/commands/skill.version.get.js.map +1 -0
  342. package/dist/commands/skill.version.list.d.ts +3 -0
  343. package/dist/commands/skill.version.list.d.ts.map +1 -0
  344. package/dist/commands/skill.version.list.js +38 -0
  345. package/dist/commands/skill.version.list.js.map +1 -0
  346. package/dist/commands/skill.version.upload.d.ts +3 -0
  347. package/dist/commands/skill.version.upload.d.ts.map +1 -0
  348. package/dist/commands/skill.version.upload.js +28 -0
  349. package/dist/commands/skill.version.upload.js.map +1 -0
  350. package/dist/commands/skill.workspace.install.d.ts +3 -0
  351. package/dist/commands/skill.workspace.install.d.ts.map +1 -0
  352. package/dist/commands/skill.workspace.install.js +52 -0
  353. package/dist/commands/skill.workspace.install.js.map +1 -0
  354. package/dist/commands.test.js +1391 -337
  355. package/dist/commands.test.js.map +1 -1
  356. package/dist/components/DevStatus.d.ts.map +1 -1
  357. package/dist/components/DevStatus.js +3 -2
  358. package/dist/components/DevStatus.js.map +1 -1
  359. package/dist/daemon/client.d.ts +30 -0
  360. package/dist/daemon/client.d.ts.map +1 -0
  361. package/dist/daemon/client.js +97 -0
  362. package/dist/daemon/client.js.map +1 -0
  363. package/dist/daemon/code-graph/builder.d.ts +6 -0
  364. package/dist/daemon/code-graph/builder.d.ts.map +1 -0
  365. package/dist/daemon/code-graph/builder.js +215 -0
  366. package/dist/daemon/code-graph/builder.js.map +1 -0
  367. package/dist/daemon/code-graph/query.d.ts +29 -0
  368. package/dist/daemon/code-graph/query.d.ts.map +1 -0
  369. package/dist/daemon/code-graph/query.js +98 -0
  370. package/dist/daemon/code-graph/query.js.map +1 -0
  371. package/dist/daemon/code-graph/types.d.ts +37 -0
  372. package/dist/daemon/code-graph/types.d.ts.map +1 -0
  373. package/dist/daemon/code-graph/types.js +5 -0
  374. package/dist/daemon/code-graph/types.js.map +1 -0
  375. package/dist/daemon/code-graph/watcher.d.ts +37 -0
  376. package/dist/daemon/code-graph/watcher.d.ts.map +1 -0
  377. package/dist/daemon/code-graph/watcher.js +79 -0
  378. package/dist/daemon/code-graph/watcher.js.map +1 -0
  379. package/dist/daemon/lifecycle.d.ts +6 -0
  380. package/dist/daemon/lifecycle.d.ts.map +1 -0
  381. package/dist/daemon/lifecycle.js +132 -0
  382. package/dist/daemon/lifecycle.js.map +1 -0
  383. package/dist/daemon/protocol.d.ts +113 -0
  384. package/dist/daemon/protocol.d.ts.map +1 -0
  385. package/dist/daemon/protocol.js +16 -0
  386. package/dist/daemon/protocol.js.map +1 -0
  387. package/dist/daemon/server.d.ts +26 -0
  388. package/dist/daemon/server.d.ts.map +1 -0
  389. package/dist/daemon/server.js +168 -0
  390. package/dist/daemon/server.js.map +1 -0
  391. package/dist/index.d.ts +1 -1
  392. package/dist/index.js +262 -310
  393. package/dist/index.js.map +1 -1
  394. package/dist/lib/api.d.ts +5 -0
  395. package/dist/lib/api.d.ts.map +1 -0
  396. package/dist/lib/api.js +52 -0
  397. package/dist/lib/api.js.map +1 -0
  398. package/dist/lib/config.d.ts +3 -0
  399. package/dist/lib/config.d.ts.map +1 -1
  400. package/dist/lib/config.js +16 -3
  401. package/dist/lib/config.js.map +1 -1
  402. package/dist/lib/config.test.js +21 -3
  403. package/dist/lib/config.test.js.map +1 -1
  404. package/dist/lib/differential-context.d.ts +46 -0
  405. package/dist/lib/differential-context.d.ts.map +1 -0
  406. package/dist/lib/differential-context.js +89 -0
  407. package/dist/lib/differential-context.js.map +1 -0
  408. package/dist/lib/resolve.d.ts +3 -0
  409. package/dist/lib/resolve.d.ts.map +1 -0
  410. package/dist/lib/resolve.js +29 -0
  411. package/dist/lib/resolve.js.map +1 -0
  412. package/dist/lib/structured-tool-io.d.ts +31 -0
  413. package/dist/lib/structured-tool-io.d.ts.map +1 -0
  414. package/dist/lib/structured-tool-io.js +56 -0
  415. package/dist/lib/structured-tool-io.js.map +1 -0
  416. package/dist/repl/__tests__/_queue_demo.test.d.ts +2 -0
  417. package/dist/repl/__tests__/_queue_demo.test.d.ts.map +1 -0
  418. package/dist/repl/__tests__/_queue_demo.test.js +40 -0
  419. package/dist/repl/__tests__/_queue_demo.test.js.map +1 -0
  420. package/dist/repl/__tests__/components.test.d.ts +2 -0
  421. package/dist/repl/__tests__/components.test.d.ts.map +1 -0
  422. package/dist/repl/__tests__/components.test.js +38 -0
  423. package/dist/repl/__tests__/components.test.js.map +1 -0
  424. package/dist/repl/__tests__/interactive.queue.test.d.ts +2 -0
  425. package/dist/repl/__tests__/interactive.queue.test.d.ts.map +1 -0
  426. package/dist/repl/__tests__/interactive.queue.test.js +124 -0
  427. package/dist/repl/__tests__/interactive.queue.test.js.map +1 -0
  428. package/dist/repl/components.d.ts +59 -0
  429. package/dist/repl/components.d.ts.map +1 -0
  430. package/dist/repl/components.js +152 -0
  431. package/dist/repl/components.js.map +1 -0
  432. package/dist/repl/interactive.d.ts +12 -0
  433. package/dist/repl/interactive.d.ts.map +1 -0
  434. package/dist/repl/interactive.js +326 -0
  435. package/dist/repl/interactive.js.map +1 -0
  436. package/dist/repl/one-shot.d.ts +9 -0
  437. package/dist/repl/one-shot.d.ts.map +1 -0
  438. package/dist/repl/one-shot.js +83 -0
  439. package/dist/repl/one-shot.js.map +1 -0
  440. package/dist/tui/__tests__/app.test.d.ts +2 -0
  441. package/dist/tui/__tests__/app.test.d.ts.map +1 -0
  442. package/dist/tui/__tests__/app.test.js +136 -0
  443. package/dist/tui/__tests__/app.test.js.map +1 -0
  444. package/dist/tui/__tests__/banner.test.d.ts +2 -0
  445. package/dist/tui/__tests__/banner.test.d.ts.map +1 -0
  446. package/dist/tui/__tests__/banner.test.js +15 -0
  447. package/dist/tui/__tests__/banner.test.js.map +1 -0
  448. package/dist/tui/__tests__/command-form.test.d.ts +2 -0
  449. package/dist/tui/__tests__/command-form.test.d.ts.map +1 -0
  450. package/dist/tui/__tests__/command-form.test.js +96 -0
  451. package/dist/tui/__tests__/command-form.test.js.map +1 -0
  452. package/dist/tui/__tests__/command-tree.test.d.ts +2 -0
  453. package/dist/tui/__tests__/command-tree.test.d.ts.map +1 -0
  454. package/dist/tui/__tests__/command-tree.test.js +55 -0
  455. package/dist/tui/__tests__/command-tree.test.js.map +1 -0
  456. package/dist/tui/__tests__/runner.test.d.ts +2 -0
  457. package/dist/tui/__tests__/runner.test.d.ts.map +1 -0
  458. package/dist/tui/__tests__/runner.test.js +38 -0
  459. package/dist/tui/__tests__/runner.test.js.map +1 -0
  460. package/dist/tui/__tests__/theme.test.d.ts +2 -0
  461. package/dist/tui/__tests__/theme.test.d.ts.map +1 -0
  462. package/dist/tui/__tests__/theme.test.js +11 -0
  463. package/dist/tui/__tests__/theme.test.js.map +1 -0
  464. package/dist/tui/agent-view/activity-feed.d.ts +3 -0
  465. package/dist/tui/agent-view/activity-feed.d.ts.map +1 -0
  466. package/dist/tui/agent-view/activity-feed.js +34 -0
  467. package/dist/tui/agent-view/activity-feed.js.map +1 -0
  468. package/dist/tui/agent-view/budget-bar.d.ts +3 -0
  469. package/dist/tui/agent-view/budget-bar.d.ts.map +1 -0
  470. package/dist/tui/agent-view/budget-bar.js +53 -0
  471. package/dist/tui/agent-view/budget-bar.js.map +1 -0
  472. package/dist/tui/agent-view/compile-panel.d.ts +3 -0
  473. package/dist/tui/agent-view/compile-panel.d.ts.map +1 -0
  474. package/dist/tui/agent-view/compile-panel.js +34 -0
  475. package/dist/tui/agent-view/compile-panel.js.map +1 -0
  476. package/dist/tui/agent-view/index.d.ts +4 -0
  477. package/dist/tui/agent-view/index.d.ts.map +1 -0
  478. package/dist/tui/agent-view/index.js +31 -0
  479. package/dist/tui/agent-view/index.js.map +1 -0
  480. package/dist/tui/agent-view/memory-panel.d.ts +3 -0
  481. package/dist/tui/agent-view/memory-panel.d.ts.map +1 -0
  482. package/dist/tui/agent-view/memory-panel.js +80 -0
  483. package/dist/tui/agent-view/memory-panel.js.map +1 -0
  484. package/dist/tui/agent-view/session-panel.d.ts +3 -0
  485. package/dist/tui/agent-view/session-panel.d.ts.map +1 -0
  486. package/dist/tui/agent-view/session-panel.js +44 -0
  487. package/dist/tui/agent-view/session-panel.js.map +1 -0
  488. package/dist/tui/agent-view/status-bar.d.ts +7 -0
  489. package/dist/tui/agent-view/status-bar.d.ts.map +1 -0
  490. package/dist/tui/agent-view/status-bar.js +22 -0
  491. package/dist/tui/agent-view/status-bar.js.map +1 -0
  492. package/dist/tui/app.d.ts +9 -0
  493. package/dist/tui/app.d.ts.map +1 -0
  494. package/dist/tui/app.js +115 -0
  495. package/dist/tui/app.js.map +1 -0
  496. package/dist/tui/banner.d.ts +5 -0
  497. package/dist/tui/banner.d.ts.map +1 -0
  498. package/dist/tui/banner.js +17 -0
  499. package/dist/tui/banner.js.map +1 -0
  500. package/dist/tui/command-form.d.ts +9 -0
  501. package/dist/tui/command-form.d.ts.map +1 -0
  502. package/dist/tui/command-form.js +76 -0
  503. package/dist/tui/command-form.js.map +1 -0
  504. package/dist/tui/command-tree.d.ts +30 -0
  505. package/dist/tui/command-tree.d.ts.map +1 -0
  506. package/dist/tui/command-tree.js +43 -0
  507. package/dist/tui/command-tree.js.map +1 -0
  508. package/dist/tui/fleet-view/agent-row.d.ts +10 -0
  509. package/dist/tui/fleet-view/agent-row.d.ts.map +1 -0
  510. package/dist/tui/fleet-view/agent-row.js +80 -0
  511. package/dist/tui/fleet-view/agent-row.js.map +1 -0
  512. package/dist/tui/fleet-view/dispatch-input.d.ts +5 -0
  513. package/dist/tui/fleet-view/dispatch-input.d.ts.map +1 -0
  514. package/dist/tui/fleet-view/dispatch-input.js +36 -0
  515. package/dist/tui/fleet-view/dispatch-input.js.map +1 -0
  516. package/dist/tui/fleet-view/fleet-app.d.ts +11 -0
  517. package/dist/tui/fleet-view/fleet-app.d.ts.map +1 -0
  518. package/dist/tui/fleet-view/fleet-app.js +95 -0
  519. package/dist/tui/fleet-view/fleet-app.js.map +1 -0
  520. package/dist/tui/fleet-view/fleet-summary.d.ts +6 -0
  521. package/dist/tui/fleet-view/fleet-summary.d.ts.map +1 -0
  522. package/dist/tui/fleet-view/fleet-summary.js +19 -0
  523. package/dist/tui/fleet-view/fleet-summary.js.map +1 -0
  524. package/dist/tui/fleet-view/index.d.ts +16 -0
  525. package/dist/tui/fleet-view/index.d.ts.map +1 -0
  526. package/dist/tui/fleet-view/index.js +61 -0
  527. package/dist/tui/fleet-view/index.js.map +1 -0
  528. package/dist/tui/runner.d.ts +7 -0
  529. package/dist/tui/runner.d.ts.map +1 -0
  530. package/dist/tui/runner.js +36 -0
  531. package/dist/tui/runner.js.map +1 -0
  532. package/dist/tui/theme.d.ts +8 -0
  533. package/dist/tui/theme.d.ts.map +1 -0
  534. package/dist/tui/theme.js +10 -0
  535. package/dist/tui/theme.js.map +1 -0
  536. package/package.json +12 -7
  537. package/README.html +0 -379
@@ -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,9 +71,9 @@ 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";
75
+ import { automationEnableCommand } from "./commands/automation.enable.js";
76
+ import { automationDisableCommand } from "./commands/automation.disable.js";
73
77
  import { automationTriggerCommand } from "./commands/automation.trigger.js";
74
78
  import { skillWorkspaceListCommand } from "./commands/skill.workspace.list.js";
75
79
  import { agentMemoryRecallCommand } from "./commands/agent.memory.recall.js";
@@ -92,20 +96,16 @@ import { agentTaskBackgroundReadCommand } from "./commands/agent.task.background
92
96
  import { agentTaskBackgroundCancelCommand } from "./commands/agent.task.background.cancel.js";
93
97
  import { assetUploadCommand } from "./commands/asset.upload.js";
94
98
  import { billingSubscriptionUpgradeStartCommand } from "./commands/billing.subscription.upgrade.start.js";
95
- import { brandkitApplyCommand } from "./commands/brandkit.apply.js";
96
99
  import { conversationPurgeCommand } from "./commands/conversation.purge.js";
97
100
  import { documentsPdfCreateCommand } from "./commands/documents.pdf.create.js";
98
101
  import { formFillCommand } from "./commands/form.fill.js";
99
102
  import { orgMemberInviteDeclineCommand } from "./commands/org.member.invite.decline.js";
100
103
  import { organizationCreateCommand } from "./commands/organization.create.js";
101
104
  import { pluginCredentialSetSecretCommand } from "./commands/plugin.credential.set_secret.js";
102
- import { pluginDenylistAddCommand } from "./commands/plugin.denylist.add.js";
103
- import { pluginDenylistRemoveCommand } from "./commands/plugin.denylist.remove.js";
104
105
  import { pluginOrgInstallBulkCommand } from "./commands/plugin.org.install_bulk.js";
105
106
  import { pluginOrgListCommand } from "./commands/plugin.org.list.js";
106
107
  import { pluginOrgSetEnabledCommand } from "./commands/plugin.org.set_enabled.js";
107
108
  import { pluginRegistryRemoveCommand } from "./commands/plugin.registry.remove.js";
108
- import { pluginRegistrySyncCommand } from "./commands/plugin.registry.sync.js";
109
109
  import { pluginSettingsSetAuthAlertsCommand } from "./commands/plugin.settings.set_auth_alerts.js";
110
110
  import { pluginWorkspaceSetEnabledCommand } from "./commands/plugin.workspace.set_enabled.js";
111
111
  import { systemInstallInstructionsCommand } from "./commands/system.install.instructions.js";
@@ -140,7 +140,9 @@ afterEach(() => {
140
140
  describe("auth login", () => {
141
141
  it("exits 1 if email or password is missing", async () => {
142
142
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
143
- 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
+ });
144
146
  await expect(() => authLoginCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
145
147
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("email and password are required"));
146
148
  consoleSpy.mockRestore();
@@ -148,8 +150,18 @@ describe("auth login", () => {
148
150
  });
149
151
  it("calls API with credentials and stores token", async () => {
150
152
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
151
- mockApiRequest.mockResolvedValueOnce({ token: "new-token", user: { email: "user@example.com" } });
152
- 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
+ ]);
153
165
  expect(mockApiRequest).toHaveBeenCalledWith("/auth/sign-in/email", expect.objectContaining({ method: "POST" }));
154
166
  expect(mockWriteConfig).toHaveBeenCalledWith(expect.objectContaining({ token: "new-token" }));
155
167
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Authenticated"));
@@ -157,9 +169,18 @@ describe("auth login", () => {
157
169
  });
158
170
  it("exits 1 on API error during login", async () => {
159
171
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
160
- 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
+ });
161
175
  mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
162
- 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");
163
184
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
164
185
  consoleSpy.mockRestore();
165
186
  exitSpy.mockRestore();
@@ -167,7 +188,14 @@ describe("auth login", () => {
167
188
  it("handles response with session.token shape", async () => {
168
189
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
169
190
  mockApiRequest.mockResolvedValueOnce({ session: { token: "session-tok" } });
170
- 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
+ ]);
171
199
  expect(mockWriteConfig).toHaveBeenCalledWith(expect.objectContaining({ token: "session-tok" }));
172
200
  consoleSpy.mockRestore();
173
201
  });
@@ -222,15 +250,22 @@ describe("auth whoami", () => {
222
250
  });
223
251
  it("falls back to config values for org/workspace", async () => {
224
252
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
225
- mockApiRequest.mockResolvedValueOnce({ user: { email: "mac@example.com" } });
226
- 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
+ });
227
260
  await authWhoamiCommand.parseAsync(["node", "cli"]);
228
261
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cfg-org"));
229
262
  consoleSpy.mockRestore();
230
263
  });
231
264
  it("exits 1 on API error", async () => {
232
265
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
233
- 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
+ });
234
269
  mockApiRequest.mockRejectedValueOnce(new Error("Forbidden"));
235
270
  await expect(() => authWhoamiCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
236
271
  consoleSpy.mockRestore();
@@ -260,7 +295,9 @@ describe("org list", () => {
260
295
  });
261
296
  it("handles data array shape from API", async () => {
262
297
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
263
- 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
+ });
264
301
  await orgListCommand.parseAsync(["node", "cli"]);
265
302
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("org-1"));
266
303
  consoleSpy.mockRestore();
@@ -272,7 +309,9 @@ describe("org list", () => {
272
309
  describe("org create", () => {
273
310
  it("creates org and prints slug", async () => {
274
311
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
275
- mockApiRequest.mockResolvedValueOnce({ organization: { slug: "new-org", name: "New Org" } });
312
+ mockApiRequest.mockResolvedValueOnce({
313
+ organization: { slug: "new-org", name: "New Org" },
314
+ });
276
315
  await orgCreateCommand.parseAsync(["node", "cli", "New Org"]);
277
316
  expect(mockApiRequest).toHaveBeenCalledWith("/organizations", expect.objectContaining({ method: "POST" }));
278
317
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("new-org"));
@@ -280,7 +319,9 @@ describe("org create", () => {
280
319
  });
281
320
  it("exits 1 on API error", async () => {
282
321
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
283
- 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
+ });
284
325
  mockApiRequest.mockRejectedValueOnce(new Error("Conflict"));
285
326
  await expect(() => orgCreateCommand.parseAsync(["node", "cli", "Dup"])).rejects.toThrow("exit");
286
327
  consoleSpy.mockRestore();
@@ -294,7 +335,13 @@ describe("org member add", () => {
294
335
  it("adds member and confirms", async () => {
295
336
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
296
337
  mockApiRequest.mockResolvedValueOnce({});
297
- 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
+ ]);
298
345
  expect(mockApiRequest).toHaveBeenCalledWith("/org/members", expect.objectContaining({ method: "POST" }));
299
346
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("new@example.com"));
300
347
  consoleSpy.mockRestore();
@@ -302,7 +349,13 @@ describe("org member add", () => {
302
349
  it("defaults role to member when no --role flag given", async () => {
303
350
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
304
351
  mockApiRequest.mockResolvedValueOnce({});
305
- 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
+ ]);
306
359
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("member"));
307
360
  consoleSpy.mockRestore();
308
361
  });
@@ -349,7 +402,9 @@ describe("workspace list", () => {
349
402
  describe("workspace create", () => {
350
403
  it("creates workspace and prints slug", async () => {
351
404
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
352
- mockApiRequest.mockResolvedValueOnce({ workspace: { slug: "my-ws", name: "My WS" } });
405
+ mockApiRequest.mockResolvedValueOnce({
406
+ workspace: { slug: "my-ws", name: "My WS" },
407
+ });
353
408
  await workspaceCreateCommand.parseAsync(["node", "cli", "My WS"]);
354
409
  expect(mockApiRequest).toHaveBeenCalledWith("/workspaces", expect.objectContaining({ method: "POST" }));
355
410
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("my-ws"));
@@ -365,7 +420,10 @@ function makeSseResponse(text) {
365
420
  const line = `data: ${JSON.stringify({ type: "text", text })}\n\nevent: done\ndata: [DONE]\n\n`;
366
421
  const encoder = new TextEncoder();
367
422
  const stream = new ReadableStream({
368
- start(c) { c.enqueue(encoder.encode(line)); c.close(); },
423
+ start(c) {
424
+ c.enqueue(encoder.encode(line));
425
+ c.close();
426
+ },
369
427
  });
370
428
  return new Response(stream, {
371
429
  status: 200,
@@ -379,9 +437,13 @@ function makeErrorResponse(status, message) {
379
437
  });
380
438
  }
381
439
  describe("chat send", () => {
382
- afterEach(() => { vi.restoreAllMocks(); });
440
+ afterEach(() => {
441
+ vi.restoreAllMocks();
442
+ });
383
443
  it("sends message and streams response to stdout", async () => {
384
- const stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
444
+ const stdoutSpy = vi
445
+ .spyOn(process.stdout, "write")
446
+ .mockImplementation(() => true);
385
447
  vi.spyOn(global, "fetch").mockResolvedValueOnce(makeSseResponse("Hello back!"));
386
448
  await chatSendCommand.parseAsync(["node", "cli", "hello"]);
387
449
  const written = stdoutSpy.mock.calls.map((c) => String(c[0])).join("");
@@ -389,19 +451,29 @@ describe("chat send", () => {
389
451
  stdoutSpy.mockRestore();
390
452
  });
391
453
  it("passes conversationId when --conversation is provided", async () => {
392
- const stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
454
+ const stdoutSpy = vi
455
+ .spyOn(process.stdout, "write")
456
+ .mockImplementation(() => true);
393
457
  let capturedBody = null;
394
458
  vi.spyOn(global, "fetch").mockImplementationOnce(async (_url, init) => {
395
459
  capturedBody = JSON.parse(init.body);
396
460
  return makeSseResponse("ok");
397
461
  });
398
- 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
+ ]);
399
469
  expect(capturedBody["conversationId"]).toBe("cnv_abc");
400
470
  stdoutSpy.mockRestore();
401
471
  });
402
472
  it("exits 1 when fetch throws a network error", async () => {
403
473
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
404
- 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
+ });
405
477
  vi.spyOn(global, "fetch").mockRejectedValueOnce(new Error("ECONNREFUSED"));
406
478
  await expect(() => chatSendCommand.parseAsync(["node", "cli", "msg"])).rejects.toThrow("exit");
407
479
  consoleSpy.mockRestore();
@@ -409,7 +481,9 @@ describe("chat send", () => {
409
481
  });
410
482
  it("exits 1 on non-ok HTTP response", async () => {
411
483
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
412
- 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
+ });
413
487
  vi.spyOn(global, "fetch").mockResolvedValueOnce(makeErrorResponse(503, "Service unavailable"));
414
488
  await expect(() => chatSendCommand.parseAsync(["node", "cli", "test"])).rejects.toThrow();
415
489
  consoleSpy.mockRestore();
@@ -440,7 +514,14 @@ describe("conversation list", () => {
440
514
  it("passes filter and limit params", async () => {
441
515
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
442
516
  mockApiRequest.mockResolvedValueOnce({ conversations: [] });
443
- 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
+ ]);
444
525
  expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("archived"));
445
526
  consoleSpy.mockRestore();
446
527
  });
@@ -456,7 +537,9 @@ describe("conversation delete", () => {
456
537
  });
457
538
  it("exits 1 on not found", async () => {
458
539
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
459
- 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
+ });
460
543
  mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
461
544
  await expect(() => conversationDeleteCommand.parseAsync(["node", "cli", "bad"])).rejects.toThrow("exit");
462
545
  consoleSpy.mockRestore();
@@ -475,7 +558,12 @@ describe("conversation archive", () => {
475
558
  it("unarchives when --unarchive flag is set", async () => {
476
559
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
477
560
  mockApiRequest.mockResolvedValueOnce({});
478
- await conversationArchiveCommand.parseAsync(["node", "cli", "cnv_abc", "--unarchive"]);
561
+ await conversationArchiveCommand.parseAsync([
562
+ "node",
563
+ "cli",
564
+ "cnv_abc",
565
+ "--unarchive",
566
+ ]);
479
567
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("unarchived"));
480
568
  consoleSpy.mockRestore();
481
569
  });
@@ -484,7 +572,12 @@ describe("conversation rename", () => {
484
572
  it("renames conversation", async () => {
485
573
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
486
574
  mockApiRequest.mockResolvedValueOnce({});
487
- await conversationRenameCommand.parseAsync(["node", "cli", "cnv_abc", "New Title"]);
575
+ await conversationRenameCommand.parseAsync([
576
+ "node",
577
+ "cli",
578
+ "cnv_abc",
579
+ "New Title",
580
+ ]);
488
581
  expect(mockApiRequest).toHaveBeenCalledWith("/conversations/cnv_abc/rename", expect.objectContaining({ method: "POST" }));
489
582
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("New Title"));
490
583
  consoleSpy.mockRestore();
@@ -496,7 +589,10 @@ describe("conversation rename", () => {
496
589
  describe("api-key create", () => {
497
590
  it("creates API key and displays secret", async () => {
498
591
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
499
- mockApiRequest.mockResolvedValueOnce({ id: "key_123", key: "oxk_abc123secret" });
592
+ mockApiRequest.mockResolvedValueOnce({
593
+ id: "key_123",
594
+ key: "oxk_abc123secret",
595
+ });
500
596
  const origIsTTY = process.stdout.isTTY;
501
597
  process.stdout.isTTY = true; // Simulate interactive TTY to show full secret
502
598
  await apiKeyCreateCommand.parseAsync(["node", "cli", "my-key"]);
@@ -508,7 +604,9 @@ describe("api-key create", () => {
508
604
  });
509
605
  it("exits 1 on API error", async () => {
510
606
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
511
- 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
+ });
512
610
  mockApiRequest.mockRejectedValueOnce(new Error("Quota exceeded"));
513
611
  await expect(() => apiKeyCreateCommand.parseAsync(["node", "cli", "key"])).rejects.toThrow("exit");
514
612
  consoleSpy.mockRestore();
@@ -534,7 +632,11 @@ describe("notifications list", () => {
534
632
  mockApiRequest.mockResolvedValueOnce({
535
633
  notifications: [
536
634
  { publicId: "ntf_1", title: "New member joined", readAt: null },
537
- { 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
+ },
538
640
  ],
539
641
  });
540
642
  await notificationsListCommand.parseAsync(["node", "cli"]);
@@ -569,7 +671,12 @@ describe("notifications mark", () => {
569
671
  it("marks notification as unread with --unread flag", async () => {
570
672
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
571
673
  mockApiRequest.mockResolvedValueOnce({});
572
- await notificationsMarkCommand.parseAsync(["node", "cli", "ntf_1", "--unread"]);
674
+ await notificationsMarkCommand.parseAsync([
675
+ "node",
676
+ "cli",
677
+ "ntf_1",
678
+ "--unread",
679
+ ]);
573
680
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("unread"));
574
681
  consoleSpy.mockRestore();
575
682
  });
@@ -581,7 +688,10 @@ describe("plugin list", () => {
581
688
  it("lists installed plugins", async () => {
582
689
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
583
690
  mockApiRequest.mockResolvedValueOnce({
584
- plugins: [{ pluginId: "github", enabled: true }, { pluginId: "slack", enabled: false }],
691
+ plugins: [
692
+ { pluginId: "github", enabled: true },
693
+ { pluginId: "slack", enabled: false },
694
+ ],
585
695
  });
586
696
  await pluginListCommand.parseAsync(["node", "cli"]);
587
697
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("github"));
@@ -607,7 +717,9 @@ describe("plugin install", () => {
607
717
  });
608
718
  it("exits 1 on install failure", async () => {
609
719
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
610
- 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
+ });
611
723
  mockApiRequest.mockRejectedValueOnce(new Error("Not found in catalog"));
612
724
  await expect(() => pluginInstallCommand.parseAsync(["node", "cli", "bad-plugin"])).rejects.toThrow("exit");
613
725
  consoleSpy.mockRestore();
@@ -653,7 +765,9 @@ describe("billing status", () => {
653
765
  });
654
766
  it("exits 1 on API error", async () => {
655
767
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
656
- 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
+ });
657
771
  mockApiRequest.mockRejectedValueOnce(new Error("Forbidden"));
658
772
  await expect(() => billingStatusCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
659
773
  consoleSpy.mockRestore();
@@ -682,7 +796,9 @@ describe("agent skill list", () => {
682
796
  it("lists agent skills successfully", async () => {
683
797
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
684
798
  mockApiRequest.mockResolvedValueOnce({
685
- skills: [{ id: "skill1", name: "memory", description: "Memory management" }],
799
+ skills: [
800
+ { id: "skill1", name: "memory", description: "Memory management" },
801
+ ],
686
802
  });
687
803
  await agentSkillListCommand.parseAsync(["node", "cli"]);
688
804
  expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/skill/list"), expect.objectContaining({ method: "GET" }));
@@ -697,7 +813,9 @@ describe("agent tool list", () => {
697
813
  it("lists agent tools successfully", async () => {
698
814
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
699
815
  mockApiRequest.mockResolvedValueOnce({
700
- tools: [{ id: "tool1", name: "search", description: "Search capability" }],
816
+ tools: [
817
+ { id: "tool1", name: "search", description: "Search capability" },
818
+ ],
701
819
  });
702
820
  await agentToolListCommand.parseAsync(["node", "cli"]);
703
821
  expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/tool/list"), expect.objectContaining({ method: "GET" }));
@@ -715,7 +833,12 @@ describe("billing credits purchase", () => {
715
833
  credits: 100,
716
834
  totalCost: 10,
717
835
  });
718
- await billingCreditsPurchaseCommand.parseAsync(["node", "cli", "-a", "100"]);
836
+ await billingCreditsPurchaseCommand.parseAsync([
837
+ "node",
838
+ "cli",
839
+ "-a",
840
+ "100",
841
+ ]);
719
842
  expect(mockApiRequest).toHaveBeenCalledWith("/billing/credits/purchase", expect.objectContaining({ method: "POST" }));
720
843
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Purchase initiated"));
721
844
  consoleSpy.mockRestore();
@@ -763,7 +886,12 @@ describe("plugin org uninstall", () => {
763
886
  id: "plugin1",
764
887
  status: "uninstalled",
765
888
  });
766
- await pluginOrgUninstallCommand.parseAsync(["node", "cli", "-p", "plugin1"]);
889
+ await pluginOrgUninstallCommand.parseAsync([
890
+ "node",
891
+ "cli",
892
+ "-p",
893
+ "plugin1",
894
+ ]);
767
895
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/uninstall", expect.objectContaining({ method: "POST" }));
768
896
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Plugin uninstalled"));
769
897
  consoleSpy.mockRestore();
@@ -776,7 +904,14 @@ describe("plugin catalog get", () => {
776
904
  it("browses plugin catalog", async () => {
777
905
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
778
906
  mockApiRequest.mockResolvedValueOnce({
779
- 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
+ ],
780
915
  });
781
916
  await pluginCatalogGetCommand.parseAsync(["node", "cli"]);
782
917
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/catalog/get?", expect.objectContaining({ method: "GET" }));
@@ -795,7 +930,14 @@ describe("org member role change", () => {
795
930
  role: "admin",
796
931
  updated: true,
797
932
  });
798
- 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
+ ]);
799
941
  expect(mockApiRequest).toHaveBeenCalledWith("/org/member/role-change", expect.objectContaining({ method: "POST" }));
800
942
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Role updated"));
801
943
  consoleSpy.mockRestore();
@@ -808,14 +950,30 @@ describe("agent approval resolve", () => {
808
950
  it("resolves approval with approve decision", async () => {
809
951
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
810
952
  mockApiRequest.mockResolvedValueOnce({ id: "apr1", status: "approved" });
811
- 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
+ ]);
812
961
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/approval/resolve", expect.objectContaining({ method: "POST" }));
813
962
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("approved"));
814
963
  consoleSpy.mockRestore();
815
964
  });
816
965
  it("rejects invalid decision", async () => {
817
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
818
- 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();
819
977
  exitSpy.mockRestore();
820
978
  });
821
979
  });
@@ -825,8 +983,19 @@ describe("agent approval resolve", () => {
825
983
  describe("archive create", () => {
826
984
  it("creates archive from conversation", async () => {
827
985
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
828
- mockApiRequest.mockResolvedValueOnce({ id: "arc1", name: "Archive 1", status: "created" });
829
- 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
+ ]);
830
999
  expect(mockApiRequest).toHaveBeenCalledWith("/archive/create", expect.objectContaining({ method: "POST" }));
831
1000
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Archive created"));
832
1001
  consoleSpy.mockRestore();
@@ -839,7 +1008,14 @@ describe("workflow run", () => {
839
1008
  it("runs workflow with input", async () => {
840
1009
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
841
1010
  mockApiRequest.mockResolvedValueOnce({ id: "run1", status: "started" });
842
- 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
+ ]);
843
1019
  expect(mockApiRequest).toHaveBeenCalledWith("/workflow/run", expect.objectContaining({ method: "POST" }));
844
1020
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("started"));
845
1021
  consoleSpy.mockRestore();
@@ -862,7 +1038,12 @@ describe("user preferences update", () => {
862
1038
  it("updates user preferences", async () => {
863
1039
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
864
1040
  mockApiRequest.mockResolvedValueOnce({ theme: "light" });
865
- await userPreferencesUpdateCommand.parseAsync(["node", "cli", "-t", "light"]);
1041
+ await userPreferencesUpdateCommand.parseAsync([
1042
+ "node",
1043
+ "cli",
1044
+ "-t",
1045
+ "light",
1046
+ ]);
866
1047
  expect(mockApiRequest).toHaveBeenCalledWith("/user/preferences/update", expect.objectContaining({ method: "POST" }));
867
1048
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("light"));
868
1049
  consoleSpy.mockRestore();
@@ -874,7 +1055,14 @@ describe("user preferences update", () => {
874
1055
  describe("workspace member list", () => {
875
1056
  it("lists workspace members", async () => {
876
1057
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
877
- 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
+ ]);
878
1066
  await workspaceMemberListCommand.parseAsync(["node", "cli"]);
879
1067
  expect(mockApiRequest).toHaveBeenCalled();
880
1068
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("member(s)"));
@@ -885,7 +1073,12 @@ describe("workspace invite send", () => {
885
1073
  it("sends workspace invitation", async () => {
886
1074
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
887
1075
  mockApiRequest.mockResolvedValueOnce({ id: "inv1", status: "sent" });
888
- await workspaceInviteSendCommand.parseAsync(["node", "cli", "-e", "user@example.com"]);
1076
+ await workspaceInviteSendCommand.parseAsync([
1077
+ "node",
1078
+ "cli",
1079
+ "-e",
1080
+ "user@example.com",
1081
+ ]);
889
1082
  expect(mockApiRequest).toHaveBeenCalledWith("/workspace/invite/send", expect.objectContaining({ method: "POST" }));
890
1083
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Invitation sent"));
891
1084
  consoleSpy.mockRestore();
@@ -897,8 +1090,18 @@ describe("workspace invite send", () => {
897
1090
  describe("conversation chat", () => {
898
1091
  it("sends chat message", async () => {
899
1092
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
900
- mockApiRequest.mockResolvedValueOnce({ id: "msg1", created_at: "2026-06-08T00:00:00Z" });
901
- 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
+ ]);
902
1105
  expect(mockApiRequest).toHaveBeenCalledWith("/conversation/chat", expect.objectContaining({ method: "POST" }));
903
1106
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Message sent"));
904
1107
  consoleSpy.mockRestore();
@@ -910,7 +1113,10 @@ describe("conversation chat", () => {
910
1113
  describe("image create", () => {
911
1114
  it("creates image from prompt", async () => {
912
1115
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
913
- mockApiRequest.mockResolvedValueOnce({ id: "img1", url: "https://example.com/img1.jpg" });
1116
+ mockApiRequest.mockResolvedValueOnce({
1117
+ id: "img1",
1118
+ url: "https://example.com/img1.jpg",
1119
+ });
914
1120
  await imageCreateCommand.parseAsync(["node", "cli", "-p", "A blue sky"]);
915
1121
  expect(mockApiRequest).toHaveBeenCalledWith("/image/create", expect.objectContaining({ method: "POST" }));
916
1122
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Image created"));
@@ -920,7 +1126,16 @@ describe("image create", () => {
920
1126
  describe("image list", () => {
921
1127
  it("lists images", async () => {
922
1128
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
923
- 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
+ });
924
1139
  await imageListCommand.parseAsync(["node", "cli"]);
925
1140
  expect(mockApiRequest).toHaveBeenCalled();
926
1141
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Images"));
@@ -930,7 +1145,10 @@ describe("image list", () => {
930
1145
  describe("image analyze", () => {
931
1146
  it("analyzes image", async () => {
932
1147
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
933
- mockApiRequest.mockResolvedValueOnce({ analysis: "sky", tags: ["nature", "outdoor"] });
1148
+ mockApiRequest.mockResolvedValueOnce({
1149
+ analysis: "sky",
1150
+ tags: ["nature", "outdoor"],
1151
+ });
934
1152
  await imageAnalyzeCommand.parseAsync(["node", "cli", "-i", "img1"]);
935
1153
  expect(mockApiRequest).toHaveBeenCalledWith("/image/analyze", expect.objectContaining({ method: "POST" }));
936
1154
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Analysis"));
@@ -953,7 +1171,17 @@ describe("document create", () => {
953
1171
  describe("document list", () => {
954
1172
  it("lists documents", async () => {
955
1173
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
956
- 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
+ });
957
1185
  await documentListCommand.parseAsync(["node", "cli"]);
958
1186
  expect(mockApiRequest).toHaveBeenCalled();
959
1187
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Documents"));
@@ -963,7 +1191,12 @@ describe("document list", () => {
963
1191
  describe("document read", () => {
964
1192
  it("reads document", async () => {
965
1193
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
966
- 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
+ });
967
1200
  await documentReadCommand.parseAsync(["node", "cli", "-d", "doc1"]);
968
1201
  expect(mockApiRequest).toHaveBeenCalled();
969
1202
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Title:"));
@@ -971,35 +1204,14 @@ describe("document read", () => {
971
1204
  });
972
1205
  });
973
1206
  // ---------------------------------------------------------------------------
974
- // form management
975
- // ---------------------------------------------------------------------------
976
- describe("form create", () => {
977
- it("creates form", async () => {
978
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
979
- mockApiRequest.mockResolvedValueOnce({ id: "form1", title: "Survey" });
980
- await formCreateCommand.parseAsync(["node", "cli", "-t", "Survey"]);
981
- expect(mockApiRequest).toHaveBeenCalledWith("/form/create", expect.objectContaining({ method: "POST" }));
982
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Form created"));
983
- consoleSpy.mockRestore();
984
- });
985
- });
986
- describe("form submit", () => {
987
- it("submits form", async () => {
988
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
989
- mockApiRequest.mockResolvedValueOnce({ id: "sub1", status: "submitted" });
990
- await formSubmitCommand.parseAsync(["node", "cli", "-f", "form1"]);
991
- expect(mockApiRequest).toHaveBeenCalledWith("/form/submit", expect.objectContaining({ method: "POST" }));
992
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("submitted"));
993
- consoleSpy.mockRestore();
994
- });
995
- });
996
- // ---------------------------------------------------------------------------
997
1207
  // automation management
998
1208
  // ---------------------------------------------------------------------------
999
1209
  describe("automation list", () => {
1000
1210
  it("lists automations", async () => {
1001
1211
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1002
- 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
+ ]);
1003
1215
  await automationListCommand.parseAsync(["node", "cli"]);
1004
1216
  expect(mockApiRequest).toHaveBeenCalled();
1005
1217
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("automation(s)"));
@@ -1007,14 +1219,138 @@ describe("automation list", () => {
1007
1219
  });
1008
1220
  });
1009
1221
  describe("automation create", () => {
1010
- it("creates automation", async () => {
1222
+ it("creates automation with the contract payload shape", async () => {
1011
1223
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1012
- mockApiRequest.mockResolvedValueOnce({ id: "auto1", name: "My Automation" });
1013
- await automationCreateCommand.parseAsync(["node", "cli", "-n", "My Automation"]);
1224
+ mockApiRequest.mockResolvedValueOnce({
1225
+ automation_id: "plt_1",
1226
+ playbook_id: "plb_1",
1227
+ name: "My Automation",
1228
+ status: "inactive",
1229
+ triggerType: "api",
1230
+ enabled: false,
1231
+ });
1232
+ await automationCreateCommand.parseAsync([
1233
+ "node",
1234
+ "cli",
1235
+ "-n",
1236
+ "My Automation",
1237
+ ]);
1014
1238
  expect(mockApiRequest).toHaveBeenCalledWith("/automation/create", expect.objectContaining({ method: "POST" }));
1239
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1240
+ expect(body).toMatchObject({
1241
+ name: "My Automation",
1242
+ triggerType: "api",
1243
+ triggerConfig: {},
1244
+ steps: [],
1245
+ enabled: false,
1246
+ });
1015
1247
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation created"));
1016
1248
  consoleSpy.mockRestore();
1017
1249
  });
1250
+ it("builds event triggerConfig from --entity-type/--event-type/--conditions and passes --enabled", async () => {
1251
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1252
+ mockApiRequest.mockResolvedValueOnce({
1253
+ automation_id: "plt_2",
1254
+ playbook_id: "plb_2",
1255
+ name: "Watcher",
1256
+ status: "active",
1257
+ triggerType: "event",
1258
+ enabled: true,
1259
+ });
1260
+ await automationCreateCommand.parseAsync([
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"}]',
1273
+ "--enabled",
1274
+ ]);
1275
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1276
+ expect(body).toMatchObject({
1277
+ name: "Watcher",
1278
+ triggerType: "event",
1279
+ triggerConfig: {
1280
+ entityType: "Contact",
1281
+ eventType: "node.updated",
1282
+ propertyConditions: [
1283
+ { property: "status", toValue: "customer", operator: "eq" },
1284
+ ],
1285
+ },
1286
+ enabled: true,
1287
+ });
1288
+ consoleSpy.mockRestore();
1289
+ });
1290
+ it("builds schedule triggerConfig from --cron/--timezone", async () => {
1291
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1292
+ mockApiRequest.mockResolvedValueOnce({
1293
+ automation_id: "plt_3",
1294
+ playbook_id: "plb_3",
1295
+ name: "Report",
1296
+ status: "inactive",
1297
+ triggerType: "schedule",
1298
+ enabled: false,
1299
+ });
1300
+ await automationCreateCommand.parseAsync([
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",
1311
+ ]);
1312
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1313
+ expect(body).toMatchObject({
1314
+ triggerType: "schedule",
1315
+ triggerConfig: {
1316
+ cronExpression: "0 9 * * 1",
1317
+ timezone: "America/New_York",
1318
+ },
1319
+ });
1320
+ consoleSpy.mockRestore();
1321
+ });
1322
+ });
1323
+ describe("automation enable", () => {
1324
+ it("enables automation", async () => {
1325
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1326
+ mockApiRequest.mockResolvedValueOnce({
1327
+ automation_id: "plt_1",
1328
+ enabled: true,
1329
+ status: "active",
1330
+ });
1331
+ await automationEnableCommand.parseAsync(["node", "cli", "plt_1"]);
1332
+ expect(mockApiRequest).toHaveBeenCalledWith("/automation/enable", expect.objectContaining({ method: "POST" }));
1333
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1334
+ expect(body).toEqual({ automation_id: "plt_1" });
1335
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation enabled"));
1336
+ consoleSpy.mockRestore();
1337
+ });
1338
+ });
1339
+ describe("automation disable", () => {
1340
+ it("disables automation", async () => {
1341
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1342
+ mockApiRequest.mockResolvedValueOnce({
1343
+ automation_id: "plt_1",
1344
+ enabled: false,
1345
+ status: "paused",
1346
+ });
1347
+ await automationDisableCommand.parseAsync(["node", "cli", "plt_1"]);
1348
+ expect(mockApiRequest).toHaveBeenCalledWith("/automation/disable", expect.objectContaining({ method: "POST" }));
1349
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1350
+ expect(body).toEqual({ automation_id: "plt_1" });
1351
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation disabled"));
1352
+ consoleSpy.mockRestore();
1353
+ });
1018
1354
  });
1019
1355
  describe("automation trigger", () => {
1020
1356
  it("triggers automation", async () => {
@@ -1032,7 +1368,16 @@ describe("automation trigger", () => {
1032
1368
  describe("skill workspace list", () => {
1033
1369
  it("lists workspace skills", async () => {
1034
1370
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1035
- 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
+ });
1036
1381
  await skillWorkspaceListCommand.parseAsync(["node", "cli"]);
1037
1382
  expect(mockApiRequest).toHaveBeenCalled();
1038
1383
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Workspace skills"));
@@ -1045,18 +1390,40 @@ describe("skill workspace list", () => {
1045
1390
  describe("agent memory recall", () => {
1046
1391
  it("recalls memory observations", async () => {
1047
1392
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1048
- 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
+ };
1049
1398
  mockApiRequest.mockResolvedValueOnce(mockResult);
1050
- 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
+ ]);
1051
1407
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/memory/recall", expect.objectContaining({ method: "POST" }));
1052
1408
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("obs1"));
1053
1409
  consoleSpy.mockRestore();
1054
1410
  });
1055
1411
  it("handles recall failure", async () => {
1056
1412
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1057
- 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
+ });
1058
1418
  mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1059
- 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();
1060
1427
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to recall"), expect.any(Error));
1061
1428
  consoleSpy.mockRestore();
1062
1429
  exitSpy.mockRestore();
@@ -1067,7 +1434,14 @@ describe("agent memory write", () => {
1067
1434
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1068
1435
  const mockResult = { id: "obs2", status: "stored" };
1069
1436
  mockApiRequest.mockResolvedValueOnce(mockResult);
1070
- 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
+ ]);
1071
1445
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/memory/write", expect.objectContaining({ method: "POST" }));
1072
1446
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("obs2"));
1073
1447
  consoleSpy.mockRestore();
@@ -1075,16 +1449,36 @@ describe("agent memory write", () => {
1075
1449
  it("writes a memory observation with tags", async () => {
1076
1450
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1077
1451
  mockApiRequest.mockResolvedValueOnce({ id: "obs3", status: "stored" });
1078
- 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
+ ]);
1079
1462
  const callBody = JSON.parse(mockApiRequest.mock.calls[0][1].body);
1080
1463
  expect(callBody.tags).toEqual(["ui", "preferences"]);
1081
1464
  consoleSpy.mockRestore();
1082
1465
  });
1083
1466
  it("handles write failure", async () => {
1084
1467
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1085
- 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
+ });
1086
1473
  mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1087
- 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();
1088
1482
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to write"), expect.any(Error));
1089
1483
  consoleSpy.mockRestore();
1090
1484
  exitSpy.mockRestore();
@@ -1096,26 +1490,59 @@ describe("agent memory write", () => {
1096
1490
  describe("documents generate", () => {
1097
1491
  it("generates a document from template", async () => {
1098
1492
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1099
- 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
+ };
1100
1498
  mockApiRequest.mockResolvedValueOnce(mockResult);
1101
- 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
+ ]);
1102
1507
  expect(mockApiRequest).toHaveBeenCalledWith("/documents/generate", expect.objectContaining({ method: "POST" }));
1103
1508
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("doc1"));
1104
1509
  consoleSpy.mockRestore();
1105
1510
  });
1106
1511
  it("fails on invalid JSON context", async () => {
1107
1512
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1108
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1109
- 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();
1110
1526
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Invalid JSON"), expect.anything());
1111
1527
  consoleSpy.mockRestore();
1112
1528
  exitSpy.mockRestore();
1113
1529
  });
1114
1530
  it("handles generate failure", async () => {
1115
1531
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1116
- 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
+ });
1117
1537
  mockApiRequest.mockRejectedValueOnce(new Error("Template not found"));
1118
- 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();
1119
1546
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
1120
1547
  consoleSpy.mockRestore();
1121
1548
  exitSpy.mockRestore();
@@ -1129,14 +1556,23 @@ describe("image generate", () => {
1129
1556
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1130
1557
  const mockResult = { url: "https://example.com/img.png", id: "img1" };
1131
1558
  mockApiRequest.mockResolvedValueOnce(mockResult);
1132
- 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
+ ]);
1133
1565
  expect(mockApiRequest).toHaveBeenCalledWith("/image/generate", expect.objectContaining({ method: "POST" }));
1134
1566
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("img1"));
1135
1567
  consoleSpy.mockRestore();
1136
1568
  });
1137
1569
  it("handles generate failure", async () => {
1138
1570
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1139
- 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
+ });
1140
1576
  mockApiRequest.mockRejectedValueOnce(new Error("Model not found"));
1141
1577
  await expect(imageGenerateCommand.parseAsync(["node", "cli", "-p", "a cat"])).rejects.toThrow();
1142
1578
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
@@ -1150,15 +1586,27 @@ describe("image generate", () => {
1150
1586
  describe("org member invite accept", () => {
1151
1587
  it("accepts an invitation", async () => {
1152
1588
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1153
- mockApiRequest.mockResolvedValueOnce({ status: "accepted", orgSlug: "my-org" });
1154
- 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
+ ]);
1155
1599
  expect(mockApiRequest).toHaveBeenCalledWith("/org/member/invite/accept", expect.objectContaining({ method: "POST" }));
1156
1600
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("accepted"));
1157
1601
  consoleSpy.mockRestore();
1158
1602
  });
1159
1603
  it("handles accept failure", async () => {
1160
1604
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1161
- 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
+ });
1162
1610
  mockApiRequest.mockRejectedValueOnce(new Error("Invitation expired"));
1163
1611
  await expect(orgMemberInviteAcceptCommand.parseAsync(["node", "cli", "-i", "inv1"])).rejects.toThrow();
1164
1612
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to accept"), expect.any(Error));
@@ -1172,7 +1620,10 @@ describe("org member invite accept", () => {
1172
1620
  describe("plugin catalog browse", () => {
1173
1621
  it("browses the plugin catalog", async () => {
1174
1622
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1175
- 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
+ };
1176
1627
  mockApiRequest.mockResolvedValueOnce(mockResult);
1177
1628
  await pluginCatalogBrowseCommand.parseAsync(["node", "cli"]);
1178
1629
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/catalog/browse", expect.objectContaining({ method: "GET" }));
@@ -1181,7 +1632,11 @@ describe("plugin catalog browse", () => {
1181
1632
  });
1182
1633
  it("handles browse failure", async () => {
1183
1634
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1184
- 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
+ });
1185
1640
  mockApiRequest.mockRejectedValueOnce(new Error("Service unavailable"));
1186
1641
  await expect(pluginCatalogBrowseCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1187
1642
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to browse"), expect.any(Error));
@@ -1195,15 +1650,27 @@ describe("plugin catalog browse", () => {
1195
1650
  describe("plugin credential reauth", () => {
1196
1651
  it("re-authenticates plugin credentials", async () => {
1197
1652
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1198
- mockApiRequest.mockResolvedValueOnce({ status: "reauthenticated", pluginId: "slack" });
1199
- 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
+ ]);
1200
1663
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/credential/reauth", expect.objectContaining({ method: "POST" }));
1201
1664
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("reauthenticated"));
1202
1665
  consoleSpy.mockRestore();
1203
1666
  });
1204
1667
  it("handles reauth failure", async () => {
1205
1668
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1206
- 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
+ });
1207
1674
  mockApiRequest.mockRejectedValueOnce(new Error("OAuth error"));
1208
1675
  await expect(pluginCredentialReauthCommand.parseAsync(["node", "cli", "-p", "slack"])).rejects.toThrow();
1209
1676
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to re-authenticate"), expect.any(Error));
@@ -1217,7 +1684,11 @@ describe("plugin credential reauth", () => {
1217
1684
  describe("plugin registry list", () => {
1218
1685
  it("lists plugin registries", async () => {
1219
1686
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1220
- 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
+ });
1221
1692
  await pluginRegistryListCommand.parseAsync(["node", "cli"]);
1222
1693
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/list", expect.objectContaining({ method: "GET" }));
1223
1694
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Official"));
@@ -1225,7 +1696,11 @@ describe("plugin registry list", () => {
1225
1696
  });
1226
1697
  it("handles list failure", async () => {
1227
1698
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1228
- 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
+ });
1229
1704
  mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1230
1705
  await expect(pluginRegistryListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1231
1706
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to list"), expect.any(Error));
@@ -1236,17 +1711,39 @@ describe("plugin registry list", () => {
1236
1711
  describe("plugin registry add", () => {
1237
1712
  it("adds a plugin registry", async () => {
1238
1713
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1239
- mockApiRequest.mockResolvedValueOnce({ id: "reg2", name: "Private", url: "https://private.example.com" });
1240
- 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
+ ]);
1241
1727
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/add", expect.objectContaining({ method: "POST" }));
1242
1728
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("reg2"));
1243
1729
  consoleSpy.mockRestore();
1244
1730
  });
1245
1731
  it("handles add failure", async () => {
1246
1732
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1247
- 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
+ });
1248
1738
  mockApiRequest.mockRejectedValueOnce(new Error("Registry already exists"));
1249
- 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();
1250
1747
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to add"), expect.any(Error));
1251
1748
  consoleSpy.mockRestore();
1252
1749
  exitSpy.mockRestore();
@@ -1266,7 +1763,11 @@ describe("svg generate", () => {
1266
1763
  });
1267
1764
  it("handles generate failure", async () => {
1268
1765
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1269
- 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
+ });
1270
1771
  mockApiRequest.mockRejectedValueOnce(new Error("Generation failed"));
1271
1772
  await expect(svgGenerateCommand.parseAsync(["node", "cli", "-d", "circle"])).rejects.toThrow();
1272
1773
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
@@ -1280,15 +1781,28 @@ describe("svg generate", () => {
1280
1781
  describe("video generate", () => {
1281
1782
  it("generates a video", async () => {
1282
1783
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1283
- mockApiRequest.mockResolvedValueOnce({ id: "vid1", status: "processing", url: null });
1284
- 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
+ ]);
1285
1795
  expect(mockApiRequest).toHaveBeenCalledWith("/video/generate", expect.objectContaining({ method: "POST" }));
1286
1796
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("vid1"));
1287
1797
  consoleSpy.mockRestore();
1288
1798
  });
1289
1799
  it("handles generate failure", async () => {
1290
1800
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1291
- 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
+ });
1292
1806
  mockApiRequest.mockRejectedValueOnce(new Error("Model not available"));
1293
1807
  await expect(videoGenerateCommand.parseAsync(["node", "cli", "-p", "a cat"])).rejects.toThrow();
1294
1808
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
@@ -1302,7 +1816,10 @@ describe("video generate", () => {
1302
1816
  describe("workspace model settings read", () => {
1303
1817
  it("reads workspace model settings", async () => {
1304
1818
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1305
- mockApiRequest.mockResolvedValueOnce({ defaultModel: "claude-haiku-4-5-20251001", maxTokens: 4096 });
1819
+ mockApiRequest.mockResolvedValueOnce({
1820
+ defaultModel: "claude-haiku-4-5-20251001",
1821
+ maxTokens: 4096,
1822
+ });
1306
1823
  await workspaceModelSettingsReadCommand.parseAsync(["node", "cli"]);
1307
1824
  expect(mockApiRequest).toHaveBeenCalledWith("/workspace/model-settings/read", expect.objectContaining({ method: "POST" }));
1308
1825
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("defaultModel"));
@@ -1310,7 +1827,11 @@ describe("workspace model settings read", () => {
1310
1827
  });
1311
1828
  it("handles read failure", async () => {
1312
1829
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1313
- 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
+ });
1314
1835
  mockApiRequest.mockRejectedValueOnce(new Error("Workspace not found"));
1315
1836
  await expect(workspaceModelSettingsReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1316
1837
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to read"), expect.any(Error));
@@ -1321,17 +1842,39 @@ describe("workspace model settings read", () => {
1321
1842
  describe("workspace model settings write", () => {
1322
1843
  it("writes workspace model settings", async () => {
1323
1844
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1324
- mockApiRequest.mockResolvedValueOnce({ success: true, key: "defaultModel", value: "claude-sonnet-4-6" });
1325
- 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
+ ]);
1326
1858
  expect(mockApiRequest).toHaveBeenCalledWith("/workspace/model-settings/write", expect.objectContaining({ method: "POST" }));
1327
1859
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("defaultModel"));
1328
1860
  consoleSpy.mockRestore();
1329
1861
  });
1330
1862
  it("handles write failure", async () => {
1331
1863
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1332
- 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
+ });
1333
1869
  mockApiRequest.mockRejectedValueOnce(new Error("Invalid setting key"));
1334
- 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();
1335
1878
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to write"), expect.any(Error));
1336
1879
  consoleSpy.mockRestore();
1337
1880
  exitSpy.mockRestore();
@@ -1343,17 +1886,43 @@ describe("workspace model settings write", () => {
1343
1886
  describe("agent mcp register", () => {
1344
1887
  it("registers an MCP server", async () => {
1345
1888
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1346
- mockApiRequest.mockResolvedValueOnce({ mcpServerId: "mcp1", healthStatus: "healthy", discoveredTools: ["tool1", "tool2"] });
1347
- 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
+ ]);
1348
1904
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/mcp/register", expect.objectContaining({ method: "POST" }));
1349
1905
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("mcp1"));
1350
1906
  consoleSpy.mockRestore();
1351
1907
  });
1352
1908
  it("handles registration failure", async () => {
1353
1909
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1354
- 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
+ });
1355
1915
  mockApiRequest.mockRejectedValueOnce(new Error("Bad URL"));
1356
- 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();
1357
1926
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
1358
1927
  consoleSpy.mockRestore();
1359
1928
  exitSpy.mockRestore();
@@ -1365,17 +1934,38 @@ describe("agent mcp register", () => {
1365
1934
  describe("agent plan approve", () => {
1366
1935
  it("approves a plan", async () => {
1367
1936
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1368
- mockApiRequest.mockResolvedValueOnce({ planId: "plan1", status: "approved" });
1369
- 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
+ ]);
1370
1949
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/plan/approve", expect.objectContaining({ method: "POST" }));
1371
1950
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("approved"));
1372
1951
  consoleSpy.mockRestore();
1373
1952
  });
1374
1953
  it("handles approval failure", async () => {
1375
1954
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1376
- 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
+ });
1377
1960
  mockApiRequest.mockRejectedValueOnce(new Error("Plan not found"));
1378
- 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();
1379
1969
  consoleSpy.mockRestore();
1380
1970
  exitSpy.mockRestore();
1381
1971
  });
@@ -1386,17 +1976,38 @@ describe("agent plan approve", () => {
1386
1976
  describe("agent task background start", () => {
1387
1977
  it("starts a background task", async () => {
1388
1978
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1389
- mockApiRequest.mockResolvedValueOnce({ taskId: "task1", inngestRunId: "run1" });
1390
- 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
+ ]);
1391
1991
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/task/background/start", expect.objectContaining({ method: "POST" }));
1392
1992
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("task1"));
1393
1993
  consoleSpy.mockRestore();
1394
1994
  });
1395
1995
  it("handles start failure", async () => {
1396
1996
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1397
- 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
+ });
1398
2002
  mockApiRequest.mockRejectedValueOnce(new Error("Queue full"));
1399
- 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();
1400
2011
  consoleSpy.mockRestore();
1401
2012
  exitSpy.mockRestore();
1402
2013
  });
@@ -1404,15 +2015,34 @@ describe("agent task background start", () => {
1404
2015
  describe("agent task background read", () => {
1405
2016
  it("reads task status", async () => {
1406
2017
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1407
- 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" });
1408
- 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
+ ]);
1409
2035
  expect(mockApiRequest).toHaveBeenCalled();
1410
2036
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("completed"));
1411
2037
  consoleSpy.mockRestore();
1412
2038
  });
1413
2039
  it("handles read failure", async () => {
1414
2040
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1415
- 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
+ });
1416
2046
  mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
1417
2047
  await expect(agentTaskBackgroundReadCommand.parseAsync(["node", "cli", "-t", "t1"])).rejects.toThrow();
1418
2048
  consoleSpy.mockRestore();
@@ -1423,7 +2053,12 @@ describe("agent task background cancel", () => {
1423
2053
  it("cancels a background task", async () => {
1424
2054
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1425
2055
  mockApiRequest.mockResolvedValueOnce({ cancelled: true });
1426
- await agentTaskBackgroundCancelCommand.parseAsync(["node", "cli", "-t", "task1"]);
2056
+ await agentTaskBackgroundCancelCommand.parseAsync([
2057
+ "node",
2058
+ "cli",
2059
+ "-t",
2060
+ "task1",
2061
+ ]);
1427
2062
  expect(mockApiRequest).toHaveBeenCalledWith("/agent/task/background/cancel", expect.objectContaining({ method: "POST" }));
1428
2063
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cancelled"));
1429
2064
  consoleSpy.mockRestore();
@@ -1431,13 +2066,22 @@ describe("agent task background cancel", () => {
1431
2066
  it("reports task could not be cancelled", async () => {
1432
2067
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1433
2068
  mockApiRequest.mockResolvedValueOnce({ cancelled: false });
1434
- await agentTaskBackgroundCancelCommand.parseAsync(["node", "cli", "-t", "task1"]);
2069
+ await agentTaskBackgroundCancelCommand.parseAsync([
2070
+ "node",
2071
+ "cli",
2072
+ "-t",
2073
+ "task1",
2074
+ ]);
1435
2075
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("could not be cancelled"));
1436
2076
  consoleSpy.mockRestore();
1437
2077
  });
1438
2078
  it("handles cancel failure", async () => {
1439
2079
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1440
- 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
+ });
1441
2085
  mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
1442
2086
  await expect(agentTaskBackgroundCancelCommand.parseAsync(["node", "cli", "-t", "t1"])).rejects.toThrow();
1443
2087
  consoleSpy.mockRestore();
@@ -1450,17 +2094,40 @@ describe("agent task background cancel", () => {
1450
2094
  describe("asset upload", () => {
1451
2095
  it("uploads an asset", async () => {
1452
2096
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1453
- mockApiRequest.mockResolvedValueOnce({ url: "https://cdn.example.com/img.png", key: "img/abc.png", contentType: "image/png", bytes: 12345 });
1454
- 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
+ ]);
1455
2111
  expect(mockApiRequest).toHaveBeenCalledWith("/asset/upload", expect.objectContaining({ method: "POST" }));
1456
2112
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Asset uploaded"));
1457
2113
  consoleSpy.mockRestore();
1458
2114
  });
1459
2115
  it("handles upload failure", async () => {
1460
2116
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1461
- 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
+ });
1462
2122
  mockApiRequest.mockRejectedValueOnce(new Error("Source URL unreachable"));
1463
- 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();
1464
2131
  consoleSpy.mockRestore();
1465
2132
  exitSpy.mockRestore();
1466
2133
  });
@@ -1471,38 +2138,47 @@ describe("asset upload", () => {
1471
2138
  describe("billing subscription upgrade start", () => {
1472
2139
  it("starts a checkout session", async () => {
1473
2140
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1474
- mockApiRequest.mockResolvedValueOnce({ checkoutUrl: "https://checkout.stripe.com/pay/cs_test_123", planSlug: "scale", interval: "month" });
1475
- 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
+ ]);
1476
2158
  expect(mockApiRequest).toHaveBeenCalledWith("/billing/subscription/upgrade/start", expect.objectContaining({ method: "POST" }));
1477
2159
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Checkout session created"));
1478
2160
  consoleSpy.mockRestore();
1479
2161
  });
1480
2162
  it("handles upgrade failure", async () => {
1481
2163
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1482
- 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
+ });
1483
2169
  mockApiRequest.mockRejectedValueOnce(new Error("Stripe error"));
1484
- await expect(billingSubscriptionUpgradeStartCommand.parseAsync(["node", "cli", "-p", "scale", "-i", "month", "--success-url", "https://a.com/ok", "--cancel-url", "https://a.com/cancel"])).rejects.toThrow();
1485
- consoleSpy.mockRestore();
1486
- exitSpy.mockRestore();
1487
- });
1488
- });
1489
- // ---------------------------------------------------------------------------
1490
- // brandkit apply
1491
- // ---------------------------------------------------------------------------
1492
- describe("brandkit apply", () => {
1493
- it("applies a brand kit", async () => {
1494
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1495
- mockApiRequest.mockResolvedValueOnce({ stub: true, applied: false, brandKitId: "bk1", targetFileId: "file1" });
1496
- await brandkitApplyCommand.parseAsync(["node", "cli", "-b", "bk1", "-f", "file1", "-w", "ws1"]);
1497
- expect(mockApiRequest).toHaveBeenCalledWith("/brandkit/apply", expect.objectContaining({ method: "POST" }));
1498
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("stub"));
1499
- consoleSpy.mockRestore();
1500
- });
1501
- it("handles apply failure", async () => {
1502
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1503
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1504
- mockApiRequest.mockRejectedValueOnce(new Error("Brand kit not found"));
1505
- 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();
1506
2182
  consoleSpy.mockRestore();
1507
2183
  exitSpy.mockRestore();
1508
2184
  });
@@ -1514,14 +2190,24 @@ describe("conversation purge", () => {
1514
2190
  it("purges archived conversations with --yes", async () => {
1515
2191
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1516
2192
  mockApiRequest.mockResolvedValueOnce({ deleted: 5 });
1517
- await conversationPurgeCommand.parseAsync(["node", "cli", "-w", "ws1", "--yes"]);
2193
+ await conversationPurgeCommand.parseAsync([
2194
+ "node",
2195
+ "cli",
2196
+ "-w",
2197
+ "ws1",
2198
+ "--yes",
2199
+ ]);
1518
2200
  expect(mockApiRequest).toHaveBeenCalledWith("/conversation/purge", expect.objectContaining({ method: "POST" }));
1519
2201
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Purged 5"));
1520
2202
  consoleSpy.mockRestore();
1521
2203
  });
1522
2204
  it("exits without --yes", async () => {
1523
2205
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1524
- 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
+ });
1525
2211
  await expect(conversationPurgeCommand.parseAsync(["node", "cli", "-w", "ws1"])).rejects.toThrow();
1526
2212
  expect(consoleSpy).toHaveBeenCalled();
1527
2213
  consoleSpy.mockRestore();
@@ -1529,9 +2215,19 @@ describe("conversation purge", () => {
1529
2215
  });
1530
2216
  it("handles purge failure", async () => {
1531
2217
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1532
- 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
+ });
1533
2223
  mockApiRequest.mockRejectedValueOnce(new Error("Workspace not found"));
1534
- 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();
1535
2231
  consoleSpy.mockRestore();
1536
2232
  exitSpy.mockRestore();
1537
2233
  });
@@ -1542,15 +2238,32 @@ describe("conversation purge", () => {
1542
2238
  describe("documents pdf create", () => {
1543
2239
  it("creates a PDF document", async () => {
1544
2240
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1545
- 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" });
1546
- 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
+ ]);
1547
2256
  expect(mockApiRequest).toHaveBeenCalledWith("/documents/pdf/create", expect.objectContaining({ method: "POST" }));
1548
2257
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("PDF created"));
1549
2258
  consoleSpy.mockRestore();
1550
2259
  });
1551
2260
  it("handles pdf create failure", async () => {
1552
2261
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1553
- 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
+ });
1554
2267
  mockApiRequest.mockRejectedValueOnce(new Error("Generation failed"));
1555
2268
  await expect(documentsPdfCreateCommand.parseAsync(["node", "cli", "-t", "Report"])).rejects.toThrow();
1556
2269
  consoleSpy.mockRestore();
@@ -1563,18 +2276,50 @@ describe("documents pdf create", () => {
1563
2276
  describe("form fill", () => {
1564
2277
  it("fills form fields", async () => {
1565
2278
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1566
- 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
+ ];
1567
2290
  mockApiRequest.mockResolvedValueOnce({ fields });
1568
- 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
+ ]);
1569
2301
  expect(mockApiRequest).toHaveBeenCalledWith("/form/fill", expect.objectContaining({ method: "POST" }));
1570
2302
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Form fill suggestion"));
1571
2303
  consoleSpy.mockRestore();
1572
2304
  });
1573
2305
  it("handles form fill failure", async () => {
1574
2306
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1575
- 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
+ });
1576
2312
  mockApiRequest.mockRejectedValueOnce(new Error("LLM error"));
1577
- 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();
1578
2323
  consoleSpy.mockRestore();
1579
2324
  exitSpy.mockRestore();
1580
2325
  });
@@ -1585,15 +2330,27 @@ describe("form fill", () => {
1585
2330
  describe("org member invite decline", () => {
1586
2331
  it("declines an invitation", async () => {
1587
2332
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1588
- mockApiRequest.mockResolvedValueOnce({ invitationPublicId: "inv1", status: "declined" });
1589
- 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
+ ]);
1590
2343
  expect(mockApiRequest).toHaveBeenCalledWith("/org/member/invite/decline", expect.objectContaining({ method: "POST" }));
1591
2344
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("declined"));
1592
2345
  consoleSpy.mockRestore();
1593
2346
  });
1594
2347
  it("handles decline failure", async () => {
1595
2348
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1596
- 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
+ });
1597
2354
  mockApiRequest.mockRejectedValueOnce(new Error("Invitation not found"));
1598
2355
  await expect(orgMemberInviteDeclineCommand.parseAsync(["node", "cli", "-i", "inv1"])).rejects.toThrow();
1599
2356
  consoleSpy.mockRestore();
@@ -1606,17 +2363,41 @@ describe("org member invite decline", () => {
1606
2363
  describe("organization create", () => {
1607
2364
  it("creates an organization", async () => {
1608
2365
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1609
- mockApiRequest.mockResolvedValueOnce({ publicId: "org1", name: "Acme Corp", slug: "acme-corp", type: "business", createdAt: "2026-06-08" });
1610
- 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
+ ]);
1611
2381
  expect(mockApiRequest).toHaveBeenCalledWith("/organization/create", expect.objectContaining({ method: "POST" }));
1612
2382
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Organization created"));
1613
2383
  consoleSpy.mockRestore();
1614
2384
  });
1615
2385
  it("handles create failure", async () => {
1616
2386
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1617
- 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
+ });
1618
2392
  mockApiRequest.mockRejectedValueOnce(new Error("Slug already taken"));
1619
- 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();
1620
2401
  consoleSpy.mockRestore();
1621
2402
  exitSpy.mockRestore();
1622
2403
  });
@@ -1628,55 +2409,36 @@ describe("plugin credential set_secret", () => {
1628
2409
  it("stores a credential", async () => {
1629
2410
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1630
2411
  mockApiRequest.mockResolvedValueOnce({ ok: true });
1631
- 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
+ ]);
1632
2422
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/credential/set_secret", expect.objectContaining({ method: "POST" }));
1633
2423
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Credential stored"));
1634
2424
  consoleSpy.mockRestore();
1635
2425
  });
1636
2426
  it("handles credential failure", async () => {
1637
2427
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1638
- 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
+ });
1639
2433
  mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
1640
- await expect(pluginCredentialSetSecretCommand.parseAsync(["node", "cli", "-l", "l1", "-a", "secret"])).rejects.toThrow();
1641
- consoleSpy.mockRestore();
1642
- exitSpy.mockRestore();
1643
- });
1644
- });
1645
- // ---------------------------------------------------------------------------
1646
- // plugin denylist
1647
- // ---------------------------------------------------------------------------
1648
- describe("plugin denylist add", () => {
1649
- it("adds a server to the denylist", async () => {
1650
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1651
- mockApiRequest.mockResolvedValueOnce({ ok: true });
1652
- await pluginDenylistAddCommand.parseAsync(["node", "cli", "-s", "bad-server"]);
1653
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/denylist/add", expect.objectContaining({ method: "POST" }));
1654
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("bad-server"));
1655
- consoleSpy.mockRestore();
1656
- });
1657
- it("handles denylist add failure", async () => {
1658
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1659
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1660
- mockApiRequest.mockRejectedValueOnce(new Error("Server not found"));
1661
- await expect(pluginDenylistAddCommand.parseAsync(["node", "cli", "-s", "srv"])).rejects.toThrow();
1662
- consoleSpy.mockRestore();
1663
- exitSpy.mockRestore();
1664
- });
1665
- });
1666
- describe("plugin denylist remove", () => {
1667
- it("removes a server from the denylist", async () => {
1668
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1669
- mockApiRequest.mockResolvedValueOnce({ ok: true });
1670
- await pluginDenylistRemoveCommand.parseAsync(["node", "cli", "-s", "bad-server"]);
1671
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/denylist/remove", expect.objectContaining({ method: "POST" }));
1672
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("bad-server"));
1673
- consoleSpy.mockRestore();
1674
- });
1675
- it("handles denylist remove failure", async () => {
1676
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1677
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1678
- mockApiRequest.mockRejectedValueOnce(new Error("Entry not found"));
1679
- await expect(pluginDenylistRemoveCommand.parseAsync(["node", "cli", "-s", "srv"])).rejects.toThrow();
2434
+ await expect(pluginCredentialSetSecretCommand.parseAsync([
2435
+ "node",
2436
+ "cli",
2437
+ "-l",
2438
+ "l1",
2439
+ "-a",
2440
+ "secret",
2441
+ ])).rejects.toThrow();
1680
2442
  consoleSpy.mockRestore();
1681
2443
  exitSpy.mockRestore();
1682
2444
  });
@@ -1687,22 +2449,41 @@ describe("plugin denylist remove", () => {
1687
2449
  describe("plugin org install bulk", () => {
1688
2450
  it("bulk installs plugins", async () => {
1689
2451
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1690
- mockApiRequest.mockResolvedValueOnce({ installed: [{ catalogServerId: "srv1", orgListingId: "listing1", error: null }] });
1691
- 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
+ ]);
1692
2461
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/install_bulk", expect.objectContaining({ method: "POST" }));
1693
2462
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("1 succeeded"));
1694
2463
  consoleSpy.mockRestore();
1695
2464
  });
1696
2465
  it("reports partial failures", async () => {
1697
2466
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1698
- mockApiRequest.mockResolvedValueOnce({ installed: [{ catalogServerId: "srv1", orgListingId: null, error: "Not found" }] });
1699
- 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
+ ]);
1700
2476
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("0 succeeded, 1 failed"));
2477
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("srv1: Not found"));
1701
2478
  consoleSpy.mockRestore();
1702
2479
  });
1703
2480
  it("handles bulk install failure", async () => {
1704
2481
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1705
- 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
+ });
1706
2487
  mockApiRequest.mockRejectedValueOnce(new Error("Bad request"));
1707
2488
  await expect(pluginOrgInstallBulkCommand.parseAsync(["node", "cli", "--items", "[]"])).rejects.toThrow();
1708
2489
  consoleSpy.mockRestore();
@@ -1716,7 +2497,15 @@ describe("plugin org list", () => {
1716
2497
  it("lists org plugins", async () => {
1717
2498
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1718
2499
  mockApiRequest.mockResolvedValueOnce({
1719
- 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
+ ],
1720
2509
  denylist: [],
1721
2510
  });
1722
2511
  await pluginOrgListCommand.parseAsync(["node", "cli"]);
@@ -1728,7 +2517,14 @@ describe("plugin org list", () => {
1728
2517
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1729
2518
  mockApiRequest.mockResolvedValueOnce({
1730
2519
  listings: [],
1731
- 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
+ ],
1732
2528
  });
1733
2529
  await pluginOrgListCommand.parseAsync(["node", "cli"]);
1734
2530
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Denylist"));
@@ -1736,7 +2532,11 @@ describe("plugin org list", () => {
1736
2532
  });
1737
2533
  it("handles list failure", async () => {
1738
2534
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1739
- 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
+ });
1740
2540
  mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
1741
2541
  await expect(pluginOrgListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1742
2542
  consoleSpy.mockRestore();
@@ -1750,7 +2550,14 @@ describe("plugin org set_enabled", () => {
1750
2550
  it("enables a plugin listing", async () => {
1751
2551
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1752
2552
  mockApiRequest.mockResolvedValueOnce({ ok: true });
1753
- 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
+ ]);
1754
2561
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/set_enabled", expect.objectContaining({ method: "POST" }));
1755
2562
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("enabled"));
1756
2563
  consoleSpy.mockRestore();
@@ -1758,15 +2565,33 @@ describe("plugin org set_enabled", () => {
1758
2565
  it("disables a plugin listing", async () => {
1759
2566
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1760
2567
  mockApiRequest.mockResolvedValueOnce({ ok: true });
1761
- 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
+ ]);
1762
2576
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("disabled"));
1763
2577
  consoleSpy.mockRestore();
1764
2578
  });
1765
2579
  it("handles set_enabled failure", async () => {
1766
2580
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1767
- 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
+ });
1768
2586
  mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
1769
- 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();
1770
2595
  consoleSpy.mockRestore();
1771
2596
  exitSpy.mockRestore();
1772
2597
  });
@@ -1785,7 +2610,11 @@ describe("plugin registry remove", () => {
1785
2610
  });
1786
2611
  it("handles remove failure", async () => {
1787
2612
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1788
- 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
+ });
1789
2618
  mockApiRequest.mockRejectedValueOnce(new Error("Registry is global default"));
1790
2619
  await expect(pluginRegistryRemoveCommand.parseAsync(["node", "cli", "-r", "r1"])).rejects.toThrow();
1791
2620
  consoleSpy.mockRestore();
@@ -1793,42 +2622,18 @@ describe("plugin registry remove", () => {
1793
2622
  });
1794
2623
  });
1795
2624
  // ---------------------------------------------------------------------------
1796
- // plugin registry sync
1797
- // ---------------------------------------------------------------------------
1798
- describe("plugin registry sync", () => {
1799
- it("triggers a registry sync", async () => {
1800
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1801
- mockApiRequest.mockResolvedValueOnce({ accepted: true });
1802
- await pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"]);
1803
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/sync", expect.objectContaining({ method: "POST" }));
1804
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Sync accepted"));
1805
- consoleSpy.mockRestore();
1806
- });
1807
- it("reports sync not accepted", async () => {
1808
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1809
- mockApiRequest.mockResolvedValueOnce({ accepted: false });
1810
- await pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"]);
1811
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("not accepted"));
1812
- consoleSpy.mockRestore();
1813
- });
1814
- it("handles sync failure", async () => {
1815
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1816
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1817
- mockApiRequest.mockRejectedValueOnce(new Error("Registry not found"));
1818
- await expect(pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"])).rejects.toThrow();
1819
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
1820
- consoleSpy.mockRestore();
1821
- exitSpy.mockRestore();
1822
- });
1823
- });
1824
- // ---------------------------------------------------------------------------
1825
2625
  // plugin settings set_auth_alerts
1826
2626
  // ---------------------------------------------------------------------------
1827
2627
  describe("plugin settings set_auth_alerts", () => {
1828
2628
  it("updates auth alert settings", async () => {
1829
2629
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1830
2630
  mockApiRequest.mockResolvedValueOnce({ ok: true });
1831
- await pluginSettingsSetAuthAlertsCommand.parseAsync(["node", "cli", "--roles", "Owner,Admin"]);
2631
+ await pluginSettingsSetAuthAlertsCommand.parseAsync([
2632
+ "node",
2633
+ "cli",
2634
+ "--roles",
2635
+ "Owner,Admin",
2636
+ ]);
1832
2637
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/settings/set_auth_alerts", expect.objectContaining({ method: "POST" }));
1833
2638
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("updated"));
1834
2639
  consoleSpy.mockRestore();
@@ -1836,15 +2641,29 @@ describe("plugin settings set_auth_alerts", () => {
1836
2641
  it("reports update failed when ok=false", async () => {
1837
2642
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1838
2643
  mockApiRequest.mockResolvedValueOnce({ ok: false });
1839
- await pluginSettingsSetAuthAlertsCommand.parseAsync(["node", "cli", "--roles", "Owner"]);
2644
+ await pluginSettingsSetAuthAlertsCommand.parseAsync([
2645
+ "node",
2646
+ "cli",
2647
+ "--roles",
2648
+ "Owner",
2649
+ ]);
1840
2650
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Update failed"));
1841
2651
  consoleSpy.mockRestore();
1842
2652
  });
1843
2653
  it("handles failure", async () => {
1844
2654
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1845
- 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
+ });
1846
2660
  mockApiRequest.mockRejectedValueOnce(new Error("Permission denied"));
1847
- 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();
1848
2667
  consoleSpy.mockRestore();
1849
2668
  exitSpy.mockRestore();
1850
2669
  });
@@ -1856,7 +2675,14 @@ describe("plugin workspace set_enabled", () => {
1856
2675
  it("enables a plugin for workspace", async () => {
1857
2676
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1858
2677
  mockApiRequest.mockResolvedValueOnce({ workspaceServerId: "wsrv1" });
1859
- 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
+ ]);
1860
2686
  expect(mockApiRequest).toHaveBeenCalledWith("/plugin/workspace/set_enabled", expect.objectContaining({ method: "POST" }));
1861
2687
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("enabled"));
1862
2688
  consoleSpy.mockRestore();
@@ -1864,15 +2690,33 @@ describe("plugin workspace set_enabled", () => {
1864
2690
  it("disables a plugin for workspace (no server ID)", async () => {
1865
2691
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1866
2692
  mockApiRequest.mockResolvedValueOnce({ workspaceServerId: null });
1867
- 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
+ ]);
1868
2701
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("disabled"));
1869
2702
  consoleSpy.mockRestore();
1870
2703
  });
1871
2704
  it("handles failure", async () => {
1872
2705
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1873
- 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
+ });
1874
2711
  mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
1875
- 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();
1876
2720
  consoleSpy.mockRestore();
1877
2721
  exitSpy.mockRestore();
1878
2722
  });
@@ -1890,16 +2734,30 @@ describe("system install instructions", () => {
1890
2734
  { label: "Authenticate", command: "oxagen auth login" },
1891
2735
  ],
1892
2736
  });
1893
- await systemInstallInstructionsCommand.parseAsync(["node", "cli", "-c", "claude-code"]);
2737
+ await systemInstallInstructionsCommand.parseAsync([
2738
+ "node",
2739
+ "cli",
2740
+ "-c",
2741
+ "claude-code",
2742
+ ]);
1894
2743
  expect(mockApiRequest).toHaveBeenCalled();
1895
2744
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("claude-code"));
1896
2745
  consoleSpy.mockRestore();
1897
2746
  });
1898
2747
  it("handles fetch failure", async () => {
1899
2748
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1900
- 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
+ });
1901
2754
  mockApiRequest.mockRejectedValueOnce(new Error("Unknown client"));
1902
- 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();
1903
2761
  consoleSpy.mockRestore();
1904
2762
  exitSpy.mockRestore();
1905
2763
  });
@@ -1943,7 +2801,11 @@ describe("user preferences read", () => {
1943
2801
  });
1944
2802
  it("handles read failure", async () => {
1945
2803
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1946
- 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
+ });
1947
2809
  mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
1948
2810
  await expect(userPreferencesReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1949
2811
  consoleSpy.mockRestore();
@@ -1963,16 +2825,30 @@ describe("user preferences write", () => {
1963
2825
  defaultImageModel: null,
1964
2826
  defaultVideoModel: null,
1965
2827
  });
1966
- await userPreferencesWriteCommand.parseAsync(["node", "cli", "--font-size", "large"]);
2828
+ await userPreferencesWriteCommand.parseAsync([
2829
+ "node",
2830
+ "cli",
2831
+ "--font-size",
2832
+ "large",
2833
+ ]);
1967
2834
  expect(mockApiRequest).toHaveBeenCalledWith("/user/preferences/write", expect.objectContaining({ method: "POST" }));
1968
2835
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("updated"));
1969
2836
  consoleSpy.mockRestore();
1970
2837
  });
1971
2838
  it("handles write failure", async () => {
1972
2839
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1973
- 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
+ });
1974
2845
  mockApiRequest.mockRejectedValueOnce(new Error("Validation failed"));
1975
- 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();
1976
2852
  consoleSpy.mockRestore();
1977
2853
  exitSpy.mockRestore();
1978
2854
  });
@@ -1998,7 +2874,11 @@ describe("workflow cancel", () => {
1998
2874
  });
1999
2875
  it("handles cancel failure", async () => {
2000
2876
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2001
- 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
+ });
2002
2882
  mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
2003
2883
  await expect(workflowCancelCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
2004
2884
  consoleSpy.mockRestore();
@@ -2009,7 +2889,15 @@ describe("workflow status", () => {
2009
2889
  it("shows workflow status and tasks", async () => {
2010
2890
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2011
2891
  mockApiRequest.mockResolvedValueOnce({
2012
- 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
+ },
2013
2901
  tasks: [
2014
2902
  { id: "t1", title: "Gather data", status: "completed" },
2015
2903
  { id: "t2", title: "Analyze data", status: "running" },
@@ -2022,7 +2910,11 @@ describe("workflow status", () => {
2022
2910
  });
2023
2911
  it("handles status fetch failure", async () => {
2024
2912
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2025
- 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
+ });
2026
2918
  mockApiRequest.mockRejectedValueOnce(new Error("Workflow not found"));
2027
2919
  await expect(workflowStatusCommand.parseAsync(["node", "cli", "-w", "wfr_xyz"])).rejects.toThrow();
2028
2920
  consoleSpy.mockRestore();
@@ -2037,7 +2929,11 @@ describe("workflow status", () => {
2037
2929
  describe("branch coverage: ApiError error paths", () => {
2038
2930
  it("automation list returns ApiError message", async () => {
2039
2931
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2040
- 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
+ });
2041
2937
  mockApiError(403, "Forbidden");
2042
2938
  await expect(automationListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2043
2939
  expect(consoleSpy).toHaveBeenCalledWith("Error: Forbidden");
@@ -2046,16 +2942,50 @@ describe("branch coverage: ApiError error paths", () => {
2046
2942
  });
2047
2943
  it("automation create returns ApiError message", async () => {
2048
2944
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2049
- 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
+ });
2050
2950
  mockApiError(400, "Name required");
2051
2951
  await expect(automationCreateCommand.parseAsync(["node", "cli", "-n", "A"])).rejects.toThrow();
2052
2952
  expect(consoleSpy).toHaveBeenCalledWith("Error: Name required");
2053
2953
  consoleSpy.mockRestore();
2054
2954
  exitSpy.mockRestore();
2055
2955
  });
2956
+ it("automation enable returns ApiError message", async () => {
2957
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2958
+ const exitSpy = vi
2959
+ .spyOn(process, "exit")
2960
+ .mockImplementation((_code) => {
2961
+ throw new Error("exit");
2962
+ });
2963
+ mockApiError(404, "Automation not found");
2964
+ await expect(automationEnableCommand.parseAsync(["node", "cli", "plt_missing"])).rejects.toThrow();
2965
+ expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
2966
+ consoleSpy.mockRestore();
2967
+ exitSpy.mockRestore();
2968
+ });
2969
+ it("automation disable returns ApiError message", async () => {
2970
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2971
+ const exitSpy = vi
2972
+ .spyOn(process, "exit")
2973
+ .mockImplementation((_code) => {
2974
+ throw new Error("exit");
2975
+ });
2976
+ mockApiError(404, "Automation not found");
2977
+ await expect(automationDisableCommand.parseAsync(["node", "cli", "plt_missing"])).rejects.toThrow();
2978
+ expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
2979
+ consoleSpy.mockRestore();
2980
+ exitSpy.mockRestore();
2981
+ });
2056
2982
  it("automation trigger returns ApiError message", async () => {
2057
2983
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2058
- 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
+ });
2059
2989
  mockApiError(404, "Automation not found");
2060
2990
  await expect(automationTriggerCommand.parseAsync(["node", "cli", "-a", "a1"])).rejects.toThrow();
2061
2991
  expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
@@ -2064,7 +2994,11 @@ describe("branch coverage: ApiError error paths", () => {
2064
2994
  });
2065
2995
  it("billing credits purchase returns ApiError message", async () => {
2066
2996
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2067
- 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
+ });
2068
3002
  mockApiError(402, "Payment failed");
2069
3003
  await expect(billingCreditsPurchaseCommand.parseAsync(["node", "cli", "-a", "10"])).rejects.toThrow();
2070
3004
  expect(consoleSpy).toHaveBeenCalledWith("Error: Payment failed");
@@ -2073,7 +3007,11 @@ describe("branch coverage: ApiError error paths", () => {
2073
3007
  });
2074
3008
  it("billing subscription read returns ApiError message", async () => {
2075
3009
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2076
- 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
+ });
2077
3015
  mockApiError(404, "Subscription not found");
2078
3016
  await expect(billingSubscriptionReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2079
3017
  expect(consoleSpy).toHaveBeenCalledWith("Error: Subscription not found");
@@ -2082,7 +3020,11 @@ describe("branch coverage: ApiError error paths", () => {
2082
3020
  });
2083
3021
  it("document list returns ApiError message", async () => {
2084
3022
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2085
- 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
+ });
2086
3028
  mockApiError(403, "Access denied");
2087
3029
  await expect(documentListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2088
3030
  expect(consoleSpy).toHaveBeenCalledWith("Error: Access denied");
@@ -2091,7 +3033,11 @@ describe("branch coverage: ApiError error paths", () => {
2091
3033
  });
2092
3034
  it("workspace member list returns ApiError message", async () => {
2093
3035
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2094
- 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
+ });
2095
3041
  mockApiError(403, "Not a member");
2096
3042
  await expect(workspaceMemberListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2097
3043
  expect(consoleSpy).toHaveBeenCalledWith("Error: Not a member");
@@ -2100,7 +3046,11 @@ describe("branch coverage: ApiError error paths", () => {
2100
3046
  });
2101
3047
  it("workflow cancel returns ApiError message", async () => {
2102
3048
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2103
- 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
+ });
2104
3054
  mockApiError(404, "Workflow not found");
2105
3055
  await expect(workflowCancelCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
2106
3056
  expect(consoleSpy).toHaveBeenCalledWith("Error: Workflow not found");
@@ -2109,7 +3059,11 @@ describe("branch coverage: ApiError error paths", () => {
2109
3059
  });
2110
3060
  it("workflow status returns ApiError message", async () => {
2111
3061
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2112
- 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
+ });
2113
3067
  mockApiError(404, "Run expired");
2114
3068
  await expect(workflowStatusCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
2115
3069
  expect(consoleSpy).toHaveBeenCalledWith("Error: Run expired");
@@ -2118,7 +3072,11 @@ describe("branch coverage: ApiError error paths", () => {
2118
3072
  });
2119
3073
  it("user preferences read returns ApiError message", async () => {
2120
3074
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2121
- 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
+ });
2122
3080
  mockApiError(401, "Unauthorized");
2123
3081
  await expect(userPreferencesReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2124
3082
  expect(consoleSpy).toHaveBeenCalledWith("Error: Unauthorized");
@@ -2127,9 +3085,18 @@ describe("branch coverage: ApiError error paths", () => {
2127
3085
  });
2128
3086
  it("user preferences write returns ApiError message", async () => {
2129
3087
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2130
- 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
+ });
2131
3093
  mockApiError(400, "Invalid font size");
2132
- 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();
2133
3100
  expect(consoleSpy).toHaveBeenCalledWith("Error: Invalid font size");
2134
3101
  consoleSpy.mockRestore();
2135
3102
  exitSpy.mockRestore();
@@ -2145,27 +3112,40 @@ describe("branch coverage: empty/optional data branches", () => {
2145
3112
  });
2146
3113
  it("automation list with workspace option", async () => {
2147
3114
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2148
- mockApiRequest.mockResolvedValueOnce([{ id: "a1", name: "Test", status: "active", triggers: [] }]);
3115
+ mockApiRequest.mockResolvedValueOnce([
3116
+ { id: "a1", name: "Test", status: "active", triggers: [] },
3117
+ ]);
2149
3118
  await automationListCommand.parseAsync(["node", "cli", "-w", "ws1"]);
2150
3119
  expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("workspace_id=ws1"), expect.anything());
2151
3120
  consoleSpy.mockRestore();
2152
3121
  });
2153
3122
  it("automation list shows 'none' when triggers are empty", async () => {
2154
3123
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2155
- mockApiRequest.mockResolvedValueOnce([{ id: "a1", name: "Untriggered", status: "active", triggers: [] }]);
3124
+ mockApiRequest.mockResolvedValueOnce([
3125
+ { id: "a1", name: "Untriggered", status: "active", triggers: [] },
3126
+ ]);
2156
3127
  await automationListCommand.parseAsync(["node", "cli"]);
2157
3128
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("triggers=none"));
2158
3129
  consoleSpy.mockRestore();
2159
3130
  });
2160
3131
  it("image create with save-to option", async () => {
2161
3132
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2162
- 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
+ });
2163
3139
  await imageCreateCommand.parseAsync(["node", "cli", "-p", "A cat"]);
2164
3140
  consoleSpy.mockRestore();
2165
3141
  });
2166
3142
  it("conversation chat ApiError path", async () => {
2167
3143
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2168
- 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
+ });
2169
3149
  mockApiError(401, "Not authenticated");
2170
3150
  await expect(conversationChatCommand.parseAsync(["node", "cli", "-m", "Hello"])).rejects.toThrow();
2171
3151
  expect(consoleSpy).toHaveBeenCalledWith("Error: Not authenticated");
@@ -2174,7 +3154,11 @@ describe("branch coverage: empty/optional data branches", () => {
2174
3154
  });
2175
3155
  it("workspace list ApiError path", async () => {
2176
3156
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2177
- 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
+ });
2178
3162
  mockApiError(403, "Org not found");
2179
3163
  await expect(workspaceListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2180
3164
  expect(consoleSpy).toHaveBeenCalledWith("Error: Org not found");
@@ -2183,7 +3167,11 @@ describe("branch coverage: empty/optional data branches", () => {
2183
3167
  });
2184
3168
  it("org list ApiError path", async () => {
2185
3169
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2186
- 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
+ });
2187
3175
  mockApiError(401, "Token expired");
2188
3176
  await expect(orgListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2189
3177
  expect(consoleSpy).toHaveBeenCalledWith("Error: Token expired");
@@ -2192,7 +3180,11 @@ describe("branch coverage: empty/optional data branches", () => {
2192
3180
  });
2193
3181
  it("api-key create ApiError path", async () => {
2194
3182
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2195
- 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
+ });
2196
3188
  mockApiError(429, "Rate limit exceeded");
2197
3189
  await expect(apiKeyCreateCommand.parseAsync(["node", "cli", "mykey"])).rejects.toThrow();
2198
3190
  expect(consoleSpy).toHaveBeenCalledWith("Error: Rate limit exceeded");
@@ -2201,7 +3193,11 @@ describe("branch coverage: empty/optional data branches", () => {
2201
3193
  });
2202
3194
  it("plugin list ApiError path", async () => {
2203
3195
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2204
- 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
+ });
2205
3201
  mockApiError(403, "Permission denied");
2206
3202
  await expect(pluginListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2207
3203
  expect(consoleSpy).toHaveBeenCalledWith("Error: Permission denied");
@@ -2210,7 +3206,11 @@ describe("branch coverage: empty/optional data branches", () => {
2210
3206
  });
2211
3207
  it("billing status ApiError path", async () => {
2212
3208
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2213
- 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
+ });
2214
3214
  mockApiError(402, "Billing error");
2215
3215
  await expect(billingStatusCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2216
3216
  expect(consoleSpy).toHaveBeenCalledWith("Error: Billing error");
@@ -2219,7 +3219,11 @@ describe("branch coverage: empty/optional data branches", () => {
2219
3219
  });
2220
3220
  it("chat send ApiError path", async () => {
2221
3221
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2222
- 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
+ });
2223
3227
  // chat.send uses native fetch (not apiRequest); mock fetch directly.
2224
3228
  vi.spyOn(global, "fetch").mockResolvedValueOnce(new Response(JSON.stringify({ error: "Service unavailable" }), {
2225
3229
  status: 503,
@@ -2231,7 +3235,11 @@ describe("branch coverage: empty/optional data branches", () => {
2231
3235
  });
2232
3236
  it("document read ApiError path", async () => {
2233
3237
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2234
- 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
+ });
2235
3243
  mockApiError(404, "Document not found");
2236
3244
  await expect(documentReadCommand.parseAsync(["node", "cli", "-d", "doc1"])).rejects.toThrow();
2237
3245
  expect(consoleSpy).toHaveBeenCalledWith("Error: Document not found");
@@ -2246,7 +3254,11 @@ describe("branch coverage: empty/optional data branches", () => {
2246
3254
  });
2247
3255
  it("workflow run ApiError path", async () => {
2248
3256
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2249
- 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
+ });
2250
3262
  mockApiError(400, "Invalid workflow spec");
2251
3263
  await expect(workflowRunCommand.parseAsync(["node", "cli", "-w", "wf1"])).rejects.toThrow();
2252
3264
  expect(consoleSpy).toHaveBeenCalledWith("Error: Invalid workflow spec");
@@ -2271,7 +3283,13 @@ describe("Environment Variable Defaults", () => {
2271
3283
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2272
3284
  mockGetOrgId.mockReturnValue("env-org-123");
2273
3285
  mockApiRequest.mockResolvedValueOnce({ members: [] });
2274
- 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
+ ]);
2275
3293
  expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2276
3294
  body: expect.stringContaining("env-org-123"),
2277
3295
  }));
@@ -2281,7 +3299,15 @@ describe("Environment Variable Defaults", () => {
2281
3299
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2282
3300
  mockGetOrgId.mockReturnValue("env-org-123");
2283
3301
  mockApiRequest.mockResolvedValueOnce({ members: [] });
2284
- 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
+ ]);
2285
3311
  expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2286
3312
  body: expect.stringContaining("cli-org-456"),
2287
3313
  }));
@@ -2306,7 +3332,12 @@ describe("Environment Variable Defaults", () => {
2306
3332
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2307
3333
  mockGetWorkspaceId.mockReturnValue("env-workspace-789");
2308
3334
  mockApiRequest.mockResolvedValueOnce([]);
2309
- await workspaceMemberListCommand.parseAsync(["node", "cli", "-w", "cli-workspace-xyz"]);
3335
+ await workspaceMemberListCommand.parseAsync([
3336
+ "node",
3337
+ "cli",
3338
+ "-w",
3339
+ "cli-workspace-xyz",
3340
+ ]);
2310
3341
  const calls = mockApiRequest.mock.calls;
2311
3342
  expect(calls.length).toBeGreaterThan(0);
2312
3343
  expect(calls[0]?.[0]).toContain("workspace_id=cli-workspace-xyz");
@@ -2331,11 +3362,17 @@ describe("Environment Variable Defaults", () => {
2331
3362
  discoveredTools: ["tool1"],
2332
3363
  });
2333
3364
  await agentMcpRegisterCommand.parseAsync([
2334
- "node", "cli", "register",
2335
- "-n", "my-mcp",
2336
- "-u", "http://localhost:9000",
2337
- "-t", "streamable-http",
2338
- "-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",
2339
3376
  ]);
2340
3377
  expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2341
3378
  body: expect.stringContaining("explicit-workspace-888"),
@@ -2352,10 +3389,15 @@ describe("Environment Variable Defaults", () => {
2352
3389
  discoveredTools: [],
2353
3390
  });
2354
3391
  await agentMcpRegisterCommand.parseAsync([
2355
- "node", "cli", "register",
2356
- "-n", "my-mcp",
2357
- "-u", "http://localhost:9000",
2358
- "-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",
2359
3401
  ]);
2360
3402
  expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2361
3403
  body: expect.stringContaining("fallback-org-111"),
@@ -2373,7 +3415,12 @@ describe("Environment Variable Defaults", () => {
2373
3415
  it("workspace member list uses OXAGEN_WORKSPACE_ID as default when no --workspace flag", async () => {
2374
3416
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2375
3417
  mockApiRequest.mockResolvedValueOnce([
2376
- { 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
+ },
2377
3424
  ]);
2378
3425
  await workspaceMemberListCommand.parseAsync(["node", "cli"]);
2379
3426
  const calls = mockApiRequest.mock.calls;
@@ -2384,11 +3431,18 @@ describe("Environment Variable Defaults", () => {
2384
3431
  it("workspace member list uses explicit --workspace to override OXAGEN_WORKSPACE_ID", async () => {
2385
3432
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2386
3433
  mockApiRequest.mockResolvedValueOnce([
2387
- { 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
+ },
2388
3440
  ]);
2389
3441
  await workspaceMemberListCommand.parseAsync([
2390
- "node", "cli",
2391
- "-w", "explicit-ws"
3442
+ "node",
3443
+ "cli",
3444
+ "-w",
3445
+ "explicit-ws",
2392
3446
  ]);
2393
3447
  const calls = mockApiRequest.mock.calls;
2394
3448
  expect(calls.length).toBeGreaterThan(0);