@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.
- package/oxagen.mjs +100056 -0
- package/package.json +12 -29
- package/dist/agent/__tests__/code-graph.test.d.ts +0 -2
- package/dist/agent/__tests__/code-graph.test.d.ts.map +0 -1
- package/dist/agent/__tests__/code-graph.test.js +0 -83
- package/dist/agent/__tests__/code-graph.test.js.map +0 -1
- package/dist/agent/__tests__/evaluator.test.d.ts +0 -2
- package/dist/agent/__tests__/evaluator.test.d.ts.map +0 -1
- package/dist/agent/__tests__/evaluator.test.js +0 -96
- package/dist/agent/__tests__/evaluator.test.js.map +0 -1
- package/dist/agent/__tests__/fleet-memory.test.d.ts +0 -2
- package/dist/agent/__tests__/fleet-memory.test.d.ts.map +0 -1
- package/dist/agent/__tests__/fleet-memory.test.js +0 -107
- package/dist/agent/__tests__/fleet-memory.test.js.map +0 -1
- package/dist/agent/__tests__/fleet-store.test.d.ts +0 -2
- package/dist/agent/__tests__/fleet-store.test.d.ts.map +0 -1
- package/dist/agent/__tests__/fleet-store.test.js +0 -93
- package/dist/agent/__tests__/fleet-store.test.js.map +0 -1
- package/dist/agent/__tests__/git-isolation.test.d.ts +0 -2
- package/dist/agent/__tests__/git-isolation.test.d.ts.map +0 -1
- package/dist/agent/__tests__/git-isolation.test.js +0 -119
- package/dist/agent/__tests__/git-isolation.test.js.map +0 -1
- package/dist/agent/__tests__/judge.test.d.ts +0 -2
- package/dist/agent/__tests__/judge.test.d.ts.map +0 -1
- package/dist/agent/__tests__/judge.test.js +0 -135
- package/dist/agent/__tests__/judge.test.js.map +0 -1
- package/dist/agent/__tests__/loop-errors.test.d.ts +0 -2
- package/dist/agent/__tests__/loop-errors.test.d.ts.map +0 -1
- package/dist/agent/__tests__/loop-errors.test.js +0 -44
- package/dist/agent/__tests__/loop-errors.test.js.map +0 -1
- package/dist/agent/__tests__/model-router.test.d.ts +0 -2
- package/dist/agent/__tests__/model-router.test.d.ts.map +0 -1
- package/dist/agent/__tests__/model-router.test.js +0 -122
- package/dist/agent/__tests__/model-router.test.js.map +0 -1
- package/dist/agent/__tests__/orchestrator-isolation.test.d.ts +0 -2
- package/dist/agent/__tests__/orchestrator-isolation.test.d.ts.map +0 -1
- package/dist/agent/__tests__/orchestrator-isolation.test.js +0 -134
- package/dist/agent/__tests__/orchestrator-isolation.test.js.map +0 -1
- package/dist/agent/__tests__/orchestrator.test.d.ts +0 -2
- package/dist/agent/__tests__/orchestrator.test.d.ts.map +0 -1
- package/dist/agent/__tests__/orchestrator.test.js +0 -201
- package/dist/agent/__tests__/orchestrator.test.js.map +0 -1
- package/dist/agent/__tests__/pipeline.test.d.ts +0 -2
- package/dist/agent/__tests__/pipeline.test.d.ts.map +0 -1
- package/dist/agent/__tests__/pipeline.test.js +0 -226
- package/dist/agent/__tests__/pipeline.test.js.map +0 -1
- package/dist/agent/__tests__/planner.test.d.ts +0 -2
- package/dist/agent/__tests__/planner.test.d.ts.map +0 -1
- package/dist/agent/__tests__/planner.test.js +0 -98
- package/dist/agent/__tests__/planner.test.js.map +0 -1
- package/dist/agent/__tests__/prompt-enhancer.test.d.ts +0 -2
- package/dist/agent/__tests__/prompt-enhancer.test.d.ts.map +0 -1
- package/dist/agent/__tests__/prompt-enhancer.test.js +0 -107
- package/dist/agent/__tests__/prompt-enhancer.test.js.map +0 -1
- package/dist/agent/__tests__/trace-format.test.d.ts +0 -2
- package/dist/agent/__tests__/trace-format.test.d.ts.map +0 -1
- package/dist/agent/__tests__/trace-format.test.js +0 -104
- package/dist/agent/__tests__/trace-format.test.js.map +0 -1
- package/dist/agent/__tests__/trace-store.test.d.ts +0 -2
- package/dist/agent/__tests__/trace-store.test.d.ts.map +0 -1
- package/dist/agent/__tests__/trace-store.test.js +0 -113
- package/dist/agent/__tests__/trace-store.test.js.map +0 -1
- package/dist/agent/code-graph.d.ts +0 -18
- package/dist/agent/code-graph.d.ts.map +0 -1
- package/dist/agent/code-graph.js +0 -119
- package/dist/agent/code-graph.js.map +0 -1
- package/dist/agent/env.d.ts +0 -11
- package/dist/agent/env.d.ts.map +0 -1
- package/dist/agent/env.js +0 -82
- package/dist/agent/env.js.map +0 -1
- package/dist/agent/evaluator.d.ts +0 -13
- package/dist/agent/evaluator.d.ts.map +0 -1
- package/dist/agent/evaluator.js +0 -146
- package/dist/agent/evaluator.js.map +0 -1
- package/dist/agent/fleet/git-isolation.d.ts +0 -142
- package/dist/agent/fleet/git-isolation.d.ts.map +0 -1
- package/dist/agent/fleet/git-isolation.js +0 -290
- package/dist/agent/fleet/git-isolation.js.map +0 -1
- package/dist/agent/fleet/memory.d.ts +0 -21
- package/dist/agent/fleet/memory.d.ts.map +0 -1
- package/dist/agent/fleet/memory.js +0 -129
- package/dist/agent/fleet/memory.js.map +0 -1
- package/dist/agent/fleet/orchestrator.d.ts +0 -103
- package/dist/agent/fleet/orchestrator.d.ts.map +0 -1
- package/dist/agent/fleet/orchestrator.js +0 -355
- package/dist/agent/fleet/orchestrator.js.map +0 -1
- package/dist/agent/fleet/store.d.ts +0 -13
- package/dist/agent/fleet/store.d.ts.map +0 -1
- package/dist/agent/fleet/store.js +0 -79
- package/dist/agent/fleet/store.js.map +0 -1
- package/dist/agent/fleet/types.d.ts +0 -105
- package/dist/agent/fleet/types.d.ts.map +0 -1
- package/dist/agent/fleet/types.js +0 -17
- package/dist/agent/fleet/types.js.map +0 -1
- package/dist/agent/judge.d.ts +0 -38
- package/dist/agent/judge.d.ts.map +0 -1
- package/dist/agent/judge.js +0 -170
- package/dist/agent/judge.js.map +0 -1
- package/dist/agent/loop.d.ts +0 -61
- package/dist/agent/loop.d.ts.map +0 -1
- package/dist/agent/loop.js +0 -134
- package/dist/agent/loop.js.map +0 -1
- package/dist/agent/memory.d.ts +0 -14
- package/dist/agent/memory.d.ts.map +0 -1
- package/dist/agent/memory.js +0 -118
- package/dist/agent/memory.js.map +0 -1
- package/dist/agent/model-router.d.ts +0 -79
- package/dist/agent/model-router.d.ts.map +0 -1
- package/dist/agent/model-router.js +0 -141
- package/dist/agent/model-router.js.map +0 -1
- package/dist/agent/model.d.ts +0 -9
- package/dist/agent/model.d.ts.map +0 -1
- package/dist/agent/model.js +0 -24
- package/dist/agent/model.js.map +0 -1
- package/dist/agent/pipeline.d.ts +0 -82
- package/dist/agent/pipeline.d.ts.map +0 -1
- package/dist/agent/pipeline.js +0 -320
- package/dist/agent/pipeline.js.map +0 -1
- package/dist/agent/planner.d.ts +0 -16
- package/dist/agent/planner.d.ts.map +0 -1
- package/dist/agent/planner.js +0 -126
- package/dist/agent/planner.js.map +0 -1
- package/dist/agent/project-context.d.ts +0 -13
- package/dist/agent/project-context.d.ts.map +0 -1
- package/dist/agent/project-context.js +0 -66
- package/dist/agent/project-context.js.map +0 -1
- package/dist/agent/prompt-enhancer.d.ts +0 -37
- package/dist/agent/prompt-enhancer.d.ts.map +0 -1
- package/dist/agent/prompt-enhancer.js +0 -115
- package/dist/agent/prompt-enhancer.js.map +0 -1
- package/dist/agent/system-prompt.d.ts +0 -9
- package/dist/agent/system-prompt.d.ts.map +0 -1
- package/dist/agent/system-prompt.js +0 -38
- package/dist/agent/system-prompt.js.map +0 -1
- package/dist/agent/tools.d.ts +0 -19
- package/dist/agent/tools.d.ts.map +0 -1
- package/dist/agent/tools.js +0 -323
- package/dist/agent/tools.js.map +0 -1
- package/dist/agent/trace-format.d.ts +0 -6
- package/dist/agent/trace-format.d.ts.map +0 -1
- package/dist/agent/trace-format.js +0 -74
- package/dist/agent/trace-format.js.map +0 -1
- package/dist/agent/trace-store.d.ts +0 -19
- package/dist/agent/trace-store.d.ts.map +0 -1
- package/dist/agent/trace-store.js +0 -82
- package/dist/agent/trace-store.js.map +0 -1
- package/dist/agent/trace.d.ts +0 -121
- package/dist/agent/trace.d.ts.map +0 -1
- package/dist/agent/trace.js +0 -2
- package/dist/agent/trace.js.map +0 -1
- package/dist/commands/__tests__/cli-parity.test.d.ts +0 -2
- package/dist/commands/__tests__/cli-parity.test.d.ts.map +0 -1
- package/dist/commands/__tests__/cli-parity.test.js +0 -110
- package/dist/commands/__tests__/cli-parity.test.js.map +0 -1
- package/dist/commands/__tests__/replay.test.d.ts +0 -2
- package/dist/commands/__tests__/replay.test.d.ts.map +0 -1
- package/dist/commands/__tests__/replay.test.js +0 -76
- package/dist/commands/__tests__/replay.test.js.map +0 -1
- package/dist/commands/agent.approval.resolve.d.ts +0 -3
- package/dist/commands/agent.approval.resolve.d.ts.map +0 -1
- package/dist/commands/agent.approval.resolve.js +0 -30
- package/dist/commands/agent.approval.resolve.js.map +0 -1
- package/dist/commands/agent.mcp.consent.list.d.ts +0 -3
- package/dist/commands/agent.mcp.consent.list.d.ts.map +0 -1
- package/dist/commands/agent.mcp.consent.list.js +0 -30
- package/dist/commands/agent.mcp.consent.list.js.map +0 -1
- package/dist/commands/agent.mcp.consent.resolve.d.ts +0 -3
- package/dist/commands/agent.mcp.consent.resolve.d.ts.map +0 -1
- package/dist/commands/agent.mcp.consent.resolve.js +0 -34
- package/dist/commands/agent.mcp.consent.resolve.js.map +0 -1
- package/dist/commands/agent.mcp.delete.d.ts +0 -3
- package/dist/commands/agent.mcp.delete.d.ts.map +0 -1
- package/dist/commands/agent.mcp.delete.js +0 -27
- package/dist/commands/agent.mcp.delete.js.map +0 -1
- package/dist/commands/agent.mcp.list.d.ts +0 -3
- package/dist/commands/agent.mcp.list.d.ts.map +0 -1
- package/dist/commands/agent.mcp.list.js +0 -25
- package/dist/commands/agent.mcp.list.js.map +0 -1
- package/dist/commands/agent.mcp.register.d.ts +0 -3
- package/dist/commands/agent.mcp.register.d.ts.map +0 -1
- package/dist/commands/agent.mcp.register.js +0 -41
- package/dist/commands/agent.mcp.register.js.map +0 -1
- package/dist/commands/agent.mcp.set_enabled.d.ts +0 -3
- package/dist/commands/agent.mcp.set_enabled.d.ts.map +0 -1
- package/dist/commands/agent.mcp.set_enabled.js +0 -33
- package/dist/commands/agent.mcp.set_enabled.js.map +0 -1
- package/dist/commands/agent.memory.recall.d.ts +0 -3
- package/dist/commands/agent.memory.recall.d.ts.map +0 -1
- package/dist/commands/agent.memory.recall.js +0 -25
- package/dist/commands/agent.memory.recall.js.map +0 -1
- package/dist/commands/agent.memory.write.d.ts +0 -3
- package/dist/commands/agent.memory.write.d.ts.map +0 -1
- package/dist/commands/agent.memory.write.js +0 -25
- package/dist/commands/agent.memory.write.js.map +0 -1
- package/dist/commands/agent.plan.approve.d.ts +0 -3
- package/dist/commands/agent.plan.approve.d.ts.map +0 -1
- package/dist/commands/agent.plan.approve.js +0 -35
- package/dist/commands/agent.plan.approve.js.map +0 -1
- package/dist/commands/agent.plan.create.d.ts +0 -3
- package/dist/commands/agent.plan.create.d.ts.map +0 -1
- package/dist/commands/agent.plan.create.js +0 -42
- package/dist/commands/agent.plan.create.js.map +0 -1
- package/dist/commands/agent.skill.list.d.ts +0 -3
- package/dist/commands/agent.skill.list.d.ts.map +0 -1
- package/dist/commands/agent.skill.list.js +0 -27
- package/dist/commands/agent.skill.list.js.map +0 -1
- package/dist/commands/agent.skill.load.d.ts +0 -3
- package/dist/commands/agent.skill.load.d.ts.map +0 -1
- package/dist/commands/agent.skill.load.js +0 -57
- package/dist/commands/agent.skill.load.js.map +0 -1
- package/dist/commands/agent.task.background.cancel.d.ts +0 -3
- package/dist/commands/agent.task.background.cancel.d.ts.map +0 -1
- package/dist/commands/agent.task.background.cancel.js +0 -30
- package/dist/commands/agent.task.background.cancel.js.map +0 -1
- package/dist/commands/agent.task.background.read.d.ts +0 -3
- package/dist/commands/agent.task.background.read.d.ts.map +0 -1
- package/dist/commands/agent.task.background.read.js +0 -28
- package/dist/commands/agent.task.background.read.js.map +0 -1
- package/dist/commands/agent.task.background.start.d.ts +0 -3
- package/dist/commands/agent.task.background.start.d.ts.map +0 -1
- package/dist/commands/agent.task.background.start.js +0 -32
- package/dist/commands/agent.task.background.start.js.map +0 -1
- package/dist/commands/agent.tool.list.d.ts +0 -3
- package/dist/commands/agent.tool.list.d.ts.map +0 -1
- package/dist/commands/agent.tool.list.js +0 -27
- package/dist/commands/agent.tool.list.js.map +0 -1
- package/dist/commands/api-key.create.d.ts +0 -3
- package/dist/commands/api-key.create.d.ts.map +0 -1
- package/dist/commands/api-key.create.js +0 -32
- package/dist/commands/api-key.create.js.map +0 -1
- package/dist/commands/api-key.revoke.d.ts +0 -3
- package/dist/commands/api-key.revoke.d.ts.map +0 -1
- package/dist/commands/api-key.revoke.js +0 -18
- package/dist/commands/api-key.revoke.js.map +0 -1
- package/dist/commands/archive.create.d.ts +0 -3
- package/dist/commands/archive.create.d.ts.map +0 -1
- package/dist/commands/archive.create.js +0 -30
- package/dist/commands/archive.create.js.map +0 -1
- package/dist/commands/asset.upload.d.ts +0 -3
- package/dist/commands/asset.upload.d.ts.map +0 -1
- package/dist/commands/asset.upload.js +0 -32
- package/dist/commands/asset.upload.js.map +0 -1
- package/dist/commands/audit.log.query.d.ts +0 -3
- package/dist/commands/audit.log.query.d.ts.map +0 -1
- package/dist/commands/audit.log.query.js +0 -42
- package/dist/commands/audit.log.query.js.map +0 -1
- package/dist/commands/auth.login.d.ts +0 -3
- package/dist/commands/auth.login.d.ts.map +0 -1
- package/dist/commands/auth.login.js +0 -32
- package/dist/commands/auth.login.js.map +0 -1
- package/dist/commands/auth.logout.d.ts +0 -3
- package/dist/commands/auth.logout.d.ts.map +0 -1
- package/dist/commands/auth.logout.js +0 -20
- package/dist/commands/auth.logout.js.map +0 -1
- package/dist/commands/auth.whoami.d.ts +0 -3
- package/dist/commands/auth.whoami.d.ts.map +0 -1
- package/dist/commands/auth.whoami.js +0 -21
- package/dist/commands/auth.whoami.js.map +0 -1
- package/dist/commands/automation.create.d.ts +0 -3
- package/dist/commands/automation.create.d.ts.map +0 -1
- package/dist/commands/automation.create.js +0 -69
- package/dist/commands/automation.create.js.map +0 -1
- package/dist/commands/automation.disable.d.ts +0 -3
- package/dist/commands/automation.disable.d.ts.map +0 -1
- package/dist/commands/automation.disable.js +0 -24
- package/dist/commands/automation.disable.js.map +0 -1
- package/dist/commands/automation.enable.d.ts +0 -3
- package/dist/commands/automation.enable.d.ts.map +0 -1
- package/dist/commands/automation.enable.js +0 -24
- package/dist/commands/automation.enable.js.map +0 -1
- package/dist/commands/automation.list.d.ts +0 -3
- package/dist/commands/automation.list.d.ts.map +0 -1
- package/dist/commands/automation.list.js +0 -28
- package/dist/commands/automation.list.js.map +0 -1
- package/dist/commands/automation.trigger.d.ts +0 -3
- package/dist/commands/automation.trigger.d.ts.map +0 -1
- package/dist/commands/automation.trigger.js +0 -33
- package/dist/commands/automation.trigger.js.map +0 -1
- package/dist/commands/automation.update.d.ts +0 -3
- package/dist/commands/automation.update.d.ts.map +0 -1
- package/dist/commands/automation.update.js +0 -42
- package/dist/commands/automation.update.js.map +0 -1
- package/dist/commands/billing.credits.purchase.d.ts +0 -3
- package/dist/commands/billing.credits.purchase.d.ts.map +0 -1
- package/dist/commands/billing.credits.purchase.js +0 -32
- package/dist/commands/billing.credits.purchase.js.map +0 -1
- package/dist/commands/billing.status.d.ts +0 -3
- package/dist/commands/billing.status.d.ts.map +0 -1
- package/dist/commands/billing.status.js +0 -32
- package/dist/commands/billing.status.js.map +0 -1
- package/dist/commands/billing.subscription.read.d.ts +0 -3
- package/dist/commands/billing.subscription.read.d.ts.map +0 -1
- package/dist/commands/billing.subscription.read.js +0 -28
- package/dist/commands/billing.subscription.read.js.map +0 -1
- package/dist/commands/billing.subscription.upgrade.start.d.ts +0 -3
- package/dist/commands/billing.subscription.upgrade.start.d.ts.map +0 -1
- package/dist/commands/billing.subscription.upgrade.start.js +0 -33
- package/dist/commands/billing.subscription.upgrade.start.js.map +0 -1
- package/dist/commands/brandkit.apply.d.ts +0 -3
- package/dist/commands/brandkit.apply.d.ts.map +0 -1
- package/dist/commands/brandkit.apply.js +0 -32
- package/dist/commands/brandkit.apply.js.map +0 -1
- package/dist/commands/chat.send.d.ts +0 -3
- package/dist/commands/chat.send.d.ts.map +0 -1
- package/dist/commands/chat.send.js +0 -136
- package/dist/commands/chat.send.js.map +0 -1
- package/dist/commands/code.d.ts +0 -14
- package/dist/commands/code.d.ts.map +0 -1
- package/dist/commands/code.js +0 -100
- package/dist/commands/code.js.map +0 -1
- package/dist/commands/config.d.ts +0 -2
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/config.js +0 -66
- package/dist/commands/config.js.map +0 -1
- package/dist/commands/conversation.archive.d.ts +0 -3
- package/dist/commands/conversation.archive.d.ts.map +0 -1
- package/dist/commands/conversation.archive.js +0 -23
- package/dist/commands/conversation.archive.js.map +0 -1
- package/dist/commands/conversation.chat.d.ts +0 -3
- package/dist/commands/conversation.chat.d.ts.map +0 -1
- package/dist/commands/conversation.chat.js +0 -28
- package/dist/commands/conversation.chat.js.map +0 -1
- package/dist/commands/conversation.delete.d.ts +0 -3
- package/dist/commands/conversation.delete.d.ts.map +0 -1
- package/dist/commands/conversation.delete.js +0 -18
- package/dist/commands/conversation.delete.js.map +0 -1
- package/dist/commands/conversation.files.list.d.ts +0 -3
- package/dist/commands/conversation.files.list.d.ts.map +0 -1
- package/dist/commands/conversation.files.list.js +0 -39
- package/dist/commands/conversation.files.list.js.map +0 -1
- package/dist/commands/conversation.list.d.ts +0 -3
- package/dist/commands/conversation.list.d.ts.map +0 -1
- package/dist/commands/conversation.list.js +0 -32
- package/dist/commands/conversation.list.js.map +0 -1
- package/dist/commands/conversation.purge.d.ts +0 -3
- package/dist/commands/conversation.purge.d.ts.map +0 -1
- package/dist/commands/conversation.purge.js +0 -30
- package/dist/commands/conversation.purge.js.map +0 -1
- package/dist/commands/conversation.rename.d.ts +0 -3
- package/dist/commands/conversation.rename.d.ts.map +0 -1
- package/dist/commands/conversation.rename.js +0 -22
- package/dist/commands/conversation.rename.js.map +0 -1
- package/dist/commands/document.create.d.ts +0 -3
- package/dist/commands/document.create.d.ts.map +0 -1
- package/dist/commands/document.create.js +0 -29
- package/dist/commands/document.create.js.map +0 -1
- package/dist/commands/document.list.d.ts +0 -3
- package/dist/commands/document.list.d.ts.map +0 -1
- package/dist/commands/document.list.js +0 -31
- package/dist/commands/document.list.js.map +0 -1
- package/dist/commands/document.read.d.ts +0 -3
- package/dist/commands/document.read.d.ts.map +0 -1
- package/dist/commands/document.read.js +0 -23
- package/dist/commands/document.read.js.map +0 -1
- package/dist/commands/documents.generate.d.ts +0 -3
- package/dist/commands/documents.generate.d.ts.map +0 -1
- package/dist/commands/documents.generate.js +0 -34
- package/dist/commands/documents.generate.js.map +0 -1
- package/dist/commands/documents.pdf.create.d.ts +0 -3
- package/dist/commands/documents.pdf.create.d.ts.map +0 -1
- package/dist/commands/documents.pdf.create.js +0 -40
- package/dist/commands/documents.pdf.create.js.map +0 -1
- package/dist/commands/env.d.ts +0 -19
- package/dist/commands/env.d.ts.map +0 -1
- package/dist/commands/env.js +0 -64
- package/dist/commands/env.js.map +0 -1
- package/dist/commands/form.create.d.ts +0 -3
- package/dist/commands/form.create.d.ts.map +0 -1
- package/dist/commands/form.create.js +0 -34
- package/dist/commands/form.create.js.map +0 -1
- package/dist/commands/form.fill.d.ts +0 -3
- package/dist/commands/form.fill.d.ts.map +0 -1
- package/dist/commands/form.fill.js +0 -37
- package/dist/commands/form.fill.js.map +0 -1
- package/dist/commands/form.submit.d.ts +0 -3
- package/dist/commands/form.submit.d.ts.map +0 -1
- package/dist/commands/form.submit.js +0 -34
- package/dist/commands/form.submit.js.map +0 -1
- package/dist/commands/graph.cypher.d.ts +0 -3
- package/dist/commands/graph.cypher.d.ts.map +0 -1
- package/dist/commands/graph.cypher.js +0 -37
- package/dist/commands/graph.cypher.js.map +0 -1
- package/dist/commands/graph.edge.delete.d.ts +0 -3
- package/dist/commands/graph.edge.delete.d.ts.map +0 -1
- package/dist/commands/graph.edge.delete.js +0 -53
- package/dist/commands/graph.edge.delete.js.map +0 -1
- package/dist/commands/graph.edge.upsert.d.ts +0 -3
- package/dist/commands/graph.edge.upsert.d.ts.map +0 -1
- package/dist/commands/graph.edge.upsert.js +0 -47
- package/dist/commands/graph.edge.upsert.js.map +0 -1
- package/dist/commands/graph.node.delete.d.ts +0 -3
- package/dist/commands/graph.node.delete.d.ts.map +0 -1
- package/dist/commands/graph.node.delete.js +0 -34
- package/dist/commands/graph.node.delete.js.map +0 -1
- package/dist/commands/graph.node.get.d.ts +0 -3
- package/dist/commands/graph.node.get.d.ts.map +0 -1
- package/dist/commands/graph.node.get.js +0 -16
- package/dist/commands/graph.node.get.js.map +0 -1
- package/dist/commands/graph.node.search.d.ts +0 -3
- package/dist/commands/graph.node.search.d.ts.map +0 -1
- package/dist/commands/graph.node.search.js +0 -31
- package/dist/commands/graph.node.search.js.map +0 -1
- package/dist/commands/graph.node.upsert.d.ts +0 -3
- package/dist/commands/graph.node.upsert.d.ts.map +0 -1
- package/dist/commands/graph.node.upsert.js +0 -39
- package/dist/commands/graph.node.upsert.js.map +0 -1
- package/dist/commands/graph.search.d.ts +0 -10
- package/dist/commands/graph.search.d.ts.map +0 -1
- package/dist/commands/graph.search.js +0 -25
- package/dist/commands/graph.search.js.map +0 -1
- package/dist/commands/image.analyze.d.ts +0 -3
- package/dist/commands/image.analyze.d.ts.map +0 -1
- package/dist/commands/image.analyze.js +0 -24
- package/dist/commands/image.analyze.js.map +0 -1
- package/dist/commands/image.create.d.ts +0 -3
- package/dist/commands/image.create.d.ts.map +0 -1
- package/dist/commands/image.create.js +0 -33
- package/dist/commands/image.create.js.map +0 -1
- package/dist/commands/image.generate.d.ts +0 -3
- package/dist/commands/image.generate.d.ts.map +0 -1
- package/dist/commands/image.generate.js +0 -35
- package/dist/commands/image.generate.js.map +0 -1
- package/dist/commands/image.list.d.ts +0 -3
- package/dist/commands/image.list.d.ts.map +0 -1
- package/dist/commands/image.list.js +0 -31
- package/dist/commands/image.list.js.map +0 -1
- package/dist/commands/markdown.generate.d.ts +0 -3
- package/dist/commands/markdown.generate.d.ts.map +0 -1
- package/dist/commands/markdown.generate.js +0 -37
- package/dist/commands/markdown.generate.js.map +0 -1
- package/dist/commands/mcp.add.d.ts +0 -13
- package/dist/commands/mcp.add.d.ts.map +0 -1
- package/dist/commands/mcp.add.js +0 -110
- package/dist/commands/mcp.add.js.map +0 -1
- package/dist/commands/mcp.auth.d.ts +0 -10
- package/dist/commands/mcp.auth.d.ts.map +0 -1
- package/dist/commands/mcp.auth.js +0 -132
- package/dist/commands/mcp.auth.js.map +0 -1
- package/dist/commands/mcp.check.d.ts +0 -10
- package/dist/commands/mcp.check.d.ts.map +0 -1
- package/dist/commands/mcp.check.js +0 -114
- package/dist/commands/mcp.check.js.map +0 -1
- package/dist/commands/mcp.list.d.ts +0 -9
- package/dist/commands/mcp.list.d.ts.map +0 -1
- package/dist/commands/mcp.list.js +0 -93
- package/dist/commands/mcp.list.js.map +0 -1
- package/dist/commands/mcp.permit.d.ts +0 -12
- package/dist/commands/mcp.permit.d.ts.map +0 -1
- package/dist/commands/mcp.permit.js +0 -117
- package/dist/commands/mcp.permit.js.map +0 -1
- package/dist/commands/mcp.remove.d.ts +0 -9
- package/dist/commands/mcp.remove.d.ts.map +0 -1
- package/dist/commands/mcp.remove.js +0 -65
- package/dist/commands/mcp.remove.js.map +0 -1
- package/dist/commands/mermaid.generate.d.ts +0 -3
- package/dist/commands/mermaid.generate.d.ts.map +0 -1
- package/dist/commands/mermaid.generate.js +0 -33
- package/dist/commands/mermaid.generate.js.map +0 -1
- package/dist/commands/notifications.list.d.ts +0 -3
- package/dist/commands/notifications.list.d.ts.map +0 -1
- package/dist/commands/notifications.list.js +0 -33
- package/dist/commands/notifications.list.js.map +0 -1
- package/dist/commands/notifications.mark.d.ts +0 -3
- package/dist/commands/notifications.mark.d.ts.map +0 -1
- package/dist/commands/notifications.mark.js +0 -23
- package/dist/commands/notifications.mark.js.map +0 -1
- package/dist/commands/ontology.neighbors.d.ts +0 -3
- package/dist/commands/ontology.neighbors.d.ts.map +0 -1
- package/dist/commands/ontology.neighbors.js +0 -34
- package/dist/commands/ontology.neighbors.js.map +0 -1
- package/dist/commands/ontology.query.d.ts +0 -3
- package/dist/commands/ontology.query.d.ts.map +0 -1
- package/dist/commands/ontology.query.js +0 -36
- package/dist/commands/ontology.query.js.map +0 -1
- package/dist/commands/org.create.d.ts +0 -3
- package/dist/commands/org.create.d.ts.map +0 -1
- package/dist/commands/org.create.js +0 -23
- package/dist/commands/org.create.js.map +0 -1
- package/dist/commands/org.list.d.ts +0 -3
- package/dist/commands/org.list.d.ts.map +0 -1
- package/dist/commands/org.list.js +0 -25
- package/dist/commands/org.list.js.map +0 -1
- package/dist/commands/org.member.add.d.ts +0 -3
- package/dist/commands/org.member.add.d.ts.map +0 -1
- package/dist/commands/org.member.add.js +0 -24
- package/dist/commands/org.member.add.js.map +0 -1
- package/dist/commands/org.member.invite.accept.d.ts +0 -3
- package/dist/commands/org.member.invite.accept.d.ts.map +0 -1
- package/dist/commands/org.member.invite.accept.js +0 -23
- package/dist/commands/org.member.invite.accept.js.map +0 -1
- package/dist/commands/org.member.invite.decline.d.ts +0 -3
- package/dist/commands/org.member.invite.decline.d.ts.map +0 -1
- package/dist/commands/org.member.invite.decline.js +0 -25
- package/dist/commands/org.member.invite.decline.js.map +0 -1
- package/dist/commands/org.member.remove.d.ts +0 -3
- package/dist/commands/org.member.remove.d.ts.map +0 -1
- package/dist/commands/org.member.remove.js +0 -23
- package/dist/commands/org.member.remove.js.map +0 -1
- package/dist/commands/org.member.role.change.d.ts +0 -3
- package/dist/commands/org.member.role.change.d.ts.map +0 -1
- package/dist/commands/org.member.role.change.js +0 -27
- package/dist/commands/org.member.role.change.js.map +0 -1
- package/dist/commands/organization.create.d.ts +0 -3
- package/dist/commands/organization.create.d.ts.map +0 -1
- package/dist/commands/organization.create.js +0 -36
- package/dist/commands/organization.create.js.map +0 -1
- package/dist/commands/plugin.catalog.browse.d.ts +0 -3
- package/dist/commands/plugin.catalog.browse.d.ts.map +0 -1
- package/dist/commands/plugin.catalog.browse.js +0 -21
- package/dist/commands/plugin.catalog.browse.js.map +0 -1
- package/dist/commands/plugin.catalog.get.d.ts +0 -3
- package/dist/commands/plugin.catalog.get.d.ts.map +0 -1
- package/dist/commands/plugin.catalog.get.js +0 -25
- package/dist/commands/plugin.catalog.get.js.map +0 -1
- package/dist/commands/plugin.credential.reauth.d.ts +0 -3
- package/dist/commands/plugin.credential.reauth.d.ts.map +0 -1
- package/dist/commands/plugin.credential.reauth.js +0 -23
- package/dist/commands/plugin.credential.reauth.js.map +0 -1
- package/dist/commands/plugin.credential.set_secret.d.ts +0 -3
- package/dist/commands/plugin.credential.set_secret.d.ts.map +0 -1
- package/dist/commands/plugin.credential.set_secret.js +0 -33
- package/dist/commands/plugin.credential.set_secret.js.map +0 -1
- package/dist/commands/plugin.denylist.add.d.ts +0 -3
- package/dist/commands/plugin.denylist.add.d.ts.map +0 -1
- package/dist/commands/plugin.denylist.add.js +0 -29
- package/dist/commands/plugin.denylist.add.js.map +0 -1
- package/dist/commands/plugin.denylist.remove.d.ts +0 -3
- package/dist/commands/plugin.denylist.remove.d.ts.map +0 -1
- package/dist/commands/plugin.denylist.remove.js +0 -27
- package/dist/commands/plugin.denylist.remove.js.map +0 -1
- package/dist/commands/plugin.install.d.ts +0 -3
- package/dist/commands/plugin.install.d.ts.map +0 -1
- package/dist/commands/plugin.install.js +0 -23
- package/dist/commands/plugin.install.js.map +0 -1
- package/dist/commands/plugin.list.d.ts +0 -3
- package/dist/commands/plugin.list.d.ts.map +0 -1
- package/dist/commands/plugin.list.js +0 -29
- package/dist/commands/plugin.list.js.map +0 -1
- package/dist/commands/plugin.org.install.d.ts +0 -3
- package/dist/commands/plugin.org.install.d.ts.map +0 -1
- package/dist/commands/plugin.org.install.js +0 -25
- package/dist/commands/plugin.org.install.js.map +0 -1
- package/dist/commands/plugin.org.install_bulk.d.ts +0 -3
- package/dist/commands/plugin.org.install_bulk.d.ts.map +0 -1
- package/dist/commands/plugin.org.install_bulk.js +0 -36
- package/dist/commands/plugin.org.install_bulk.js.map +0 -1
- package/dist/commands/plugin.org.list.d.ts +0 -3
- package/dist/commands/plugin.org.list.d.ts.map +0 -1
- package/dist/commands/plugin.org.list.js +0 -37
- package/dist/commands/plugin.org.list.js.map +0 -1
- package/dist/commands/plugin.org.set_enabled.d.ts +0 -3
- package/dist/commands/plugin.org.set_enabled.d.ts.map +0 -1
- package/dist/commands/plugin.org.set_enabled.js +0 -28
- package/dist/commands/plugin.org.set_enabled.js.map +0 -1
- package/dist/commands/plugin.org.uninstall.d.ts +0 -3
- package/dist/commands/plugin.org.uninstall.d.ts.map +0 -1
- package/dist/commands/plugin.org.uninstall.js +0 -23
- package/dist/commands/plugin.org.uninstall.js.map +0 -1
- package/dist/commands/plugin.registry.add.d.ts +0 -3
- package/dist/commands/plugin.registry.add.d.ts.map +0 -1
- package/dist/commands/plugin.registry.add.js +0 -25
- package/dist/commands/plugin.registry.add.js.map +0 -1
- package/dist/commands/plugin.registry.list.d.ts +0 -3
- package/dist/commands/plugin.registry.list.d.ts.map +0 -1
- package/dist/commands/plugin.registry.list.js +0 -18
- package/dist/commands/plugin.registry.list.js.map +0 -1
- package/dist/commands/plugin.registry.remove.d.ts +0 -3
- package/dist/commands/plugin.registry.remove.d.ts.map +0 -1
- package/dist/commands/plugin.registry.remove.js +0 -25
- package/dist/commands/plugin.registry.remove.js.map +0 -1
- package/dist/commands/plugin.registry.sync.d.ts +0 -3
- package/dist/commands/plugin.registry.sync.d.ts.map +0 -1
- package/dist/commands/plugin.registry.sync.js +0 -27
- package/dist/commands/plugin.registry.sync.js.map +0 -1
- package/dist/commands/plugin.settings.set_auth_alerts.d.ts +0 -3
- package/dist/commands/plugin.settings.set_auth_alerts.d.ts.map +0 -1
- package/dist/commands/plugin.settings.set_auth_alerts.js +0 -31
- package/dist/commands/plugin.settings.set_auth_alerts.js.map +0 -1
- package/dist/commands/plugin.uninstall.d.ts +0 -3
- package/dist/commands/plugin.uninstall.d.ts.map +0 -1
- package/dist/commands/plugin.uninstall.js +0 -23
- package/dist/commands/plugin.uninstall.js.map +0 -1
- package/dist/commands/plugin.workspace.set_enabled.d.ts +0 -3
- package/dist/commands/plugin.workspace.set_enabled.d.ts.map +0 -1
- package/dist/commands/plugin.workspace.set_enabled.js +0 -36
- package/dist/commands/plugin.workspace.set_enabled.js.map +0 -1
- package/dist/commands/privacy.erase.d.ts +0 -3
- package/dist/commands/privacy.erase.d.ts.map +0 -1
- package/dist/commands/privacy.erase.js +0 -61
- package/dist/commands/privacy.erase.js.map +0 -1
- package/dist/commands/privacy.erase.test.d.ts +0 -2
- package/dist/commands/privacy.erase.test.d.ts.map +0 -1
- package/dist/commands/privacy.erase.test.js +0 -132
- package/dist/commands/privacy.erase.test.js.map +0 -1
- package/dist/commands/privacy.export.d.ts +0 -3
- package/dist/commands/privacy.export.d.ts.map +0 -1
- package/dist/commands/privacy.export.js +0 -36
- package/dist/commands/privacy.export.js.map +0 -1
- package/dist/commands/replay.d.ts +0 -5
- package/dist/commands/replay.d.ts.map +0 -1
- package/dist/commands/replay.js +0 -28
- package/dist/commands/replay.js.map +0 -1
- package/dist/commands/research.swarm.start.d.ts +0 -3
- package/dist/commands/research.swarm.start.d.ts.map +0 -1
- package/dist/commands/research.swarm.start.js +0 -35
- package/dist/commands/research.swarm.start.js.map +0 -1
- package/dist/commands/research.swarm.status.d.ts +0 -3
- package/dist/commands/research.swarm.status.d.ts.map +0 -1
- package/dist/commands/research.swarm.status.js +0 -26
- package/dist/commands/research.swarm.status.js.map +0 -1
- package/dist/commands/schema/schema.config.d.ts +0 -3
- package/dist/commands/schema/schema.config.d.ts.map +0 -1
- package/dist/commands/schema/schema.config.js +0 -34
- package/dist/commands/schema/schema.config.js.map +0 -1
- package/dist/commands/schema/schema.disable.d.ts +0 -3
- package/dist/commands/schema/schema.disable.d.ts.map +0 -1
- package/dist/commands/schema/schema.disable.js +0 -22
- package/dist/commands/schema/schema.disable.js.map +0 -1
- package/dist/commands/schema/schema.enable.d.ts +0 -3
- package/dist/commands/schema/schema.enable.d.ts.map +0 -1
- package/dist/commands/schema/schema.enable.js +0 -22
- package/dist/commands/schema/schema.enable.js.map +0 -1
- package/dist/commands/schema/schema.export.d.ts +0 -3
- package/dist/commands/schema/schema.export.d.ts.map +0 -1
- package/dist/commands/schema/schema.export.js +0 -31
- package/dist/commands/schema/schema.export.js.map +0 -1
- package/dist/commands/schema/schema.get.d.ts +0 -3
- package/dist/commands/schema/schema.get.d.ts.map +0 -1
- package/dist/commands/schema/schema.get.js +0 -23
- package/dist/commands/schema/schema.get.js.map +0 -1
- package/dist/commands/schema/schema.label.d.ts +0 -5
- package/dist/commands/schema/schema.label.d.ts.map +0 -1
- package/dist/commands/schema/schema.label.js +0 -60
- package/dist/commands/schema/schema.label.js.map +0 -1
- package/dist/commands/schema/schema.list.d.ts +0 -3
- package/dist/commands/schema/schema.list.d.ts.map +0 -1
- package/dist/commands/schema/schema.list.js +0 -30
- package/dist/commands/schema/schema.list.js.map +0 -1
- package/dist/commands/schema/schema.prop.d.ts +0 -5
- package/dist/commands/schema/schema.prop.d.ts.map +0 -1
- package/dist/commands/schema/schema.prop.js +0 -72
- package/dist/commands/schema/schema.prop.js.map +0 -1
- package/dist/commands/schema/schema.reconcile.d.ts +0 -10
- package/dist/commands/schema/schema.reconcile.d.ts.map +0 -1
- package/dist/commands/schema/schema.reconcile.js +0 -65
- package/dist/commands/schema/schema.reconcile.js.map +0 -1
- package/dist/commands/schema/schema.rel.d.ts +0 -5
- package/dist/commands/schema/schema.rel.d.ts.map +0 -1
- package/dist/commands/schema/schema.rel.js +0 -65
- package/dist/commands/schema/schema.rel.js.map +0 -1
- package/dist/commands/schema/schema.version.d.ts +0 -7
- package/dist/commands/schema/schema.version.d.ts.map +0 -1
- package/dist/commands/schema/schema.version.js +0 -96
- package/dist/commands/schema/schema.version.js.map +0 -1
- package/dist/commands/secret.d.ts +0 -23
- package/dist/commands/secret.d.ts.map +0 -1
- package/dist/commands/secret.js +0 -90
- package/dist/commands/secret.js.map +0 -1
- package/dist/commands/skill.create.d.ts +0 -3
- package/dist/commands/skill.create.d.ts.map +0 -1
- package/dist/commands/skill.create.js +0 -52
- package/dist/commands/skill.create.js.map +0 -1
- package/dist/commands/skill.edit.d.ts +0 -3
- package/dist/commands/skill.edit.d.ts.map +0 -1
- package/dist/commands/skill.edit.js +0 -28
- package/dist/commands/skill.edit.js.map +0 -1
- package/dist/commands/skill.enable.d.ts +0 -3
- package/dist/commands/skill.enable.d.ts.map +0 -1
- package/dist/commands/skill.enable.js +0 -31
- package/dist/commands/skill.enable.js.map +0 -1
- package/dist/commands/skill.export.d.ts +0 -3
- package/dist/commands/skill.export.d.ts.map +0 -1
- package/dist/commands/skill.export.js +0 -25
- package/dist/commands/skill.export.js.map +0 -1
- package/dist/commands/skill.metrics.read.d.ts +0 -3
- package/dist/commands/skill.metrics.read.d.ts.map +0 -1
- package/dist/commands/skill.metrics.read.js +0 -56
- package/dist/commands/skill.metrics.read.js.map +0 -1
- package/dist/commands/skill.version.activate.d.ts +0 -3
- package/dist/commands/skill.version.activate.d.ts.map +0 -1
- package/dist/commands/skill.version.activate.js +0 -24
- package/dist/commands/skill.version.activate.js.map +0 -1
- package/dist/commands/skill.version.get.d.ts +0 -3
- package/dist/commands/skill.version.get.d.ts.map +0 -1
- package/dist/commands/skill.version.get.js +0 -43
- package/dist/commands/skill.version.get.js.map +0 -1
- package/dist/commands/skill.version.list.d.ts +0 -3
- package/dist/commands/skill.version.list.d.ts.map +0 -1
- package/dist/commands/skill.version.list.js +0 -38
- package/dist/commands/skill.version.list.js.map +0 -1
- package/dist/commands/skill.version.upload.d.ts +0 -3
- package/dist/commands/skill.version.upload.d.ts.map +0 -1
- package/dist/commands/skill.version.upload.js +0 -28
- package/dist/commands/skill.version.upload.js.map +0 -1
- package/dist/commands/skill.workspace.install.d.ts +0 -3
- package/dist/commands/skill.workspace.install.d.ts.map +0 -1
- package/dist/commands/skill.workspace.install.js +0 -52
- package/dist/commands/skill.workspace.install.js.map +0 -1
- package/dist/commands/skill.workspace.list.d.ts +0 -3
- package/dist/commands/skill.workspace.list.d.ts.map +0 -1
- package/dist/commands/skill.workspace.list.js +0 -34
- package/dist/commands/skill.workspace.list.js.map +0 -1
- package/dist/commands/svg.generate.d.ts +0 -3
- package/dist/commands/svg.generate.d.ts.map +0 -1
- package/dist/commands/svg.generate.js +0 -29
- package/dist/commands/svg.generate.js.map +0 -1
- package/dist/commands/system.install.instructions.d.ts +0 -3
- package/dist/commands/system.install.instructions.d.ts.map +0 -1
- package/dist/commands/system.install.instructions.js +0 -34
- package/dist/commands/system.install.instructions.js.map +0 -1
- package/dist/commands/user.preferences.get.d.ts +0 -3
- package/dist/commands/user.preferences.get.d.ts.map +0 -1
- package/dist/commands/user.preferences.get.js +0 -20
- package/dist/commands/user.preferences.get.js.map +0 -1
- package/dist/commands/user.preferences.read.d.ts +0 -3
- package/dist/commands/user.preferences.read.d.ts.map +0 -1
- package/dist/commands/user.preferences.read.js +0 -30
- package/dist/commands/user.preferences.read.js.map +0 -1
- package/dist/commands/user.preferences.update.d.ts +0 -3
- package/dist/commands/user.preferences.update.d.ts.map +0 -1
- package/dist/commands/user.preferences.update.js +0 -36
- package/dist/commands/user.preferences.update.js.map +0 -1
- package/dist/commands/user.preferences.write.d.ts +0 -3
- package/dist/commands/user.preferences.write.d.ts.map +0 -1
- package/dist/commands/user.preferences.write.js +0 -47
- package/dist/commands/user.preferences.write.js.map +0 -1
- package/dist/commands/video.generate.d.ts +0 -3
- package/dist/commands/video.generate.d.ts.map +0 -1
- package/dist/commands/video.generate.js +0 -27
- package/dist/commands/video.generate.js.map +0 -1
- package/dist/commands/web.fetch.d.ts +0 -3
- package/dist/commands/web.fetch.d.ts.map +0 -1
- package/dist/commands/web.fetch.js +0 -39
- package/dist/commands/web.fetch.js.map +0 -1
- package/dist/commands/web.search.d.ts +0 -3
- package/dist/commands/web.search.d.ts.map +0 -1
- package/dist/commands/web.search.js +0 -50
- package/dist/commands/web.search.js.map +0 -1
- package/dist/commands/workflow.cancel.d.ts +0 -3
- package/dist/commands/workflow.cancel.d.ts.map +0 -1
- package/dist/commands/workflow.cancel.js +0 -25
- package/dist/commands/workflow.cancel.js.map +0 -1
- package/dist/commands/workflow.run.d.ts +0 -3
- package/dist/commands/workflow.run.d.ts.map +0 -1
- package/dist/commands/workflow.run.js +0 -41
- package/dist/commands/workflow.run.js.map +0 -1
- package/dist/commands/workflow.status.d.ts +0 -3
- package/dist/commands/workflow.status.d.ts.map +0 -1
- package/dist/commands/workflow.status.js +0 -34
- package/dist/commands/workflow.status.js.map +0 -1
- package/dist/commands/workspace.create.d.ts +0 -3
- package/dist/commands/workspace.create.d.ts.map +0 -1
- package/dist/commands/workspace.create.js +0 -25
- package/dist/commands/workspace.create.js.map +0 -1
- package/dist/commands/workspace.invite.send.d.ts +0 -3
- package/dist/commands/workspace.invite.send.d.ts.map +0 -1
- package/dist/commands/workspace.invite.send.js +0 -33
- package/dist/commands/workspace.invite.send.js.map +0 -1
- package/dist/commands/workspace.list.d.ts +0 -3
- package/dist/commands/workspace.list.d.ts.map +0 -1
- package/dist/commands/workspace.list.js +0 -28
- package/dist/commands/workspace.list.js.map +0 -1
- package/dist/commands/workspace.member.list.d.ts +0 -3
- package/dist/commands/workspace.member.list.d.ts.map +0 -1
- package/dist/commands/workspace.member.list.js +0 -28
- package/dist/commands/workspace.member.list.js.map +0 -1
- package/dist/commands/workspace.model.settings.read.d.ts +0 -3
- package/dist/commands/workspace.model.settings.read.d.ts.map +0 -1
- package/dist/commands/workspace.model.settings.read.js +0 -22
- package/dist/commands/workspace.model.settings.read.js.map +0 -1
- package/dist/commands/workspace.model.settings.write.d.ts +0 -3
- package/dist/commands/workspace.model.settings.write.d.ts.map +0 -1
- package/dist/commands/workspace.model.settings.write.js +0 -26
- package/dist/commands/workspace.model.settings.write.js.map +0 -1
- package/dist/commands.test.d.ts +0 -2
- package/dist/commands.test.d.ts.map +0 -1
- package/dist/commands.test.js +0 -3454
- package/dist/commands.test.js.map +0 -1
- package/dist/components/DevStatus.d.ts +0 -2
- package/dist/components/DevStatus.d.ts.map +0 -1
- package/dist/components/DevStatus.js +0 -62
- package/dist/components/DevStatus.js.map +0 -1
- package/dist/components/DevStatus.test.d.ts +0 -2
- package/dist/components/DevStatus.test.d.ts.map +0 -1
- package/dist/components/DevStatus.test.js +0 -108
- package/dist/components/DevStatus.test.js.map +0 -1
- package/dist/daemon/client.d.ts +0 -30
- package/dist/daemon/client.d.ts.map +0 -1
- package/dist/daemon/client.js +0 -97
- package/dist/daemon/client.js.map +0 -1
- package/dist/daemon/code-graph/builder.d.ts +0 -6
- package/dist/daemon/code-graph/builder.d.ts.map +0 -1
- package/dist/daemon/code-graph/builder.js +0 -215
- package/dist/daemon/code-graph/builder.js.map +0 -1
- package/dist/daemon/code-graph/query.d.ts +0 -29
- package/dist/daemon/code-graph/query.d.ts.map +0 -1
- package/dist/daemon/code-graph/query.js +0 -98
- package/dist/daemon/code-graph/query.js.map +0 -1
- package/dist/daemon/code-graph/types.d.ts +0 -37
- package/dist/daemon/code-graph/types.d.ts.map +0 -1
- package/dist/daemon/code-graph/types.js +0 -5
- package/dist/daemon/code-graph/types.js.map +0 -1
- package/dist/daemon/code-graph/watcher.d.ts +0 -37
- package/dist/daemon/code-graph/watcher.d.ts.map +0 -1
- package/dist/daemon/code-graph/watcher.js +0 -79
- package/dist/daemon/code-graph/watcher.js.map +0 -1
- package/dist/daemon/lifecycle.d.ts +0 -6
- package/dist/daemon/lifecycle.d.ts.map +0 -1
- package/dist/daemon/lifecycle.js +0 -132
- package/dist/daemon/lifecycle.js.map +0 -1
- package/dist/daemon/protocol.d.ts +0 -113
- package/dist/daemon/protocol.d.ts.map +0 -1
- package/dist/daemon/protocol.js +0 -16
- package/dist/daemon/protocol.js.map +0 -1
- package/dist/daemon/server.d.ts +0 -26
- package/dist/daemon/server.d.ts.map +0 -1
- package/dist/daemon/server.js +0 -168
- package/dist/daemon/server.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -270
- package/dist/index.js.map +0 -1
- package/dist/lib/api-client.d.ts +0 -7
- package/dist/lib/api-client.d.ts.map +0 -1
- package/dist/lib/api-client.js +0 -40
- package/dist/lib/api-client.js.map +0 -1
- package/dist/lib/api-client.test.d.ts +0 -2
- package/dist/lib/api-client.test.d.ts.map +0 -1
- package/dist/lib/api-client.test.js +0 -89
- package/dist/lib/api-client.test.js.map +0 -1
- package/dist/lib/api.d.ts +0 -5
- package/dist/lib/api.d.ts.map +0 -1
- package/dist/lib/api.js +0 -52
- package/dist/lib/api.js.map +0 -1
- package/dist/lib/config.d.ts +0 -17
- package/dist/lib/config.d.ts.map +0 -1
- package/dist/lib/config.js +0 -51
- package/dist/lib/config.js.map +0 -1
- package/dist/lib/config.test.d.ts +0 -2
- package/dist/lib/config.test.d.ts.map +0 -1
- package/dist/lib/config.test.js +0 -121
- package/dist/lib/config.test.js.map +0 -1
- package/dist/lib/differential-context.d.ts +0 -46
- package/dist/lib/differential-context.d.ts.map +0 -1
- package/dist/lib/differential-context.js +0 -89
- package/dist/lib/differential-context.js.map +0 -1
- package/dist/lib/resolve.d.ts +0 -3
- package/dist/lib/resolve.d.ts.map +0 -1
- package/dist/lib/resolve.js +0 -29
- package/dist/lib/resolve.js.map +0 -1
- package/dist/lib/structured-tool-io.d.ts +0 -31
- package/dist/lib/structured-tool-io.d.ts.map +0 -1
- package/dist/lib/structured-tool-io.js +0 -56
- package/dist/lib/structured-tool-io.js.map +0 -1
- package/dist/repl/__tests__/_queue_demo.test.d.ts +0 -2
- package/dist/repl/__tests__/_queue_demo.test.d.ts.map +0 -1
- package/dist/repl/__tests__/_queue_demo.test.js +0 -40
- package/dist/repl/__tests__/_queue_demo.test.js.map +0 -1
- package/dist/repl/__tests__/components.test.d.ts +0 -2
- package/dist/repl/__tests__/components.test.d.ts.map +0 -1
- package/dist/repl/__tests__/components.test.js +0 -38
- package/dist/repl/__tests__/components.test.js.map +0 -1
- package/dist/repl/__tests__/interactive.queue.test.d.ts +0 -2
- package/dist/repl/__tests__/interactive.queue.test.d.ts.map +0 -1
- package/dist/repl/__tests__/interactive.queue.test.js +0 -124
- package/dist/repl/__tests__/interactive.queue.test.js.map +0 -1
- package/dist/repl/components.d.ts +0 -59
- package/dist/repl/components.d.ts.map +0 -1
- package/dist/repl/components.js +0 -152
- package/dist/repl/components.js.map +0 -1
- package/dist/repl/interactive.d.ts +0 -12
- package/dist/repl/interactive.d.ts.map +0 -1
- package/dist/repl/interactive.js +0 -326
- package/dist/repl/interactive.js.map +0 -1
- package/dist/repl/one-shot.d.ts +0 -9
- package/dist/repl/one-shot.d.ts.map +0 -1
- package/dist/repl/one-shot.js +0 -83
- package/dist/repl/one-shot.js.map +0 -1
- package/dist/tui/__tests__/app.test.d.ts +0 -2
- package/dist/tui/__tests__/app.test.d.ts.map +0 -1
- package/dist/tui/__tests__/app.test.js +0 -136
- package/dist/tui/__tests__/app.test.js.map +0 -1
- package/dist/tui/__tests__/banner.test.d.ts +0 -2
- package/dist/tui/__tests__/banner.test.d.ts.map +0 -1
- package/dist/tui/__tests__/banner.test.js +0 -15
- package/dist/tui/__tests__/banner.test.js.map +0 -1
- package/dist/tui/__tests__/command-form.test.d.ts +0 -2
- package/dist/tui/__tests__/command-form.test.d.ts.map +0 -1
- package/dist/tui/__tests__/command-form.test.js +0 -96
- package/dist/tui/__tests__/command-form.test.js.map +0 -1
- package/dist/tui/__tests__/command-tree.test.d.ts +0 -2
- package/dist/tui/__tests__/command-tree.test.d.ts.map +0 -1
- package/dist/tui/__tests__/command-tree.test.js +0 -55
- package/dist/tui/__tests__/command-tree.test.js.map +0 -1
- package/dist/tui/__tests__/runner.test.d.ts +0 -2
- package/dist/tui/__tests__/runner.test.d.ts.map +0 -1
- package/dist/tui/__tests__/runner.test.js +0 -38
- package/dist/tui/__tests__/runner.test.js.map +0 -1
- package/dist/tui/__tests__/theme.test.d.ts +0 -2
- package/dist/tui/__tests__/theme.test.d.ts.map +0 -1
- package/dist/tui/__tests__/theme.test.js +0 -11
- package/dist/tui/__tests__/theme.test.js.map +0 -1
- package/dist/tui/agent-view/activity-feed.d.ts +0 -3
- package/dist/tui/agent-view/activity-feed.d.ts.map +0 -1
- package/dist/tui/agent-view/activity-feed.js +0 -34
- package/dist/tui/agent-view/activity-feed.js.map +0 -1
- package/dist/tui/agent-view/budget-bar.d.ts +0 -3
- package/dist/tui/agent-view/budget-bar.d.ts.map +0 -1
- package/dist/tui/agent-view/budget-bar.js +0 -53
- package/dist/tui/agent-view/budget-bar.js.map +0 -1
- package/dist/tui/agent-view/compile-panel.d.ts +0 -3
- package/dist/tui/agent-view/compile-panel.d.ts.map +0 -1
- package/dist/tui/agent-view/compile-panel.js +0 -34
- package/dist/tui/agent-view/compile-panel.js.map +0 -1
- package/dist/tui/agent-view/index.d.ts +0 -4
- package/dist/tui/agent-view/index.d.ts.map +0 -1
- package/dist/tui/agent-view/index.js +0 -31
- package/dist/tui/agent-view/index.js.map +0 -1
- package/dist/tui/agent-view/memory-panel.d.ts +0 -3
- package/dist/tui/agent-view/memory-panel.d.ts.map +0 -1
- package/dist/tui/agent-view/memory-panel.js +0 -80
- package/dist/tui/agent-view/memory-panel.js.map +0 -1
- package/dist/tui/agent-view/session-panel.d.ts +0 -3
- package/dist/tui/agent-view/session-panel.d.ts.map +0 -1
- package/dist/tui/agent-view/session-panel.js +0 -44
- package/dist/tui/agent-view/session-panel.js.map +0 -1
- package/dist/tui/agent-view/status-bar.d.ts +0 -7
- package/dist/tui/agent-view/status-bar.d.ts.map +0 -1
- package/dist/tui/agent-view/status-bar.js +0 -22
- package/dist/tui/agent-view/status-bar.js.map +0 -1
- package/dist/tui/app.d.ts +0 -9
- package/dist/tui/app.d.ts.map +0 -1
- package/dist/tui/app.js +0 -115
- package/dist/tui/app.js.map +0 -1
- package/dist/tui/banner.d.ts +0 -5
- package/dist/tui/banner.d.ts.map +0 -1
- package/dist/tui/banner.js +0 -17
- package/dist/tui/banner.js.map +0 -1
- package/dist/tui/command-form.d.ts +0 -9
- package/dist/tui/command-form.d.ts.map +0 -1
- package/dist/tui/command-form.js +0 -76
- package/dist/tui/command-form.js.map +0 -1
- package/dist/tui/command-tree.d.ts +0 -30
- package/dist/tui/command-tree.d.ts.map +0 -1
- package/dist/tui/command-tree.js +0 -43
- package/dist/tui/command-tree.js.map +0 -1
- package/dist/tui/fleet-view/agent-row.d.ts +0 -10
- package/dist/tui/fleet-view/agent-row.d.ts.map +0 -1
- package/dist/tui/fleet-view/agent-row.js +0 -80
- package/dist/tui/fleet-view/agent-row.js.map +0 -1
- package/dist/tui/fleet-view/dispatch-input.d.ts +0 -5
- package/dist/tui/fleet-view/dispatch-input.d.ts.map +0 -1
- package/dist/tui/fleet-view/dispatch-input.js +0 -36
- package/dist/tui/fleet-view/dispatch-input.js.map +0 -1
- package/dist/tui/fleet-view/fleet-app.d.ts +0 -11
- package/dist/tui/fleet-view/fleet-app.d.ts.map +0 -1
- package/dist/tui/fleet-view/fleet-app.js +0 -95
- package/dist/tui/fleet-view/fleet-app.js.map +0 -1
- package/dist/tui/fleet-view/fleet-summary.d.ts +0 -6
- package/dist/tui/fleet-view/fleet-summary.d.ts.map +0 -1
- package/dist/tui/fleet-view/fleet-summary.js +0 -19
- package/dist/tui/fleet-view/fleet-summary.js.map +0 -1
- package/dist/tui/fleet-view/index.d.ts +0 -16
- package/dist/tui/fleet-view/index.d.ts.map +0 -1
- package/dist/tui/fleet-view/index.js +0 -61
- package/dist/tui/fleet-view/index.js.map +0 -1
- package/dist/tui/runner.d.ts +0 -7
- package/dist/tui/runner.d.ts.map +0 -1
- package/dist/tui/runner.js +0 -36
- package/dist/tui/runner.js.map +0 -1
- package/dist/tui/theme.d.ts +0 -8
- package/dist/tui/theme.d.ts.map +0 -1
- package/dist/tui/theme.js +0 -10
- package/dist/tui/theme.js.map +0 -1
package/dist/commands.test.js
DELETED
|
@@ -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
|