@oxagen/cli 0.3.3 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (320) hide show
  1. package/README.md +234 -318
  2. package/dist/commands/agent.mcp.consent.list.d.ts +3 -0
  3. package/dist/commands/agent.mcp.consent.list.d.ts.map +1 -0
  4. package/dist/commands/agent.mcp.consent.list.js +30 -0
  5. package/dist/commands/agent.mcp.consent.list.js.map +1 -0
  6. package/dist/commands/agent.mcp.consent.resolve.d.ts +3 -0
  7. package/dist/commands/agent.mcp.consent.resolve.d.ts.map +1 -0
  8. package/dist/commands/agent.mcp.consent.resolve.js +34 -0
  9. package/dist/commands/agent.mcp.consent.resolve.js.map +1 -0
  10. package/dist/commands/agent.mcp.delete.d.ts +3 -0
  11. package/dist/commands/agent.mcp.delete.d.ts.map +1 -0
  12. package/dist/commands/agent.mcp.delete.js +27 -0
  13. package/dist/commands/agent.mcp.delete.js.map +1 -0
  14. package/dist/commands/agent.mcp.list.d.ts.map +1 -1
  15. package/dist/commands/agent.mcp.list.js +4 -2
  16. package/dist/commands/agent.mcp.list.js.map +1 -1
  17. package/dist/commands/agent.mcp.register.d.ts.map +1 -1
  18. package/dist/commands/agent.mcp.register.js +3 -2
  19. package/dist/commands/agent.mcp.register.js.map +1 -1
  20. package/dist/commands/agent.mcp.set_enabled.d.ts +3 -0
  21. package/dist/commands/agent.mcp.set_enabled.d.ts.map +1 -0
  22. package/dist/commands/agent.mcp.set_enabled.js +33 -0
  23. package/dist/commands/agent.mcp.set_enabled.js.map +1 -0
  24. package/dist/commands/agent.plan.approve.d.ts.map +1 -1
  25. package/dist/commands/agent.plan.approve.js +2 -1
  26. package/dist/commands/agent.plan.approve.js.map +1 -1
  27. package/dist/commands/agent.plan.create.d.ts.map +1 -1
  28. package/dist/commands/agent.plan.create.js +2 -1
  29. package/dist/commands/agent.plan.create.js.map +1 -1
  30. package/dist/commands/agent.skill.list.d.ts.map +1 -1
  31. package/dist/commands/agent.skill.list.js +4 -2
  32. package/dist/commands/agent.skill.list.js.map +1 -1
  33. package/dist/commands/agent.task.background.cancel.d.ts.map +1 -1
  34. package/dist/commands/agent.task.background.cancel.js +2 -1
  35. package/dist/commands/agent.task.background.cancel.js.map +1 -1
  36. package/dist/commands/agent.task.background.read.d.ts.map +1 -1
  37. package/dist/commands/agent.task.background.read.js.map +1 -1
  38. package/dist/commands/agent.task.background.start.d.ts.map +1 -1
  39. package/dist/commands/agent.task.background.start.js +2 -1
  40. package/dist/commands/agent.task.background.start.js.map +1 -1
  41. package/dist/commands/agent.tool.list.d.ts.map +1 -1
  42. package/dist/commands/agent.tool.list.js +4 -2
  43. package/dist/commands/agent.tool.list.js.map +1 -1
  44. package/dist/commands/api-key.create.d.ts.map +1 -1
  45. package/dist/commands/api-key.create.js +2 -1
  46. package/dist/commands/api-key.create.js.map +1 -1
  47. package/dist/commands/archive.create.d.ts.map +1 -1
  48. package/dist/commands/archive.create.js +2 -1
  49. package/dist/commands/archive.create.js.map +1 -1
  50. package/dist/commands/asset.upload.d.ts.map +1 -1
  51. package/dist/commands/asset.upload.js +2 -1
  52. package/dist/commands/asset.upload.js.map +1 -1
  53. package/dist/commands/audit.log.query.d.ts +3 -0
  54. package/dist/commands/audit.log.query.d.ts.map +1 -0
  55. package/dist/commands/audit.log.query.js +42 -0
  56. package/dist/commands/audit.log.query.js.map +1 -0
  57. package/dist/commands/automation.create.d.ts.map +1 -1
  58. package/dist/commands/automation.create.js +43 -4
  59. package/dist/commands/automation.create.js.map +1 -1
  60. package/dist/commands/automation.disable.d.ts +3 -0
  61. package/dist/commands/automation.disable.d.ts.map +1 -0
  62. package/dist/commands/automation.disable.js +24 -0
  63. package/dist/commands/automation.disable.js.map +1 -0
  64. package/dist/commands/automation.enable.d.ts +3 -0
  65. package/dist/commands/automation.enable.d.ts.map +1 -0
  66. package/dist/commands/automation.enable.js +24 -0
  67. package/dist/commands/automation.enable.js.map +1 -0
  68. package/dist/commands/automation.list.d.ts.map +1 -1
  69. package/dist/commands/automation.list.js +3 -1
  70. package/dist/commands/automation.list.js.map +1 -1
  71. package/dist/commands/automation.update.d.ts +3 -0
  72. package/dist/commands/automation.update.d.ts.map +1 -0
  73. package/dist/commands/automation.update.js +42 -0
  74. package/dist/commands/automation.update.js.map +1 -0
  75. package/dist/commands/billing.credits.purchase.d.ts.map +1 -1
  76. package/dist/commands/billing.credits.purchase.js +2 -1
  77. package/dist/commands/billing.credits.purchase.js.map +1 -1
  78. package/dist/commands/billing.status.d.ts.map +1 -1
  79. package/dist/commands/billing.status.js +2 -1
  80. package/dist/commands/billing.status.js.map +1 -1
  81. package/dist/commands/billing.subscription.read.d.ts.map +1 -1
  82. package/dist/commands/billing.subscription.read.js +4 -2
  83. package/dist/commands/billing.subscription.read.js.map +1 -1
  84. package/dist/commands/billing.subscription.upgrade.start.d.ts.map +1 -1
  85. package/dist/commands/billing.subscription.upgrade.start.js +2 -1
  86. package/dist/commands/billing.subscription.upgrade.start.js.map +1 -1
  87. package/dist/commands/brandkit.apply.d.ts.map +1 -1
  88. package/dist/commands/brandkit.apply.js +3 -2
  89. package/dist/commands/brandkit.apply.js.map +1 -1
  90. package/dist/commands/chat.send.d.ts.map +1 -1
  91. package/dist/commands/chat.send.js +124 -19
  92. package/dist/commands/chat.send.js.map +1 -1
  93. package/dist/commands/conversation.files.list.d.ts +3 -0
  94. package/dist/commands/conversation.files.list.d.ts.map +1 -0
  95. package/dist/commands/conversation.files.list.js +39 -0
  96. package/dist/commands/conversation.files.list.js.map +1 -0
  97. package/dist/commands/conversation.purge.d.ts.map +1 -1
  98. package/dist/commands/conversation.purge.js +3 -2
  99. package/dist/commands/conversation.purge.js.map +1 -1
  100. package/dist/commands/document.list.d.ts.map +1 -1
  101. package/dist/commands/document.list.js +4 -2
  102. package/dist/commands/document.list.js.map +1 -1
  103. package/dist/commands/documents.pdf.create.d.ts.map +1 -1
  104. package/dist/commands/documents.pdf.create.js +3 -2
  105. package/dist/commands/documents.pdf.create.js.map +1 -1
  106. package/dist/commands/form.fill.d.ts.map +1 -1
  107. package/dist/commands/form.fill.js +2 -1
  108. package/dist/commands/form.fill.js.map +1 -1
  109. package/dist/commands/graph.cypher.d.ts +3 -0
  110. package/dist/commands/graph.cypher.d.ts.map +1 -0
  111. package/dist/commands/graph.cypher.js +37 -0
  112. package/dist/commands/graph.cypher.js.map +1 -0
  113. package/dist/commands/graph.edge.delete.d.ts +3 -0
  114. package/dist/commands/graph.edge.delete.d.ts.map +1 -0
  115. package/dist/commands/graph.edge.delete.js +53 -0
  116. package/dist/commands/graph.edge.delete.js.map +1 -0
  117. package/dist/commands/graph.edge.upsert.d.ts +3 -0
  118. package/dist/commands/graph.edge.upsert.d.ts.map +1 -0
  119. package/dist/commands/graph.edge.upsert.js +47 -0
  120. package/dist/commands/graph.edge.upsert.js.map +1 -0
  121. package/dist/commands/graph.node.delete.d.ts +3 -0
  122. package/dist/commands/graph.node.delete.d.ts.map +1 -0
  123. package/dist/commands/graph.node.delete.js +34 -0
  124. package/dist/commands/graph.node.delete.js.map +1 -0
  125. package/dist/commands/graph.node.get.d.ts +3 -0
  126. package/dist/commands/graph.node.get.d.ts.map +1 -0
  127. package/dist/commands/graph.node.get.js +16 -0
  128. package/dist/commands/graph.node.get.js.map +1 -0
  129. package/dist/commands/graph.node.search.d.ts +3 -0
  130. package/dist/commands/graph.node.search.d.ts.map +1 -0
  131. package/dist/commands/graph.node.search.js +31 -0
  132. package/dist/commands/graph.node.search.js.map +1 -0
  133. package/dist/commands/graph.node.upsert.d.ts +3 -0
  134. package/dist/commands/graph.node.upsert.d.ts.map +1 -0
  135. package/dist/commands/graph.node.upsert.js +39 -0
  136. package/dist/commands/graph.node.upsert.js.map +1 -0
  137. package/dist/commands/image.list.d.ts.map +1 -1
  138. package/dist/commands/image.list.js +4 -2
  139. package/dist/commands/image.list.js.map +1 -1
  140. package/dist/commands/markdown.generate.d.ts +3 -0
  141. package/dist/commands/markdown.generate.d.ts.map +1 -0
  142. package/dist/commands/markdown.generate.js +37 -0
  143. package/dist/commands/markdown.generate.js.map +1 -0
  144. package/dist/commands/mermaid.generate.d.ts +3 -0
  145. package/dist/commands/mermaid.generate.d.ts.map +1 -0
  146. package/dist/commands/mermaid.generate.js +33 -0
  147. package/dist/commands/mermaid.generate.js.map +1 -0
  148. package/dist/commands/ontology.neighbors.d.ts +3 -0
  149. package/dist/commands/ontology.neighbors.d.ts.map +1 -0
  150. package/dist/commands/ontology.neighbors.js +34 -0
  151. package/dist/commands/ontology.neighbors.js.map +1 -0
  152. package/dist/commands/ontology.query.d.ts +3 -0
  153. package/dist/commands/ontology.query.d.ts.map +1 -0
  154. package/dist/commands/ontology.query.js +36 -0
  155. package/dist/commands/ontology.query.js.map +1 -0
  156. package/dist/commands/org.member.add.d.ts.map +1 -1
  157. package/dist/commands/org.member.add.js +2 -1
  158. package/dist/commands/org.member.add.js.map +1 -1
  159. package/dist/commands/org.member.invite.decline.d.ts.map +1 -1
  160. package/dist/commands/org.member.invite.decline.js +2 -1
  161. package/dist/commands/org.member.invite.decline.js.map +1 -1
  162. package/dist/commands/org.member.remove.d.ts.map +1 -1
  163. package/dist/commands/org.member.remove.js +2 -1
  164. package/dist/commands/org.member.remove.js.map +1 -1
  165. package/dist/commands/org.member.role.change.d.ts.map +1 -1
  166. package/dist/commands/org.member.role.change.js +2 -1
  167. package/dist/commands/org.member.role.change.js.map +1 -1
  168. package/dist/commands/plugin.credential.reauth.d.ts.map +1 -1
  169. package/dist/commands/plugin.credential.reauth.js.map +1 -1
  170. package/dist/commands/plugin.credential.set_secret.d.ts.map +1 -1
  171. package/dist/commands/plugin.credential.set_secret.js +2 -1
  172. package/dist/commands/plugin.credential.set_secret.js.map +1 -1
  173. package/dist/commands/plugin.denylist.add.d.ts.map +1 -1
  174. package/dist/commands/plugin.denylist.add.js +2 -1
  175. package/dist/commands/plugin.denylist.add.js.map +1 -1
  176. package/dist/commands/plugin.denylist.remove.d.ts.map +1 -1
  177. package/dist/commands/plugin.denylist.remove.js +2 -1
  178. package/dist/commands/plugin.denylist.remove.js.map +1 -1
  179. package/dist/commands/plugin.install.d.ts.map +1 -1
  180. package/dist/commands/plugin.install.js +2 -1
  181. package/dist/commands/plugin.install.js.map +1 -1
  182. package/dist/commands/plugin.list.d.ts.map +1 -1
  183. package/dist/commands/plugin.list.js +2 -1
  184. package/dist/commands/plugin.list.js.map +1 -1
  185. package/dist/commands/plugin.org.install.d.ts.map +1 -1
  186. package/dist/commands/plugin.org.install.js +2 -1
  187. package/dist/commands/plugin.org.install.js.map +1 -1
  188. package/dist/commands/plugin.org.install_bulk.d.ts.map +1 -1
  189. package/dist/commands/plugin.org.install_bulk.js +2 -1
  190. package/dist/commands/plugin.org.install_bulk.js.map +1 -1
  191. package/dist/commands/plugin.org.list.d.ts.map +1 -1
  192. package/dist/commands/plugin.org.list.js +4 -2
  193. package/dist/commands/plugin.org.list.js.map +1 -1
  194. package/dist/commands/plugin.org.set_enabled.d.ts.map +1 -1
  195. package/dist/commands/plugin.org.set_enabled.js +2 -1
  196. package/dist/commands/plugin.org.set_enabled.js.map +1 -1
  197. package/dist/commands/plugin.org.uninstall.d.ts.map +1 -1
  198. package/dist/commands/plugin.org.uninstall.js +2 -1
  199. package/dist/commands/plugin.org.uninstall.js.map +1 -1
  200. package/dist/commands/plugin.registry.add.d.ts.map +1 -1
  201. package/dist/commands/plugin.registry.add.js.map +1 -1
  202. package/dist/commands/plugin.registry.list.d.ts.map +1 -1
  203. package/dist/commands/plugin.registry.list.js.map +1 -1
  204. package/dist/commands/plugin.registry.remove.d.ts.map +1 -1
  205. package/dist/commands/plugin.registry.remove.js +2 -1
  206. package/dist/commands/plugin.registry.remove.js.map +1 -1
  207. package/dist/commands/plugin.registry.sync.d.ts.map +1 -1
  208. package/dist/commands/plugin.registry.sync.js +2 -1
  209. package/dist/commands/plugin.registry.sync.js.map +1 -1
  210. package/dist/commands/plugin.settings.set_auth_alerts.d.ts.map +1 -1
  211. package/dist/commands/plugin.settings.set_auth_alerts.js +3 -2
  212. package/dist/commands/plugin.settings.set_auth_alerts.js.map +1 -1
  213. package/dist/commands/plugin.uninstall.d.ts.map +1 -1
  214. package/dist/commands/plugin.uninstall.js +2 -1
  215. package/dist/commands/plugin.uninstall.js.map +1 -1
  216. package/dist/commands/plugin.workspace.set_enabled.d.ts.map +1 -1
  217. package/dist/commands/plugin.workspace.set_enabled.js +3 -2
  218. package/dist/commands/plugin.workspace.set_enabled.js.map +1 -1
  219. package/dist/commands/privacy.erase.d.ts.map +1 -1
  220. package/dist/commands/privacy.erase.js +2 -1
  221. package/dist/commands/privacy.erase.js.map +1 -1
  222. package/dist/commands/privacy.erase.test.d.ts +2 -0
  223. package/dist/commands/privacy.erase.test.d.ts.map +1 -0
  224. package/dist/commands/privacy.erase.test.js +125 -0
  225. package/dist/commands/privacy.erase.test.js.map +1 -0
  226. package/dist/commands/privacy.export.d.ts.map +1 -1
  227. package/dist/commands/privacy.export.js.map +1 -1
  228. package/dist/commands/research.swarm.start.d.ts +3 -0
  229. package/dist/commands/research.swarm.start.d.ts.map +1 -0
  230. package/dist/commands/research.swarm.start.js +35 -0
  231. package/dist/commands/research.swarm.start.js.map +1 -0
  232. package/dist/commands/research.swarm.status.d.ts +3 -0
  233. package/dist/commands/research.swarm.status.d.ts.map +1 -0
  234. package/dist/commands/research.swarm.status.js +26 -0
  235. package/dist/commands/research.swarm.status.js.map +1 -0
  236. package/dist/commands/skill.edit.d.ts +3 -0
  237. package/dist/commands/skill.edit.d.ts.map +1 -0
  238. package/dist/commands/skill.edit.js +28 -0
  239. package/dist/commands/skill.edit.js.map +1 -0
  240. package/dist/commands/skill.export.d.ts +3 -0
  241. package/dist/commands/skill.export.d.ts.map +1 -0
  242. package/dist/commands/skill.export.js +25 -0
  243. package/dist/commands/skill.export.js.map +1 -0
  244. package/dist/commands/skill.metrics.read.d.ts +3 -0
  245. package/dist/commands/skill.metrics.read.d.ts.map +1 -0
  246. package/dist/commands/skill.metrics.read.js +56 -0
  247. package/dist/commands/skill.metrics.read.js.map +1 -0
  248. package/dist/commands/skill.version.activate.d.ts +3 -0
  249. package/dist/commands/skill.version.activate.d.ts.map +1 -0
  250. package/dist/commands/skill.version.activate.js +24 -0
  251. package/dist/commands/skill.version.activate.js.map +1 -0
  252. package/dist/commands/skill.version.get.d.ts +3 -0
  253. package/dist/commands/skill.version.get.d.ts.map +1 -0
  254. package/dist/commands/skill.version.get.js +43 -0
  255. package/dist/commands/skill.version.get.js.map +1 -0
  256. package/dist/commands/skill.version.list.d.ts +3 -0
  257. package/dist/commands/skill.version.list.d.ts.map +1 -0
  258. package/dist/commands/skill.version.list.js +38 -0
  259. package/dist/commands/skill.version.list.js.map +1 -0
  260. package/dist/commands/skill.version.upload.d.ts +3 -0
  261. package/dist/commands/skill.version.upload.d.ts.map +1 -0
  262. package/dist/commands/skill.version.upload.js +28 -0
  263. package/dist/commands/skill.version.upload.js.map +1 -0
  264. package/dist/commands/skill.workspace.install.d.ts +3 -0
  265. package/dist/commands/skill.workspace.install.d.ts.map +1 -0
  266. package/dist/commands/skill.workspace.install.js +52 -0
  267. package/dist/commands/skill.workspace.install.js.map +1 -0
  268. package/dist/commands/skill.workspace.list.d.ts.map +1 -1
  269. package/dist/commands/skill.workspace.list.js +4 -2
  270. package/dist/commands/skill.workspace.list.js.map +1 -1
  271. package/dist/commands/system.install.instructions.d.ts.map +1 -1
  272. package/dist/commands/system.install.instructions.js +7 -4
  273. package/dist/commands/system.install.instructions.js.map +1 -1
  274. package/dist/commands/web.fetch.d.ts +3 -0
  275. package/dist/commands/web.fetch.d.ts.map +1 -0
  276. package/dist/commands/web.fetch.js +39 -0
  277. package/dist/commands/web.fetch.js.map +1 -0
  278. package/dist/commands/web.search.d.ts +3 -0
  279. package/dist/commands/web.search.d.ts.map +1 -0
  280. package/dist/commands/web.search.js +50 -0
  281. package/dist/commands/web.search.js.map +1 -0
  282. package/dist/commands/workflow.cancel.d.ts.map +1 -1
  283. package/dist/commands/workflow.cancel.js +2 -1
  284. package/dist/commands/workflow.cancel.js.map +1 -1
  285. package/dist/commands/workflow.run.d.ts.map +1 -1
  286. package/dist/commands/workflow.run.js +2 -1
  287. package/dist/commands/workflow.run.js.map +1 -1
  288. package/dist/commands/workflow.status.d.ts.map +1 -1
  289. package/dist/commands/workflow.status.js +4 -2
  290. package/dist/commands/workflow.status.js.map +1 -1
  291. package/dist/commands/workspace.create.d.ts.map +1 -1
  292. package/dist/commands/workspace.create.js +2 -1
  293. package/dist/commands/workspace.create.js.map +1 -1
  294. package/dist/commands/workspace.list.d.ts.map +1 -1
  295. package/dist/commands/workspace.list.js +2 -1
  296. package/dist/commands/workspace.list.js.map +1 -1
  297. package/dist/commands/workspace.member.list.d.ts.map +1 -1
  298. package/dist/commands/workspace.member.list.js +3 -1
  299. package/dist/commands/workspace.member.list.js.map +1 -1
  300. package/dist/commands/workspace.model.settings.read.d.ts.map +1 -1
  301. package/dist/commands/workspace.model.settings.read.js +2 -1
  302. package/dist/commands/workspace.model.settings.read.js.map +1 -1
  303. package/dist/commands/workspace.model.settings.write.d.ts.map +1 -1
  304. package/dist/commands/workspace.model.settings.write.js +2 -1
  305. package/dist/commands/workspace.model.settings.write.js.map +1 -1
  306. package/dist/commands.test.js +319 -96
  307. package/dist/commands.test.js.map +1 -1
  308. package/dist/components/DevStatus.d.ts.map +1 -1
  309. package/dist/components/DevStatus.js +1 -1
  310. package/dist/components/DevStatus.js.map +1 -1
  311. package/dist/index.js +84 -7
  312. package/dist/index.js.map +1 -1
  313. package/dist/lib/config.d.ts +2 -0
  314. package/dist/lib/config.d.ts.map +1 -1
  315. package/dist/lib/config.js +16 -3
  316. package/dist/lib/config.js.map +1 -1
  317. package/dist/lib/config.test.js +21 -3
  318. package/dist/lib/config.test.js.map +1 -1
  319. package/package.json +1 -1
  320. package/README.html +0 -379
