@oxagen/cli 0.6.0 → 0.6.2

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 (974) hide show
  1. package/oxagen.mjs +100056 -0
  2. package/package.json +12 -29
  3. package/dist/agent/__tests__/code-graph.test.d.ts +0 -2
  4. package/dist/agent/__tests__/code-graph.test.d.ts.map +0 -1
  5. package/dist/agent/__tests__/code-graph.test.js +0 -83
  6. package/dist/agent/__tests__/code-graph.test.js.map +0 -1
  7. package/dist/agent/__tests__/evaluator.test.d.ts +0 -2
  8. package/dist/agent/__tests__/evaluator.test.d.ts.map +0 -1
  9. package/dist/agent/__tests__/evaluator.test.js +0 -96
  10. package/dist/agent/__tests__/evaluator.test.js.map +0 -1
  11. package/dist/agent/__tests__/fleet-memory.test.d.ts +0 -2
  12. package/dist/agent/__tests__/fleet-memory.test.d.ts.map +0 -1
  13. package/dist/agent/__tests__/fleet-memory.test.js +0 -107
  14. package/dist/agent/__tests__/fleet-memory.test.js.map +0 -1
  15. package/dist/agent/__tests__/fleet-store.test.d.ts +0 -2
  16. package/dist/agent/__tests__/fleet-store.test.d.ts.map +0 -1
  17. package/dist/agent/__tests__/fleet-store.test.js +0 -93
  18. package/dist/agent/__tests__/fleet-store.test.js.map +0 -1
  19. package/dist/agent/__tests__/git-isolation.test.d.ts +0 -2
  20. package/dist/agent/__tests__/git-isolation.test.d.ts.map +0 -1
  21. package/dist/agent/__tests__/git-isolation.test.js +0 -119
  22. package/dist/agent/__tests__/git-isolation.test.js.map +0 -1
  23. package/dist/agent/__tests__/judge.test.d.ts +0 -2
  24. package/dist/agent/__tests__/judge.test.d.ts.map +0 -1
  25. package/dist/agent/__tests__/judge.test.js +0 -135
  26. package/dist/agent/__tests__/judge.test.js.map +0 -1
  27. package/dist/agent/__tests__/loop-errors.test.d.ts +0 -2
  28. package/dist/agent/__tests__/loop-errors.test.d.ts.map +0 -1
  29. package/dist/agent/__tests__/loop-errors.test.js +0 -44
  30. package/dist/agent/__tests__/loop-errors.test.js.map +0 -1
  31. package/dist/agent/__tests__/model-router.test.d.ts +0 -2
  32. package/dist/agent/__tests__/model-router.test.d.ts.map +0 -1
  33. package/dist/agent/__tests__/model-router.test.js +0 -122
  34. package/dist/agent/__tests__/model-router.test.js.map +0 -1
  35. package/dist/agent/__tests__/orchestrator-isolation.test.d.ts +0 -2
  36. package/dist/agent/__tests__/orchestrator-isolation.test.d.ts.map +0 -1
  37. package/dist/agent/__tests__/orchestrator-isolation.test.js +0 -134
  38. package/dist/agent/__tests__/orchestrator-isolation.test.js.map +0 -1
  39. package/dist/agent/__tests__/orchestrator.test.d.ts +0 -2
  40. package/dist/agent/__tests__/orchestrator.test.d.ts.map +0 -1
  41. package/dist/agent/__tests__/orchestrator.test.js +0 -201
  42. package/dist/agent/__tests__/orchestrator.test.js.map +0 -1
  43. package/dist/agent/__tests__/pipeline.test.d.ts +0 -2
  44. package/dist/agent/__tests__/pipeline.test.d.ts.map +0 -1
  45. package/dist/agent/__tests__/pipeline.test.js +0 -226
  46. package/dist/agent/__tests__/pipeline.test.js.map +0 -1
  47. package/dist/agent/__tests__/planner.test.d.ts +0 -2
  48. package/dist/agent/__tests__/planner.test.d.ts.map +0 -1
  49. package/dist/agent/__tests__/planner.test.js +0 -98
  50. package/dist/agent/__tests__/planner.test.js.map +0 -1
  51. package/dist/agent/__tests__/prompt-enhancer.test.d.ts +0 -2
  52. package/dist/agent/__tests__/prompt-enhancer.test.d.ts.map +0 -1
  53. package/dist/agent/__tests__/prompt-enhancer.test.js +0 -107
  54. package/dist/agent/__tests__/prompt-enhancer.test.js.map +0 -1
  55. package/dist/agent/__tests__/trace-format.test.d.ts +0 -2
  56. package/dist/agent/__tests__/trace-format.test.d.ts.map +0 -1
  57. package/dist/agent/__tests__/trace-format.test.js +0 -104
  58. package/dist/agent/__tests__/trace-format.test.js.map +0 -1
  59. package/dist/agent/__tests__/trace-store.test.d.ts +0 -2
  60. package/dist/agent/__tests__/trace-store.test.d.ts.map +0 -1
  61. package/dist/agent/__tests__/trace-store.test.js +0 -113
  62. package/dist/agent/__tests__/trace-store.test.js.map +0 -1
  63. package/dist/agent/code-graph.d.ts +0 -18
  64. package/dist/agent/code-graph.d.ts.map +0 -1
  65. package/dist/agent/code-graph.js +0 -119
  66. package/dist/agent/code-graph.js.map +0 -1
  67. package/dist/agent/env.d.ts +0 -11
  68. package/dist/agent/env.d.ts.map +0 -1
  69. package/dist/agent/env.js +0 -82
  70. package/dist/agent/env.js.map +0 -1
  71. package/dist/agent/evaluator.d.ts +0 -13
  72. package/dist/agent/evaluator.d.ts.map +0 -1
  73. package/dist/agent/evaluator.js +0 -146
  74. package/dist/agent/evaluator.js.map +0 -1
  75. package/dist/agent/fleet/git-isolation.d.ts +0 -142
  76. package/dist/agent/fleet/git-isolation.d.ts.map +0 -1
  77. package/dist/agent/fleet/git-isolation.js +0 -290
  78. package/dist/agent/fleet/git-isolation.js.map +0 -1
  79. package/dist/agent/fleet/memory.d.ts +0 -21
  80. package/dist/agent/fleet/memory.d.ts.map +0 -1
  81. package/dist/agent/fleet/memory.js +0 -129
  82. package/dist/agent/fleet/memory.js.map +0 -1
  83. package/dist/agent/fleet/orchestrator.d.ts +0 -103
  84. package/dist/agent/fleet/orchestrator.d.ts.map +0 -1
  85. package/dist/agent/fleet/orchestrator.js +0 -355
  86. package/dist/agent/fleet/orchestrator.js.map +0 -1
  87. package/dist/agent/fleet/store.d.ts +0 -13
  88. package/dist/agent/fleet/store.d.ts.map +0 -1
  89. package/dist/agent/fleet/store.js +0 -79
  90. package/dist/agent/fleet/store.js.map +0 -1
  91. package/dist/agent/fleet/types.d.ts +0 -105
  92. package/dist/agent/fleet/types.d.ts.map +0 -1
  93. package/dist/agent/fleet/types.js +0 -17
  94. package/dist/agent/fleet/types.js.map +0 -1
  95. package/dist/agent/judge.d.ts +0 -38
  96. package/dist/agent/judge.d.ts.map +0 -1
  97. package/dist/agent/judge.js +0 -170
  98. package/dist/agent/judge.js.map +0 -1
  99. package/dist/agent/loop.d.ts +0 -61
  100. package/dist/agent/loop.d.ts.map +0 -1
  101. package/dist/agent/loop.js +0 -134
  102. package/dist/agent/loop.js.map +0 -1
  103. package/dist/agent/memory.d.ts +0 -14
  104. package/dist/agent/memory.d.ts.map +0 -1
  105. package/dist/agent/memory.js +0 -118
  106. package/dist/agent/memory.js.map +0 -1
  107. package/dist/agent/model-router.d.ts +0 -79
  108. package/dist/agent/model-router.d.ts.map +0 -1
  109. package/dist/agent/model-router.js +0 -141
  110. package/dist/agent/model-router.js.map +0 -1
  111. package/dist/agent/model.d.ts +0 -9
  112. package/dist/agent/model.d.ts.map +0 -1
  113. package/dist/agent/model.js +0 -24
  114. package/dist/agent/model.js.map +0 -1
  115. package/dist/agent/pipeline.d.ts +0 -82
  116. package/dist/agent/pipeline.d.ts.map +0 -1
  117. package/dist/agent/pipeline.js +0 -320
  118. package/dist/agent/pipeline.js.map +0 -1
  119. package/dist/agent/planner.d.ts +0 -16
  120. package/dist/agent/planner.d.ts.map +0 -1
  121. package/dist/agent/planner.js +0 -126
  122. package/dist/agent/planner.js.map +0 -1
  123. package/dist/agent/project-context.d.ts +0 -13
  124. package/dist/agent/project-context.d.ts.map +0 -1
  125. package/dist/agent/project-context.js +0 -66
  126. package/dist/agent/project-context.js.map +0 -1
  127. package/dist/agent/prompt-enhancer.d.ts +0 -37
  128. package/dist/agent/prompt-enhancer.d.ts.map +0 -1
  129. package/dist/agent/prompt-enhancer.js +0 -115
  130. package/dist/agent/prompt-enhancer.js.map +0 -1
  131. package/dist/agent/system-prompt.d.ts +0 -9
  132. package/dist/agent/system-prompt.d.ts.map +0 -1
  133. package/dist/agent/system-prompt.js +0 -38
  134. package/dist/agent/system-prompt.js.map +0 -1
  135. package/dist/agent/tools.d.ts +0 -19
  136. package/dist/agent/tools.d.ts.map +0 -1
  137. package/dist/agent/tools.js +0 -323
  138. package/dist/agent/tools.js.map +0 -1
  139. package/dist/agent/trace-format.d.ts +0 -6
  140. package/dist/agent/trace-format.d.ts.map +0 -1
  141. package/dist/agent/trace-format.js +0 -74
  142. package/dist/agent/trace-format.js.map +0 -1
  143. package/dist/agent/trace-store.d.ts +0 -19
  144. package/dist/agent/trace-store.d.ts.map +0 -1
  145. package/dist/agent/trace-store.js +0 -82
  146. package/dist/agent/trace-store.js.map +0 -1
  147. package/dist/agent/trace.d.ts +0 -121
  148. package/dist/agent/trace.d.ts.map +0 -1
  149. package/dist/agent/trace.js +0 -2
  150. package/dist/agent/trace.js.map +0 -1
  151. package/dist/commands/__tests__/cli-parity.test.d.ts +0 -2
  152. package/dist/commands/__tests__/cli-parity.test.d.ts.map +0 -1
  153. package/dist/commands/__tests__/cli-parity.test.js +0 -110
  154. package/dist/commands/__tests__/cli-parity.test.js.map +0 -1
  155. package/dist/commands/__tests__/replay.test.d.ts +0 -2
  156. package/dist/commands/__tests__/replay.test.d.ts.map +0 -1
  157. package/dist/commands/__tests__/replay.test.js +0 -76
  158. package/dist/commands/__tests__/replay.test.js.map +0 -1
  159. package/dist/commands/agent.approval.resolve.d.ts +0 -3
  160. package/dist/commands/agent.approval.resolve.d.ts.map +0 -1
  161. package/dist/commands/agent.approval.resolve.js +0 -30
  162. package/dist/commands/agent.approval.resolve.js.map +0 -1
  163. package/dist/commands/agent.mcp.consent.list.d.ts +0 -3
  164. package/dist/commands/agent.mcp.consent.list.d.ts.map +0 -1
  165. package/dist/commands/agent.mcp.consent.list.js +0 -30
  166. package/dist/commands/agent.mcp.consent.list.js.map +0 -1
  167. package/dist/commands/agent.mcp.consent.resolve.d.ts +0 -3
  168. package/dist/commands/agent.mcp.consent.resolve.d.ts.map +0 -1
  169. package/dist/commands/agent.mcp.consent.resolve.js +0 -34
  170. package/dist/commands/agent.mcp.consent.resolve.js.map +0 -1
  171. package/dist/commands/agent.mcp.delete.d.ts +0 -3
  172. package/dist/commands/agent.mcp.delete.d.ts.map +0 -1
  173. package/dist/commands/agent.mcp.delete.js +0 -27
  174. package/dist/commands/agent.mcp.delete.js.map +0 -1
  175. package/dist/commands/agent.mcp.list.d.ts +0 -3
  176. package/dist/commands/agent.mcp.list.d.ts.map +0 -1
  177. package/dist/commands/agent.mcp.list.js +0 -25
  178. package/dist/commands/agent.mcp.list.js.map +0 -1
  179. package/dist/commands/agent.mcp.register.d.ts +0 -3
  180. package/dist/commands/agent.mcp.register.d.ts.map +0 -1
  181. package/dist/commands/agent.mcp.register.js +0 -41
  182. package/dist/commands/agent.mcp.register.js.map +0 -1
  183. package/dist/commands/agent.mcp.set_enabled.d.ts +0 -3
  184. package/dist/commands/agent.mcp.set_enabled.d.ts.map +0 -1
  185. package/dist/commands/agent.mcp.set_enabled.js +0 -33
  186. package/dist/commands/agent.mcp.set_enabled.js.map +0 -1
  187. package/dist/commands/agent.memory.recall.d.ts +0 -3
  188. package/dist/commands/agent.memory.recall.d.ts.map +0 -1
  189. package/dist/commands/agent.memory.recall.js +0 -25
  190. package/dist/commands/agent.memory.recall.js.map +0 -1
  191. package/dist/commands/agent.memory.write.d.ts +0 -3
  192. package/dist/commands/agent.memory.write.d.ts.map +0 -1
  193. package/dist/commands/agent.memory.write.js +0 -25
  194. package/dist/commands/agent.memory.write.js.map +0 -1
  195. package/dist/commands/agent.plan.approve.d.ts +0 -3
  196. package/dist/commands/agent.plan.approve.d.ts.map +0 -1
  197. package/dist/commands/agent.plan.approve.js +0 -35
  198. package/dist/commands/agent.plan.approve.js.map +0 -1
  199. package/dist/commands/agent.plan.create.d.ts +0 -3
  200. package/dist/commands/agent.plan.create.d.ts.map +0 -1
  201. package/dist/commands/agent.plan.create.js +0 -42
  202. package/dist/commands/agent.plan.create.js.map +0 -1
  203. package/dist/commands/agent.skill.list.d.ts +0 -3
  204. package/dist/commands/agent.skill.list.d.ts.map +0 -1
  205. package/dist/commands/agent.skill.list.js +0 -27
  206. package/dist/commands/agent.skill.list.js.map +0 -1
  207. package/dist/commands/agent.skill.load.d.ts +0 -3
  208. package/dist/commands/agent.skill.load.d.ts.map +0 -1
  209. package/dist/commands/agent.skill.load.js +0 -57
  210. package/dist/commands/agent.skill.load.js.map +0 -1
  211. package/dist/commands/agent.task.background.cancel.d.ts +0 -3
  212. package/dist/commands/agent.task.background.cancel.d.ts.map +0 -1
  213. package/dist/commands/agent.task.background.cancel.js +0 -30
  214. package/dist/commands/agent.task.background.cancel.js.map +0 -1
  215. package/dist/commands/agent.task.background.read.d.ts +0 -3
  216. package/dist/commands/agent.task.background.read.d.ts.map +0 -1
  217. package/dist/commands/agent.task.background.read.js +0 -28
  218. package/dist/commands/agent.task.background.read.js.map +0 -1
  219. package/dist/commands/agent.task.background.start.d.ts +0 -3
  220. package/dist/commands/agent.task.background.start.d.ts.map +0 -1
  221. package/dist/commands/agent.task.background.start.js +0 -32
  222. package/dist/commands/agent.task.background.start.js.map +0 -1
  223. package/dist/commands/agent.tool.list.d.ts +0 -3
  224. package/dist/commands/agent.tool.list.d.ts.map +0 -1
  225. package/dist/commands/agent.tool.list.js +0 -27
  226. package/dist/commands/agent.tool.list.js.map +0 -1
  227. package/dist/commands/api-key.create.d.ts +0 -3
  228. package/dist/commands/api-key.create.d.ts.map +0 -1
  229. package/dist/commands/api-key.create.js +0 -32
  230. package/dist/commands/api-key.create.js.map +0 -1
  231. package/dist/commands/api-key.revoke.d.ts +0 -3
  232. package/dist/commands/api-key.revoke.d.ts.map +0 -1
  233. package/dist/commands/api-key.revoke.js +0 -18
  234. package/dist/commands/api-key.revoke.js.map +0 -1
  235. package/dist/commands/archive.create.d.ts +0 -3
  236. package/dist/commands/archive.create.d.ts.map +0 -1
  237. package/dist/commands/archive.create.js +0 -30
  238. package/dist/commands/archive.create.js.map +0 -1
  239. package/dist/commands/asset.upload.d.ts +0 -3
  240. package/dist/commands/asset.upload.d.ts.map +0 -1
  241. package/dist/commands/asset.upload.js +0 -32
  242. package/dist/commands/asset.upload.js.map +0 -1
  243. package/dist/commands/audit.log.query.d.ts +0 -3
  244. package/dist/commands/audit.log.query.d.ts.map +0 -1
  245. package/dist/commands/audit.log.query.js +0 -42
  246. package/dist/commands/audit.log.query.js.map +0 -1
  247. package/dist/commands/auth.login.d.ts +0 -3
  248. package/dist/commands/auth.login.d.ts.map +0 -1
  249. package/dist/commands/auth.login.js +0 -32
  250. package/dist/commands/auth.login.js.map +0 -1
  251. package/dist/commands/auth.logout.d.ts +0 -3
  252. package/dist/commands/auth.logout.d.ts.map +0 -1
  253. package/dist/commands/auth.logout.js +0 -20
  254. package/dist/commands/auth.logout.js.map +0 -1
  255. package/dist/commands/auth.whoami.d.ts +0 -3
  256. package/dist/commands/auth.whoami.d.ts.map +0 -1
  257. package/dist/commands/auth.whoami.js +0 -21
  258. package/dist/commands/auth.whoami.js.map +0 -1
  259. package/dist/commands/automation.create.d.ts +0 -3
  260. package/dist/commands/automation.create.d.ts.map +0 -1
  261. package/dist/commands/automation.create.js +0 -69
  262. package/dist/commands/automation.create.js.map +0 -1
  263. package/dist/commands/automation.disable.d.ts +0 -3
  264. package/dist/commands/automation.disable.d.ts.map +0 -1
  265. package/dist/commands/automation.disable.js +0 -24
  266. package/dist/commands/automation.disable.js.map +0 -1
  267. package/dist/commands/automation.enable.d.ts +0 -3
  268. package/dist/commands/automation.enable.d.ts.map +0 -1
  269. package/dist/commands/automation.enable.js +0 -24
  270. package/dist/commands/automation.enable.js.map +0 -1
  271. package/dist/commands/automation.list.d.ts +0 -3
  272. package/dist/commands/automation.list.d.ts.map +0 -1
  273. package/dist/commands/automation.list.js +0 -28
  274. package/dist/commands/automation.list.js.map +0 -1
  275. package/dist/commands/automation.trigger.d.ts +0 -3
  276. package/dist/commands/automation.trigger.d.ts.map +0 -1
  277. package/dist/commands/automation.trigger.js +0 -33
  278. package/dist/commands/automation.trigger.js.map +0 -1
  279. package/dist/commands/automation.update.d.ts +0 -3
  280. package/dist/commands/automation.update.d.ts.map +0 -1
  281. package/dist/commands/automation.update.js +0 -42
  282. package/dist/commands/automation.update.js.map +0 -1
  283. package/dist/commands/billing.credits.purchase.d.ts +0 -3
  284. package/dist/commands/billing.credits.purchase.d.ts.map +0 -1
  285. package/dist/commands/billing.credits.purchase.js +0 -32
  286. package/dist/commands/billing.credits.purchase.js.map +0 -1
  287. package/dist/commands/billing.status.d.ts +0 -3
  288. package/dist/commands/billing.status.d.ts.map +0 -1
  289. package/dist/commands/billing.status.js +0 -32
  290. package/dist/commands/billing.status.js.map +0 -1
  291. package/dist/commands/billing.subscription.read.d.ts +0 -3
  292. package/dist/commands/billing.subscription.read.d.ts.map +0 -1
  293. package/dist/commands/billing.subscription.read.js +0 -28
  294. package/dist/commands/billing.subscription.read.js.map +0 -1
  295. package/dist/commands/billing.subscription.upgrade.start.d.ts +0 -3
  296. package/dist/commands/billing.subscription.upgrade.start.d.ts.map +0 -1
  297. package/dist/commands/billing.subscription.upgrade.start.js +0 -33
  298. package/dist/commands/billing.subscription.upgrade.start.js.map +0 -1
  299. package/dist/commands/brandkit.apply.d.ts +0 -3
  300. package/dist/commands/brandkit.apply.d.ts.map +0 -1
  301. package/dist/commands/brandkit.apply.js +0 -32
  302. package/dist/commands/brandkit.apply.js.map +0 -1
  303. package/dist/commands/chat.send.d.ts +0 -3
  304. package/dist/commands/chat.send.d.ts.map +0 -1
  305. package/dist/commands/chat.send.js +0 -136
  306. package/dist/commands/chat.send.js.map +0 -1
  307. package/dist/commands/code.d.ts +0 -14
  308. package/dist/commands/code.d.ts.map +0 -1
  309. package/dist/commands/code.js +0 -100
  310. package/dist/commands/code.js.map +0 -1
  311. package/dist/commands/config.d.ts +0 -2
  312. package/dist/commands/config.d.ts.map +0 -1
  313. package/dist/commands/config.js +0 -66
  314. package/dist/commands/config.js.map +0 -1
  315. package/dist/commands/conversation.archive.d.ts +0 -3
  316. package/dist/commands/conversation.archive.d.ts.map +0 -1
  317. package/dist/commands/conversation.archive.js +0 -23
  318. package/dist/commands/conversation.archive.js.map +0 -1
  319. package/dist/commands/conversation.chat.d.ts +0 -3
  320. package/dist/commands/conversation.chat.d.ts.map +0 -1
  321. package/dist/commands/conversation.chat.js +0 -28
  322. package/dist/commands/conversation.chat.js.map +0 -1
  323. package/dist/commands/conversation.delete.d.ts +0 -3
  324. package/dist/commands/conversation.delete.d.ts.map +0 -1
  325. package/dist/commands/conversation.delete.js +0 -18
  326. package/dist/commands/conversation.delete.js.map +0 -1
  327. package/dist/commands/conversation.files.list.d.ts +0 -3
  328. package/dist/commands/conversation.files.list.d.ts.map +0 -1
  329. package/dist/commands/conversation.files.list.js +0 -39
  330. package/dist/commands/conversation.files.list.js.map +0 -1
  331. package/dist/commands/conversation.list.d.ts +0 -3
  332. package/dist/commands/conversation.list.d.ts.map +0 -1
  333. package/dist/commands/conversation.list.js +0 -32
  334. package/dist/commands/conversation.list.js.map +0 -1
  335. package/dist/commands/conversation.purge.d.ts +0 -3
  336. package/dist/commands/conversation.purge.d.ts.map +0 -1
  337. package/dist/commands/conversation.purge.js +0 -30
  338. package/dist/commands/conversation.purge.js.map +0 -1
  339. package/dist/commands/conversation.rename.d.ts +0 -3
  340. package/dist/commands/conversation.rename.d.ts.map +0 -1
  341. package/dist/commands/conversation.rename.js +0 -22
  342. package/dist/commands/conversation.rename.js.map +0 -1
  343. package/dist/commands/document.create.d.ts +0 -3
  344. package/dist/commands/document.create.d.ts.map +0 -1
  345. package/dist/commands/document.create.js +0 -29
  346. package/dist/commands/document.create.js.map +0 -1
  347. package/dist/commands/document.list.d.ts +0 -3
  348. package/dist/commands/document.list.d.ts.map +0 -1
  349. package/dist/commands/document.list.js +0 -31
  350. package/dist/commands/document.list.js.map +0 -1
  351. package/dist/commands/document.read.d.ts +0 -3
  352. package/dist/commands/document.read.d.ts.map +0 -1
  353. package/dist/commands/document.read.js +0 -23
  354. package/dist/commands/document.read.js.map +0 -1
  355. package/dist/commands/documents.generate.d.ts +0 -3
  356. package/dist/commands/documents.generate.d.ts.map +0 -1
  357. package/dist/commands/documents.generate.js +0 -34
  358. package/dist/commands/documents.generate.js.map +0 -1
  359. package/dist/commands/documents.pdf.create.d.ts +0 -3
  360. package/dist/commands/documents.pdf.create.d.ts.map +0 -1
  361. package/dist/commands/documents.pdf.create.js +0 -40
  362. package/dist/commands/documents.pdf.create.js.map +0 -1
  363. package/dist/commands/env.d.ts +0 -19
  364. package/dist/commands/env.d.ts.map +0 -1
  365. package/dist/commands/env.js +0 -64
  366. package/dist/commands/env.js.map +0 -1
  367. package/dist/commands/form.create.d.ts +0 -3
  368. package/dist/commands/form.create.d.ts.map +0 -1
  369. package/dist/commands/form.create.js +0 -34
  370. package/dist/commands/form.create.js.map +0 -1
  371. package/dist/commands/form.fill.d.ts +0 -3
  372. package/dist/commands/form.fill.d.ts.map +0 -1
  373. package/dist/commands/form.fill.js +0 -37
  374. package/dist/commands/form.fill.js.map +0 -1
  375. package/dist/commands/form.submit.d.ts +0 -3
  376. package/dist/commands/form.submit.d.ts.map +0 -1
  377. package/dist/commands/form.submit.js +0 -34
  378. package/dist/commands/form.submit.js.map +0 -1
  379. package/dist/commands/graph.cypher.d.ts +0 -3
  380. package/dist/commands/graph.cypher.d.ts.map +0 -1
  381. package/dist/commands/graph.cypher.js +0 -37
  382. package/dist/commands/graph.cypher.js.map +0 -1
  383. package/dist/commands/graph.edge.delete.d.ts +0 -3
  384. package/dist/commands/graph.edge.delete.d.ts.map +0 -1
  385. package/dist/commands/graph.edge.delete.js +0 -53
  386. package/dist/commands/graph.edge.delete.js.map +0 -1
  387. package/dist/commands/graph.edge.upsert.d.ts +0 -3
  388. package/dist/commands/graph.edge.upsert.d.ts.map +0 -1
  389. package/dist/commands/graph.edge.upsert.js +0 -47
  390. package/dist/commands/graph.edge.upsert.js.map +0 -1
  391. package/dist/commands/graph.node.delete.d.ts +0 -3
  392. package/dist/commands/graph.node.delete.d.ts.map +0 -1
  393. package/dist/commands/graph.node.delete.js +0 -34
  394. package/dist/commands/graph.node.delete.js.map +0 -1
  395. package/dist/commands/graph.node.get.d.ts +0 -3
  396. package/dist/commands/graph.node.get.d.ts.map +0 -1
  397. package/dist/commands/graph.node.get.js +0 -16
  398. package/dist/commands/graph.node.get.js.map +0 -1
  399. package/dist/commands/graph.node.search.d.ts +0 -3
  400. package/dist/commands/graph.node.search.d.ts.map +0 -1
  401. package/dist/commands/graph.node.search.js +0 -31
  402. package/dist/commands/graph.node.search.js.map +0 -1
  403. package/dist/commands/graph.node.upsert.d.ts +0 -3
  404. package/dist/commands/graph.node.upsert.d.ts.map +0 -1
  405. package/dist/commands/graph.node.upsert.js +0 -39
  406. package/dist/commands/graph.node.upsert.js.map +0 -1
  407. package/dist/commands/graph.search.d.ts +0 -10
  408. package/dist/commands/graph.search.d.ts.map +0 -1
  409. package/dist/commands/graph.search.js +0 -25
  410. package/dist/commands/graph.search.js.map +0 -1
  411. package/dist/commands/image.analyze.d.ts +0 -3
  412. package/dist/commands/image.analyze.d.ts.map +0 -1
  413. package/dist/commands/image.analyze.js +0 -24
  414. package/dist/commands/image.analyze.js.map +0 -1
  415. package/dist/commands/image.create.d.ts +0 -3
  416. package/dist/commands/image.create.d.ts.map +0 -1
  417. package/dist/commands/image.create.js +0 -33
  418. package/dist/commands/image.create.js.map +0 -1
  419. package/dist/commands/image.generate.d.ts +0 -3
  420. package/dist/commands/image.generate.d.ts.map +0 -1
  421. package/dist/commands/image.generate.js +0 -35
  422. package/dist/commands/image.generate.js.map +0 -1
  423. package/dist/commands/image.list.d.ts +0 -3
  424. package/dist/commands/image.list.d.ts.map +0 -1
  425. package/dist/commands/image.list.js +0 -31
  426. package/dist/commands/image.list.js.map +0 -1
  427. package/dist/commands/markdown.generate.d.ts +0 -3
  428. package/dist/commands/markdown.generate.d.ts.map +0 -1
  429. package/dist/commands/markdown.generate.js +0 -37
  430. package/dist/commands/markdown.generate.js.map +0 -1
  431. package/dist/commands/mcp.add.d.ts +0 -13
  432. package/dist/commands/mcp.add.d.ts.map +0 -1
  433. package/dist/commands/mcp.add.js +0 -110
  434. package/dist/commands/mcp.add.js.map +0 -1
  435. package/dist/commands/mcp.auth.d.ts +0 -10
  436. package/dist/commands/mcp.auth.d.ts.map +0 -1
  437. package/dist/commands/mcp.auth.js +0 -132
  438. package/dist/commands/mcp.auth.js.map +0 -1
  439. package/dist/commands/mcp.check.d.ts +0 -10
  440. package/dist/commands/mcp.check.d.ts.map +0 -1
  441. package/dist/commands/mcp.check.js +0 -114
  442. package/dist/commands/mcp.check.js.map +0 -1
  443. package/dist/commands/mcp.list.d.ts +0 -9
  444. package/dist/commands/mcp.list.d.ts.map +0 -1
  445. package/dist/commands/mcp.list.js +0 -93
  446. package/dist/commands/mcp.list.js.map +0 -1
  447. package/dist/commands/mcp.permit.d.ts +0 -12
  448. package/dist/commands/mcp.permit.d.ts.map +0 -1
  449. package/dist/commands/mcp.permit.js +0 -117
  450. package/dist/commands/mcp.permit.js.map +0 -1
  451. package/dist/commands/mcp.remove.d.ts +0 -9
  452. package/dist/commands/mcp.remove.d.ts.map +0 -1
  453. package/dist/commands/mcp.remove.js +0 -65
  454. package/dist/commands/mcp.remove.js.map +0 -1
  455. package/dist/commands/mermaid.generate.d.ts +0 -3
  456. package/dist/commands/mermaid.generate.d.ts.map +0 -1
  457. package/dist/commands/mermaid.generate.js +0 -33
  458. package/dist/commands/mermaid.generate.js.map +0 -1
  459. package/dist/commands/notifications.list.d.ts +0 -3
  460. package/dist/commands/notifications.list.d.ts.map +0 -1
  461. package/dist/commands/notifications.list.js +0 -33
  462. package/dist/commands/notifications.list.js.map +0 -1
  463. package/dist/commands/notifications.mark.d.ts +0 -3
  464. package/dist/commands/notifications.mark.d.ts.map +0 -1
  465. package/dist/commands/notifications.mark.js +0 -23
  466. package/dist/commands/notifications.mark.js.map +0 -1
  467. package/dist/commands/ontology.neighbors.d.ts +0 -3
  468. package/dist/commands/ontology.neighbors.d.ts.map +0 -1
  469. package/dist/commands/ontology.neighbors.js +0 -34
  470. package/dist/commands/ontology.neighbors.js.map +0 -1
  471. package/dist/commands/ontology.query.d.ts +0 -3
  472. package/dist/commands/ontology.query.d.ts.map +0 -1
  473. package/dist/commands/ontology.query.js +0 -36
  474. package/dist/commands/ontology.query.js.map +0 -1
  475. package/dist/commands/org.create.d.ts +0 -3
  476. package/dist/commands/org.create.d.ts.map +0 -1
  477. package/dist/commands/org.create.js +0 -23
  478. package/dist/commands/org.create.js.map +0 -1
  479. package/dist/commands/org.list.d.ts +0 -3
  480. package/dist/commands/org.list.d.ts.map +0 -1
  481. package/dist/commands/org.list.js +0 -25
  482. package/dist/commands/org.list.js.map +0 -1
  483. package/dist/commands/org.member.add.d.ts +0 -3
  484. package/dist/commands/org.member.add.d.ts.map +0 -1
  485. package/dist/commands/org.member.add.js +0 -24
  486. package/dist/commands/org.member.add.js.map +0 -1
  487. package/dist/commands/org.member.invite.accept.d.ts +0 -3
  488. package/dist/commands/org.member.invite.accept.d.ts.map +0 -1
  489. package/dist/commands/org.member.invite.accept.js +0 -23
  490. package/dist/commands/org.member.invite.accept.js.map +0 -1
  491. package/dist/commands/org.member.invite.decline.d.ts +0 -3
  492. package/dist/commands/org.member.invite.decline.d.ts.map +0 -1
  493. package/dist/commands/org.member.invite.decline.js +0 -25
  494. package/dist/commands/org.member.invite.decline.js.map +0 -1
  495. package/dist/commands/org.member.remove.d.ts +0 -3
  496. package/dist/commands/org.member.remove.d.ts.map +0 -1
  497. package/dist/commands/org.member.remove.js +0 -23
  498. package/dist/commands/org.member.remove.js.map +0 -1
  499. package/dist/commands/org.member.role.change.d.ts +0 -3
  500. package/dist/commands/org.member.role.change.d.ts.map +0 -1
  501. package/dist/commands/org.member.role.change.js +0 -27
  502. package/dist/commands/org.member.role.change.js.map +0 -1
  503. package/dist/commands/organization.create.d.ts +0 -3
  504. package/dist/commands/organization.create.d.ts.map +0 -1
  505. package/dist/commands/organization.create.js +0 -36
  506. package/dist/commands/organization.create.js.map +0 -1
  507. package/dist/commands/plugin.catalog.browse.d.ts +0 -3
  508. package/dist/commands/plugin.catalog.browse.d.ts.map +0 -1
  509. package/dist/commands/plugin.catalog.browse.js +0 -21
  510. package/dist/commands/plugin.catalog.browse.js.map +0 -1
  511. package/dist/commands/plugin.catalog.get.d.ts +0 -3
  512. package/dist/commands/plugin.catalog.get.d.ts.map +0 -1
  513. package/dist/commands/plugin.catalog.get.js +0 -25
  514. package/dist/commands/plugin.catalog.get.js.map +0 -1
  515. package/dist/commands/plugin.credential.reauth.d.ts +0 -3
  516. package/dist/commands/plugin.credential.reauth.d.ts.map +0 -1
  517. package/dist/commands/plugin.credential.reauth.js +0 -23
  518. package/dist/commands/plugin.credential.reauth.js.map +0 -1
  519. package/dist/commands/plugin.credential.set_secret.d.ts +0 -3
  520. package/dist/commands/plugin.credential.set_secret.d.ts.map +0 -1
  521. package/dist/commands/plugin.credential.set_secret.js +0 -33
  522. package/dist/commands/plugin.credential.set_secret.js.map +0 -1
  523. package/dist/commands/plugin.denylist.add.d.ts +0 -3
  524. package/dist/commands/plugin.denylist.add.d.ts.map +0 -1
  525. package/dist/commands/plugin.denylist.add.js +0 -29
  526. package/dist/commands/plugin.denylist.add.js.map +0 -1
  527. package/dist/commands/plugin.denylist.remove.d.ts +0 -3
  528. package/dist/commands/plugin.denylist.remove.d.ts.map +0 -1
  529. package/dist/commands/plugin.denylist.remove.js +0 -27
  530. package/dist/commands/plugin.denylist.remove.js.map +0 -1
  531. package/dist/commands/plugin.install.d.ts +0 -3
  532. package/dist/commands/plugin.install.d.ts.map +0 -1
  533. package/dist/commands/plugin.install.js +0 -23
  534. package/dist/commands/plugin.install.js.map +0 -1
  535. package/dist/commands/plugin.list.d.ts +0 -3
  536. package/dist/commands/plugin.list.d.ts.map +0 -1
  537. package/dist/commands/plugin.list.js +0 -29
  538. package/dist/commands/plugin.list.js.map +0 -1
  539. package/dist/commands/plugin.org.install.d.ts +0 -3
  540. package/dist/commands/plugin.org.install.d.ts.map +0 -1
  541. package/dist/commands/plugin.org.install.js +0 -25
  542. package/dist/commands/plugin.org.install.js.map +0 -1
  543. package/dist/commands/plugin.org.install_bulk.d.ts +0 -3
  544. package/dist/commands/plugin.org.install_bulk.d.ts.map +0 -1
  545. package/dist/commands/plugin.org.install_bulk.js +0 -36
  546. package/dist/commands/plugin.org.install_bulk.js.map +0 -1
  547. package/dist/commands/plugin.org.list.d.ts +0 -3
  548. package/dist/commands/plugin.org.list.d.ts.map +0 -1
  549. package/dist/commands/plugin.org.list.js +0 -37
  550. package/dist/commands/plugin.org.list.js.map +0 -1
  551. package/dist/commands/plugin.org.set_enabled.d.ts +0 -3
  552. package/dist/commands/plugin.org.set_enabled.d.ts.map +0 -1
  553. package/dist/commands/plugin.org.set_enabled.js +0 -28
  554. package/dist/commands/plugin.org.set_enabled.js.map +0 -1
  555. package/dist/commands/plugin.org.uninstall.d.ts +0 -3
  556. package/dist/commands/plugin.org.uninstall.d.ts.map +0 -1
  557. package/dist/commands/plugin.org.uninstall.js +0 -23
  558. package/dist/commands/plugin.org.uninstall.js.map +0 -1
  559. package/dist/commands/plugin.registry.add.d.ts +0 -3
  560. package/dist/commands/plugin.registry.add.d.ts.map +0 -1
  561. package/dist/commands/plugin.registry.add.js +0 -25
  562. package/dist/commands/plugin.registry.add.js.map +0 -1
  563. package/dist/commands/plugin.registry.list.d.ts +0 -3
  564. package/dist/commands/plugin.registry.list.d.ts.map +0 -1
  565. package/dist/commands/plugin.registry.list.js +0 -18
  566. package/dist/commands/plugin.registry.list.js.map +0 -1
  567. package/dist/commands/plugin.registry.remove.d.ts +0 -3
  568. package/dist/commands/plugin.registry.remove.d.ts.map +0 -1
  569. package/dist/commands/plugin.registry.remove.js +0 -25
  570. package/dist/commands/plugin.registry.remove.js.map +0 -1
  571. package/dist/commands/plugin.registry.sync.d.ts +0 -3
  572. package/dist/commands/plugin.registry.sync.d.ts.map +0 -1
  573. package/dist/commands/plugin.registry.sync.js +0 -27
  574. package/dist/commands/plugin.registry.sync.js.map +0 -1
  575. package/dist/commands/plugin.settings.set_auth_alerts.d.ts +0 -3
  576. package/dist/commands/plugin.settings.set_auth_alerts.d.ts.map +0 -1
  577. package/dist/commands/plugin.settings.set_auth_alerts.js +0 -31
  578. package/dist/commands/plugin.settings.set_auth_alerts.js.map +0 -1
  579. package/dist/commands/plugin.uninstall.d.ts +0 -3
  580. package/dist/commands/plugin.uninstall.d.ts.map +0 -1
  581. package/dist/commands/plugin.uninstall.js +0 -23
  582. package/dist/commands/plugin.uninstall.js.map +0 -1
  583. package/dist/commands/plugin.workspace.set_enabled.d.ts +0 -3
  584. package/dist/commands/plugin.workspace.set_enabled.d.ts.map +0 -1
  585. package/dist/commands/plugin.workspace.set_enabled.js +0 -36
  586. package/dist/commands/plugin.workspace.set_enabled.js.map +0 -1
  587. package/dist/commands/privacy.erase.d.ts +0 -3
  588. package/dist/commands/privacy.erase.d.ts.map +0 -1
  589. package/dist/commands/privacy.erase.js +0 -61
  590. package/dist/commands/privacy.erase.js.map +0 -1
  591. package/dist/commands/privacy.erase.test.d.ts +0 -2
  592. package/dist/commands/privacy.erase.test.d.ts.map +0 -1
  593. package/dist/commands/privacy.erase.test.js +0 -132
  594. package/dist/commands/privacy.erase.test.js.map +0 -1
  595. package/dist/commands/privacy.export.d.ts +0 -3
  596. package/dist/commands/privacy.export.d.ts.map +0 -1
  597. package/dist/commands/privacy.export.js +0 -36
  598. package/dist/commands/privacy.export.js.map +0 -1
  599. package/dist/commands/replay.d.ts +0 -5
  600. package/dist/commands/replay.d.ts.map +0 -1
  601. package/dist/commands/replay.js +0 -28
  602. package/dist/commands/replay.js.map +0 -1
  603. package/dist/commands/research.swarm.start.d.ts +0 -3
  604. package/dist/commands/research.swarm.start.d.ts.map +0 -1
  605. package/dist/commands/research.swarm.start.js +0 -35
  606. package/dist/commands/research.swarm.start.js.map +0 -1
  607. package/dist/commands/research.swarm.status.d.ts +0 -3
  608. package/dist/commands/research.swarm.status.d.ts.map +0 -1
  609. package/dist/commands/research.swarm.status.js +0 -26
  610. package/dist/commands/research.swarm.status.js.map +0 -1
  611. package/dist/commands/schema/schema.config.d.ts +0 -3
  612. package/dist/commands/schema/schema.config.d.ts.map +0 -1
  613. package/dist/commands/schema/schema.config.js +0 -34
  614. package/dist/commands/schema/schema.config.js.map +0 -1
  615. package/dist/commands/schema/schema.disable.d.ts +0 -3
  616. package/dist/commands/schema/schema.disable.d.ts.map +0 -1
  617. package/dist/commands/schema/schema.disable.js +0 -22
  618. package/dist/commands/schema/schema.disable.js.map +0 -1
  619. package/dist/commands/schema/schema.enable.d.ts +0 -3
  620. package/dist/commands/schema/schema.enable.d.ts.map +0 -1
  621. package/dist/commands/schema/schema.enable.js +0 -22
  622. package/dist/commands/schema/schema.enable.js.map +0 -1
  623. package/dist/commands/schema/schema.export.d.ts +0 -3
  624. package/dist/commands/schema/schema.export.d.ts.map +0 -1
  625. package/dist/commands/schema/schema.export.js +0 -31
  626. package/dist/commands/schema/schema.export.js.map +0 -1
  627. package/dist/commands/schema/schema.get.d.ts +0 -3
  628. package/dist/commands/schema/schema.get.d.ts.map +0 -1
  629. package/dist/commands/schema/schema.get.js +0 -23
  630. package/dist/commands/schema/schema.get.js.map +0 -1
  631. package/dist/commands/schema/schema.label.d.ts +0 -5
  632. package/dist/commands/schema/schema.label.d.ts.map +0 -1
  633. package/dist/commands/schema/schema.label.js +0 -60
  634. package/dist/commands/schema/schema.label.js.map +0 -1
  635. package/dist/commands/schema/schema.list.d.ts +0 -3
  636. package/dist/commands/schema/schema.list.d.ts.map +0 -1
  637. package/dist/commands/schema/schema.list.js +0 -30
  638. package/dist/commands/schema/schema.list.js.map +0 -1
  639. package/dist/commands/schema/schema.prop.d.ts +0 -5
  640. package/dist/commands/schema/schema.prop.d.ts.map +0 -1
  641. package/dist/commands/schema/schema.prop.js +0 -72
  642. package/dist/commands/schema/schema.prop.js.map +0 -1
  643. package/dist/commands/schema/schema.reconcile.d.ts +0 -10
  644. package/dist/commands/schema/schema.reconcile.d.ts.map +0 -1
  645. package/dist/commands/schema/schema.reconcile.js +0 -65
  646. package/dist/commands/schema/schema.reconcile.js.map +0 -1
  647. package/dist/commands/schema/schema.rel.d.ts +0 -5
  648. package/dist/commands/schema/schema.rel.d.ts.map +0 -1
  649. package/dist/commands/schema/schema.rel.js +0 -65
  650. package/dist/commands/schema/schema.rel.js.map +0 -1
  651. package/dist/commands/schema/schema.version.d.ts +0 -7
  652. package/dist/commands/schema/schema.version.d.ts.map +0 -1
  653. package/dist/commands/schema/schema.version.js +0 -96
  654. package/dist/commands/schema/schema.version.js.map +0 -1
  655. package/dist/commands/secret.d.ts +0 -23
  656. package/dist/commands/secret.d.ts.map +0 -1
  657. package/dist/commands/secret.js +0 -90
  658. package/dist/commands/secret.js.map +0 -1
  659. package/dist/commands/skill.create.d.ts +0 -3
  660. package/dist/commands/skill.create.d.ts.map +0 -1
  661. package/dist/commands/skill.create.js +0 -52
  662. package/dist/commands/skill.create.js.map +0 -1
  663. package/dist/commands/skill.edit.d.ts +0 -3
  664. package/dist/commands/skill.edit.d.ts.map +0 -1
  665. package/dist/commands/skill.edit.js +0 -28
  666. package/dist/commands/skill.edit.js.map +0 -1
  667. package/dist/commands/skill.enable.d.ts +0 -3
  668. package/dist/commands/skill.enable.d.ts.map +0 -1
  669. package/dist/commands/skill.enable.js +0 -31
  670. package/dist/commands/skill.enable.js.map +0 -1
  671. package/dist/commands/skill.export.d.ts +0 -3
  672. package/dist/commands/skill.export.d.ts.map +0 -1
  673. package/dist/commands/skill.export.js +0 -25
  674. package/dist/commands/skill.export.js.map +0 -1
  675. package/dist/commands/skill.metrics.read.d.ts +0 -3
  676. package/dist/commands/skill.metrics.read.d.ts.map +0 -1
  677. package/dist/commands/skill.metrics.read.js +0 -56
  678. package/dist/commands/skill.metrics.read.js.map +0 -1
  679. package/dist/commands/skill.version.activate.d.ts +0 -3
  680. package/dist/commands/skill.version.activate.d.ts.map +0 -1
  681. package/dist/commands/skill.version.activate.js +0 -24
  682. package/dist/commands/skill.version.activate.js.map +0 -1
  683. package/dist/commands/skill.version.get.d.ts +0 -3
  684. package/dist/commands/skill.version.get.d.ts.map +0 -1
  685. package/dist/commands/skill.version.get.js +0 -43
  686. package/dist/commands/skill.version.get.js.map +0 -1
  687. package/dist/commands/skill.version.list.d.ts +0 -3
  688. package/dist/commands/skill.version.list.d.ts.map +0 -1
  689. package/dist/commands/skill.version.list.js +0 -38
  690. package/dist/commands/skill.version.list.js.map +0 -1
  691. package/dist/commands/skill.version.upload.d.ts +0 -3
  692. package/dist/commands/skill.version.upload.d.ts.map +0 -1
  693. package/dist/commands/skill.version.upload.js +0 -28
  694. package/dist/commands/skill.version.upload.js.map +0 -1
  695. package/dist/commands/skill.workspace.install.d.ts +0 -3
  696. package/dist/commands/skill.workspace.install.d.ts.map +0 -1
  697. package/dist/commands/skill.workspace.install.js +0 -52
  698. package/dist/commands/skill.workspace.install.js.map +0 -1
  699. package/dist/commands/skill.workspace.list.d.ts +0 -3
  700. package/dist/commands/skill.workspace.list.d.ts.map +0 -1
  701. package/dist/commands/skill.workspace.list.js +0 -34
  702. package/dist/commands/skill.workspace.list.js.map +0 -1
  703. package/dist/commands/svg.generate.d.ts +0 -3
  704. package/dist/commands/svg.generate.d.ts.map +0 -1
  705. package/dist/commands/svg.generate.js +0 -29
  706. package/dist/commands/svg.generate.js.map +0 -1
  707. package/dist/commands/system.install.instructions.d.ts +0 -3
  708. package/dist/commands/system.install.instructions.d.ts.map +0 -1
  709. package/dist/commands/system.install.instructions.js +0 -34
  710. package/dist/commands/system.install.instructions.js.map +0 -1
  711. package/dist/commands/user.preferences.get.d.ts +0 -3
  712. package/dist/commands/user.preferences.get.d.ts.map +0 -1
  713. package/dist/commands/user.preferences.get.js +0 -20
  714. package/dist/commands/user.preferences.get.js.map +0 -1
  715. package/dist/commands/user.preferences.read.d.ts +0 -3
  716. package/dist/commands/user.preferences.read.d.ts.map +0 -1
  717. package/dist/commands/user.preferences.read.js +0 -30
  718. package/dist/commands/user.preferences.read.js.map +0 -1
  719. package/dist/commands/user.preferences.update.d.ts +0 -3
  720. package/dist/commands/user.preferences.update.d.ts.map +0 -1
  721. package/dist/commands/user.preferences.update.js +0 -36
  722. package/dist/commands/user.preferences.update.js.map +0 -1
  723. package/dist/commands/user.preferences.write.d.ts +0 -3
  724. package/dist/commands/user.preferences.write.d.ts.map +0 -1
  725. package/dist/commands/user.preferences.write.js +0 -47
  726. package/dist/commands/user.preferences.write.js.map +0 -1
  727. package/dist/commands/video.generate.d.ts +0 -3
  728. package/dist/commands/video.generate.d.ts.map +0 -1
  729. package/dist/commands/video.generate.js +0 -27
  730. package/dist/commands/video.generate.js.map +0 -1
  731. package/dist/commands/web.fetch.d.ts +0 -3
  732. package/dist/commands/web.fetch.d.ts.map +0 -1
  733. package/dist/commands/web.fetch.js +0 -39
  734. package/dist/commands/web.fetch.js.map +0 -1
  735. package/dist/commands/web.search.d.ts +0 -3
  736. package/dist/commands/web.search.d.ts.map +0 -1
  737. package/dist/commands/web.search.js +0 -50
  738. package/dist/commands/web.search.js.map +0 -1
  739. package/dist/commands/workflow.cancel.d.ts +0 -3
  740. package/dist/commands/workflow.cancel.d.ts.map +0 -1
  741. package/dist/commands/workflow.cancel.js +0 -25
  742. package/dist/commands/workflow.cancel.js.map +0 -1
  743. package/dist/commands/workflow.run.d.ts +0 -3
  744. package/dist/commands/workflow.run.d.ts.map +0 -1
  745. package/dist/commands/workflow.run.js +0 -41
  746. package/dist/commands/workflow.run.js.map +0 -1
  747. package/dist/commands/workflow.status.d.ts +0 -3
  748. package/dist/commands/workflow.status.d.ts.map +0 -1
  749. package/dist/commands/workflow.status.js +0 -34
  750. package/dist/commands/workflow.status.js.map +0 -1
  751. package/dist/commands/workspace.create.d.ts +0 -3
  752. package/dist/commands/workspace.create.d.ts.map +0 -1
  753. package/dist/commands/workspace.create.js +0 -25
  754. package/dist/commands/workspace.create.js.map +0 -1
  755. package/dist/commands/workspace.invite.send.d.ts +0 -3
  756. package/dist/commands/workspace.invite.send.d.ts.map +0 -1
  757. package/dist/commands/workspace.invite.send.js +0 -33
  758. package/dist/commands/workspace.invite.send.js.map +0 -1
  759. package/dist/commands/workspace.list.d.ts +0 -3
  760. package/dist/commands/workspace.list.d.ts.map +0 -1
  761. package/dist/commands/workspace.list.js +0 -28
  762. package/dist/commands/workspace.list.js.map +0 -1
  763. package/dist/commands/workspace.member.list.d.ts +0 -3
  764. package/dist/commands/workspace.member.list.d.ts.map +0 -1
  765. package/dist/commands/workspace.member.list.js +0 -28
  766. package/dist/commands/workspace.member.list.js.map +0 -1
  767. package/dist/commands/workspace.model.settings.read.d.ts +0 -3
  768. package/dist/commands/workspace.model.settings.read.d.ts.map +0 -1
  769. package/dist/commands/workspace.model.settings.read.js +0 -22
  770. package/dist/commands/workspace.model.settings.read.js.map +0 -1
  771. package/dist/commands/workspace.model.settings.write.d.ts +0 -3
  772. package/dist/commands/workspace.model.settings.write.d.ts.map +0 -1
  773. package/dist/commands/workspace.model.settings.write.js +0 -26
  774. package/dist/commands/workspace.model.settings.write.js.map +0 -1
  775. package/dist/commands.test.d.ts +0 -2
  776. package/dist/commands.test.d.ts.map +0 -1
  777. package/dist/commands.test.js +0 -3454
  778. package/dist/commands.test.js.map +0 -1
  779. package/dist/components/DevStatus.d.ts +0 -2
  780. package/dist/components/DevStatus.d.ts.map +0 -1
  781. package/dist/components/DevStatus.js +0 -62
  782. package/dist/components/DevStatus.js.map +0 -1
  783. package/dist/components/DevStatus.test.d.ts +0 -2
  784. package/dist/components/DevStatus.test.d.ts.map +0 -1
  785. package/dist/components/DevStatus.test.js +0 -108
  786. package/dist/components/DevStatus.test.js.map +0 -1
  787. package/dist/daemon/client.d.ts +0 -30
  788. package/dist/daemon/client.d.ts.map +0 -1
  789. package/dist/daemon/client.js +0 -97
  790. package/dist/daemon/client.js.map +0 -1
  791. package/dist/daemon/code-graph/builder.d.ts +0 -6
  792. package/dist/daemon/code-graph/builder.d.ts.map +0 -1
  793. package/dist/daemon/code-graph/builder.js +0 -215
  794. package/dist/daemon/code-graph/builder.js.map +0 -1
  795. package/dist/daemon/code-graph/query.d.ts +0 -29
  796. package/dist/daemon/code-graph/query.d.ts.map +0 -1
  797. package/dist/daemon/code-graph/query.js +0 -98
  798. package/dist/daemon/code-graph/query.js.map +0 -1
  799. package/dist/daemon/code-graph/types.d.ts +0 -37
  800. package/dist/daemon/code-graph/types.d.ts.map +0 -1
  801. package/dist/daemon/code-graph/types.js +0 -5
  802. package/dist/daemon/code-graph/types.js.map +0 -1
  803. package/dist/daemon/code-graph/watcher.d.ts +0 -37
  804. package/dist/daemon/code-graph/watcher.d.ts.map +0 -1
  805. package/dist/daemon/code-graph/watcher.js +0 -79
  806. package/dist/daemon/code-graph/watcher.js.map +0 -1
  807. package/dist/daemon/lifecycle.d.ts +0 -6
  808. package/dist/daemon/lifecycle.d.ts.map +0 -1
  809. package/dist/daemon/lifecycle.js +0 -132
  810. package/dist/daemon/lifecycle.js.map +0 -1
  811. package/dist/daemon/protocol.d.ts +0 -113
  812. package/dist/daemon/protocol.d.ts.map +0 -1
  813. package/dist/daemon/protocol.js +0 -16
  814. package/dist/daemon/protocol.js.map +0 -1
  815. package/dist/daemon/server.d.ts +0 -26
  816. package/dist/daemon/server.d.ts.map +0 -1
  817. package/dist/daemon/server.js +0 -168
  818. package/dist/daemon/server.js.map +0 -1
  819. package/dist/index.d.ts +0 -3
  820. package/dist/index.d.ts.map +0 -1
  821. package/dist/index.js +0 -270
  822. package/dist/index.js.map +0 -1
  823. package/dist/lib/api-client.d.ts +0 -7
  824. package/dist/lib/api-client.d.ts.map +0 -1
  825. package/dist/lib/api-client.js +0 -40
  826. package/dist/lib/api-client.js.map +0 -1
  827. package/dist/lib/api-client.test.d.ts +0 -2
  828. package/dist/lib/api-client.test.d.ts.map +0 -1
  829. package/dist/lib/api-client.test.js +0 -89
  830. package/dist/lib/api-client.test.js.map +0 -1
  831. package/dist/lib/api.d.ts +0 -5
  832. package/dist/lib/api.d.ts.map +0 -1
  833. package/dist/lib/api.js +0 -52
  834. package/dist/lib/api.js.map +0 -1
  835. package/dist/lib/config.d.ts +0 -17
  836. package/dist/lib/config.d.ts.map +0 -1
  837. package/dist/lib/config.js +0 -51
  838. package/dist/lib/config.js.map +0 -1
  839. package/dist/lib/config.test.d.ts +0 -2
  840. package/dist/lib/config.test.d.ts.map +0 -1
  841. package/dist/lib/config.test.js +0 -121
  842. package/dist/lib/config.test.js.map +0 -1
  843. package/dist/lib/differential-context.d.ts +0 -46
  844. package/dist/lib/differential-context.d.ts.map +0 -1
  845. package/dist/lib/differential-context.js +0 -89
  846. package/dist/lib/differential-context.js.map +0 -1
  847. package/dist/lib/resolve.d.ts +0 -3
  848. package/dist/lib/resolve.d.ts.map +0 -1
  849. package/dist/lib/resolve.js +0 -29
  850. package/dist/lib/resolve.js.map +0 -1
  851. package/dist/lib/structured-tool-io.d.ts +0 -31
  852. package/dist/lib/structured-tool-io.d.ts.map +0 -1
  853. package/dist/lib/structured-tool-io.js +0 -56
  854. package/dist/lib/structured-tool-io.js.map +0 -1
  855. package/dist/repl/__tests__/_queue_demo.test.d.ts +0 -2
  856. package/dist/repl/__tests__/_queue_demo.test.d.ts.map +0 -1
  857. package/dist/repl/__tests__/_queue_demo.test.js +0 -40
  858. package/dist/repl/__tests__/_queue_demo.test.js.map +0 -1
  859. package/dist/repl/__tests__/components.test.d.ts +0 -2
  860. package/dist/repl/__tests__/components.test.d.ts.map +0 -1
  861. package/dist/repl/__tests__/components.test.js +0 -38
  862. package/dist/repl/__tests__/components.test.js.map +0 -1
  863. package/dist/repl/__tests__/interactive.queue.test.d.ts +0 -2
  864. package/dist/repl/__tests__/interactive.queue.test.d.ts.map +0 -1
  865. package/dist/repl/__tests__/interactive.queue.test.js +0 -124
  866. package/dist/repl/__tests__/interactive.queue.test.js.map +0 -1
  867. package/dist/repl/components.d.ts +0 -59
  868. package/dist/repl/components.d.ts.map +0 -1
  869. package/dist/repl/components.js +0 -152
  870. package/dist/repl/components.js.map +0 -1
  871. package/dist/repl/interactive.d.ts +0 -12
  872. package/dist/repl/interactive.d.ts.map +0 -1
  873. package/dist/repl/interactive.js +0 -326
  874. package/dist/repl/interactive.js.map +0 -1
  875. package/dist/repl/one-shot.d.ts +0 -9
  876. package/dist/repl/one-shot.d.ts.map +0 -1
  877. package/dist/repl/one-shot.js +0 -83
  878. package/dist/repl/one-shot.js.map +0 -1
  879. package/dist/tui/__tests__/app.test.d.ts +0 -2
  880. package/dist/tui/__tests__/app.test.d.ts.map +0 -1
  881. package/dist/tui/__tests__/app.test.js +0 -136
  882. package/dist/tui/__tests__/app.test.js.map +0 -1
  883. package/dist/tui/__tests__/banner.test.d.ts +0 -2
  884. package/dist/tui/__tests__/banner.test.d.ts.map +0 -1
  885. package/dist/tui/__tests__/banner.test.js +0 -15
  886. package/dist/tui/__tests__/banner.test.js.map +0 -1
  887. package/dist/tui/__tests__/command-form.test.d.ts +0 -2
  888. package/dist/tui/__tests__/command-form.test.d.ts.map +0 -1
  889. package/dist/tui/__tests__/command-form.test.js +0 -96
  890. package/dist/tui/__tests__/command-form.test.js.map +0 -1
  891. package/dist/tui/__tests__/command-tree.test.d.ts +0 -2
  892. package/dist/tui/__tests__/command-tree.test.d.ts.map +0 -1
  893. package/dist/tui/__tests__/command-tree.test.js +0 -55
  894. package/dist/tui/__tests__/command-tree.test.js.map +0 -1
  895. package/dist/tui/__tests__/runner.test.d.ts +0 -2
  896. package/dist/tui/__tests__/runner.test.d.ts.map +0 -1
  897. package/dist/tui/__tests__/runner.test.js +0 -38
  898. package/dist/tui/__tests__/runner.test.js.map +0 -1
  899. package/dist/tui/__tests__/theme.test.d.ts +0 -2
  900. package/dist/tui/__tests__/theme.test.d.ts.map +0 -1
  901. package/dist/tui/__tests__/theme.test.js +0 -11
  902. package/dist/tui/__tests__/theme.test.js.map +0 -1
  903. package/dist/tui/agent-view/activity-feed.d.ts +0 -3
  904. package/dist/tui/agent-view/activity-feed.d.ts.map +0 -1
  905. package/dist/tui/agent-view/activity-feed.js +0 -34
  906. package/dist/tui/agent-view/activity-feed.js.map +0 -1
  907. package/dist/tui/agent-view/budget-bar.d.ts +0 -3
  908. package/dist/tui/agent-view/budget-bar.d.ts.map +0 -1
  909. package/dist/tui/agent-view/budget-bar.js +0 -53
  910. package/dist/tui/agent-view/budget-bar.js.map +0 -1
  911. package/dist/tui/agent-view/compile-panel.d.ts +0 -3
  912. package/dist/tui/agent-view/compile-panel.d.ts.map +0 -1
  913. package/dist/tui/agent-view/compile-panel.js +0 -34
  914. package/dist/tui/agent-view/compile-panel.js.map +0 -1
  915. package/dist/tui/agent-view/index.d.ts +0 -4
  916. package/dist/tui/agent-view/index.d.ts.map +0 -1
  917. package/dist/tui/agent-view/index.js +0 -31
  918. package/dist/tui/agent-view/index.js.map +0 -1
  919. package/dist/tui/agent-view/memory-panel.d.ts +0 -3
  920. package/dist/tui/agent-view/memory-panel.d.ts.map +0 -1
  921. package/dist/tui/agent-view/memory-panel.js +0 -80
  922. package/dist/tui/agent-view/memory-panel.js.map +0 -1
  923. package/dist/tui/agent-view/session-panel.d.ts +0 -3
  924. package/dist/tui/agent-view/session-panel.d.ts.map +0 -1
  925. package/dist/tui/agent-view/session-panel.js +0 -44
  926. package/dist/tui/agent-view/session-panel.js.map +0 -1
  927. package/dist/tui/agent-view/status-bar.d.ts +0 -7
  928. package/dist/tui/agent-view/status-bar.d.ts.map +0 -1
  929. package/dist/tui/agent-view/status-bar.js +0 -22
  930. package/dist/tui/agent-view/status-bar.js.map +0 -1
  931. package/dist/tui/app.d.ts +0 -9
  932. package/dist/tui/app.d.ts.map +0 -1
  933. package/dist/tui/app.js +0 -115
  934. package/dist/tui/app.js.map +0 -1
  935. package/dist/tui/banner.d.ts +0 -5
  936. package/dist/tui/banner.d.ts.map +0 -1
  937. package/dist/tui/banner.js +0 -17
  938. package/dist/tui/banner.js.map +0 -1
  939. package/dist/tui/command-form.d.ts +0 -9
  940. package/dist/tui/command-form.d.ts.map +0 -1
  941. package/dist/tui/command-form.js +0 -76
  942. package/dist/tui/command-form.js.map +0 -1
  943. package/dist/tui/command-tree.d.ts +0 -30
  944. package/dist/tui/command-tree.d.ts.map +0 -1
  945. package/dist/tui/command-tree.js +0 -43
  946. package/dist/tui/command-tree.js.map +0 -1
  947. package/dist/tui/fleet-view/agent-row.d.ts +0 -10
  948. package/dist/tui/fleet-view/agent-row.d.ts.map +0 -1
  949. package/dist/tui/fleet-view/agent-row.js +0 -80
  950. package/dist/tui/fleet-view/agent-row.js.map +0 -1
  951. package/dist/tui/fleet-view/dispatch-input.d.ts +0 -5
  952. package/dist/tui/fleet-view/dispatch-input.d.ts.map +0 -1
  953. package/dist/tui/fleet-view/dispatch-input.js +0 -36
  954. package/dist/tui/fleet-view/dispatch-input.js.map +0 -1
  955. package/dist/tui/fleet-view/fleet-app.d.ts +0 -11
  956. package/dist/tui/fleet-view/fleet-app.d.ts.map +0 -1
  957. package/dist/tui/fleet-view/fleet-app.js +0 -95
  958. package/dist/tui/fleet-view/fleet-app.js.map +0 -1
  959. package/dist/tui/fleet-view/fleet-summary.d.ts +0 -6
  960. package/dist/tui/fleet-view/fleet-summary.d.ts.map +0 -1
  961. package/dist/tui/fleet-view/fleet-summary.js +0 -19
  962. package/dist/tui/fleet-view/fleet-summary.js.map +0 -1
  963. package/dist/tui/fleet-view/index.d.ts +0 -16
  964. package/dist/tui/fleet-view/index.d.ts.map +0 -1
  965. package/dist/tui/fleet-view/index.js +0 -61
  966. package/dist/tui/fleet-view/index.js.map +0 -1
  967. package/dist/tui/runner.d.ts +0 -7
  968. package/dist/tui/runner.d.ts.map +0 -1
  969. package/dist/tui/runner.js +0 -36
  970. package/dist/tui/runner.js.map +0 -1
  971. package/dist/tui/theme.d.ts +0 -8
  972. package/dist/tui/theme.d.ts.map +0 -1
  973. package/dist/tui/theme.js +0 -10
  974. package/dist/tui/theme.js.map +0 -1