@@ -6,6 +6,8 @@ vi.mock("./lib/config.js", () => ({
6
6
  readConfig: vi.fn(() => ({ token: "test-token", orgSlug: "my-org", workspaceSlug: "default" })),
7
7
  writeConfig: vi.fn(),
8
8
  clearConfig: vi.fn(),
9
+ getOrgId: vi.fn(() => "my-org"),
10
+ getWorkspaceId: vi.fn(() => "default"),
9
11
  }));
10
12
  vi.mock("./lib/api-client.js", () => ({
11
13
  apiRequest: vi.fn(),
@@ -68,6 +70,8 @@ import { documentReadCommand } from "./commands/document.read.js";
68
70
  import { formCreateCommand } from "./commands/form.create.js";
69
71
  import { formSubmitCommand } from "./commands/form.submit.js";
70
72
  import { automationCreateCommand } from "./commands/automation.create.js";
73
+ import { automationEnableCommand } from "./commands/automation.enable.js";
74
+ import { automationDisableCommand } from "./commands/automation.disable.js";
71
75
  import { automationTriggerCommand } from "./commands/automation.trigger.js";
72
76
  import { skillWorkspaceListCommand } from "./commands/skill.workspace.list.js";
73
77
  import { agentMemoryRecallCommand } from "./commands/agent.memory.recall.js";
@@ -97,13 +101,10 @@ import { formFillCommand } from "./commands/form.fill.js";
97
101
  import { orgMemberInviteDeclineCommand } from "./commands/org.member.invite.decline.js";
98
102
  import { organizationCreateCommand } from "./commands/organization.create.js";
99
103
  import { pluginCredentialSetSecretCommand } from "./commands/plugin.credential.set_secret.js";
100
- import { pluginDenylistAddCommand } from "./commands/plugin.denylist.add.js";
101
- import { pluginDenylistRemoveCommand } from "./commands/plugin.denylist.remove.js";
102
104
  import { pluginOrgInstallBulkCommand } from "./commands/plugin.org.install_bulk.js";
103
105
  import { pluginOrgListCommand } from "./commands/plugin.org.list.js";
104
106
  import { pluginOrgSetEnabledCommand } from "./commands/plugin.org.set_enabled.js";
105
107
  import { pluginRegistryRemoveCommand } from "./commands/plugin.registry.remove.js";
106
- import { pluginRegistrySyncCommand } from "./commands/plugin.registry.sync.js";
107
108
  import { pluginSettingsSetAuthAlertsCommand } from "./commands/plugin.settings.set_auth_alerts.js";
108
109
  import { pluginWorkspaceSetEnabledCommand } from "./commands/plugin.workspace.set_enabled.js";
109
110
  import { systemInstallInstructionsCommand } from "./commands/system.install.instructions.js";
@@ -118,6 +119,8 @@ const mockRequireAuth = vi.mocked(apiClient.requireAuth);
118
119
  const mockWriteConfig = vi.mocked(config.writeConfig);
119
120
  const mockClearConfig = vi.mocked(config.clearConfig);
120
121
  const mockGetToken = vi.mocked(config.getToken);
122
+ const mockGetOrgId = vi.mocked(config.getOrgId);
123
+ const mockGetWorkspaceId = vi.mocked(config.getWorkspaceId);
121
124
  // Helper: throw an ApiError through apiRequest mock (covers instanceof branch in catch blocks)
122
125
  function mockApiError(status, message) {
123
126
  const ApiErrorClass = apiClient.ApiError;
@@ -355,33 +358,62 @@ describe("workspace create", () => {
355
358
  // ---------------------------------------------------------------------------
356
359
  // chat send
357
360
  // ---------------------------------------------------------------------------
361
+ // chat.send uses native fetch() directly for SSE streaming (not apiRequest).
362
+ // Build minimal SSE response helpers here.
363
+ function makeSseResponse(text) {
364
+ const line = `data: ${JSON.stringify({ type: "text", text })}\n\nevent: done\ndata: [DONE]\n\n`;
365
+ const encoder = new TextEncoder();
366
+ const stream = new ReadableStream({
367
+ start(c) { c.enqueue(encoder.encode(line)); c.close(); },
368
+ });
369
+ return new Response(stream, {
370
+ status: 200,
371
+ headers: { "content-type": "text/event-stream" },
372
+ });
373
+ }
374
+ function makeErrorResponse(status, message) {
375
+ return new Response(JSON.stringify({ error: message }), {
376
+ status,
377
+ headers: { "content-type": "application/json" },
378
+ });
379
+ }
358
380
  describe("chat send", () => {
359
- it("sends message and prints response", async () => {
360
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
361
- mockApiRequest.mockResolvedValueOnce({ content: "Hello back!" });
381
+ afterEach(() => { vi.restoreAllMocks(); });
382
+ it("sends message and streams response to stdout", async () => {
383
+ const stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
384
+ vi.spyOn(global, "fetch").mockResolvedValueOnce(makeSseResponse("Hello back!"));
362
385
  await chatSendCommand.parseAsync(["node", "cli", "hello"]);
363
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("hello"));
364
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Hello back!"));
365
- consoleSpy.mockRestore();
366
- });
367
- it("passes conversation id when provided", async () => {
368
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
369
- mockApiRequest.mockResolvedValueOnce({ content: "response" });
386
+ const written = stdoutSpy.mock.calls.map((c) => String(c[0])).join("");
387
+ expect(written).toContain("Hello back!");
388
+ stdoutSpy.mockRestore();
389
+ });
390
+ it("passes conversationId when --conversation is provided", async () => {
391
+ const stdoutSpy = vi.spyOn(process.stdout, "write").mockImplementation(() => true);
392
+ let capturedBody = null;
393
+ vi.spyOn(global, "fetch").mockImplementationOnce(async (_url, init) => {
394
+ capturedBody = JSON.parse(init.body);
395
+ return makeSseResponse("ok");
396
+ });
370
397
  await chatSendCommand.parseAsync(["node", "cli", "hi", "--conversation", "cnv_abc"]);
371
- const calls = mockApiRequest.mock.calls;
372
- const init = calls[0]?.[1];
373
- const callBody = JSON.parse(init?.body);
374
- expect(callBody.conversationId).toBe("cnv_abc");
375
- consoleSpy.mockRestore();
398
+ expect(capturedBody["conversationId"]).toBe("cnv_abc");
399
+ stdoutSpy.mockRestore();
376
400
  });
377
- it("exits 1 on API error", async () => {
401
+ it("exits 1 when fetch throws a network error", async () => {
378
402
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
379
403
  const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
380
- mockApiRequest.mockRejectedValueOnce(new Error("timeout"));
404
+ vi.spyOn(global, "fetch").mockRejectedValueOnce(new Error("ECONNREFUSED"));
381
405
  await expect(() => chatSendCommand.parseAsync(["node", "cli", "msg"])).rejects.toThrow("exit");
382
406
  consoleSpy.mockRestore();
383
407
  exitSpy.mockRestore();
384
408
  });
409
+ it("exits 1 on non-ok HTTP response", async () => {
410
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
411
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation(() => { throw new Error("exit"); });
412
+ vi.spyOn(global, "fetch").mockResolvedValueOnce(makeErrorResponse(503, "Service unavailable"));
413
+ await expect(() => chatSendCommand.parseAsync(["node", "cli", "test"])).rejects.toThrow();
414
+ consoleSpy.mockRestore();
415
+ exitSpy.mockRestore();
416
+ });
385
417
  });
386
418
  // ---------------------------------------------------------------------------
387
419
  // conversation commands
@@ -637,7 +669,7 @@ describe("agent mcp list", () => {
637
669
  servers: [{ id: "mcp1", name: "claude", status: "active" }],
638
670
  });
639
671
  await agentMcpListCommand.parseAsync(["node", "cli"]);
640
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/mcp/list?", expect.objectContaining({ method: "GET" }));
672
+ expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/mcp/list"), expect.objectContaining({ method: "GET" }));
641
673
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("MCP Servers"));
642
674
  consoleSpy.mockRestore();
643
675
  });
@@ -652,7 +684,7 @@ describe("agent skill list", () => {
652
684
  skills: [{ id: "skill1", name: "memory", description: "Memory management" }],
653
685
  });
654
686
  await agentSkillListCommand.parseAsync(["node", "cli"]);
655
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/skill/list?", expect.objectContaining({ method: "GET" }));
687
+ expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/skill/list"), expect.objectContaining({ method: "GET" }));
656
688
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Agent Skills"));
657
689
  consoleSpy.mockRestore();
658
690
  });
@@ -667,7 +699,7 @@ describe("agent tool list", () => {
667
699
  tools: [{ id: "tool1", name: "search", description: "Search capability" }],
668
700
  });
669
701
  await agentToolListCommand.parseAsync(["node", "cli"]);
670
- expect(mockApiRequest).toHaveBeenCalledWith("/agent/tool/list?", expect.objectContaining({ method: "GET" }));
702
+ expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/agent/tool/list"), expect.objectContaining({ method: "GET" }));
671
703
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Agent Tools"));
672
704
  consoleSpy.mockRestore();
673
705
  });
@@ -698,7 +730,7 @@ describe("billing subscription read", () => {
698
730
  subscription: { id: "sub1", plan: "scale", status: "active" },
699
731
  });
700
732
  await billingSubscriptionReadCommand.parseAsync(["node", "cli"]);
701
- expect(mockApiRequest).toHaveBeenCalledWith("/billing/subscription/read?", expect.objectContaining({ method: "GET" }));
733
+ expect(mockApiRequest).toHaveBeenCalledWith(expect.stringContaining("/billing/subscription/read"), expect.objectContaining({ method: "GET" }));
702
734
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Current Subscription"));
703
735
  consoleSpy.mockRestore();
704
736
  });
@@ -974,14 +1006,109 @@ describe("automation list", () => {
974
1006
  });
975
1007
  });
976
1008
  describe("automation create", () => {
977
- it("creates automation", async () => {
1009
+ it("creates automation with the contract payload shape", async () => {
978
1010
  const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
979
- mockApiRequest.mockResolvedValueOnce({ id: "auto1", name: "My Automation" });
1011
+ mockApiRequest.mockResolvedValueOnce({
1012
+ automation_id: "plt_1",
1013
+ playbook_id: "plb_1",
1014
+ name: "My Automation",
1015
+ status: "inactive",
1016
+ triggerType: "api",
1017
+ enabled: false,
1018
+ });
980
1019
  await automationCreateCommand.parseAsync(["node", "cli", "-n", "My Automation"]);
981
1020
  expect(mockApiRequest).toHaveBeenCalledWith("/automation/create", expect.objectContaining({ method: "POST" }));
1021
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1022
+ expect(body).toMatchObject({
1023
+ name: "My Automation",
1024
+ triggerType: "api",
1025
+ triggerConfig: {},
1026
+ steps: [],
1027
+ enabled: false,
1028
+ });
982
1029
  expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation created"));
983
1030
  consoleSpy.mockRestore();
984
1031
  });
1032
+ it("builds event triggerConfig from --entity-type/--event-type/--conditions and passes --enabled", async () => {
1033
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1034
+ mockApiRequest.mockResolvedValueOnce({
1035
+ automation_id: "plt_2",
1036
+ playbook_id: "plb_2",
1037
+ name: "Watcher",
1038
+ status: "active",
1039
+ triggerType: "event",
1040
+ enabled: true,
1041
+ });
1042
+ await automationCreateCommand.parseAsync([
1043
+ "node", "cli",
1044
+ "-n", "Watcher",
1045
+ "--trigger-type", "event",
1046
+ "--entity-type", "Contact",
1047
+ "--event-type", "node.updated",
1048
+ "--conditions", '[{"property":"status","toValue":"customer","operator":"eq"}]',
1049
+ "--enabled",
1050
+ ]);
1051
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1052
+ expect(body).toMatchObject({
1053
+ name: "Watcher",
1054
+ triggerType: "event",
1055
+ triggerConfig: {
1056
+ entityType: "Contact",
1057
+ eventType: "node.updated",
1058
+ propertyConditions: [{ property: "status", toValue: "customer", operator: "eq" }],
1059
+ },
1060
+ enabled: true,
1061
+ });
1062
+ consoleSpy.mockRestore();
1063
+ });
1064
+ it("builds schedule triggerConfig from --cron/--timezone", async () => {
1065
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1066
+ mockApiRequest.mockResolvedValueOnce({
1067
+ automation_id: "plt_3",
1068
+ playbook_id: "plb_3",
1069
+ name: "Report",
1070
+ status: "inactive",
1071
+ triggerType: "schedule",
1072
+ enabled: false,
1073
+ });
1074
+ await automationCreateCommand.parseAsync([
1075
+ "node", "cli",
1076
+ "-n", "Report",
1077
+ "--trigger-type", "schedule",
1078
+ "--cron", "0 9 * * 1",
1079
+ "--timezone", "America/New_York",
1080
+ ]);
1081
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1082
+ expect(body).toMatchObject({
1083
+ triggerType: "schedule",
1084
+ triggerConfig: { cronExpression: "0 9 * * 1", timezone: "America/New_York" },
1085
+ });
1086
+ consoleSpy.mockRestore();
1087
+ });
1088
+ });
1089
+ describe("automation enable", () => {
1090
+ it("enables automation", async () => {
1091
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1092
+ mockApiRequest.mockResolvedValueOnce({ automation_id: "plt_1", enabled: true, status: "active" });
1093
+ await automationEnableCommand.parseAsync(["node", "cli", "plt_1"]);
1094
+ expect(mockApiRequest).toHaveBeenCalledWith("/automation/enable", expect.objectContaining({ method: "POST" }));
1095
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1096
+ expect(body).toEqual({ automation_id: "plt_1" });
1097
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation enabled"));
1098
+ consoleSpy.mockRestore();
1099
+ });
1100
+ });
1101
+ describe("automation disable", () => {
1102
+ it("disables automation", async () => {
1103
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1104
+ mockApiRequest.mockResolvedValueOnce({ automation_id: "plt_1", enabled: false, status: "paused" });
1105
+ await automationDisableCommand.parseAsync(["node", "cli", "plt_1"]);
1106
+ expect(mockApiRequest).toHaveBeenCalledWith("/automation/disable", expect.objectContaining({ method: "POST" }));
1107
+ const body = JSON.parse((mockApiRequest.mock.calls[0]?.[1]).body);
1108
+ expect(body).toEqual({ automation_id: "plt_1" });
1109
+ expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Automation disabled"));
1110
+ consoleSpy.mockRestore();
1111
+ });
985
1112
  });
986
1113
  describe("automation trigger", () => {
987
1114
  it("triggers automation", async () => {
@@ -1610,45 +1737,6 @@ describe("plugin credential set_secret", () => {
1610
1737
  });
1611
1738
  });
1612
1739
  // ---------------------------------------------------------------------------
1613
- // plugin denylist
1614
- // ---------------------------------------------------------------------------
1615
- describe("plugin denylist add", () => {
1616
- it("adds a server to the denylist", async () => {
1617
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1618
- mockApiRequest.mockResolvedValueOnce({ ok: true });
1619
- await pluginDenylistAddCommand.parseAsync(["node", "cli", "-s", "bad-server"]);
1620
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/denylist/add", expect.objectContaining({ method: "POST" }));
1621
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("bad-server"));
1622
- consoleSpy.mockRestore();
1623
- });
1624
- it("handles denylist add failure", async () => {
1625
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1626
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1627
- mockApiRequest.mockRejectedValueOnce(new Error("Server not found"));
1628
- await expect(pluginDenylistAddCommand.parseAsync(["node", "cli", "-s", "srv"])).rejects.toThrow();
1629
- consoleSpy.mockRestore();
1630
- exitSpy.mockRestore();
1631
- });
1632
- });
1633
- describe("plugin denylist remove", () => {
1634
- it("removes a server from the denylist", async () => {
1635
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1636
- mockApiRequest.mockResolvedValueOnce({ ok: true });
1637
- await pluginDenylistRemoveCommand.parseAsync(["node", "cli", "-s", "bad-server"]);
1638
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/denylist/remove", expect.objectContaining({ method: "POST" }));
1639
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("bad-server"));
1640
- consoleSpy.mockRestore();
1641
- });
1642
- it("handles denylist remove failure", async () => {
1643
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1644
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1645
- mockApiRequest.mockRejectedValueOnce(new Error("Entry not found"));
1646
- await expect(pluginDenylistRemoveCommand.parseAsync(["node", "cli", "-s", "srv"])).rejects.toThrow();
1647
- consoleSpy.mockRestore();
1648
- exitSpy.mockRestore();
1649
- });
1650
- });
1651
- // ---------------------------------------------------------------------------
1652
1740
  // plugin org install bulk
1653
1741
  // ---------------------------------------------------------------------------
1654
1742
  describe("plugin org install bulk", () => {
@@ -1760,35 +1848,6 @@ describe("plugin registry remove", () => {
1760
1848
  });
1761
1849
  });
1762
1850
  // ---------------------------------------------------------------------------
1763
- // plugin registry sync
1764
- // ---------------------------------------------------------------------------
1765
- describe("plugin registry sync", () => {
1766
- it("triggers a registry sync", async () => {
1767
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1768
- mockApiRequest.mockResolvedValueOnce({ accepted: true });
1769
- await pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"]);
1770
- expect(mockApiRequest).toHaveBeenCalledWith("/plugin/registry/sync", expect.objectContaining({ method: "POST" }));
1771
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Sync accepted"));
1772
- consoleSpy.mockRestore();
1773
- });
1774
- it("reports sync not accepted", async () => {
1775
- const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
1776
- mockApiRequest.mockResolvedValueOnce({ accepted: false });
1777
- await pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"]);
1778
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("not accepted"));
1779
- consoleSpy.mockRestore();
1780
- });
1781
- it("handles sync failure", async () => {
1782
- const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
1783
- const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("process.exit"); });
1784
- mockApiRequest.mockRejectedValueOnce(new Error("Registry not found"));
1785
- await expect(pluginRegistrySyncCommand.parseAsync(["node", "cli", "-r", "reg1"])).rejects.toThrow();
1786
- expect(consoleSpy).toHaveBeenCalledWith(expect.stringContaining("Error:"));
1787
- consoleSpy.mockRestore();
1788
- exitSpy.mockRestore();
1789
- });
1790
- });
1791
- // ---------------------------------------------------------------------------
1792
1851
  // plugin settings set_auth_alerts