@@ -1,3454 +0,0 @@
1
- import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
2
- // Mock config and api-client before importing commands that use them
3
- vi.mock("./lib/config.js", () => ({
4
- getToken: vi.fn(() => "test-token"),
5
- getApiUrl: vi.fn(() => "http://localhost:4000"),
6
- readConfig: vi.fn(() => ({
7
- token: "test-token",
8
- orgSlug: "my-org",
9
- workspaceSlug: "default",
10
- })),
11
- writeConfig: vi.fn(),
12
- clearConfig: vi.fn(),
13
- getOrgId: vi.fn(() => "my-org"),
14
- getWorkspaceId: vi.fn(() => "default"),
15
- }));
16
- vi.mock("./lib/api-client.js", () => ({
17
- apiRequest: vi.fn(),
18
- requireAuth: vi.fn(),
19
- ApiError: class ApiError extends Error {
20
- status;
21
- constructor(status, message) {
22
- super(message);
23
- this.status = status;
24
- this.name = "ApiError";
25
- }
26
- },
27
- }));
28
- import { authLoginCommand } from "./commands/auth.login.js";
29
- import { authLogoutCommand } from "./commands/auth.logout.js";
30
- import { authWhoamiCommand } from "./commands/auth.whoami.js";
31
- import { orgListCommand } from "./commands/org.list.js";
32
- import { orgCreateCommand } from "./commands/org.create.js";
33
- import { orgMemberAddCommand } from "./commands/org.member.add.js";
34
- import { orgMemberRemoveCommand } from "./commands/org.member.remove.js";
35
- import { workspaceListCommand } from "./commands/workspace.list.js";
36
- import { workspaceCreateCommand } from "./commands/workspace.create.js";
37
- import { chatSendCommand } from "./commands/chat.send.js";
38
- import { conversationListCommand } from "./commands/conversation.list.js";
39
- import { conversationDeleteCommand } from "./commands/conversation.delete.js";
40
- import { conversationArchiveCommand } from "./commands/conversation.archive.js";
41
- import { conversationRenameCommand } from "./commands/conversation.rename.js";
42
- import { apiKeyCreateCommand } from "./commands/api-key.create.js";
43
- import { apiKeyRevokeCommand } from "./commands/api-key.revoke.js";
44
- import { notificationsListCommand } from "./commands/notifications.list.js";
45
- import { notificationsMarkCommand } from "./commands/notifications.mark.js";
46
- import { pluginListCommand } from "./commands/plugin.list.js";
47
- import { pluginInstallCommand } from "./commands/plugin.install.js";
48
- import { pluginUninstallCommand } from "./commands/plugin.uninstall.js";
49
- import { pluginOrgInstallCommand } from "./commands/plugin.org.install.js";
50
- import { pluginOrgUninstallCommand } from "./commands/plugin.org.uninstall.js";
51
- import { pluginCatalogGetCommand } from "./commands/plugin.catalog.get.js";
52
- import { billingStatusCommand } from "./commands/billing.status.js";
53
- import { billingCreditsPurchaseCommand } from "./commands/billing.credits.purchase.js";
54
- import { billingSubscriptionReadCommand } from "./commands/billing.subscription.read.js";
55
- import { agentMcpListCommand } from "./commands/agent.mcp.list.js";
56
- import { agentSkillListCommand } from "./commands/agent.skill.list.js";
57
- import { agentToolListCommand } from "./commands/agent.tool.list.js";
58
- import { orgMemberRoleChangeCommand } from "./commands/org.member.role.change.js";
59
- import { agentApprovalResolveCommand } from "./commands/agent.approval.resolve.js";
60
- import { archiveCreateCommand } from "./commands/archive.create.js";
61
- import { workflowRunCommand } from "./commands/workflow.run.js";
62
- import { userPreferencesGetCommand } from "./commands/user.preferences.get.js";
63
- import { userPreferencesUpdateCommand } from "./commands/user.preferences.update.js";
64
- import { workspaceMemberListCommand } from "./commands/workspace.member.list.js";
65
- import { workspaceInviteSendCommand } from "./commands/workspace.invite.send.js";
66
- import { conversationChatCommand } from "./commands/conversation.chat.js";
67
- import { imageCreateCommand } from "./commands/image.create.js";
68
- import { documentCreateCommand } from "./commands/document.create.js";
69
- import { automationListCommand } from "./commands/automation.list.js";
70
- import { imageListCommand } from "./commands/image.list.js";
71
- import { imageAnalyzeCommand } from "./commands/image.analyze.js";
72
- import { documentListCommand } from "./commands/document.list.js";
73
- import { documentReadCommand } from "./commands/document.read.js";
74
- import { automationCreateCommand } from "./commands/automation.create.js";
75
- import { automationEnableCommand } from "./commands/automation.enable.js";
76
- import { automationDisableCommand } from "./commands/automation.disable.js";
77
- import { automationTriggerCommand } from "./commands/automation.trigger.js";
78
- import { skillWorkspaceListCommand } from "./commands/skill.workspace.list.js";
79
- import { agentMemoryRecallCommand } from "./commands/agent.memory.recall.js";
80
- import { agentMemoryWriteCommand } from "./commands/agent.memory.write.js";
81
- import { documentsGenerateCommand } from "./commands/documents.generate.js";
82
- import { imageGenerateCommand } from "./commands/image.generate.js";
83
- import { orgMemberInviteAcceptCommand } from "./commands/org.member.invite.accept.js";
84
- import { pluginCatalogBrowseCommand } from "./commands/plugin.catalog.browse.js";
85
- import { pluginCredentialReauthCommand } from "./commands/plugin.credential.reauth.js";
86
- import { pluginRegistryAddCommand } from "./commands/plugin.registry.add.js";
87
- import { pluginRegistryListCommand } from "./commands/plugin.registry.list.js";
88
- import { svgGenerateCommand } from "./commands/svg.generate.js";
89
- import { videoGenerateCommand } from "./commands/video.generate.js";
90
- import { workspaceModelSettingsReadCommand } from "./commands/workspace.model.settings.read.js";
91
- import { workspaceModelSettingsWriteCommand } from "./commands/workspace.model.settings.write.js";
92
- import { agentMcpRegisterCommand } from "./commands/agent.mcp.register.js";
93
- import { agentPlanApproveCommand } from "./commands/agent.plan.approve.js";
94
- import { agentTaskBackgroundStartCommand } from "./commands/agent.task.background.start.js";
95
- import { agentTaskBackgroundReadCommand } from "./commands/agent.task.background.read.js";
96
- import { agentTaskBackgroundCancelCommand } from "./commands/agent.task.background.cancel.js";
97
- import { assetUploadCommand } from "./commands/asset.upload.js";
98
- import { billingSubscriptionUpgradeStartCommand } from "./commands/billing.subscription.upgrade.start.js";
99
- import { conversationPurgeCommand } from "./commands/conversation.purge.js";
100
- import { documentsPdfCreateCommand } from "./commands/documents.pdf.create.js";
101
- import { formFillCommand } from "./commands/form.fill.js";
102
- import { orgMemberInviteDeclineCommand } from "./commands/org.member.invite.decline.js";
103
- import { organizationCreateCommand } from "./commands/organization.create.js";
104
- import { pluginCredentialSetSecretCommand } from "./commands/plugin.credential.set_secret.js";
105
- import { pluginOrgInstallBulkCommand } from "./commands/plugin.org.install_bulk.js";
106
- import { pluginOrgListCommand } from "./commands/plugin.org.list.js";
107
- import { pluginOrgSetEnabledCommand } from "./commands/plugin.org.set_enabled.js";
108
- import { pluginRegistryRemoveCommand } from "./commands/plugin.registry.remove.js";
109
- import { pluginSettingsSetAuthAlertsCommand } from "./commands/plugin.settings.set_auth_alerts.js";
110
- import { pluginWorkspaceSetEnabledCommand } from "./commands/plugin.workspace.set_enabled.js";
111
- import { systemInstallInstructionsCommand } from "./commands/system.install.instructions.js";
112
- import { userPreferencesReadCommand } from "./commands/user.preferences.read.js";
113
- import { userPreferencesWriteCommand } from "./commands/user.preferences.write.js";
114
- import { workflowCancelCommand } from "./commands/workflow.cancel.js";
115
- import { workflowStatusCommand } from "./commands/workflow.status.js";
116
- import * as apiClient from "./lib/api-client.js";
117
- import * as config from "./lib/config.js";
118
- const mockApiRequest = vi.mocked(apiClient.apiRequest);
119
- const mockRequireAuth = vi.mocked(apiClient.requireAuth);
120
- const mockWriteConfig = vi.mocked(config.writeConfig);
121
- const mockClearConfig = vi.mocked(config.clearConfig);
122
- const mockGetToken = vi.mocked(config.getToken);
123
- const mockGetOrgId = vi.mocked(config.getOrgId);
124
- const mockGetWorkspaceId = vi.mocked(config.getWorkspaceId);
125
- // Helper: throw an ApiError through apiRequest mock (covers instanceof branch in catch blocks)
126
- function mockApiError(status, message) {
127
- const ApiErrorClass = apiClient.ApiError;
128
- mockApiRequest.mockRejectedValueOnce(new ApiErrorClass(status, message));
129
- }
130
- beforeEach(() => {
131
- vi.clearAllMocks();
132
- mockRequireAuth.mockImplementation(() => { });
133
- });
134
- afterEach(() => {
135
- vi.restoreAllMocks();
136
- });
137
- // ---------------------------------------------------------------------------
138
- // auth login
139
- // ---------------------------------------------------------------------------
140
- describe("auth login", () => {
141
- it("exits 1 if email or password is missing", async () => {
142
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
143
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
144
- throw new Error("exit");
145
- });
146
- await expect(() => authLoginCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
147
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("email and password are required"));
148
- consoleSpy.mockRestore();
149
- exitSpy.mockRestore();
150
- });
151
- it("calls API with credentials and stores token", async () => {
152
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
165
- expect(mockApiRequest).toHaveBeenCalledWith("/auth/sign-in/email", expect.objectContaining({ method: "POST" }));
166
- expect(mockWriteConfig).toHaveBeenCalledWith(expect.objectContaining({ token: "new-token" }));
167
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Authenticated"));
168
- consoleSpy.mockRestore();
169
- });
170
- it("exits 1 on API error during login", async () => {
171
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
172
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
173
- throw new Error("exit");
174
- });
175
- mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
176
- await expect(() => authLoginCommand.parseAsync([
177
- "node",
178
- "cli",
179
- "--email",
180
- "a@b.com",
181
- "--password",
182
- "pw",
183
- ])).rejects.toThrow("exit");
184
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
185
- consoleSpy.mockRestore();
186
- exitSpy.mockRestore();
187
- });
188
- it("handles response with session.token shape", async () => {
189
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
190
- mockApiRequest.mockResolvedValueOnce({ session: { token: "session-tok" } });
191
- await authLoginCommand.parseAsync([
192
- "node",
193
- "cli",
194
- "-e",
195
- "a@b.com",
196
- "-p",
197
- "pw",
198
- ]);
199
- expect(mockWriteConfig).toHaveBeenCalledWith(expect.objectContaining({ token: "session-tok" }));
200
- consoleSpy.mockRestore();
201
- });
202
- });
203
- // ---------------------------------------------------------------------------
204
- // auth logout
205
- // ---------------------------------------------------------------------------
206
- describe("auth logout", () => {
207
- it("clears config and reports success", async () => {
208
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
209
- mockGetToken.mockReturnValue("old-token");
210
- mockApiRequest.mockResolvedValueOnce({});
211
- await authLogoutCommand.parseAsync(["node", "cli"]);
212
- expect(mockClearConfig).toHaveBeenCalled();
213
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Signing out"));
214
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Signed out"));
215
- consoleSpy.mockRestore();
216
- });
217
- it("clears config even if sign-out API fails", async () => {
218
- mockGetToken.mockReturnValue("tok");
219
- mockApiRequest.mockRejectedValueOnce(new Error("network error"));
220
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
221
- await authLogoutCommand.parseAsync(["node", "cli"]);
222
- expect(mockClearConfig).toHaveBeenCalled();
223
- consoleSpy.mockRestore();
224
- });
225
- it("skips sign-out API call when no token is stored", async () => {
226
- mockGetToken.mockReturnValue(undefined);
227
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
228
- await authLogoutCommand.parseAsync(["node", "cli"]);
229
- expect(mockApiRequest).not.toHaveBeenCalled();
230
- expect(mockClearConfig).toHaveBeenCalled();
231
- consoleSpy.mockRestore();
232
- });
233
- });
234
- // ---------------------------------------------------------------------------
235
- // auth whoami
236
- // ---------------------------------------------------------------------------
237
- describe("auth whoami", () => {
238
- it("displays user, org, and workspace", async () => {
239
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
240
- mockApiRequest.mockResolvedValueOnce({
241
- user: { email: "mac@example.com" },
242
- org: { slug: "my-org" },
243
- workspace: { slug: "default" },
244
- });
245
- await authWhoamiCommand.parseAsync(["node", "cli"]);
246
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("mac@example.com"));
247
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("my-org"));
248
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("default"));
249
- consoleSpy.mockRestore();
250
- });
251
- it("falls back to config values for org/workspace", async () => {
252
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- });
260
- await authWhoamiCommand.parseAsync(["node", "cli"]);
261
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cfg-org"));
262
- consoleSpy.mockRestore();
263
- });
264
- it("exits 1 on API error", async () => {
265
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
266
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
267
- throw new Error("exit");
268
- });
269
- mockApiRequest.mockRejectedValueOnce(new Error("Forbidden"));
270
- await expect(() => authWhoamiCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
271
- consoleSpy.mockRestore();
272
- exitSpy.mockRestore();
273
- });
274
- });
275
- // ---------------------------------------------------------------------------
276
- // org list
277
- // ---------------------------------------------------------------------------
278
- describe("org list", () => {
279
- it("prints organization list", async () => {
280
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
281
- mockApiRequest.mockResolvedValueOnce({
282
- organizations: [{ slug: "acme", name: "ACME Corp" }],
283
- });
284
- await orgListCommand.parseAsync(["node", "cli"]);
285
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Organizations"));
286
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("acme"));
287
- consoleSpy.mockRestore();
288
- });
289
- it("prints empty message when no orgs", async () => {
290
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
291
- mockApiRequest.mockResolvedValueOnce({ organizations: [] });
292
- await orgListCommand.parseAsync(["node", "cli"]);
293
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("No organizations"));
294
- consoleSpy.mockRestore();
295
- });
296
- it("handles data array shape from API", async () => {
297
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
298
- mockApiRequest.mockResolvedValueOnce({
299
- data: [{ id: "id1", slug: "org-1", name: "Org 1" }],
300
- });
301
- await orgListCommand.parseAsync(["node", "cli"]);
302
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("org-1"));
303
- consoleSpy.mockRestore();
304
- });
305
- });
306
- // ---------------------------------------------------------------------------
307
- // org create
308
- // ---------------------------------------------------------------------------
309
- describe("org create", () => {
310
- it("creates org and prints slug", async () => {
311
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
312
- mockApiRequest.mockResolvedValueOnce({
313
- organization: { slug: "new-org", name: "New Org" },
314
- });
315
- await orgCreateCommand.parseAsync(["node", "cli", "New Org"]);
316
- expect(mockApiRequest).toHaveBeenCalledWith("/organizations", expect.objectContaining({ method: "POST" }));
317
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("new-org"));
318
- consoleSpy.mockRestore();
319
- });
320
- it("exits 1 on API error", async () => {
321
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
322
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
323
- throw new Error("exit");
324
- });
325
- mockApiRequest.mockRejectedValueOnce(new Error("Conflict"));
326
- await expect(() => orgCreateCommand.parseAsync(["node", "cli", "Dup"])).rejects.toThrow("exit");
327
- consoleSpy.mockRestore();
328
- exitSpy.mockRestore();
329
- });
330
- });
331
- // ---------------------------------------------------------------------------
332
- // org member add / remove
333
- // ---------------------------------------------------------------------------
334
- describe("org member add", () => {
335
- it("adds member and confirms", async () => {
336
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
337
- mockApiRequest.mockResolvedValueOnce({});
338
- await orgMemberAddCommand.parseAsync([
339
- "node",
340
- "cli",
341
- "new@example.com",
342
- "--role",
343
- "admin",
344
- ]);
345
- expect(mockApiRequest).toHaveBeenCalledWith("/org/members", expect.objectContaining({ method: "POST" }));
346
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("new@example.com"));
347
- consoleSpy.mockRestore();
348
- });
349
- it("defaults role to member when no --role flag given", async () => {
350
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
351
- mockApiRequest.mockResolvedValueOnce({});
352
- await orgMemberAddCommand.parseAsync([
353
- "node",
354
- "cli",
355
- "x@example.com",
356
- "--role",
357
- "member",
358
- ]);
359
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("member"));
360
- consoleSpy.mockRestore();
361
- });
362
- });
363
- describe("org member remove", () => {
364
- it("removes member and confirms", async () => {
365
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
366
- mockApiRequest.mockResolvedValueOnce({});
367
- await orgMemberRemoveCommand.parseAsync(["node", "cli", "old@example.com"]);
368
- expect(mockApiRequest).toHaveBeenCalledWith("/org/members", expect.objectContaining({ method: "DELETE" }));
369
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("old@example.com"));
370
- consoleSpy.mockRestore();
371
- });
372
- });
373
- // ---------------------------------------------------------------------------
374
- // workspace list / create
375
- // ---------------------------------------------------------------------------
376
- describe("workspace list", () => {
377
- it("prints workspace list", async () => {
378
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
379
- mockApiRequest.mockResolvedValueOnce({
380
- workspaces: [{ slug: "default", name: "Default" }],
381
- });
382
- await workspaceListCommand.parseAsync(["node", "cli"]);
383
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Workspaces"));
384
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("default"));
385
- consoleSpy.mockRestore();
386
- });
387
- it("prints empty message when no workspaces", async () => {
388
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
389
- mockApiRequest.mockResolvedValueOnce({ workspaces: [] });
390
- await workspaceListCommand.parseAsync(["node", "cli"]);
391
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("No workspaces"));
392
- consoleSpy.mockRestore();
393
- });
394
- it("passes org query param when provided", async () => {
395
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
396
- mockApiRequest.mockResolvedValueOnce({ workspaces: [] });
397
- await workspaceListCommand.parseAsync(["node", "cli", "--org", "my-org"]);
398
- expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("my-org"));
399
- consoleSpy.mockRestore();
400
- });
401
- });
402
- describe("workspace create", () => {
403
- it("creates workspace and prints slug", async () => {
404
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
405
- mockApiRequest.mockResolvedValueOnce({
406
- workspace: { slug: "my-ws", name: "My WS" },
407
- });
408
- await workspaceCreateCommand.parseAsync(["node", "cli", "My WS"]);
409
- expect(mockApiRequest).toHaveBeenCalledWith("/workspaces", expect.objectContaining({ method: "POST" }));
410
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("my-ws"));
411
- consoleSpy.mockRestore();
412
- });
413
- });
414
- // ---------------------------------------------------------------------------
415
- // chat send
416
- // ---------------------------------------------------------------------------
417
- // chat.send uses native fetch() directly for SSE streaming (not apiRequest).
418
- // Build minimal SSE response helpers here.
419
- function makeSseResponse(text) {
420
- const line = `data: ${JSON.stringify({ type: "text", text })}\n\nevent: done\ndata: [DONE]\n\n`;
421
- const encoder = new TextEncoder();
422
- const stream = new ReadableStream({
423
- start(c) {
424
- c.enqueue(encoder.encode(line));
425
- c.close();
426
- },
427
- });
428
- return new Response(stream, {
429
- status: 200,
430
- headers: { "content-type": "text/event-stream" },
431
- });
432
- }
433
- function makeErrorResponse(status, message) {
434
- return new Response(JSON.stringify({ error: message }), {
435
- status,
436
- headers: { "content-type": "application/json" },
437
- });
438
- }
439
- describe("chat send", () => {
440
- afterEach(() => {
441
- vi.restoreAllMocks();
442
- });
443
- it("sends message and streams response to stdout", async () => {
444
- const stdoutSpy = vi
445
- .spyOn(process.stdout, "write")
446
- .mockImplementation(() => true);
447
- vi.spyOn(global, "fetch").mockResolvedValueOnce(makeSseResponse("Hello back!"));
448
- await chatSendCommand.parseAsync(["node", "cli", "hello"]);
449
- const written = stdoutSpy.mock.calls.map((c) => String(c[0])).join("");
450
- expect(written).toContain("Hello back!");
451
- stdoutSpy.mockRestore();
452
- });
453
- it("passes conversationId when --conversation is provided", async () => {
454
- const stdoutSpy = vi
455
- .spyOn(process.stdout, "write")
456
- .mockImplementation(() => true);
457
- let capturedBody = null;
458
- vi.spyOn(global, "fetch").mockImplementationOnce(async (_url, init) => {
459
- capturedBody = JSON.parse(init.body);
460
- return makeSseResponse("ok");
461
- });
462
- await chatSendCommand.parseAsync([
463
- "node",
464
- "cli",
465
- "hi",
466
- "--conversation",
467
- "cnv_abc",
468
- ]);
469
- expect(capturedBody["conversationId"]).toBe("cnv_abc");
470
- stdoutSpy.mockRestore();
471
- });
472
- it("exits 1 when fetch throws a network error", async () => {
473
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
474
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
475
- throw new Error("exit");
476
- });
477
- vi.spyOn(global, "fetch").mockRejectedValueOnce(new Error("ECONNREFUSED"));
478
- await expect(() => chatSendCommand.parseAsync(["node", "cli", "msg"])).rejects.toThrow("exit");
479
- consoleSpy.mockRestore();
480
- exitSpy.mockRestore();
481
- });
482
- it("exits 1 on non-ok HTTP response", async () => {
483
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
484
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
485
- throw new Error("exit");
486
- });
487
- vi.spyOn(global, "fetch").mockResolvedValueOnce(makeErrorResponse(503, "Service unavailable"));
488
- await expect(() => chatSendCommand.parseAsync(["node", "cli", "test"])).rejects.toThrow();
489
- consoleSpy.mockRestore();
490
- exitSpy.mockRestore();
491
- });
492
- });
493
- // ---------------------------------------------------------------------------
494
- // conversation commands
495
- // ---------------------------------------------------------------------------
496
- describe("conversation list", () => {
497
- it("lists conversations", async () => {
498
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
499
- mockApiRequest.mockResolvedValueOnce({
500
- conversations: [{ publicId: "cnv_1", title: "First conversation" }],
501
- });
502
- await conversationListCommand.parseAsync(["node", "cli"]);
503
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Conversations"));
504
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cnv_1"));
505
- consoleSpy.mockRestore();
506
- });
507
- it("shows empty message when no conversations", async () => {
508
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
509
- mockApiRequest.mockResolvedValueOnce({ conversations: [] });
510
- await conversationListCommand.parseAsync(["node", "cli"]);
511
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("No conversations"));
512
- consoleSpy.mockRestore();
513
- });
514
- it("passes filter and limit params", async () => {
515
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
516
- mockApiRequest.mockResolvedValueOnce({ conversations: [] });
517
- await conversationListCommand.parseAsync([
518
- "node",
519
- "cli",
520
- "--filter",
521
- "archived",
522
- "--limit",
523
- "5",
524
- ]);
525
- expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("archived"));
526
- consoleSpy.mockRestore();
527
- });
528
- });
529
- describe("conversation delete", () => {
530
- it("deletes conversation and confirms", async () => {
531
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
532
- mockApiRequest.mockResolvedValueOnce({});
533
- await conversationDeleteCommand.parseAsync(["node", "cli", "cnv_abc"]);
534
- expect(mockApiRequest).toHaveBeenCalledWith("/conversations/cnv_abc", expect.objectContaining({ method: "DELETE" }));
535
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cnv_abc"));
536
- consoleSpy.mockRestore();
537
- });
538
- it("exits 1 on not found", async () => {
539
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
540
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
541
- throw new Error("exit");
542
- });
543
- mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
544
- await expect(() => conversationDeleteCommand.parseAsync(["node", "cli", "bad"])).rejects.toThrow("exit");
545
- consoleSpy.mockRestore();
546
- exitSpy.mockRestore();
547
- });
548
- });
549
- describe("conversation archive", () => {
550
- it("archives conversation", async () => {
551
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
552
- mockApiRequest.mockResolvedValueOnce({});
553
- await conversationArchiveCommand.parseAsync(["node", "cli", "cnv_abc"]);
554
- expect(mockApiRequest).toHaveBeenCalledWith("/conversations/cnv_abc/archive", expect.anything());
555
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("archived"));
556
- consoleSpy.mockRestore();
557
- });
558
- it("unarchives when --unarchive flag is set", async () => {
559
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
560
- mockApiRequest.mockResolvedValueOnce({});
561
- await conversationArchiveCommand.parseAsync([
562
- "node",
563
- "cli",
564
- "cnv_abc",
565
- "--unarchive",
566
- ]);
567
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("unarchived"));
568
- consoleSpy.mockRestore();
569
- });
570
- });
571
- describe("conversation rename", () => {
572
- it("renames conversation", async () => {
573
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
574
- mockApiRequest.mockResolvedValueOnce({});
575
- await conversationRenameCommand.parseAsync([
576
- "node",
577
- "cli",
578
- "cnv_abc",
579
- "New Title",
580
- ]);
581
- expect(mockApiRequest).toHaveBeenCalledWith("/conversations/cnv_abc/rename", expect.objectContaining({ method: "POST" }));
582
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("New Title"));
583
- consoleSpy.mockRestore();
584
- });
585
- });
586
- // ---------------------------------------------------------------------------
587
- // api-key
588
- // ---------------------------------------------------------------------------
589
- describe("api-key create", () => {
590
- it("creates API key and displays secret", async () => {
591
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
592
- mockApiRequest.mockResolvedValueOnce({
593
- id: "key_123",
594
- key: "oxk_abc123secret",
595
- });
596
- const origIsTTY = process.stdout.isTTY;
597
- process.stdout.isTTY = true; // Simulate interactive TTY to show full secret
598
- await apiKeyCreateCommand.parseAsync(["node", "cli", "my-key"]);
599
- process.stdout.isTTY = origIsTTY; // Restore
600
- expect(mockApiRequest).toHaveBeenCalledWith("/api-keys", expect.objectContaining({ method: "POST" }));
601
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("key_123"));
602
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("oxk_abc123secret"));
603
- consoleSpy.mockRestore();
604
- });
605
- it("exits 1 on API error", async () => {
606
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
607
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
608
- throw new Error("exit");
609
- });
610
- mockApiRequest.mockRejectedValueOnce(new Error("Quota exceeded"));
611
- await expect(() => apiKeyCreateCommand.parseAsync(["node", "cli", "key"])).rejects.toThrow("exit");
612
- consoleSpy.mockRestore();
613
- exitSpy.mockRestore();
614
- });
615
- });
616
- describe("api-key revoke", () => {
617
- it("revokes API key", async () => {
618
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
619
- mockApiRequest.mockResolvedValueOnce({});
620
- await apiKeyRevokeCommand.parseAsync(["node", "cli", "key_123"]);
621
- expect(mockApiRequest).toHaveBeenCalledWith("/api-keys/key_123", expect.objectContaining({ method: "DELETE" }));
622
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("key_123"));
623
- consoleSpy.mockRestore();
624
- });
625
- });
626
- // ---------------------------------------------------------------------------
627
- // notifications
628
- // ---------------------------------------------------------------------------
629
- describe("notifications list", () => {
630
- it("lists notifications with unread marker", async () => {
631
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
632
- mockApiRequest.mockResolvedValueOnce({
633
- notifications: [
634
- { publicId: "ntf_1", title: "New member joined", readAt: null },
635
- {
636
- publicId: "ntf_2",
637
- title: "Subscription renewed",
638
- readAt: "2026-06-01",
639
- },
640
- ],
641
- });
642
- await notificationsListCommand.parseAsync(["node", "cli"]);
643
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("ntf_1"));
644
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("ntf_2"));
645
- consoleSpy.mockRestore();
646
- });
647
- it("shows empty message when none", async () => {
648
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
649
- mockApiRequest.mockResolvedValueOnce({ notifications: [] });
650
- await notificationsListCommand.parseAsync(["node", "cli"]);
651
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("No notifications"));
652
- consoleSpy.mockRestore();
653
- });
654
- it("passes unread filter", async () => {
655
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
656
- mockApiRequest.mockResolvedValueOnce({ notifications: [] });
657
- await notificationsListCommand.parseAsync(["node", "cli", "--unread"]);
658
- expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("unread"));
659
- consoleSpy.mockRestore();
660
- });
661
- });
662
- describe("notifications mark", () => {
663
- it("marks notification as read", async () => {
664
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
665
- mockApiRequest.mockResolvedValueOnce({});
666
- await notificationsMarkCommand.parseAsync(["node", "cli", "ntf_1"]);
667
- expect(mockApiRequest).toHaveBeenCalledWith("/notifications/ntf_1/mark", expect.anything());
668
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("read"));
669
- consoleSpy.mockRestore();
670
- });
671
- it("marks notification as unread with --unread flag", async () => {
672
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
673
- mockApiRequest.mockResolvedValueOnce({});
674
- await notificationsMarkCommand.parseAsync([
675
- "node",
676
- "cli",
677
- "ntf_1",
678
- "--unread",
679
- ]);
680
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("unread"));
681
- consoleSpy.mockRestore();
682
- });
683
- });
684
- // ---------------------------------------------------------------------------
685
- // plugin
686
- // ---------------------------------------------------------------------------
687
- describe("plugin list", () => {
688
- it("lists installed plugins", async () => {
689
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
690
- mockApiRequest.mockResolvedValueOnce({
691
- plugins: [
692
- { pluginId: "github", enabled: true },
693
- { pluginId: "slack", enabled: false },
694
- ],
695
- });
696
- await pluginListCommand.parseAsync(["node", "cli"]);
697
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("github"));
698
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("enabled"));
699
- consoleSpy.mockRestore();
700
- });
701
- it("shows empty message when no plugins", async () => {
702
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
703
- mockApiRequest.mockResolvedValueOnce({ plugins: [] });
704
- await pluginListCommand.parseAsync(["node", "cli"]);
705
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("No plugins"));
706
- consoleSpy.mockRestore();
707
- });
708
- });
709
- describe("plugin install", () => {
710
- it("installs plugin", async () => {
711
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
712
- mockApiRequest.mockResolvedValueOnce({});
713
- await pluginInstallCommand.parseAsync(["node", "cli", "github"]);
714
- expect(mockApiRequest).toHaveBeenCalledWith("/plugins/install", expect.objectContaining({ method: "POST" }));
715
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("github"));
716
- consoleSpy.mockRestore();
717
- });
718
- it("exits 1 on install failure", async () => {
719
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
720
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
721
- throw new Error("exit");
722
- });
723
- mockApiRequest.mockRejectedValueOnce(new Error("Not found in catalog"));
724
- await expect(() => pluginInstallCommand.parseAsync(["node", "cli", "bad-plugin"])).rejects.toThrow("exit");
725
- consoleSpy.mockRestore();
726
- exitSpy.mockRestore();
727
- });
728
- });
729
- describe("plugin uninstall", () => {
730
- it("uninstalls plugin", async () => {
731
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
732
- mockApiRequest.mockResolvedValueOnce({});
733
- await pluginUninstallCommand.parseAsync(["node", "cli", "slack"]);
734
- expect(mockApiRequest).toHaveBeenCalledWith("/plugins/uninstall", expect.objectContaining({ method: "POST" }));
735
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("slack"));
736
- consoleSpy.mockRestore();
737
- });
738
- });
739
- // ---------------------------------------------------------------------------
740
- // billing status
741
- // ---------------------------------------------------------------------------
742
- describe("billing status", () => {
743
- it("shows subscription plan and status", async () => {
744
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
745
- mockApiRequest.mockResolvedValueOnce({
746
- subscription: {
747
- plan: { name: "Scale" },
748
- status: "active",
749
- currentPeriodEnd: "2026-07-01",
750
- },
751
- creditBalance: { balanceUsd: 42.5 },
752
- });
753
- await billingStatusCommand.parseAsync(["node", "cli"]);
754
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Scale"));
755
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("active"));
756
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("42.50"));
757
- consoleSpy.mockRestore();
758
- });
759
- it("shows 'No active subscription' when absent", async () => {
760
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
761
- mockApiRequest.mockResolvedValueOnce({});
762
- await billingStatusCommand.parseAsync(["node", "cli"]);
763
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("No active subscription"));
764
- consoleSpy.mockRestore();
765
- });
766
- it("exits 1 on API error", async () => {
767
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
768
- const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => {
769
- throw new Error("exit");
770
- });
771
- mockApiRequest.mockRejectedValueOnce(new Error("Forbidden"));
772
- await expect(() => billingStatusCommand.parseAsync(["node", "cli"])).rejects.toThrow("exit");
773
- consoleSpy.mockRestore();
774
- exitSpy.mockRestore();
775
- });
776
- });
777
- // ---------------------------------------------------------------------------
778
- // agent mcp list
779
- // ---------------------------------------------------------------------------
780
- describe("agent mcp list", () => {
781
- it("lists MCP servers successfully", async () => {
782
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
783
- mockApiRequest.mockResolvedValueOnce({
784
- servers: [{ id: "mcp1", name: "claude", status: "active" }],
785
- });
786
- await agentMcpListCommand.parseAsync(["node", "cli"]);
787
- expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/mcp/list"), expect.objectContaining({ method: "GET" }));
788
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("MCP Servers"));
789
- consoleSpy.mockRestore();
790
- });
791
- });
792
- // ---------------------------------------------------------------------------
793
- // agent skill list
794
- // ---------------------------------------------------------------------------
795
- describe("agent skill list", () => {
796
- it("lists agent skills successfully", async () => {
797
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
798
- mockApiRequest.mockResolvedValueOnce({
799
- skills: [
800
- { id: "skill1", name: "memory", description: "Memory management" },
801
- ],
802
- });
803
- await agentSkillListCommand.parseAsync(["node", "cli"]);
804
- expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/skill/list"), expect.objectContaining({ method: "GET" }));
805
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Agent Skills"));
806
- consoleSpy.mockRestore();
807
- });
808
- });
809
- // ---------------------------------------------------------------------------
810
- // agent tool list
811
- // ---------------------------------------------------------------------------
812
- describe("agent tool list", () => {
813
- it("lists agent tools successfully", async () => {
814
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
815
- mockApiRequest.mockResolvedValueOnce({
816
- tools: [
817
- { id: "tool1", name: "search", description: "Search capability" },
818
- ],
819
- });
820
- await agentToolListCommand.parseAsync(["node", "cli"]);
821
- expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/tool/list"), expect.objectContaining({ method: "GET" }));
822
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Agent Tools"));
823
- consoleSpy.mockRestore();
824
- });
825
- });
826
- // ---------------------------------------------------------------------------
827
- // billing credits purchase
828
- // ---------------------------------------------------------------------------
829
- describe("billing credits purchase", () => {
830
- it("purchases credits successfully", async () => {
831
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
832
- mockApiRequest.mockResolvedValueOnce({
833
- credits: 100,
834
- totalCost: 10,
835
- });
836
- await billingCreditsPurchaseCommand.parseAsync([
837
- "node",
838
- "cli",
839
- "-a",
840
- "100",
841
- ]);
842
- expect(mockApiRequest).toHaveBeenCalledWith("/billing/credits/purchase", expect.objectContaining({ method: "POST" }));
843
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Purchase initiated"));
844
- consoleSpy.mockRestore();
845
- });
846
- });
847
- // ---------------------------------------------------------------------------
848
- // billing subscription read
849
- // ---------------------------------------------------------------------------
850
- describe("billing subscription read", () => {
851
- it("reads subscription details successfully", async () => {
852
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
853
- mockApiRequest.mockResolvedValueOnce({
854
- subscription: { id: "sub1", plan: "scale", status: "active" },
855
- });
856
- await billingSubscriptionReadCommand.parseAsync(["node", "cli"]);
857
- expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/billing/subscription/read"), expect.objectContaining({ method: "GET" }));
858
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Current Subscription"));
859
- consoleSpy.mockRestore();
860
- });
861
- });
862
- // ---------------------------------------------------------------------------
863
- // plugin org install
864
- // ---------------------------------------------------------------------------
865
- describe("plugin org install", () => {
866
- it("installs plugin for organization", async () => {
867
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
868
- mockApiRequest.mockResolvedValueOnce({
869
- id: "plugin1",
870
- name: "github",
871
- status: "installed",
872
- });
873
- await pluginOrgInstallCommand.parseAsync(["node", "cli", "-n", "github"]);
874
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/install", expect.objectContaining({ method: "POST" }));
875
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Plugin installed"));
876
- consoleSpy.mockRestore();
877
- });
878
- });
879
- // ---------------------------------------------------------------------------
880
- // plugin org uninstall
881
- // ---------------------------------------------------------------------------
882
- describe("plugin org uninstall", () => {
883
- it("uninstalls plugin from organization", async () => {
884
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
885
- mockApiRequest.mockResolvedValueOnce({
886
- id: "plugin1",
887
- status: "uninstalled",
888
- });
889
- await pluginOrgUninstallCommand.parseAsync([
890
- "node",
891
- "cli",
892
- "-p",
893
- "plugin1",
894
- ]);
895
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/uninstall", expect.objectContaining({ method: "POST" }));
896
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Plugin uninstalled"));
897
- consoleSpy.mockRestore();
898
- });
899
- });
900
- // ---------------------------------------------------------------------------
901
- // plugin catalog get
902
- // ---------------------------------------------------------------------------
903
- describe("plugin catalog get", () => {
904
- it("browses plugin catalog", async () => {
905
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
906
- mockApiRequest.mockResolvedValueOnce({
907
- plugins: [
908
- {
909
- id: "p1",
910
- name: "github",
911
- description: "GitHub integration",
912
- category: "vcs",
913
- },
914
- ],
915
- });
916
- await pluginCatalogGetCommand.parseAsync(["node", "cli"]);
917
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/catalog/get?", expect.objectContaining({ method: "GET" }));
918
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Available Plugins"));
919
- consoleSpy.mockRestore();
920
- });
921
- });
922
- // ---------------------------------------------------------------------------
923
- // org member role change
924
- // ---------------------------------------------------------------------------
925
- describe("org member role change", () => {
926
- it("changes member role successfully", async () => {
927
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
928
- mockApiRequest.mockResolvedValueOnce({
929
- userId: "user1",
930
- role: "admin",
931
- updated: true,
932
- });
933
- await orgMemberRoleChangeCommand.parseAsync([
934
- "node",
935
- "cli",
936
- "-u",
937
- "user1",
938
- "-r",
939
- "admin",
940
- ]);
941
- expect(mockApiRequest).toHaveBeenCalledWith("/org/member/role-change", expect.objectContaining({ method: "POST" }));
942
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Role updated"));
943
- consoleSpy.mockRestore();
944
- });
945
- });
946
- // ---------------------------------------------------------------------------
947
- // agent approval resolve
948
- // ---------------------------------------------------------------------------
949
- describe("agent approval resolve", () => {
950
- it("resolves approval with approve decision", async () => {
951
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
952
- mockApiRequest.mockResolvedValueOnce({ id: "apr1", status: "approved" });
953
- await agentApprovalResolveCommand.parseAsync([
954
- "node",
955
- "cli",
956
- "-a",
957
- "apr1",
958
- "-d",
959
- "approve",
960
- ]);
961
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/approval/resolve", expect.objectContaining({ method: "POST" }));
962
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("approved"));
963
- consoleSpy.mockRestore();
964
- });
965
- it("rejects invalid decision", async () => {
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();
977
- exitSpy.mockRestore();
978
- });
979
- });
980
- // ---------------------------------------------------------------------------
981
- // archive create
982
- // ---------------------------------------------------------------------------
983
- describe("archive create", () => {
984
- it("creates archive from conversation", async () => {
985
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
999
- expect(mockApiRequest).toHaveBeenCalledWith("/archive/create", expect.objectContaining({ method: "POST" }));
1000
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Archive created"));
1001
- consoleSpy.mockRestore();
1002
- });
1003
- });
1004
- // ---------------------------------------------------------------------------
1005
- // workflow run
1006
- // ---------------------------------------------------------------------------
1007
- describe("workflow run", () => {
1008
- it("runs workflow with input", async () => {
1009
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1010
- mockApiRequest.mockResolvedValueOnce({ id: "run1", status: "started" });
1011
- await workflowRunCommand.parseAsync([
1012
- "node",
1013
- "cli",
1014
- "-w",
1015
- "wf1",
1016
- "--input",
1017
- '{"key":"value"}',
1018
- ]);
1019
- expect(mockApiRequest).toHaveBeenCalledWith("/workflow/run", expect.objectContaining({ method: "POST" }));
1020
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("started"));
1021
- consoleSpy.mockRestore();
1022
- });
1023
- });
1024
- // ---------------------------------------------------------------------------
1025
- // user preferences
1026
- // ---------------------------------------------------------------------------
1027
- describe("user preferences get", () => {
1028
- it("fetches user preferences", async () => {
1029
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1030
- mockApiRequest.mockResolvedValueOnce({ theme: "dark", language: "en" });
1031
- await userPreferencesGetCommand.parseAsync(["node", "cli"]);
1032
- expect(mockApiRequest).toHaveBeenCalledWith("/user/preferences/get", expect.any(Object));
1033
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("dark"));
1034
- consoleSpy.mockRestore();
1035
- });
1036
- });
1037
- describe("user preferences update", () => {
1038
- it("updates user preferences", async () => {
1039
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1040
- mockApiRequest.mockResolvedValueOnce({ theme: "light" });
1041
- await userPreferencesUpdateCommand.parseAsync([
1042
- "node",
1043
- "cli",
1044
- "-t",
1045
- "light",
1046
- ]);
1047
- expect(mockApiRequest).toHaveBeenCalledWith("/user/preferences/update", expect.objectContaining({ method: "POST" }));
1048
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("light"));
1049
- consoleSpy.mockRestore();
1050
- });
1051
- });
1052
- // ---------------------------------------------------------------------------
1053
- // workspace management
1054
- // ---------------------------------------------------------------------------
1055
- describe("workspace member list", () => {
1056
- it("lists workspace members", async () => {
1057
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1058
- mockApiRequest.mockResolvedValueOnce([
1059
- {
1060
- id: "m1",
1061
- email: "user@example.com",
1062
- role: "member",
1063
- joined_at: "2026-06-08",
1064
- },
1065
- ]);
1066
- await workspaceMemberListCommand.parseAsync(["node", "cli"]);
1067
- expect(mockApiRequest).toHaveBeenCalled();
1068
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("member(s)"));
1069
- consoleSpy.mockRestore();
1070
- });
1071
- });
1072
- describe("workspace invite send", () => {
1073
- it("sends workspace invitation", async () => {
1074
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1075
- mockApiRequest.mockResolvedValueOnce({ id: "inv1", status: "sent" });
1076
- await workspaceInviteSendCommand.parseAsync([
1077
- "node",
1078
- "cli",
1079
- "-e",
1080
- "user@example.com",
1081
- ]);
1082
- expect(mockApiRequest).toHaveBeenCalledWith("/workspace/invite/send", expect.objectContaining({ method: "POST" }));
1083
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Invitation sent"));
1084
- consoleSpy.mockRestore();
1085
- });
1086
- });
1087
- // ---------------------------------------------------------------------------
1088
- // conversation chat
1089
- // ---------------------------------------------------------------------------
1090
- describe("conversation chat", () => {
1091
- it("sends chat message", async () => {
1092
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
1105
- expect(mockApiRequest).toHaveBeenCalledWith("/conversation/chat", expect.objectContaining({ method: "POST" }));
1106
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Message sent"));
1107
- consoleSpy.mockRestore();
1108
- });
1109
- });
1110
- // ---------------------------------------------------------------------------
1111
- // image management
1112
- // ---------------------------------------------------------------------------
1113
- describe("image create", () => {
1114
- it("creates image from prompt", async () => {
1115
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1116
- mockApiRequest.mockResolvedValueOnce({
1117
- id: "img1",
1118
- url: "https://example.com/img1.jpg",
1119
- });
1120
- await imageCreateCommand.parseAsync(["node", "cli", "-p", "A blue sky"]);
1121
- expect(mockApiRequest).toHaveBeenCalledWith("/image/create", expect.objectContaining({ method: "POST" }));
1122
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Image created"));
1123
- consoleSpy.mockRestore();
1124
- });
1125
- });
1126
- describe("image list", () => {
1127
- it("lists images", async () => {
1128
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- });
1139
- await imageListCommand.parseAsync(["node", "cli"]);
1140
- expect(mockApiRequest).toHaveBeenCalled();
1141
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Images"));
1142
- consoleSpy.mockRestore();
1143
- });
1144
- });
1145
- describe("image analyze", () => {
1146
- it("analyzes image", async () => {
1147
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1148
- mockApiRequest.mockResolvedValueOnce({
1149
- analysis: "sky",
1150
- tags: ["nature", "outdoor"],
1151
- });
1152
- await imageAnalyzeCommand.parseAsync(["node", "cli", "-i", "img1"]);
1153
- expect(mockApiRequest).toHaveBeenCalledWith("/image/analyze", expect.objectContaining({ method: "POST" }));
1154
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Analysis"));
1155
- consoleSpy.mockRestore();
1156
- });
1157
- });
1158
- // ---------------------------------------------------------------------------
1159
- // document management
1160
- // ---------------------------------------------------------------------------
1161
- describe("document create", () => {
1162
- it("creates document", async () => {
1163
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1164
- mockApiRequest.mockResolvedValueOnce({ id: "doc1", title: "My Doc" });
1165
- await documentCreateCommand.parseAsync(["node", "cli", "-t", "My Doc"]);
1166
- expect(mockApiRequest).toHaveBeenCalledWith("/document/create", expect.objectContaining({ method: "POST" }));
1167
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Document created"));
1168
- consoleSpy.mockRestore();
1169
- });
1170
- });
1171
- describe("document list", () => {
1172
- it("lists documents", async () => {
1173
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- });
1185
- await documentListCommand.parseAsync(["node", "cli"]);
1186
- expect(mockApiRequest).toHaveBeenCalled();
1187
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Documents"));
1188
- consoleSpy.mockRestore();
1189
- });
1190
- });
1191
- describe("document read", () => {
1192
- it("reads document", async () => {
1193
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1194
- mockApiRequest.mockResolvedValueOnce({
1195
- title: "Doc 1",
1196
- content: "Content...",
1197
- metadata: {},
1198
- created_at: "2026-06-08",
1199
- });
1200
- await documentReadCommand.parseAsync(["node", "cli", "-d", "doc1"]);
1201
- expect(mockApiRequest).toHaveBeenCalled();
1202
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Title:"));
1203
- consoleSpy.mockRestore();
1204
- });
1205
- });
1206
- // ---------------------------------------------------------------------------
1207
- // automation management
1208
- // ---------------------------------------------------------------------------
1209
- describe("automation list", () => {
1210
- it("lists automations", async () => {
1211
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1212
- mockApiRequest.mockResolvedValueOnce([
1213
- { id: "auto1", name: "Auto 1", status: "active", triggers: ["event1"] },
1214
- ]);
1215
- await automationListCommand.parseAsync(["node", "cli"]);
1216
- expect(mockApiRequest).toHaveBeenCalled();
1217
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("automation(s)"));
1218
- consoleSpy.mockRestore();
1219
- });
1220
- });
1221
- describe("automation create", () => {
1222
- it("creates automation with the contract payload shape", async () => {
1223
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
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
- });
1247
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation created"));
1248
- consoleSpy.mockRestore();
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
- });
1354
- });
1355
- describe("automation trigger", () => {
1356
- it("triggers automation", async () => {
1357
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1358
- mockApiRequest.mockResolvedValueOnce({ id: "exec1", status: "running" });
1359
- await automationTriggerCommand.parseAsync(["node", "cli", "-a", "auto1"]);
1360
- expect(mockApiRequest).toHaveBeenCalledWith("/automation/trigger", expect.objectContaining({ method: "POST" }));
1361
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("running"));
1362
- consoleSpy.mockRestore();
1363
- });
1364
- });
1365
- // ---------------------------------------------------------------------------
1366
- // skill management
1367
- // ---------------------------------------------------------------------------
1368
- describe("skill workspace list", () => {
1369
- it("lists workspace skills", async () => {
1370
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1371
- mockApiRequest.mockResolvedValueOnce({
1372
- skills: [
1373
- {
1374
- id: "skill1",
1375
- name: "Research",
1376
- enabled: true,
1377
- description: "Research skill",
1378
- },
1379
- ],
1380
- });
1381
- await skillWorkspaceListCommand.parseAsync(["node", "cli"]);
1382
- expect(mockApiRequest).toHaveBeenCalled();
1383
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Workspace skills"));
1384
- consoleSpy.mockRestore();
1385
- });
1386
- });
1387
- // ---------------------------------------------------------------------------
1388
- // agent memory commands
1389
- // ---------------------------------------------------------------------------
1390
- describe("agent memory recall", () => {
1391
- it("recalls memory observations", async () => {
1392
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1393
- const mockResult = {
1394
- observations: [
1395
- { id: "obs1", text: "User prefers dark mode", score: 0.9 },
1396
- ],
1397
- };
1398
- mockApiRequest.mockResolvedValueOnce(mockResult);
1399
- await agentMemoryRecallCommand.parseAsync([
1400
- "node",
1401
- "cli",
1402
- "-a",
1403
- "agent1",
1404
- "-q",
1405
- "user preferences",
1406
- ]);
1407
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/memory/recall", expect.objectContaining({ method: "POST" }));
1408
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("obs1"));
1409
- consoleSpy.mockRestore();
1410
- });
1411
- it("handles recall failure", async () => {
1412
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1413
- const exitSpy = vi
1414
- .spyOn(process, "exit")
1415
- .mockImplementation((_code) => {
1416
- throw new Error("process.exit");
1417
- });
1418
- mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1419
- await expect(agentMemoryRecallCommand.parseAsync([
1420
- "node",
1421
- "cli",
1422
- "-a",
1423
- "agent1",
1424
- "-q",
1425
- "query",
1426
- ])).rejects.toThrow();
1427
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to recall"), expect.any(Error));
1428
- consoleSpy.mockRestore();
1429
- exitSpy.mockRestore();
1430
- });
1431
- });
1432
- describe("agent memory write", () => {
1433
- it("writes a memory observation", async () => {
1434
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1435
- const mockResult = { id: "obs2", status: "stored" };
1436
- mockApiRequest.mockResolvedValueOnce(mockResult);
1437
- await agentMemoryWriteCommand.parseAsync([
1438
- "node",
1439
- "cli",
1440
- "-a",
1441
- "agent1",
1442
- "-t",
1443
- "User prefers TypeScript",
1444
- ]);
1445
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/memory/write", expect.objectContaining({ method: "POST" }));
1446
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("obs2"));
1447
- consoleSpy.mockRestore();
1448
- });
1449
- it("writes a memory observation with tags", async () => {
1450
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1451
- mockApiRequest.mockResolvedValueOnce({ id: "obs3", status: "stored" });
1452
- await agentMemoryWriteCommand.parseAsync([
1453
- "node",
1454
- "cli",
1455
- "-a",
1456
- "agent1",
1457
- "-t",
1458
- "Uses dark mode",
1459
- "--tags",
1460
- "ui,preferences",
1461
- ]);
1462
- const callBody = JSON.parse(mockApiRequest.mock.calls[0][1].body);
1463
- expect(callBody.tags).toEqual(["ui", "preferences"]);
1464
- consoleSpy.mockRestore();
1465
- });
1466
- it("handles write failure", async () => {
1467
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1468
- const exitSpy = vi
1469
- .spyOn(process, "exit")
1470
- .mockImplementation((_code) => {
1471
- throw new Error("process.exit");
1472
- });
1473
- mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1474
- await expect(agentMemoryWriteCommand.parseAsync([
1475
- "node",
1476
- "cli",
1477
- "-a",
1478
- "agent1",
1479
- "-t",
1480
- "text",
1481
- ])).rejects.toThrow();
1482
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to write"), expect.any(Error));
1483
- consoleSpy.mockRestore();
1484
- exitSpy.mockRestore();
1485
- });
1486
- });
1487
- // ---------------------------------------------------------------------------
1488
- // documents generate
1489
- // ---------------------------------------------------------------------------
1490
- describe("documents generate", () => {
1491
- it("generates a document from template", async () => {
1492
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1493
- const mockResult = {
1494
- id: "doc1",
1495
- status: "complete",
1496
- url: "https://example.com/doc.pdf",
1497
- };
1498
- mockApiRequest.mockResolvedValueOnce(mockResult);
1499
- await documentsGenerateCommand.parseAsync([
1500
- "node",
1501
- "cli",
1502
- "-t",
1503
- "report",
1504
- "-c",
1505
- '{"title":"Q1 Report"}',
1506
- ]);
1507
- expect(mockApiRequest).toHaveBeenCalledWith("/documents/generate", expect.objectContaining({ method: "POST" }));
1508
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("doc1"));
1509
- consoleSpy.mockRestore();
1510
- });
1511
- it("fails on invalid JSON context", async () => {
1512
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
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();
1526
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Invalid JSON"), expect.anything());
1527
- consoleSpy.mockRestore();
1528
- exitSpy.mockRestore();
1529
- });
1530
- it("handles generate failure", async () => {
1531
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1532
- const exitSpy = vi
1533
- .spyOn(process, "exit")
1534
- .mockImplementation((_code) => {
1535
- throw new Error("process.exit");
1536
- });
1537
- mockApiRequest.mockRejectedValueOnce(new Error("Template not found"));
1538
- await expect(documentsGenerateCommand.parseAsync([
1539
- "node",
1540
- "cli",
1541
- "-t",
1542
- "report",
1543
- "-c",
1544
- "{}",
1545
- ])).rejects.toThrow();
1546
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
1547
- consoleSpy.mockRestore();
1548
- exitSpy.mockRestore();
1549
- });
1550
- });
1551
- // ---------------------------------------------------------------------------
1552
- // image generate
1553
- // ---------------------------------------------------------------------------
1554
- describe("image generate", () => {
1555
- it("generates an image and logs JSON result", async () => {
1556
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1557
- const mockResult = { url: "https://example.com/img.png", id: "img1" };
1558
- mockApiRequest.mockResolvedValueOnce(mockResult);
1559
- await imageGenerateCommand.parseAsync([
1560
- "node",
1561
- "cli",
1562
- "-p",
1563
- "A sunset over the ocean",
1564
- ]);
1565
- expect(mockApiRequest).toHaveBeenCalledWith("/image/generate", expect.objectContaining({ method: "POST" }));
1566
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("img1"));
1567
- consoleSpy.mockRestore();
1568
- });
1569
- it("handles generate failure", async () => {
1570
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1571
- const exitSpy = vi
1572
- .spyOn(process, "exit")
1573
- .mockImplementation((_code) => {
1574
- throw new Error("process.exit");
1575
- });
1576
- mockApiRequest.mockRejectedValueOnce(new Error("Model not found"));
1577
- await expect(imageGenerateCommand.parseAsync(["node", "cli", "-p", "a cat"])).rejects.toThrow();
1578
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
1579
- consoleSpy.mockRestore();
1580
- exitSpy.mockRestore();
1581
- });
1582
- });
1583
- // ---------------------------------------------------------------------------
1584
- // org member invite accept
1585
- // ---------------------------------------------------------------------------
1586
- describe("org member invite accept", () => {
1587
- it("accepts an invitation", async () => {
1588
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1589
- mockApiRequest.mockResolvedValueOnce({
1590
- status: "accepted",
1591
- orgSlug: "my-org",
1592
- });
1593
- await orgMemberInviteAcceptCommand.parseAsync([
1594
- "node",
1595
- "cli",
1596
- "-i",
1597
- "invite123",
1598
- ]);
1599
- expect(mockApiRequest).toHaveBeenCalledWith("/org/member/invite/accept", expect.objectContaining({ method: "POST" }));
1600
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("accepted"));
1601
- consoleSpy.mockRestore();
1602
- });
1603
- it("handles accept failure", async () => {
1604
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1605
- const exitSpy = vi
1606
- .spyOn(process, "exit")
1607
- .mockImplementation((_code) => {
1608
- throw new Error("process.exit");
1609
- });
1610
- mockApiRequest.mockRejectedValueOnce(new Error("Invitation expired"));
1611
- await expect(orgMemberInviteAcceptCommand.parseAsync(["node", "cli", "-i", "inv1"])).rejects.toThrow();
1612
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to accept"), expect.any(Error));
1613
- consoleSpy.mockRestore();
1614
- exitSpy.mockRestore();
1615
- });
1616
- });
1617
- // ---------------------------------------------------------------------------
1618
- // plugin catalog browse
1619
- // ---------------------------------------------------------------------------
1620
- describe("plugin catalog browse", () => {
1621
- it("browses the plugin catalog", async () => {
1622
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1623
- const mockResult = {
1624
- plugins: [{ id: "p1", name: "Slack", category: "messaging" }],
1625
- total: 1,
1626
- };
1627
- mockApiRequest.mockResolvedValueOnce(mockResult);
1628
- await pluginCatalogBrowseCommand.parseAsync(["node", "cli"]);
1629
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/catalog/browse", expect.objectContaining({ method: "GET" }));
1630
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Slack"));
1631
- consoleSpy.mockRestore();
1632
- });
1633
- it("handles browse failure", async () => {
1634
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1635
- const exitSpy = vi
1636
- .spyOn(process, "exit")
1637
- .mockImplementation((_code) => {
1638
- throw new Error("process.exit");
1639
- });
1640
- mockApiRequest.mockRejectedValueOnce(new Error("Service unavailable"));
1641
- await expect(pluginCatalogBrowseCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1642
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to browse"), expect.any(Error));
1643
- consoleSpy.mockRestore();
1644
- exitSpy.mockRestore();
1645
- });
1646
- });
1647
- // ---------------------------------------------------------------------------
1648
- // plugin credential reauth
1649
- // ---------------------------------------------------------------------------
1650
- describe("plugin credential reauth", () => {
1651
- it("re-authenticates plugin credentials", async () => {
1652
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1653
- mockApiRequest.mockResolvedValueOnce({
1654
- status: "reauthenticated",
1655
- pluginId: "slack",
1656
- });
1657
- await pluginCredentialReauthCommand.parseAsync([
1658
- "node",
1659
- "cli",
1660
- "-p",
1661
- "slack",
1662
- ]);
1663
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/credential/reauth", expect.objectContaining({ method: "POST" }));
1664
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("reauthenticated"));
1665
- consoleSpy.mockRestore();
1666
- });
1667
- it("handles reauth failure", async () => {
1668
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1669
- const exitSpy = vi
1670
- .spyOn(process, "exit")
1671
- .mockImplementation((_code) => {
1672
- throw new Error("process.exit");
1673
- });
1674
- mockApiRequest.mockRejectedValueOnce(new Error("OAuth error"));
1675
- await expect(pluginCredentialReauthCommand.parseAsync(["node", "cli", "-p", "slack"])).rejects.toThrow();
1676
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to re-authenticate"), expect.any(Error));
1677
- consoleSpy.mockRestore();
1678
- exitSpy.mockRestore();
1679
- });
1680
- });
1681
- // ---------------------------------------------------------------------------
1682
- // plugin registry
1683
- // ---------------------------------------------------------------------------
1684
- describe("plugin registry list", () => {
1685
- it("lists plugin registries", async () => {
1686
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1687
- mockApiRequest.mockResolvedValueOnce({
1688
- registries: [
1689
- { id: "reg1", name: "Official", url: "https://registry.oxagen.ai" },
1690
- ],
1691
- });
1692
- await pluginRegistryListCommand.parseAsync(["node", "cli"]);
1693
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/list", expect.objectContaining({ method: "GET" }));
1694
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Official"));
1695
- consoleSpy.mockRestore();
1696
- });
1697
- it("handles list failure", async () => {
1698
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1699
- const exitSpy = vi
1700
- .spyOn(process, "exit")
1701
- .mockImplementation((_code) => {
1702
- throw new Error("process.exit");
1703
- });
1704
- mockApiRequest.mockRejectedValueOnce(new Error("Network error"));
1705
- await expect(pluginRegistryListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1706
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to list"), expect.any(Error));
1707
- consoleSpy.mockRestore();
1708
- exitSpy.mockRestore();
1709
- });
1710
- });
1711
- describe("plugin registry add", () => {
1712
- it("adds a plugin registry", async () => {
1713
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
1727
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/add", expect.objectContaining({ method: "POST" }));
1728
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("reg2"));
1729
- consoleSpy.mockRestore();
1730
- });
1731
- it("handles add failure", async () => {
1732
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1733
- const exitSpy = vi
1734
- .spyOn(process, "exit")
1735
- .mockImplementation((_code) => {
1736
- throw new Error("process.exit");
1737
- });
1738
- mockApiRequest.mockRejectedValueOnce(new Error("Registry already exists"));
1739
- await expect(pluginRegistryAddCommand.parseAsync([
1740
- "node",
1741
- "cli",
1742
- "-n",
1743
- "Private",
1744
- "-u",
1745
- "https://x.com",
1746
- ])).rejects.toThrow();
1747
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to add"), expect.any(Error));
1748
- consoleSpy.mockRestore();
1749
- exitSpy.mockRestore();
1750
- });
1751
- });
1752
- // ---------------------------------------------------------------------------
1753
- // svg generate
1754
- // ---------------------------------------------------------------------------
1755
- describe("svg generate", () => {
1756
- it("generates SVG and logs it", async () => {
1757
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1758
- mockApiRequest.mockResolvedValueOnce({ svg: "<svg><rect/></svg>" });
1759
- await svgGenerateCommand.parseAsync(["node", "cli", "-d", "A red circle"]);
1760
- expect(mockApiRequest).toHaveBeenCalledWith("/svg/generate", expect.objectContaining({ method: "POST" }));
1761
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("<svg>"));
1762
- consoleSpy.mockRestore();
1763
- });
1764
- it("handles generate failure", async () => {
1765
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1766
- const exitSpy = vi
1767
- .spyOn(process, "exit")
1768
- .mockImplementation((_code) => {
1769
- throw new Error("process.exit");
1770
- });
1771
- mockApiRequest.mockRejectedValueOnce(new Error("Generation failed"));
1772
- await expect(svgGenerateCommand.parseAsync(["node", "cli", "-d", "circle"])).rejects.toThrow();
1773
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
1774
- consoleSpy.mockRestore();
1775
- exitSpy.mockRestore();
1776
- });
1777
- });
1778
- // ---------------------------------------------------------------------------
1779
- // video generate
1780
- // ---------------------------------------------------------------------------
1781
- describe("video generate", () => {
1782
- it("generates a video", async () => {
1783
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
1795
- expect(mockApiRequest).toHaveBeenCalledWith("/video/generate", expect.objectContaining({ method: "POST" }));
1796
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("vid1"));
1797
- consoleSpy.mockRestore();
1798
- });
1799
- it("handles generate failure", async () => {
1800
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1801
- const exitSpy = vi
1802
- .spyOn(process, "exit")
1803
- .mockImplementation((_code) => {
1804
- throw new Error("process.exit");
1805
- });
1806
- mockApiRequest.mockRejectedValueOnce(new Error("Model not available"));
1807
- await expect(videoGenerateCommand.parseAsync(["node", "cli", "-p", "a cat"])).rejects.toThrow();
1808
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to generate"), expect.any(Error));
1809
- consoleSpy.mockRestore();
1810
- exitSpy.mockRestore();
1811
- });
1812
- });
1813
- // ---------------------------------------------------------------------------
1814
- // workspace model settings
1815
- // ---------------------------------------------------------------------------
1816
- describe("workspace model settings read", () => {
1817
- it("reads workspace model settings", async () => {
1818
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1819
- mockApiRequest.mockResolvedValueOnce({
1820
- defaultModel: "claude-haiku-4-5-20251001",
1821
- maxTokens: 4096,
1822
- });
1823
- await workspaceModelSettingsReadCommand.parseAsync(["node", "cli"]);
1824
- expect(mockApiRequest).toHaveBeenCalledWith("/workspace/model-settings/read", expect.objectContaining({ method: "POST" }));
1825
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("defaultModel"));
1826
- consoleSpy.mockRestore();
1827
- });
1828
- it("handles read failure", async () => {
1829
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1830
- const exitSpy = vi
1831
- .spyOn(process, "exit")
1832
- .mockImplementation((_code) => {
1833
- throw new Error("process.exit");
1834
- });
1835
- mockApiRequest.mockRejectedValueOnce(new Error("Workspace not found"));
1836
- await expect(workspaceModelSettingsReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
1837
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to read"), expect.any(Error));
1838
- consoleSpy.mockRestore();
1839
- exitSpy.mockRestore();
1840
- });
1841
- });
1842
- describe("workspace model settings write", () => {
1843
- it("writes workspace model settings", async () => {
1844
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
1858
- expect(mockApiRequest).toHaveBeenCalledWith("/workspace/model-settings/write", expect.objectContaining({ method: "POST" }));
1859
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("defaultModel"));
1860
- consoleSpy.mockRestore();
1861
- });
1862
- it("handles write failure", async () => {
1863
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1864
- const exitSpy = vi
1865
- .spyOn(process, "exit")
1866
- .mockImplementation((_code) => {
1867
- throw new Error("process.exit");
1868
- });
1869
- mockApiRequest.mockRejectedValueOnce(new Error("Invalid setting key"));
1870
- await expect(workspaceModelSettingsWriteCommand.parseAsync([
1871
- "node",
1872
- "cli",
1873
- "-k",
1874
- "badKey",
1875
- "-v",
1876
- "value",
1877
- ])).rejects.toThrow();
1878
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Failed to write"), expect.any(Error));
1879
- consoleSpy.mockRestore();
1880
- exitSpy.mockRestore();
1881
- });
1882
- });
1883
- // ---------------------------------------------------------------------------
1884
- // agent mcp register
1885
- // ---------------------------------------------------------------------------
1886
- describe("agent mcp register", () => {
1887
- it("registers an MCP server", async () => {
1888
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
1904
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/mcp/register", expect.objectContaining({ method: "POST" }));
1905
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("mcp1"));
1906
- consoleSpy.mockRestore();
1907
- });
1908
- it("handles registration failure", async () => {
1909
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1910
- const exitSpy = vi
1911
- .spyOn(process, "exit")
1912
- .mockImplementation((_code) => {
1913
- throw new Error("process.exit");
1914
- });
1915
- mockApiRequest.mockRejectedValueOnce(new Error("Bad URL"));
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();
1926
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
1927
- consoleSpy.mockRestore();
1928
- exitSpy.mockRestore();
1929
- });
1930
- });
1931
- // ---------------------------------------------------------------------------
1932
- // agent plan approve
1933
- // ---------------------------------------------------------------------------
1934
- describe("agent plan approve", () => {
1935
- it("approves a plan", async () => {
1936
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
1949
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/plan/approve", expect.objectContaining({ method: "POST" }));
1950
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("approved"));
1951
- consoleSpy.mockRestore();
1952
- });
1953
- it("handles approval failure", async () => {
1954
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1955
- const exitSpy = vi
1956
- .spyOn(process, "exit")
1957
- .mockImplementation((_code) => {
1958
- throw new Error("process.exit");
1959
- });
1960
- mockApiRequest.mockRejectedValueOnce(new Error("Plan not found"));
1961
- await expect(agentPlanApproveCommand.parseAsync([
1962
- "node",
1963
- "cli",
1964
- "-p",
1965
- "p1",
1966
- "-d",
1967
- "deny",
1968
- ])).rejects.toThrow();
1969
- consoleSpy.mockRestore();
1970
- exitSpy.mockRestore();
1971
- });
1972
- });
1973
- // ---------------------------------------------------------------------------
1974
- // agent task background
1975
- // ---------------------------------------------------------------------------
1976
- describe("agent task background start", () => {
1977
- it("starts a background task", async () => {
1978
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
1991
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/task/background/start", expect.objectContaining({ method: "POST" }));
1992
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("task1"));
1993
- consoleSpy.mockRestore();
1994
- });
1995
- it("handles start failure", async () => {
1996
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1997
- const exitSpy = vi
1998
- .spyOn(process, "exit")
1999
- .mockImplementation((_code) => {
2000
- throw new Error("process.exit");
2001
- });
2002
- mockApiRequest.mockRejectedValueOnce(new Error("Queue full"));
2003
- await expect(agentTaskBackgroundStartCommand.parseAsync([
2004
- "node",
2005
- "cli",
2006
- "-k",
2007
- "kind",
2008
- "--payload",
2009
- "{}",
2010
- ])).rejects.toThrow();
2011
- consoleSpy.mockRestore();
2012
- exitSpy.mockRestore();
2013
- });
2014
- });
2015
- describe("agent task background read", () => {
2016
- it("reads task status", async () => {
2017
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
2035
- expect(mockApiRequest).toHaveBeenCalled();
2036
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("completed"));
2037
- consoleSpy.mockRestore();
2038
- });
2039
- it("handles read failure", async () => {
2040
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2041
- const exitSpy = vi
2042
- .spyOn(process, "exit")
2043
- .mockImplementation((_code) => {
2044
- throw new Error("process.exit");
2045
- });
2046
- mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
2047
- await expect(agentTaskBackgroundReadCommand.parseAsync(["node", "cli", "-t", "t1"])).rejects.toThrow();
2048
- consoleSpy.mockRestore();
2049
- exitSpy.mockRestore();
2050
- });
2051
- });
2052
- describe("agent task background cancel", () => {
2053
- it("cancels a background task", async () => {
2054
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2055
- mockApiRequest.mockResolvedValueOnce({ cancelled: true });
2056
- await agentTaskBackgroundCancelCommand.parseAsync([
2057
- "node",
2058
- "cli",
2059
- "-t",
2060
- "task1",
2061
- ]);
2062
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/task/background/cancel", expect.objectContaining({ method: "POST" }));
2063
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cancelled"));
2064
- consoleSpy.mockRestore();
2065
- });
2066
- it("reports task could not be cancelled", async () => {
2067
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2068
- mockApiRequest.mockResolvedValueOnce({ cancelled: false });
2069
- await agentTaskBackgroundCancelCommand.parseAsync([
2070
- "node",
2071
- "cli",
2072
- "-t",
2073
- "task1",
2074
- ]);
2075
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("could not be cancelled"));
2076
- consoleSpy.mockRestore();
2077
- });
2078
- it("handles cancel failure", async () => {
2079
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2080
- const exitSpy = vi
2081
- .spyOn(process, "exit")
2082
- .mockImplementation((_code) => {
2083
- throw new Error("process.exit");
2084
- });
2085
- mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
2086
- await expect(agentTaskBackgroundCancelCommand.parseAsync(["node", "cli", "-t", "t1"])).rejects.toThrow();
2087
- consoleSpy.mockRestore();
2088
- exitSpy.mockRestore();
2089
- });
2090
- });
2091
- // ---------------------------------------------------------------------------
2092
- // asset upload
2093
- // ---------------------------------------------------------------------------
2094
- describe("asset upload", () => {
2095
- it("uploads an asset", async () => {
2096
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
2111
- expect(mockApiRequest).toHaveBeenCalledWith("/asset/upload", expect.objectContaining({ method: "POST" }));
2112
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Asset uploaded"));
2113
- consoleSpy.mockRestore();
2114
- });
2115
- it("handles upload failure", async () => {
2116
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2117
- const exitSpy = vi
2118
- .spyOn(process, "exit")
2119
- .mockImplementation((_code) => {
2120
- throw new Error("process.exit");
2121
- });
2122
- mockApiRequest.mockRejectedValueOnce(new Error("Source URL unreachable"));
2123
- await expect(assetUploadCommand.parseAsync([
2124
- "node",
2125
- "cli",
2126
- "-s",
2127
- "https://bad.url",
2128
- "-k",
2129
- "image",
2130
- ])).rejects.toThrow();
2131
- consoleSpy.mockRestore();
2132
- exitSpy.mockRestore();
2133
- });
2134
- });
2135
- // ---------------------------------------------------------------------------
2136
- // billing subscription upgrade start
2137
- // ---------------------------------------------------------------------------
2138
- describe("billing subscription upgrade start", () => {
2139
- it("starts a checkout session", async () => {
2140
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
2158
- expect(mockApiRequest).toHaveBeenCalledWith("/billing/subscription/upgrade/start", expect.objectContaining({ method: "POST" }));
2159
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Checkout session created"));
2160
- consoleSpy.mockRestore();
2161
- });
2162
- it("handles upgrade failure", async () => {
2163
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2164
- const exitSpy = vi
2165
- .spyOn(process, "exit")
2166
- .mockImplementation((_code) => {
2167
- throw new Error("process.exit");
2168
- });
2169
- mockApiRequest.mockRejectedValueOnce(new Error("Stripe error"));
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();
2182
- consoleSpy.mockRestore();
2183
- exitSpy.mockRestore();
2184
- });
2185
- });
2186
- // ---------------------------------------------------------------------------
2187
- // conversation purge
2188
- // ---------------------------------------------------------------------------
2189
- describe("conversation purge", () => {
2190
- it("purges archived conversations with --yes", async () => {
2191
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2192
- mockApiRequest.mockResolvedValueOnce({ deleted: 5 });
2193
- await conversationPurgeCommand.parseAsync([
2194
- "node",
2195
- "cli",
2196
- "-w",
2197
- "ws1",
2198
- "--yes",
2199
- ]);
2200
- expect(mockApiRequest).toHaveBeenCalledWith("/conversation/purge", expect.objectContaining({ method: "POST" }));
2201
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Purged 5"));
2202
- consoleSpy.mockRestore();
2203
- });
2204
- it("exits without --yes", async () => {
2205
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2206
- const exitSpy = vi
2207
- .spyOn(process, "exit")
2208
- .mockImplementation((_code) => {
2209
- throw new Error("process.exit");
2210
- });
2211
- await expect(conversationPurgeCommand.parseAsync(["node", "cli", "-w", "ws1"])).rejects.toThrow();
2212
- expect(consoleSpy).toHaveBeenCalled();
2213
- consoleSpy.mockRestore();
2214
- exitSpy.mockRestore();
2215
- });
2216
- it("handles purge failure", async () => {
2217
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2218
- const exitSpy = vi
2219
- .spyOn(process, "exit")
2220
- .mockImplementation((_code) => {
2221
- throw new Error("process.exit");
2222
- });
2223
- mockApiRequest.mockRejectedValueOnce(new Error("Workspace not found"));
2224
- await expect(conversationPurgeCommand.parseAsync([
2225
- "node",
2226
- "cli",
2227
- "-w",
2228
- "ws1",
2229
- "--yes",
2230
- ])).rejects.toThrow();
2231
- consoleSpy.mockRestore();
2232
- exitSpy.mockRestore();
2233
- });
2234
- });
2235
- // ---------------------------------------------------------------------------
2236
- // documents pdf create
2237
- // ---------------------------------------------------------------------------
2238
- describe("documents pdf create", () => {
2239
- it("creates a PDF document", async () => {
2240
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
2256
- expect(mockApiRequest).toHaveBeenCalledWith("/documents/pdf/create", expect.objectContaining({ method: "POST" }));
2257
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("PDF created"));
2258
- consoleSpy.mockRestore();
2259
- });
2260
- it("handles pdf create failure", async () => {
2261
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2262
- const exitSpy = vi
2263
- .spyOn(process, "exit")
2264
- .mockImplementation((_code) => {
2265
- throw new Error("process.exit");
2266
- });
2267
- mockApiRequest.mockRejectedValueOnce(new Error("Generation failed"));
2268
- await expect(documentsPdfCreateCommand.parseAsync(["node", "cli", "-t", "Report"])).rejects.toThrow();
2269
- consoleSpy.mockRestore();
2270
- exitSpy.mockRestore();
2271
- });
2272
- });
2273
- // ---------------------------------------------------------------------------
2274
- // form fill
2275
- // ---------------------------------------------------------------------------
2276
- describe("form fill", () => {
2277
- it("fills form fields", async () => {
2278
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ];
2290
- mockApiRequest.mockResolvedValueOnce({ fields });
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
- ]);
2301
- expect(mockApiRequest).toHaveBeenCalledWith("/form/fill", expect.objectContaining({ method: "POST" }));
2302
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Form fill suggestion"));
2303
- consoleSpy.mockRestore();
2304
- });
2305
- it("handles form fill failure", async () => {
2306
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2307
- const exitSpy = vi
2308
- .spyOn(process, "exit")
2309
- .mockImplementation((_code) => {
2310
- throw new Error("process.exit");
2311
- });
2312
- mockApiRequest.mockRejectedValueOnce(new Error("LLM error"));
2313
- await expect(formFillCommand.parseAsync([
2314
- "node",
2315
- "cli",
2316
- "-r",
2317
- "/p",
2318
- "-i",
2319
- "fill",
2320
- "--fields",
2321
- "[]",
2322
- ])).rejects.toThrow();
2323
- consoleSpy.mockRestore();
2324
- exitSpy.mockRestore();
2325
- });
2326
- });
2327
- // ---------------------------------------------------------------------------
2328
- // org member invite decline
2329
- // ---------------------------------------------------------------------------
2330
- describe("org member invite decline", () => {
2331
- it("declines an invitation", async () => {
2332
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2333
- mockApiRequest.mockResolvedValueOnce({
2334
- invitationPublicId: "inv1",
2335
- status: "declined",
2336
- });
2337
- await orgMemberInviteDeclineCommand.parseAsync([
2338
- "node",
2339
- "cli",
2340
- "-i",
2341
- "inv1",
2342
- ]);
2343
- expect(mockApiRequest).toHaveBeenCalledWith("/org/member/invite/decline", expect.objectContaining({ method: "POST" }));
2344
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("declined"));
2345
- consoleSpy.mockRestore();
2346
- });
2347
- it("handles decline failure", async () => {
2348
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2349
- const exitSpy = vi
2350
- .spyOn(process, "exit")
2351
- .mockImplementation((_code) => {
2352
- throw new Error("process.exit");
2353
- });
2354
- mockApiRequest.mockRejectedValueOnce(new Error("Invitation not found"));
2355
- await expect(orgMemberInviteDeclineCommand.parseAsync(["node", "cli", "-i", "inv1"])).rejects.toThrow();
2356
- consoleSpy.mockRestore();
2357
- exitSpy.mockRestore();
2358
- });
2359
- });
2360
- // ---------------------------------------------------------------------------
2361
- // organization create
2362
- // ---------------------------------------------------------------------------
2363
- describe("organization create", () => {
2364
- it("creates an organization", async () => {
2365
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
2381
- expect(mockApiRequest).toHaveBeenCalledWith("/organization/create", expect.objectContaining({ method: "POST" }));
2382
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Organization created"));
2383
- consoleSpy.mockRestore();
2384
- });
2385
- it("handles create failure", async () => {
2386
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2387
- const exitSpy = vi
2388
- .spyOn(process, "exit")
2389
- .mockImplementation((_code) => {
2390
- throw new Error("process.exit");
2391
- });
2392
- mockApiRequest.mockRejectedValueOnce(new Error("Slug already taken"));
2393
- await expect(organizationCreateCommand.parseAsync([
2394
- "node",
2395
- "cli",
2396
- "-n",
2397
- "Acme",
2398
- "-s",
2399
- "acme",
2400
- ])).rejects.toThrow();
2401
- consoleSpy.mockRestore();
2402
- exitSpy.mockRestore();
2403
- });
2404
- });
2405
- // ---------------------------------------------------------------------------
2406
- // plugin credential set_secret
2407
- // ---------------------------------------------------------------------------
2408
- describe("plugin credential set_secret", () => {
2409
- it("stores a credential", async () => {
2410
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2411
- mockApiRequest.mockResolvedValueOnce({ ok: true });
2412
- await pluginCredentialSetSecretCommand.parseAsync([
2413
- "node",
2414
- "cli",
2415
- "-l",
2416
- "listing1",
2417
- "-a",
2418
- "secret",
2419
- "--secret",
2420
- "my-secret",
2421
- ]);
2422
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/credential/set_secret", expect.objectContaining({ method: "POST" }));
2423
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Credential stored"));
2424
- consoleSpy.mockRestore();
2425
- });
2426
- it("handles credential failure", async () => {
2427
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2428
- const exitSpy = vi
2429
- .spyOn(process, "exit")
2430
- .mockImplementation((_code) => {
2431
- throw new Error("process.exit");
2432
- });
2433
- mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
2434
- await expect(pluginCredentialSetSecretCommand.parseAsync([
2435
- "node",
2436
- "cli",
2437
- "-l",
2438
- "l1",
2439
- "-a",
2440
- "secret",
2441
- ])).rejects.toThrow();
2442
- consoleSpy.mockRestore();
2443
- exitSpy.mockRestore();
2444
- });
2445
- });
2446
- // ---------------------------------------------------------------------------
2447
- // plugin org install bulk
2448
- // ---------------------------------------------------------------------------
2449
- describe("plugin org install bulk", () => {
2450
- it("bulk installs plugins", async () => {
2451
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
2461
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/install_bulk", expect.objectContaining({ method: "POST" }));
2462
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("1 succeeded"));
2463
- consoleSpy.mockRestore();
2464
- });
2465
- it("reports partial failures", async () => {
2466
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- ]);
2476
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("0 succeeded, 1 failed"));
2477
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("srv1: Not found"));
2478
- consoleSpy.mockRestore();
2479
- });
2480
- it("handles bulk install failure", async () => {
2481
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2482
- const exitSpy = vi
2483
- .spyOn(process, "exit")
2484
- .mockImplementation((_code) => {
2485
- throw new Error("process.exit");
2486
- });
2487
- mockApiRequest.mockRejectedValueOnce(new Error("Bad request"));
2488
- await expect(pluginOrgInstallBulkCommand.parseAsync(["node", "cli", "--items", "[]"])).rejects.toThrow();
2489
- consoleSpy.mockRestore();
2490
- exitSpy.mockRestore();
2491
- });
2492
- });
2493
- // ---------------------------------------------------------------------------
2494
- // plugin org list
2495
- // ---------------------------------------------------------------------------
2496
- describe("plugin org list", () => {
2497
- it("lists org plugins", async () => {
2498
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2499
- mockApiRequest.mockResolvedValueOnce({
2500
- listings: [
2501
- {
2502
- id: "l1",
2503
- publicId: "pub1",
2504
- name: "Slack",
2505
- pluginType: "mcp_server",
2506
- enabled: true,
2507
- },
2508
- ],
2509
- denylist: [],
2510
- });
2511
- await pluginOrgListCommand.parseAsync(["node", "cli"]);
2512
- expect(mockApiRequest).toHaveBeenCalled();
2513
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Slack"));
2514
- consoleSpy.mockRestore();
2515
- });
2516
- it("shows denylist when populated", async () => {
2517
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2518
- mockApiRequest.mockResolvedValueOnce({
2519
- listings: [],
2520
- denylist: [
2521
- {
2522
- id: "d1",
2523
- serverName: "bad-server",
2524
- pluginType: "mcp_server",
2525
- reason: "Security risk",
2526
- },
2527
- ],
2528
- });
2529
- await pluginOrgListCommand.parseAsync(["node", "cli"]);
2530
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Denylist"));
2531
- consoleSpy.mockRestore();
2532
- });
2533
- it("handles list failure", async () => {
2534
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2535
- const exitSpy = vi
2536
- .spyOn(process, "exit")
2537
- .mockImplementation((_code) => {
2538
- throw new Error("process.exit");
2539
- });
2540
- mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
2541
- await expect(pluginOrgListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2542
- consoleSpy.mockRestore();
2543
- exitSpy.mockRestore();
2544
- });
2545
- });
2546
- // ---------------------------------------------------------------------------
2547
- // plugin org set_enabled
2548
- // ---------------------------------------------------------------------------
2549
- describe("plugin org set_enabled", () => {
2550
- it("enables a plugin listing", async () => {
2551
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2552
- mockApiRequest.mockResolvedValueOnce({ ok: true });
2553
- await pluginOrgSetEnabledCommand.parseAsync([
2554
- "node",
2555
- "cli",
2556
- "-l",
2557
- "listing1",
2558
- "--enabled",
2559
- "true",
2560
- ]);
2561
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/org/set_enabled", expect.objectContaining({ method: "POST" }));
2562
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("enabled"));
2563
- consoleSpy.mockRestore();
2564
- });
2565
- it("disables a plugin listing", async () => {
2566
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2567
- mockApiRequest.mockResolvedValueOnce({ ok: true });
2568
- await pluginOrgSetEnabledCommand.parseAsync([
2569
- "node",
2570
- "cli",
2571
- "-l",
2572
- "listing1",
2573
- "--enabled",
2574
- "false",
2575
- ]);
2576
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("disabled"));
2577
- consoleSpy.mockRestore();
2578
- });
2579
- it("handles set_enabled failure", async () => {
2580
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2581
- const exitSpy = vi
2582
- .spyOn(process, "exit")
2583
- .mockImplementation((_code) => {
2584
- throw new Error("process.exit");
2585
- });
2586
- mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
2587
- await expect(pluginOrgSetEnabledCommand.parseAsync([
2588
- "node",
2589
- "cli",
2590
- "-l",
2591
- "l1",
2592
- "--enabled",
2593
- "true",
2594
- ])).rejects.toThrow();
2595
- consoleSpy.mockRestore();
2596
- exitSpy.mockRestore();
2597
- });
2598
- });
2599
- // ---------------------------------------------------------------------------
2600
- // plugin registry remove
2601
- // ---------------------------------------------------------------------------
2602
- describe("plugin registry remove", () => {
2603
- it("removes a registry", async () => {
2604
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2605
- mockApiRequest.mockResolvedValueOnce({ ok: true });
2606
- await pluginRegistryRemoveCommand.parseAsync(["node", "cli", "-r", "reg1"]);
2607
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/remove", expect.objectContaining({ method: "DELETE" }));
2608
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("reg1 removed"));
2609
- consoleSpy.mockRestore();
2610
- });
2611
- it("handles remove failure", async () => {
2612
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2613
- const exitSpy = vi
2614
- .spyOn(process, "exit")
2615
- .mockImplementation((_code) => {
2616
- throw new Error("process.exit");
2617
- });
2618
- mockApiRequest.mockRejectedValueOnce(new Error("Registry is global default"));
2619
- await expect(pluginRegistryRemoveCommand.parseAsync(["node", "cli", "-r", "r1"])).rejects.toThrow();
2620
- consoleSpy.mockRestore();
2621
- exitSpy.mockRestore();
2622
- });
2623
- });
2624
- // ---------------------------------------------------------------------------
2625
- // plugin settings set_auth_alerts
2626
- // ---------------------------------------------------------------------------
2627
- describe("plugin settings set_auth_alerts", () => {
2628
- it("updates auth alert settings", async () => {
2629
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2630
- mockApiRequest.mockResolvedValueOnce({ ok: true });
2631
- await pluginSettingsSetAuthAlertsCommand.parseAsync([
2632
- "node",
2633
- "cli",
2634
- "--roles",
2635
- "Owner,Admin",
2636
- ]);
2637
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/settings/set_auth_alerts", expect.objectContaining({ method: "POST" }));
2638
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("updated"));
2639
- consoleSpy.mockRestore();
2640
- });
2641
- it("reports update failed when ok=false", async () => {
2642
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2643
- mockApiRequest.mockResolvedValueOnce({ ok: false });
2644
- await pluginSettingsSetAuthAlertsCommand.parseAsync([
2645
- "node",
2646
- "cli",
2647
- "--roles",
2648
- "Owner",
2649
- ]);
2650
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Update failed"));
2651
- consoleSpy.mockRestore();
2652
- });
2653
- it("handles failure", async () => {
2654
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2655
- const exitSpy = vi
2656
- .spyOn(process, "exit")
2657
- .mockImplementation((_code) => {
2658
- throw new Error("process.exit");
2659
- });
2660
- mockApiRequest.mockRejectedValueOnce(new Error("Permission denied"));
2661
- await expect(pluginSettingsSetAuthAlertsCommand.parseAsync([
2662
- "node",
2663
- "cli",
2664
- "--roles",
2665
- "Owner",
2666
- ])).rejects.toThrow();
2667
- consoleSpy.mockRestore();
2668
- exitSpy.mockRestore();
2669
- });
2670
- });
2671
- // ---------------------------------------------------------------------------
2672
- // plugin workspace set_enabled
2673
- // ---------------------------------------------------------------------------
2674
- describe("plugin workspace set_enabled", () => {
2675
- it("enables a plugin for workspace", async () => {
2676
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2677
- mockApiRequest.mockResolvedValueOnce({ workspaceServerId: "wsrv1" });
2678
- await pluginWorkspaceSetEnabledCommand.parseAsync([
2679
- "node",
2680
- "cli",
2681
- "-l",
2682
- "listing1",
2683
- "--enabled",
2684
- "true",
2685
- ]);
2686
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/workspace/set_enabled", expect.objectContaining({ method: "POST" }));
2687
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("enabled"));
2688
- consoleSpy.mockRestore();
2689
- });
2690
- it("disables a plugin for workspace (no server ID)", async () => {
2691
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2692
- mockApiRequest.mockResolvedValueOnce({ workspaceServerId: null });
2693
- await pluginWorkspaceSetEnabledCommand.parseAsync([
2694
- "node",
2695
- "cli",
2696
- "-l",
2697
- "listing1",
2698
- "--enabled",
2699
- "false",
2700
- ]);
2701
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("disabled"));
2702
- consoleSpy.mockRestore();
2703
- });
2704
- it("handles failure", async () => {
2705
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2706
- const exitSpy = vi
2707
- .spyOn(process, "exit")
2708
- .mockImplementation((_code) => {
2709
- throw new Error("process.exit");
2710
- });
2711
- mockApiRequest.mockRejectedValueOnce(new Error("Listing not found"));
2712
- await expect(pluginWorkspaceSetEnabledCommand.parseAsync([
2713
- "node",
2714
- "cli",
2715
- "-l",
2716
- "l1",
2717
- "--enabled",
2718
- "true",
2719
- ])).rejects.toThrow();
2720
- consoleSpy.mockRestore();
2721
- exitSpy.mockRestore();
2722
- });
2723
- });
2724
- // ---------------------------------------------------------------------------
2725
- // system install instructions
2726
- // ---------------------------------------------------------------------------
2727
- describe("system install instructions", () => {
2728
- it("shows installation steps", async () => {
2729
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2730
- mockApiRequest.mockResolvedValueOnce({
2731
- client: "claude-code",
2732
- steps: [
2733
- { label: "Install the CLI", command: "npm install -g @oxagen/cli" },
2734
- { label: "Authenticate", command: "oxagen auth login" },
2735
- ],
2736
- });
2737
- await systemInstallInstructionsCommand.parseAsync([
2738
- "node",
2739
- "cli",
2740
- "-c",
2741
- "claude-code",
2742
- ]);
2743
- expect(mockApiRequest).toHaveBeenCalled();
2744
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("claude-code"));
2745
- consoleSpy.mockRestore();
2746
- });
2747
- it("handles fetch failure", async () => {
2748
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2749
- const exitSpy = vi
2750
- .spyOn(process, "exit")
2751
- .mockImplementation((_code) => {
2752
- throw new Error("process.exit");
2753
- });
2754
- mockApiRequest.mockRejectedValueOnce(new Error("Unknown client"));
2755
- await expect(systemInstallInstructionsCommand.parseAsync([
2756
- "node",
2757
- "cli",
2758
- "-c",
2759
- "unknown",
2760
- ])).rejects.toThrow();
2761
- consoleSpy.mockRestore();
2762
- exitSpy.mockRestore();
2763
- });
2764
- });
2765
- // ---------------------------------------------------------------------------
2766
- // user preferences read/write
2767
- // ---------------------------------------------------------------------------
2768
- describe("user preferences read", () => {
2769
- it("reads user preferences", async () => {
2770
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2771
- mockApiRequest.mockResolvedValueOnce({
2772
- fontSize: "medium",
2773
- density: "comfortable",
2774
- enterToSubmit: true,
2775
- pendingPromptBehavior: "queue",
2776
- defaultTextTier: "balanced",
2777
- defaultTextModel: "claude-haiku-4-5",
2778
- defaultImageModel: null,
2779
- defaultVideoModel: null,
2780
- });
2781
- await userPreferencesReadCommand.parseAsync(["node", "cli"]);
2782
- expect(mockApiRequest).toHaveBeenCalledWith("/user/preferences/read", expect.objectContaining({ method: "GET" }));
2783
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("preferences"));
2784
- consoleSpy.mockRestore();
2785
- });
2786
- it("shows optional fields when set", async () => {
2787
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2788
- mockApiRequest.mockResolvedValueOnce({
2789
- fontSize: "large",
2790
- density: "spacious",
2791
- enterToSubmit: false,
2792
- pendingPromptBehavior: "interrupt",
2793
- defaultTextTier: "precise",
2794
- defaultTextModel: "claude-sonnet-4-6",
2795
- defaultImageModel: "gpt-image-1",
2796
- defaultVideoModel: "veo-3.0",
2797
- });
2798
- await userPreferencesReadCommand.parseAsync(["node", "cli"]);
2799
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("gpt-image-1"));
2800
- consoleSpy.mockRestore();
2801
- });
2802
- it("handles read failure", async () => {
2803
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2804
- const exitSpy = vi
2805
- .spyOn(process, "exit")
2806
- .mockImplementation((_code) => {
2807
- throw new Error("process.exit");
2808
- });
2809
- mockApiRequest.mockRejectedValueOnce(new Error("Unauthorized"));
2810
- await expect(userPreferencesReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2811
- consoleSpy.mockRestore();
2812
- exitSpy.mockRestore();
2813
- });
2814
- });
2815
- describe("user preferences write", () => {
2816
- it("updates user preferences", async () => {
2817
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2818
- mockApiRequest.mockResolvedValueOnce({
2819
- fontSize: "large",
2820
- density: "comfortable",
2821
- enterToSubmit: true,
2822
- pendingPromptBehavior: "queue",
2823
- defaultTextTier: null,
2824
- defaultTextModel: null,
2825
- defaultImageModel: null,
2826
- defaultVideoModel: null,
2827
- });
2828
- await userPreferencesWriteCommand.parseAsync([
2829
- "node",
2830
- "cli",
2831
- "--font-size",
2832
- "large",
2833
- ]);
2834
- expect(mockApiRequest).toHaveBeenCalledWith("/user/preferences/write", expect.objectContaining({ method: "POST" }));
2835
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("updated"));
2836
- consoleSpy.mockRestore();
2837
- });
2838
- it("handles write failure", async () => {
2839
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2840
- const exitSpy = vi
2841
- .spyOn(process, "exit")
2842
- .mockImplementation((_code) => {
2843
- throw new Error("process.exit");
2844
- });
2845
- mockApiRequest.mockRejectedValueOnce(new Error("Validation failed"));
2846
- await expect(userPreferencesWriteCommand.parseAsync([
2847
- "node",
2848
- "cli",
2849
- "--density",
2850
- "bad",
2851
- ])).rejects.toThrow();
2852
- consoleSpy.mockRestore();
2853
- exitSpy.mockRestore();
2854
- });
2855
- });
2856
- // ---------------------------------------------------------------------------
2857
- // workflow cancel / status
2858
- // ---------------------------------------------------------------------------
2859
- describe("workflow cancel", () => {
2860
- it("cancels a workflow", async () => {
2861
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2862
- mockApiRequest.mockResolvedValueOnce({ cancelled: true });
2863
- await workflowCancelCommand.parseAsync(["node", "cli", "-w", "wfr_abc"]);
2864
- expect(mockApiRequest).toHaveBeenCalledWith("/workflow/cancel", expect.objectContaining({ method: "POST" }));
2865
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("cancelled"));
2866
- consoleSpy.mockRestore();
2867
- });
2868
- it("reports workflow could not be cancelled", async () => {
2869
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2870
- mockApiRequest.mockResolvedValueOnce({ cancelled: false });
2871
- await workflowCancelCommand.parseAsync(["node", "cli", "-w", "wfr_abc"]);
2872
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("could not be cancelled"));
2873
- consoleSpy.mockRestore();
2874
- });
2875
- it("handles cancel failure", async () => {
2876
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2877
- const exitSpy = vi
2878
- .spyOn(process, "exit")
2879
- .mockImplementation((_code) => {
2880
- throw new Error("process.exit");
2881
- });
2882
- mockApiRequest.mockRejectedValueOnce(new Error("Not found"));
2883
- await expect(workflowCancelCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
2884
- consoleSpy.mockRestore();
2885
- exitSpy.mockRestore();
2886
- });
2887
- });
2888
- describe("workflow status", () => {
2889
- it("shows workflow status and tasks", async () => {
2890
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2891
- mockApiRequest.mockResolvedValueOnce({
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
- },
2901
- tasks: [
2902
- { id: "t1", title: "Gather data", status: "completed" },
2903
- { id: "t2", title: "Analyze data", status: "running" },
2904
- ],
2905
- });
2906
- await workflowStatusCommand.parseAsync(["node", "cli", "-w", "wfr_abc"]);
2907
- expect(mockApiRequest).toHaveBeenCalled();
2908
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("running"));
2909
- consoleSpy.mockRestore();
2910
- });
2911
- it("handles status fetch failure", async () => {
2912
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2913
- const exitSpy = vi
2914
- .spyOn(process, "exit")
2915
- .mockImplementation((_code) => {
2916
- throw new Error("process.exit");
2917
- });
2918
- mockApiRequest.mockRejectedValueOnce(new Error("Workflow not found"));
2919
- await expect(workflowStatusCommand.parseAsync(["node", "cli", "-w", "wfr_xyz"])).rejects.toThrow();
2920
- consoleSpy.mockRestore();
2921
- exitSpy.mockRestore();
2922
- });
2923
- });
2924
- // ---------------------------------------------------------------------------
2925
- // Branch coverage: ApiError paths and edge cases
2926
- // These tests exercise the `err instanceof ApiError ? ... : String(err)` branch
2927
- // in catch blocks (currently always false), plus empty/optional data branches.
2928
- // ---------------------------------------------------------------------------
2929
- describe("branch coverage: ApiError error paths", () => {
2930
- it("automation list returns ApiError message", async () => {
2931
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2932
- const exitSpy = vi
2933
- .spyOn(process, "exit")
2934
- .mockImplementation((_code) => {
2935
- throw new Error("exit");
2936
- });
2937
- mockApiError(403, "Forbidden");
2938
- await expect(automationListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
2939
- expect(consoleSpy).toHaveBeenCalledWith("Error: Forbidden");
2940
- consoleSpy.mockRestore();
2941
- exitSpy.mockRestore();
2942
- });
2943
- it("automation create returns ApiError message", async () => {
2944
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2945
- const exitSpy = vi
2946
- .spyOn(process, "exit")
2947
- .mockImplementation((_code) => {
2948
- throw new Error("exit");
2949
- });
2950
- mockApiError(400, "Name required");
2951
- await expect(automationCreateCommand.parseAsync(["node", "cli", "-n", "A"])).rejects.toThrow();
2952
- expect(consoleSpy).toHaveBeenCalledWith("Error: Name required");
2953
- consoleSpy.mockRestore();
2954
- exitSpy.mockRestore();
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
- });
2982
- it("automation trigger returns ApiError message", async () => {
2983
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2984
- const exitSpy = vi
2985
- .spyOn(process, "exit")
2986
- .mockImplementation((_code) => {
2987
- throw new Error("exit");
2988
- });
2989
- mockApiError(404, "Automation not found");
2990
- await expect(automationTriggerCommand.parseAsync(["node", "cli", "-a", "a1"])).rejects.toThrow();
2991
- expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
2992
- consoleSpy.mockRestore();
2993
- exitSpy.mockRestore();
2994
- });
2995
- it("billing credits purchase returns ApiError message", async () => {
2996
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2997
- const exitSpy = vi
2998
- .spyOn(process, "exit")
2999
- .mockImplementation((_code) => {
3000
- throw new Error("exit");
3001
- });
3002
- mockApiError(402, "Payment failed");
3003
- await expect(billingCreditsPurchaseCommand.parseAsync(["node", "cli", "-a", "10"])).rejects.toThrow();
3004
- expect(consoleSpy).toHaveBeenCalledWith("Error: Payment failed");
3005
- consoleSpy.mockRestore();
3006
- exitSpy.mockRestore();
3007
- });
3008
- it("billing subscription read returns ApiError message", async () => {
3009
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3010
- const exitSpy = vi
3011
- .spyOn(process, "exit")
3012
- .mockImplementation((_code) => {
3013
- throw new Error("exit");
3014
- });
3015
- mockApiError(404, "Subscription not found");
3016
- await expect(billingSubscriptionReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
3017
- expect(consoleSpy).toHaveBeenCalledWith("Error: Subscription not found");
3018
- consoleSpy.mockRestore();
3019
- exitSpy.mockRestore();
3020
- });
3021
- it("document list returns ApiError message", async () => {
3022
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3023
- const exitSpy = vi
3024
- .spyOn(process, "exit")
3025
- .mockImplementation((_code) => {
3026
- throw new Error("exit");
3027
- });
3028
- mockApiError(403, "Access denied");
3029
- await expect(documentListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
3030
- expect(consoleSpy).toHaveBeenCalledWith("Error: Access denied");
3031
- consoleSpy.mockRestore();
3032
- exitSpy.mockRestore();
3033
- });
3034
- it("workspace member list returns ApiError message", async () => {
3035
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3036
- const exitSpy = vi
3037
- .spyOn(process, "exit")
3038
- .mockImplementation((_code) => {
3039
- throw new Error("exit");
3040
- });
3041
- mockApiError(403, "Not a member");
3042
- await expect(workspaceMemberListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
3043
- expect(consoleSpy).toHaveBeenCalledWith("Error: Not a member");
3044
- consoleSpy.mockRestore();
3045
- exitSpy.mockRestore();
3046
- });
3047
- it("workflow cancel returns ApiError message", async () => {
3048
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3049
- const exitSpy = vi
3050
- .spyOn(process, "exit")
3051
- .mockImplementation((_code) => {
3052
- throw new Error("exit");
3053
- });
3054
- mockApiError(404, "Workflow not found");
3055
- await expect(workflowCancelCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
3056
- expect(consoleSpy).toHaveBeenCalledWith("Error: Workflow not found");
3057
- consoleSpy.mockRestore();
3058
- exitSpy.mockRestore();
3059
- });
3060
- it("workflow status returns ApiError message", async () => {
3061
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3062
- const exitSpy = vi
3063
- .spyOn(process, "exit")
3064
- .mockImplementation((_code) => {
3065
- throw new Error("exit");
3066
- });
3067
- mockApiError(404, "Run expired");
3068
- await expect(workflowStatusCommand.parseAsync(["node", "cli", "-w", "wfr_abc"])).rejects.toThrow();
3069
- expect(consoleSpy).toHaveBeenCalledWith("Error: Run expired");
3070
- consoleSpy.mockRestore();
3071
- exitSpy.mockRestore();
3072
- });
3073
- it("user preferences read returns ApiError message", async () => {
3074
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3075
- const exitSpy = vi
3076
- .spyOn(process, "exit")
3077
- .mockImplementation((_code) => {
3078
- throw new Error("exit");
3079
- });
3080
- mockApiError(401, "Unauthorized");
3081
- await expect(userPreferencesReadCommand.parseAsync(["node", "cli"])).rejects.toThrow();
3082
- expect(consoleSpy).toHaveBeenCalledWith("Error: Unauthorized");
3083
- consoleSpy.mockRestore();
3084
- exitSpy.mockRestore();
3085
- });
3086
- it("user preferences write returns ApiError message", async () => {
3087
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3088
- const exitSpy = vi
3089
- .spyOn(process, "exit")
3090
- .mockImplementation((_code) => {
3091
- throw new Error("exit");
3092
- });
3093
- mockApiError(400, "Invalid font size");
3094
- await expect(userPreferencesWriteCommand.parseAsync([
3095
- "node",
3096
- "cli",
3097
- "--font-size",
3098
- "xxx",
3099
- ])).rejects.toThrow();
3100
- expect(consoleSpy).toHaveBeenCalledWith("Error: Invalid font size");
3101
- consoleSpy.mockRestore();
3102
- exitSpy.mockRestore();
3103
- });
3104
- });
3105
- describe("branch coverage: empty/optional data branches", () => {
3106
- it("automation list shows empty message when no automations found", async () => {
3107
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3108
- mockApiRequest.mockResolvedValueOnce([]);
3109
- await automationListCommand.parseAsync(["node", "cli"]);
3110
- expect(consoleSpy).toHaveBeenCalledWith("No automations found.");
3111
- consoleSpy.mockRestore();
3112
- });
3113
- it("automation list with workspace option", async () => {
3114
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3115
- mockApiRequest.mockResolvedValueOnce([
3116
- { id: "a1", name: "Test", status: "active", triggers: [] },
3117
- ]);
3118
- await automationListCommand.parseAsync(["node", "cli", "-w", "ws1"]);
3119
- expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("workspace_id=ws1"), expect.anything());
3120
- consoleSpy.mockRestore();
3121
- });
3122
- it("automation list shows 'none' when triggers are empty", async () => {
3123
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3124
- mockApiRequest.mockResolvedValueOnce([
3125
- { id: "a1", name: "Untriggered", status: "active", triggers: [] },
3126
- ]);
3127
- await automationListCommand.parseAsync(["node", "cli"]);
3128
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("triggers=none"));
3129
- consoleSpy.mockRestore();
3130
- });
3131
- it("image create with save-to option", async () => {
3132
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
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
- });
3139
- await imageCreateCommand.parseAsync(["node", "cli", "-p", "A cat"]);
3140
- consoleSpy.mockRestore();
3141
- });
3142
- it("conversation chat ApiError path", async () => {
3143
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3144
- const exitSpy = vi
3145
- .spyOn(process, "exit")
3146
- .mockImplementation((_code) => {
3147
- throw new Error("exit");
3148
- });
3149
- mockApiError(401, "Not authenticated");
3150
- await expect(conversationChatCommand.parseAsync(["node", "cli", "-m", "Hello"])).rejects.toThrow();
3151
- expect(consoleSpy).toHaveBeenCalledWith("Error: Not authenticated");
3152
- consoleSpy.mockRestore();
3153
- exitSpy.mockRestore();
3154
- });
3155
- it("workspace list ApiError path", async () => {
3156
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3157
- const exitSpy = vi
3158
- .spyOn(process, "exit")
3159
- .mockImplementation((_code) => {
3160
- throw new Error("exit");
3161
- });
3162
- mockApiError(403, "Org not found");
3163
- await expect(workspaceListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
3164
- expect(consoleSpy).toHaveBeenCalledWith("Error: Org not found");
3165
- consoleSpy.mockRestore();
3166
- exitSpy.mockRestore();
3167
- });
3168
- it("org list ApiError path", async () => {
3169
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3170
- const exitSpy = vi
3171
- .spyOn(process, "exit")
3172
- .mockImplementation((_code) => {
3173
- throw new Error("exit");
3174
- });
3175
- mockApiError(401, "Token expired");
3176
- await expect(orgListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
3177
- expect(consoleSpy).toHaveBeenCalledWith("Error: Token expired");
3178
- consoleSpy.mockRestore();
3179
- exitSpy.mockRestore();
3180
- });
3181
- it("api-key create ApiError path", async () => {
3182
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3183
- const exitSpy = vi
3184
- .spyOn(process, "exit")
3185
- .mockImplementation((_code) => {
3186
- throw new Error("exit");
3187
- });
3188
- mockApiError(429, "Rate limit exceeded");
3189
- await expect(apiKeyCreateCommand.parseAsync(["node", "cli", "mykey"])).rejects.toThrow();
3190
- expect(consoleSpy).toHaveBeenCalledWith("Error: Rate limit exceeded");
3191
- consoleSpy.mockRestore();
3192
- exitSpy.mockRestore();
3193
- });
3194
- it("plugin list ApiError path", async () => {
3195
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3196
- const exitSpy = vi
3197
- .spyOn(process, "exit")
3198
- .mockImplementation((_code) => {
3199
- throw new Error("exit");
3200
- });
3201
- mockApiError(403, "Permission denied");
3202
- await expect(pluginListCommand.parseAsync(["node", "cli"])).rejects.toThrow();
3203
- expect(consoleSpy).toHaveBeenCalledWith("Error: Permission denied");
3204
- consoleSpy.mockRestore();
3205
- exitSpy.mockRestore();
3206
- });
3207
- it("billing status ApiError path", async () => {
3208
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3209
- const exitSpy = vi
3210
- .spyOn(process, "exit")
3211
- .mockImplementation((_code) => {
3212
- throw new Error("exit");
3213
- });
3214
- mockApiError(402, "Billing error");
3215
- await expect(billingStatusCommand.parseAsync(["node", "cli"])).rejects.toThrow();
3216
- expect(consoleSpy).toHaveBeenCalledWith("Error: Billing error");
3217
- consoleSpy.mockRestore();
3218
- exitSpy.mockRestore();
3219
- });
3220
- it("chat send ApiError path", async () => {
3221
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3222
- const exitSpy = vi
3223
- .spyOn(process, "exit")
3224
- .mockImplementation((_code) => {
3225
- throw new Error("exit");
3226
- });
3227
- // chat.send uses native fetch (not apiRequest); mock fetch directly.
3228
- vi.spyOn(global, "fetch").mockResolvedValueOnce(new Response(JSON.stringify({ error: "Service unavailable" }), {
3229
- status: 503,
3230
- headers: { "content-type": "application/json" },
3231
- }));
3232
- await expect(chatSendCommand.parseAsync(["node", "cli", "test"])).rejects.toThrow();
3233
- consoleSpy.mockRestore();
3234
- exitSpy.mockRestore();
3235
- });
3236
- it("document read ApiError path", async () => {
3237
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3238
- const exitSpy = vi
3239
- .spyOn(process, "exit")
3240
- .mockImplementation((_code) => {
3241
- throw new Error("exit");
3242
- });
3243
- mockApiError(404, "Document not found");
3244
- await expect(documentReadCommand.parseAsync(["node", "cli", "-d", "doc1"])).rejects.toThrow();
3245
- expect(consoleSpy).toHaveBeenCalledWith("Error: Document not found");
3246
- consoleSpy.mockRestore();
3247
- exitSpy.mockRestore();
3248
- });
3249
- it("notification list with empty results", async () => {
3250
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3251
- mockApiRequest.mockResolvedValueOnce({ notifications: [] });
3252
- await notificationsListCommand.parseAsync(["node", "cli"]);
3253
- consoleSpy.mockRestore();
3254
- });
3255
- it("workflow run ApiError path", async () => {
3256
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
3257
- const exitSpy = vi
3258
- .spyOn(process, "exit")
3259
- .mockImplementation((_code) => {
3260
- throw new Error("exit");
3261
- });
3262
- mockApiError(400, "Invalid workflow spec");
3263
- await expect(workflowRunCommand.parseAsync(["node", "cli", "-w", "wf1"])).rejects.toThrow();
3264
- expect(consoleSpy).toHaveBeenCalledWith("Error: Invalid workflow spec");
3265
- consoleSpy.mockRestore();
3266
- exitSpy.mockRestore();
3267
- });
3268
- });
3269
- describe("Environment Variable Defaults", () => {
3270
- beforeEach(() => {
3271
- mockGetOrgId.mockReturnValue("default-org");
3272
- mockGetWorkspaceId.mockReturnValue("default-workspace");
3273
- mockGetToken.mockReturnValue("default-token");
3274
- });
3275
- afterEach(() => {
3276
- delete process.env.OXAGEN_ORG_ID;
3277
- delete process.env.OXAGEN_WORKSPACE_ID;
3278
- delete process.env.OXAGEN_API_TOKEN;
3279
- vi.clearAllMocks();
3280
- });
3281
- describe("OXAGEN_ORG_ID environment variable", () => {
3282
- it("org member list uses OXAGEN_ORG_ID env var when no --org flag provided", async () => {
3283
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3284
- mockGetOrgId.mockReturnValue("env-org-123");
3285
- mockApiRequest.mockResolvedValueOnce({ members: [] });
3286
- await orgMemberAddCommand.parseAsync([
3287
- "node",
3288
- "cli",
3289
- "user@example.com",
3290
- "--role",
3291
- "admin",
3292
- ]);
3293
- expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
3294
- body: expect.stringContaining("env-org-123"),
3295
- }));
3296
- consoleSpy.mockRestore();
3297
- });
3298
- it("org member list uses command-line --org flag to override OXAGEN_ORG_ID env var", async () => {
3299
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3300
- mockGetOrgId.mockReturnValue("env-org-123");
3301
- mockApiRequest.mockResolvedValueOnce({ members: [] });
3302
- await orgMemberAddCommand.parseAsync([
3303
- "node",
3304
- "cli",
3305
- "user@example.com",
3306
- "--role",
3307
- "admin",
3308
- "--org",
3309
- "cli-org-456",
3310
- ]);
3311
- expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
3312
- body: expect.stringContaining("cli-org-456"),
3313
- }));
3314
- consoleSpy.mockRestore();
3315
- });
3316
- });
3317
- describe("OXAGEN_WORKSPACE_ID environment variable", () => {
3318
- afterEach(() => {
3319
- mockApiRequest.mockClear();
3320
- });
3321
- it("workspace member list uses env var default when no --workspace flag", async () => {
3322
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3323
- mockGetWorkspaceId.mockReturnValue("env-workspace-789");
3324
- mockApiRequest.mockResolvedValueOnce([]);
3325
- await workspaceMemberListCommand.parseAsync(["node", "cli"]);
3326
- const calls = mockApiRequest.mock.calls;
3327
- expect(calls.length).toBeGreaterThan(0);
3328
- expect(calls[0]?.[0]).toContain("workspace_id=env-workspace-789");
3329
- consoleSpy.mockRestore();
3330
- });
3331
- it("workspace member list uses explicit flag to override env var", async () => {
3332
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3333
- mockGetWorkspaceId.mockReturnValue("env-workspace-789");
3334
- mockApiRequest.mockResolvedValueOnce([]);
3335
- await workspaceMemberListCommand.parseAsync([
3336
- "node",
3337
- "cli",
3338
- "-w",
3339
- "cli-workspace-xyz",
3340
- ]);
3341
- const calls = mockApiRequest.mock.calls;
3342
- expect(calls.length).toBeGreaterThan(0);
3343
- expect(calls[0]?.[0]).toContain("workspace_id=cli-workspace-xyz");
3344
- consoleSpy.mockRestore();
3345
- });
3346
- });
3347
- describe("OXAGEN_API_TOKEN environment variable", () => {
3348
- it("uses OXAGEN_API_TOKEN for Bearer token in Authorization header", async () => {
3349
- mockGetToken.mockReturnValue("sk-token-from-env");
3350
- mockApiRequest.mockResolvedValueOnce({ key: "key123" });
3351
- await apiKeyCreateCommand.parseAsync(["node", "cli", "mykey"]);
3352
- expect(mockApiRequest).toHaveBeenCalled();
3353
- });
3354
- });
3355
- describe("Precedence: env vars > command-line args (fallback pattern)", () => {
3356
- it("agent mcp register: workspace_id uses command-line --workspace when provided", async () => {
3357
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3358
- mockGetWorkspaceId.mockReturnValue("env-workspace-999");
3359
- mockApiRequest.mockResolvedValueOnce({
3360
- mcpServerId: "mcp-123",
3361
- healthStatus: "healthy",
3362
- discoveredTools: ["tool1"],
3363
- });
3364
- await agentMcpRegisterCommand.parseAsync([
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",
3376
- ]);
3377
- expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
3378
- body: expect.stringContaining("explicit-workspace-888"),
3379
- }));
3380
- consoleSpy.mockRestore();
3381
- });
3382
- it("agent mcp register: org_id uses getOrgId fallback when no --org flag provided", async () => {
3383
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3384
- mockGetOrgId.mockReturnValue("fallback-org-111");
3385
- mockGetWorkspaceId.mockReturnValue("any-workspace");
3386
- mockApiRequest.mockResolvedValueOnce({
3387
- mcpServerId: "mcp-456",
3388
- healthStatus: "healthy",
3389
- discoveredTools: [],
3390
- });
3391
- await agentMcpRegisterCommand.parseAsync([
3392
- "node",
3393
- "cli",
3394
- "register",
3395
- "-n",
3396
- "my-mcp",
3397
- "-u",
3398
- "http://localhost:9000",
3399
- "-t",
3400
- "streamable-http",
3401
- ]);
3402
- expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
3403
- body: expect.stringContaining("fallback-org-111"),
3404
- }));
3405
- consoleSpy.mockRestore();
3406
- });
3407
- });
3408
- describe("Multiple commands with env var defaults", () => {
3409
- beforeEach(() => {
3410
- vi.clearAllMocks();
3411
- mockGetWorkspaceId.mockReturnValue("env-ws-default");
3412
- // Commander retains option values between parseAsync calls; reset to avoid cross-test pollution
3413
- workspaceMemberListCommand.setOptionValue("workspace", undefined);
3414
- });
3415
- it("workspace member list uses OXAGEN_WORKSPACE_ID as default when no --workspace flag", async () => {
3416
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3417
- mockApiRequest.mockResolvedValueOnce([
3418
- {
3419
- id: "user1",
3420
- email: "user@test.com",
3421
- role: "member",
3422
- joined_at: "2024-01-01",
3423
- },
3424
- ]);
3425
- await workspaceMemberListCommand.parseAsync(["node", "cli"]);
3426
- const calls = mockApiRequest.mock.calls;
3427
- expect(calls.length).toBeGreaterThan(0);
3428
- expect(calls[0]?.[0]).toContain("workspace_id=env-ws-default");
3429
- consoleSpy.mockRestore();
3430
- });
3431
- it("workspace member list uses explicit --workspace to override OXAGEN_WORKSPACE_ID", async () => {
3432
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
3433
- mockApiRequest.mockResolvedValueOnce([
3434
- {
3435
- id: "user1",
3436
- email: "user@test.com",
3437
- role: "member",
3438
- joined_at: "2024-01-01",
3439
- },
3440
- ]);
3441
- await workspaceMemberListCommand.parseAsync([
3442
- "node",
3443
- "cli",
3444
- "-w",
3445
- "explicit-ws",
3446
- ]);
3447
- const calls = mockApiRequest.mock.calls;
3448
- expect(calls.length).toBeGreaterThan(0);
3449
- expect(calls[0]?.[0]).toContain("workspace_id=explicit-ws");
3450
- consoleSpy.mockRestore();
3451
- });
3452
- });
3453
- });
3454
- //# sourceMappingURL=commands.test.js.map