1793
1852
  // ---------------------------------------------------------------------------
1794
1853
  describe("plugin settings set_auth_alerts", () => {
@@ -2020,6 +2079,24 @@ describe("branch coverage: ApiError error paths", () => {
2020
2079
  consoleSpy.mockRestore();
2021
2080
  exitSpy.mockRestore();
2022
2081
  });
2082
+ it("automation enable returns ApiError message", async () => {
2083
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2084
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2085
+ mockApiError(404, "Automation not found");
2086
+ await expect(automationEnableCommand.parseAsync(["node", "cli", "plt_missing"])).rejects.toThrow();
2087
+ expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
2088
+ consoleSpy.mockRestore();
2089
+ exitSpy.mockRestore();
2090
+ });
2091
+ it("automation disable returns ApiError message", async () => {
2092
+ const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2093
+ const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2094
+ mockApiError(404, "Automation not found");
2095
+ await expect(automationDisableCommand.parseAsync(["node", "cli", "plt_missing"])).rejects.toThrow();
2096
+ expect(consoleSpy).toHaveBeenCalledWith("Error: Automation not found");
2097
+ consoleSpy.mockRestore();
2098
+ exitSpy.mockRestore();
2099
+ });
2023
2100
  it("automation trigger returns ApiError message", async () => {
2024
2101
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2025
2102
  const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
@@ -2187,9 +2264,12 @@ describe("branch coverage: empty/optional data branches", () => {
2187
2264
  it("chat send ApiError path", async () => {
2188
2265
  const consoleSpy = vi.spyOn(console, "error").mockImplementation(() => { });
2189
2266
  const exitSpy = vi.spyOn(process, "exit").mockImplementation((_code) => { throw new Error("exit"); });
2190
- mockApiError(503, "Service unavailable");
2267
+ // chat.send uses native fetch (not apiRequest); mock fetch directly.
2268
+ vi.spyOn(global, "fetch").mockResolvedValueOnce(new Response(JSON.stringify({ error: "Service unavailable" }), {
2269
+ status: 503,
2270
+ headers: { "content-type": "application/json" },
2271
+ }));
2191
2272
  await expect(chatSendCommand.parseAsync(["node", "cli", "test"])).rejects.toThrow();
2192
- expect(consoleSpy).toHaveBeenCalledWith("Error: Service unavailable");
2193
2273
  consoleSpy.mockRestore();
2194
2274
  exitSpy.mockRestore();
2195
2275
  });
@@ -2218,4 +2298,147 @@ describe("branch coverage: empty/optional data branches", () => {
2218
2298
  exitSpy.mockRestore();
2219
2299
  });
2220
2300
  });
2301
+ describe("Environment Variable Defaults", () => {
2302
+ beforeEach(() => {
2303
+ mockGetOrgId.mockReturnValue("default-org");
2304
+ mockGetWorkspaceId.mockReturnValue("default-workspace");
2305
+ mockGetToken.mockReturnValue("default-token");
2306
+ });
2307
+ afterEach(() => {
2308
+ delete process.env.OXAGEN_ORG_ID;
2309
+ delete process.env.OXAGEN_WORKSPACE_ID;
2310
+ delete process.env.OXAGEN_API_TOKEN;
2311
+ vi.clearAllMocks();
2312
+ });
2313
+ describe("OXAGEN_ORG_ID environment variable", () => {
2314
+ it("org member list uses OXAGEN_ORG_ID env var when no --org flag provided", async () => {
2315
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2316
+ mockGetOrgId.mockReturnValue("env-org-123");
2317
+ mockApiRequest.mockResolvedValueOnce({ members: [] });
2318
+ await orgMemberAddCommand.parseAsync(["node", "cli", "user@example.com", "--role", "admin"]);
2319
+ expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2320
+ body: expect.stringContaining("env-org-123"),
2321
+ }));
2322
+ consoleSpy.mockRestore();
2323
+ });
2324
+ it("org member list uses command-line --org flag to override OXAGEN_ORG_ID env var", async () => {
2325
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2326
+ mockGetOrgId.mockReturnValue("env-org-123");
2327
+ mockApiRequest.mockResolvedValueOnce({ members: [] });
2328
+ await orgMemberAddCommand.parseAsync(["node", "cli", "user@example.com", "--role", "admin", "--org", "cli-org-456"]);
2329
+ expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2330
+ body: expect.stringContaining("cli-org-456"),
2331
+ }));
2332
+ consoleSpy.mockRestore();
2333
+ });
2334
+ });
2335
+ describe("OXAGEN_WORKSPACE_ID environment variable", () => {
2336
+ afterEach(() => {
2337
+ mockApiRequest.mockClear();
2338
+ });
2339
+ it("workspace member list uses env var default when no --workspace flag", async () => {
2340
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2341
+ mockGetWorkspaceId.mockReturnValue("env-workspace-789");
2342
+ mockApiRequest.mockResolvedValueOnce([]);
2343
+ await workspaceMemberListCommand.parseAsync(["node", "cli"]);
2344
+ const calls = mockApiRequest.mock.calls;
2345
+ expect(calls.length).toBeGreaterThan(0);
2346
+ expect(calls[0]?.[0]).toContain("workspace_id=env-workspace-789");
2347
+ consoleSpy.mockRestore();
2348
+ });
2349
+ it("workspace member list uses explicit flag to override env var", async () => {
2350
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2351
+ mockGetWorkspaceId.mockReturnValue("env-workspace-789");
2352
+ mockApiRequest.mockResolvedValueOnce([]);
2353
+ await workspaceMemberListCommand.parseAsync(["node", "cli", "-w", "cli-workspace-xyz"]);
2354
+ const calls = mockApiRequest.mock.calls;
2355
+ expect(calls.length).toBeGreaterThan(0);
2356
+ expect(calls[0]?.[0]).toContain("workspace_id=cli-workspace-xyz");
2357
+ consoleSpy.mockRestore();
2358
+ });
2359
+ });
2360
+ describe("OXAGEN_API_TOKEN environment variable", () => {
2361
+ it("uses OXAGEN_API_TOKEN for Bearer token in Authorization header", async () => {
2362
+ mockGetToken.mockReturnValue("sk-token-from-env");
2363
+ mockApiRequest.mockResolvedValueOnce({ key: "key123" });
2364
+ await apiKeyCreateCommand.parseAsync(["node", "cli", "mykey"]);
2365
+ expect(mockApiRequest).toHaveBeenCalled();
2366
+ });
2367
+ });
2368
+ describe("Precedence: env vars > command-line args (fallback pattern)", () => {
2369
+ it("agent mcp register: workspace_id uses command-line --workspace when provided", async () => {
2370
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2371
+ mockGetWorkspaceId.mockReturnValue("env-workspace-999");
2372
+ mockApiRequest.mockResolvedValueOnce({
2373
+ mcpServerId: "mcp-123",
2374
+ healthStatus: "healthy",
2375
+ discoveredTools: ["tool1"],
2376
+ });
2377
+ await agentMcpRegisterCommand.parseAsync([
2378
+ "node", "cli", "register",
2379
+ "-n", "my-mcp",
2380
+ "-u", "http://localhost:9000",
2381
+ "-t", "streamable-http",
2382
+ "-w", "explicit-workspace-888"
2383
+ ]);
2384
+ expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2385
+ body: expect.stringContaining("explicit-workspace-888"),
2386
+ }));
2387
+ consoleSpy.mockRestore();
2388
+ });
2389
+ it("agent mcp register: org_id uses getOrgId fallback when no --org flag provided", async () => {
2390
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2391
+ mockGetOrgId.mockReturnValue("fallback-org-111");
2392
+ mockGetWorkspaceId.mockReturnValue("any-workspace");
2393
+ mockApiRequest.mockResolvedValueOnce({
2394
+ mcpServerId: "mcp-456",
2395
+ healthStatus: "healthy",
2396
+ discoveredTools: [],
2397
+ });
2398
+ await agentMcpRegisterCommand.parseAsync([
2399
+ "node", "cli", "register",
2400
+ "-n", "my-mcp",
2401
+ "-u", "http://localhost:9000",
2402
+ "-t", "streamable-http"
2403
+ ]);
2404
+ expect(mockApiRequest).toHaveBeenCalledWith(expect.any(String), expect.objectContaining({
2405
+ body: expect.stringContaining("fallback-org-111"),
2406
+ }));
2407
+ consoleSpy.mockRestore();
2408
+ });
2409
+ });
2410
+ describe("Multiple commands with env var defaults", () => {
2411
+ beforeEach(() => {
2412
+ vi.clearAllMocks();
2413
+ mockGetWorkspaceId.mockReturnValue("env-ws-default");
2414
+ // Commander retains option values between parseAsync calls; reset to avoid cross-test pollution
2415
+ workspaceMemberListCommand.setOptionValue("workspace", undefined);
2416
+ });
2417
+ it("workspace member list uses OXAGEN_WORKSPACE_ID as default when no --workspace flag", async () => {
2418
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2419
+ mockApiRequest.mockResolvedValueOnce([
2420
+ { id: "user1", email: "user@test.com", role: "member", joined_at: "2024-01-01" }
2421
+ ]);
2422
+ await workspaceMemberListCommand.parseAsync(["node", "cli"]);
2423
+ const calls = mockApiRequest.mock.calls;
2424
+ expect(calls.length).toBeGreaterThan(0);
2425
+ expect(calls[0]?.[0]).toContain("workspace_id=env-ws-default");
2426
+ consoleSpy.mockRestore();
2427
+ });
2428
+ it("workspace member list uses explicit --workspace to override OXAGEN_WORKSPACE_ID", async () => {
2429
+ const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
2430
+ mockApiRequest.mockResolvedValueOnce([
2431
+ { id: "user1", email: "user@test.com", role: "member", joined_at: "2024-01-01" }
2432
+ ]);
2433
+ await workspaceMemberListCommand.parseAsync([
2434
+ "node", "cli",
2435
+ "-w", "explicit-ws"
2436
+ ]);
2437
+ const calls = mockApiRequest.mock.calls;
2438
+ expect(calls.length).toBeGreaterThan(0);
2439
+ expect(calls[0]?.[0]).toContain("workspace_id=explicit-ws");
2440
+ consoleSpy.mockRestore();
2441
+ });
2442
+ });
2443
+ });
2221
2444
  //# sourceMappingURL=commands.test.js.map