lua-cli 3.12.2 ā 3.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -13
- package/dist/api/agent.api.service.d.ts +20 -20
- package/dist/api/agent.api.service.d.ts.map +1 -1
- package/dist/api/agent.api.service.js +1 -1
- package/dist/api/agent.api.service.js.map +1 -1
- package/dist/api/agents.api.service.d.ts +3 -3
- package/dist/api/agents.api.service.d.ts.map +1 -1
- package/dist/api/agents.api.service.js +11 -9
- package/dist/api/agents.api.service.js.map +1 -1
- package/dist/api/ai.api.service.d.ts +4 -4
- package/dist/api/ai.api.service.d.ts.map +1 -1
- package/dist/api/ai.api.service.js +10 -8
- package/dist/api/ai.api.service.js.map +1 -1
- package/dist/api/auth.api.service.d.ts +3 -3
- package/dist/api/auth.api.service.d.ts.map +1 -1
- package/dist/api/auth.api.service.js +1 -1
- package/dist/api/auth.api.service.js.map +1 -1
- package/dist/api/backup.api.service.d.ts.map +1 -1
- package/dist/api/backup.api.service.js +21 -7
- package/dist/api/backup.api.service.js.map +1 -1
- package/dist/api/basket.api.service.d.ts +5 -5
- package/dist/api/basket.api.service.d.ts.map +1 -1
- package/dist/api/basket.api.service.js +4 -4
- package/dist/api/basket.api.service.js.map +1 -1
- package/dist/api/cdn.api.service.d.ts +1 -1
- package/dist/api/cdn.api.service.js +3 -3
- package/dist/api/cdn.api.service.js.map +1 -1
- package/dist/api/chat.api.service.d.ts +4 -4
- package/dist/api/chat.api.service.js +3 -3
- package/dist/api/chat.api.service.js.map +1 -1
- package/dist/api/credentials.js +3 -3
- package/dist/api/custom.data.api.service.d.ts +4 -4
- package/dist/api/custom.data.api.service.d.ts.map +1 -1
- package/dist/api/custom.data.api.service.js +2 -2
- package/dist/api/custom.data.api.service.js.map +1 -1
- package/dist/api/developer.api.service.d.ts +3 -3
- package/dist/api/developer.api.service.d.ts.map +1 -1
- package/dist/api/developer.api.service.js +7 -3
- package/dist/api/developer.api.service.js.map +1 -1
- package/dist/api/device-trigger.api.service.d.ts +3 -3
- package/dist/api/device-trigger.api.service.d.ts.map +1 -1
- package/dist/api/device-trigger.api.service.js +1 -1
- package/dist/api/device-trigger.api.service.js.map +1 -1
- package/dist/api/device.api.service.d.ts +3 -3
- package/dist/api/device.api.service.d.ts.map +1 -1
- package/dist/api/device.api.service.js +1 -1
- package/dist/api/device.api.service.js.map +1 -1
- package/dist/api/http.client.d.ts +1 -1
- package/dist/api/http.client.d.ts.map +1 -1
- package/dist/api/http.client.js +6 -6
- package/dist/api/http.client.js.map +1 -1
- package/dist/api/job.api.service.d.ts +13 -14
- package/dist/api/job.api.service.d.ts.map +1 -1
- package/dist/api/job.api.service.js +12 -20
- package/dist/api/job.api.service.js.map +1 -1
- package/dist/api/lazy-instances.d.ts +12 -12
- package/dist/api/lazy-instances.js +14 -14
- package/dist/api/logs.api.service.d.ts +9 -6
- package/dist/api/logs.api.service.d.ts.map +1 -1
- package/dist/api/logs.api.service.js +12 -11
- package/dist/api/logs.api.service.js.map +1 -1
- package/dist/api/marketplace.api.service.d.ts +1 -1
- package/dist/api/marketplace.api.service.d.ts.map +1 -1
- package/dist/api/marketplace.api.service.js +18 -18
- package/dist/api/marketplace.api.service.js.map +1 -1
- package/dist/api/order.api.service.d.ts +4 -4
- package/dist/api/order.api.service.d.ts.map +1 -1
- package/dist/api/order.api.service.js +2 -2
- package/dist/api/order.api.service.js.map +1 -1
- package/dist/api/persona.api.service.d.ts +3 -3
- package/dist/api/persona.api.service.d.ts.map +1 -1
- package/dist/api/persona.api.service.js +2 -2
- package/dist/api/persona.api.service.js.map +1 -1
- package/dist/api/postprocessor.api.service.d.ts +8 -9
- package/dist/api/postprocessor.api.service.d.ts.map +1 -1
- package/dist/api/postprocessor.api.service.js +1 -2
- package/dist/api/postprocessor.api.service.js.map +1 -1
- package/dist/api/preprocessor.api.service.d.ts +8 -9
- package/dist/api/preprocessor.api.service.d.ts.map +1 -1
- package/dist/api/preprocessor.api.service.js +1 -2
- package/dist/api/preprocessor.api.service.js.map +1 -1
- package/dist/api/products.api.service.d.ts +9 -9
- package/dist/api/products.api.service.d.ts.map +1 -1
- package/dist/api/products.api.service.js +10 -10
- package/dist/api/products.api.service.js.map +1 -1
- package/dist/api/resource.api.service.d.ts +2 -2
- package/dist/api/resource.api.service.js +1 -1
- package/dist/api/skills.api.service.d.ts +4 -4
- package/dist/api/skills.api.service.d.ts.map +1 -1
- package/dist/api/skills.api.service.js +1 -1
- package/dist/api/skills.api.service.js.map +1 -1
- package/dist/api/tool.api.service.d.ts +2 -2
- package/dist/api/tool.api.service.js +1 -1
- package/dist/api/unifiedto.api.service.d.ts +3 -3
- package/dist/api/unifiedto.api.service.d.ts.map +1 -1
- package/dist/api/unifiedto.api.service.js +28 -10
- package/dist/api/unifiedto.api.service.js.map +1 -1
- package/dist/api/user.data.api.service.d.ts +6 -6
- package/dist/api/user.data.api.service.d.ts.map +1 -1
- package/dist/api/user.data.api.service.js +5 -5
- package/dist/api/user.data.api.service.js.map +1 -1
- package/dist/api/webhook.api.service.d.ts +3 -3
- package/dist/api/webhook.api.service.d.ts.map +1 -1
- package/dist/api/webhook.api.service.js +1 -1
- package/dist/api/webhook.api.service.js.map +1 -1
- package/dist/api/whatsapp-templates.api.service.d.ts +3 -3
- package/dist/api/whatsapp-templates.api.service.js +1 -1
- package/dist/api-exports.d.ts +25 -25
- package/dist/api-exports.d.ts.map +1 -1
- package/dist/api-exports.js +26 -26
- package/dist/api-exports.js.map +1 -1
- package/dist/cli/command-definitions.d.ts +1 -1
- package/dist/cli/command-definitions.d.ts.map +1 -1
- package/dist/cli/command-definitions.js +209 -196
- package/dist/cli/command-definitions.js.map +1 -1
- package/dist/commands/agents.js +2 -2
- package/dist/commands/apiKey.js +12 -12
- package/dist/commands/channels.d.ts.map +1 -1
- package/dist/commands/channels.js +165 -174
- package/dist/commands/channels.js.map +1 -1
- package/dist/commands/chat-log-probe.d.ts +59 -0
- package/dist/commands/chat-log-probe.d.ts.map +1 -0
- package/dist/commands/chat-log-probe.js +87 -0
- package/dist/commands/chat-log-probe.js.map +1 -0
- package/dist/commands/chat.d.ts.map +1 -1
- package/dist/commands/chat.js +143 -40
- package/dist/commands/chat.js.map +1 -1
- package/dist/commands/chatClear.d.ts.map +1 -1
- package/dist/commands/chatClear.js +10 -6
- package/dist/commands/chatClear.js.map +1 -1
- package/dist/commands/compile.d.ts +7 -0
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +49 -12
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/completion.d.ts.map +1 -1
- package/dist/commands/completion.js +8 -9
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/configure.js +5 -5
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +132 -35
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/destroy.d.ts.map +1 -1
- package/dist/commands/destroy.js +27 -17
- package/dist/commands/destroy.js.map +1 -1
- package/dist/commands/devices.d.ts.map +1 -1
- package/dist/commands/devices.js +4 -5
- package/dist/commands/devices.js.map +1 -1
- package/dist/commands/env.d.ts.map +1 -1
- package/dist/commands/env.js +101 -80
- package/dist/commands/env.js.map +1 -1
- package/dist/commands/features.d.ts.map +1 -1
- package/dist/commands/features.js +71 -82
- package/dist/commands/features.js.map +1 -1
- package/dist/commands/governance.d.ts.map +1 -1
- package/dist/commands/governance.js +17 -15
- package/dist/commands/governance.js.map +1 -1
- package/dist/commands/index.d.ts +37 -36
- package/dist/commands/index.d.ts.map +1 -1
- package/dist/commands/index.js +37 -36
- package/dist/commands/index.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +80 -70
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/integrations.d.ts.map +1 -1
- package/dist/commands/integrations.js +373 -341
- package/dist/commands/integrations.js.map +1 -1
- package/dist/commands/jobs.d.ts.map +1 -1
- package/dist/commands/jobs.js +110 -78
- package/dist/commands/jobs.js.map +1 -1
- package/dist/commands/log-tip.d.ts +79 -0
- package/dist/commands/log-tip.d.ts.map +1 -0
- package/dist/commands/log-tip.js +83 -0
- package/dist/commands/log-tip.js.map +1 -0
- package/dist/commands/logs.d.ts.map +1 -1
- package/dist/commands/logs.js +166 -198
- package/dist/commands/logs.js.map +1 -1
- package/dist/commands/marketplace.d.ts.map +1 -1
- package/dist/commands/marketplace.js +381 -427
- package/dist/commands/marketplace.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js +54 -56
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/models.d.ts.map +1 -1
- package/dist/commands/models.js +4 -3
- package/dist/commands/models.js.map +1 -1
- package/dist/commands/persona.d.ts.map +1 -1
- package/dist/commands/persona.js +100 -126
- package/dist/commands/persona.js.map +1 -1
- package/dist/commands/postprocessors.d.ts.map +1 -1
- package/dist/commands/postprocessors.js +87 -61
- package/dist/commands/postprocessors.js.map +1 -1
- package/dist/commands/preprocessors.d.ts.map +1 -1
- package/dist/commands/preprocessors.js +87 -61
- package/dist/commands/preprocessors.js.map +1 -1
- package/dist/commands/production.d.ts.map +1 -1
- package/dist/commands/production.js +101 -113
- package/dist/commands/production.js.map +1 -1
- package/dist/commands/push-helpers.d.ts +42 -0
- package/dist/commands/push-helpers.d.ts.map +1 -0
- package/dist/commands/push-helpers.js +48 -0
- package/dist/commands/push-helpers.js.map +1 -0
- package/dist/commands/push.d.ts +2 -0
- package/dist/commands/push.d.ts.map +1 -1
- package/dist/commands/push.js +388 -124
- package/dist/commands/push.js.map +1 -1
- package/dist/commands/pushBackup.d.ts.map +1 -1
- package/dist/commands/pushBackup.js +8 -4
- package/dist/commands/pushBackup.js.map +1 -1
- package/dist/commands/resources.d.ts.map +1 -1
- package/dist/commands/resources.js +47 -60
- package/dist/commands/resources.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +117 -89
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +14 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +731 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/sync.d.ts.map +1 -1
- package/dist/commands/sync.js +70 -30
- package/dist/commands/sync.js.map +1 -1
- package/dist/commands/telemetry.d.ts.map +1 -1
- package/dist/commands/telemetry.js +4 -0
- package/dist/commands/telemetry.js.map +1 -1
- package/dist/commands/test-output.helpers.d.ts +24 -0
- package/dist/commands/test-output.helpers.d.ts.map +1 -0
- package/dist/commands/test-output.helpers.js +62 -0
- package/dist/commands/test-output.helpers.js.map +1 -0
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +291 -121
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/update.d.ts.map +1 -1
- package/dist/commands/update.js +15 -3
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/webhooks.d.ts.map +1 -1
- package/dist/commands/webhooks.js +94 -87
- package/dist/commands/webhooks.js.map +1 -1
- package/dist/compiler/agent-traverser.d.ts +50 -14
- package/dist/compiler/agent-traverser.d.ts.map +1 -1
- package/dist/compiler/agent-traverser.js +189 -86
- package/dist/compiler/agent-traverser.js.map +1 -1
- package/dist/compiler/bundler.d.ts.map +1 -1
- package/dist/compiler/bundler.js +5 -5
- package/dist/compiler/bundler.js.map +1 -1
- package/dist/compiler/compiler.d.ts +32 -0
- package/dist/compiler/compiler.d.ts.map +1 -1
- package/dist/compiler/compiler.js +154 -28
- package/dist/compiler/compiler.js.map +1 -1
- package/dist/compiler/index.d.ts +3 -3
- package/dist/compiler/index.d.ts.map +1 -1
- package/dist/compiler/index.js +3 -3
- package/dist/compiler/index.js.map +1 -1
- package/dist/compiler/plugins/agent.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/agent.plugin.js +2 -4
- package/dist/compiler/plugins/agent.plugin.js.map +1 -1
- package/dist/compiler/plugins/base.d.ts +21 -0
- package/dist/compiler/plugins/base.d.ts.map +1 -1
- package/dist/compiler/plugins/base.js +13 -3
- package/dist/compiler/plugins/base.js.map +1 -1
- package/dist/compiler/plugins/device-trigger.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/device-trigger.plugin.js +8 -4
- package/dist/compiler/plugins/device-trigger.plugin.js.map +1 -1
- package/dist/compiler/plugins/device.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/device.plugin.js +4 -4
- package/dist/compiler/plugins/device.plugin.js.map +1 -1
- package/dist/compiler/plugins/job.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/job.plugin.js +15 -11
- package/dist/compiler/plugins/job.plugin.js.map +1 -1
- package/dist/compiler/plugins/mcp-server.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/mcp-server.plugin.js +10 -4
- package/dist/compiler/plugins/mcp-server.plugin.js.map +1 -1
- package/dist/compiler/plugins/registry.js +2 -2
- package/dist/compiler/plugins/registry.js.map +1 -1
- package/dist/compiler/plugins/skill.plugin.d.ts +35 -9
- package/dist/compiler/plugins/skill.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/skill.plugin.js +129 -87
- package/dist/compiler/plugins/skill.plugin.js.map +1 -1
- package/dist/compiler/plugins/tool.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/tool.plugin.js +13 -9
- package/dist/compiler/plugins/tool.plugin.js.map +1 -1
- package/dist/compiler/plugins/webhook.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/webhook.plugin.js +7 -5
- package/dist/compiler/plugins/webhook.plugin.js.map +1 -1
- package/dist/compiler/source-writer.d.ts.map +1 -1
- package/dist/compiler/source-writer.js +2 -4
- package/dist/compiler/source-writer.js.map +1 -1
- package/dist/compiler/types.d.ts +33 -0
- package/dist/compiler/types.d.ts.map +1 -1
- package/dist/compiler/types.js.map +1 -1
- package/dist/compiler/utils/ast-helpers.d.ts +1 -16
- package/dist/compiler/utils/ast-helpers.d.ts.map +1 -1
- package/dist/compiler/utils/ast-helpers.js +14 -38
- package/dist/compiler/utils/ast-helpers.js.map +1 -1
- package/dist/compiler/utils/common.d.ts +14 -0
- package/dist/compiler/utils/common.d.ts.map +1 -1
- package/dist/compiler/utils/common.js +39 -11
- package/dist/compiler/utils/common.js.map +1 -1
- package/dist/compiler/utils/file-discovery.d.ts.map +1 -1
- package/dist/compiler/utils/file-discovery.js +2 -10
- package/dist/compiler/utils/file-discovery.js.map +1 -1
- package/dist/compiler/utils/path-resolver.d.ts +67 -10
- package/dist/compiler/utils/path-resolver.d.ts.map +1 -1
- package/dist/compiler/utils/path-resolver.js +120 -24
- package/dist/compiler/utils/path-resolver.js.map +1 -1
- package/dist/compiler/utils/reference-resolver.d.ts +196 -0
- package/dist/compiler/utils/reference-resolver.d.ts.map +1 -0
- package/dist/compiler/utils/reference-resolver.js +1026 -0
- package/dist/compiler/utils/reference-resolver.js.map +1 -0
- package/dist/compiler/utils/schema-converter.d.ts +25 -0
- package/dist/compiler/utils/schema-converter.d.ts.map +1 -1
- package/dist/compiler/utils/schema-converter.js +80 -4
- package/dist/compiler/utils/schema-converter.js.map +1 -1
- package/dist/compiler/utils/workspace.d.ts +35 -0
- package/dist/compiler/utils/workspace.d.ts.map +1 -0
- package/dist/compiler/utils/workspace.js +121 -0
- package/dist/compiler/utils/workspace.js.map +1 -0
- package/dist/compiler/utils/zod-runtime.mjs +5334 -0
- package/dist/config/compile.constants.d.ts.map +1 -1
- package/dist/config/compile.constants.js +3 -1
- package/dist/config/compile.constants.js.map +1 -1
- package/dist/config/constants.d.ts.map +1 -1
- package/dist/config/constants.js +1 -5
- package/dist/config/constants.js.map +1 -1
- package/dist/errors/auth.error.d.ts.map +1 -1
- package/dist/errors/auth.error.js +3 -5
- package/dist/errors/auth.error.js.map +1 -1
- package/dist/errors/index.d.ts +1 -1
- package/dist/errors/index.js +1 -1
- package/dist/index.js +9 -8
- package/dist/index.js.map +1 -1
- package/dist/instances/basket.instance.d.ts +3 -3
- package/dist/instances/basket.instance.d.ts.map +1 -1
- package/dist/instances/basket.instance.js +26 -8
- package/dist/instances/basket.instance.js.map +1 -1
- package/dist/instances/data.entry.instance.d.ts +2 -2
- package/dist/instances/data.entry.instance.d.ts.map +1 -1
- package/dist/instances/data.entry.instance.js +5 -5
- package/dist/instances/data.entry.instance.js.map +1 -1
- package/dist/instances/order.instance.d.ts +2 -2
- package/dist/instances/order.instance.d.ts.map +1 -1
- package/dist/instances/order.instance.js +20 -9
- package/dist/instances/order.instance.js.map +1 -1
- package/dist/instances/product.instance.d.ts +1 -1
- package/dist/instances/product.instance.d.ts.map +1 -1
- package/dist/instances/product.instance.js +3 -3
- package/dist/instances/product.instance.js.map +1 -1
- package/dist/instances/product.pagination.instance.d.ts +2 -2
- package/dist/instances/product.pagination.instance.d.ts.map +1 -1
- package/dist/instances/product.pagination.instance.js +6 -7
- package/dist/instances/product.pagination.instance.js.map +1 -1
- package/dist/instances/product.search.instance.d.ts +3 -3
- package/dist/instances/product.search.instance.d.ts.map +1 -1
- package/dist/instances/product.search.instance.js +3 -4
- package/dist/instances/product.search.instance.js.map +1 -1
- package/dist/instances/user.instance.d.ts +3 -3
- package/dist/instances/user.instance.d.ts.map +1 -1
- package/dist/instances/user.instance.js +19 -36
- package/dist/instances/user.instance.js.map +1 -1
- package/dist/interfaces/agent.d.ts +8 -8
- package/dist/interfaces/agent.d.ts.map +1 -1
- package/dist/interfaces/backup.d.ts +19 -1
- package/dist/interfaces/backup.d.ts.map +1 -1
- package/dist/interfaces/device-triggers.d.ts +0 -2
- package/dist/interfaces/device-triggers.d.ts.map +1 -1
- package/dist/interfaces/devices.d.ts +0 -1
- package/dist/interfaces/devices.d.ts.map +1 -1
- package/dist/interfaces/index.d.ts +8 -8
- package/dist/interfaces/index.d.ts.map +1 -1
- package/dist/interfaces/jobs.d.ts +2 -3
- package/dist/interfaces/jobs.d.ts.map +1 -1
- package/dist/interfaces/logs.d.ts +7 -4
- package/dist/interfaces/logs.d.ts.map +1 -1
- package/dist/interfaces/message.d.ts +3 -3
- package/dist/interfaces/message.d.ts.map +1 -1
- package/dist/interfaces/orders.d.ts +1 -1
- package/dist/interfaces/webhooks.d.ts +2 -2
- package/dist/interfaces/webhooks.d.ts.map +1 -1
- package/dist/primitives/agent.handler.d.ts.map +1 -1
- package/dist/primitives/agent.handler.js +1 -1
- package/dist/primitives/agent.handler.js.map +1 -1
- package/dist/primitives/base.handler.d.ts +12 -2
- package/dist/primitives/base.handler.d.ts.map +1 -1
- package/dist/primitives/base.handler.js +104 -73
- package/dist/primitives/base.handler.js.map +1 -1
- package/dist/primitives/device-trigger.handler.d.ts +1 -1
- package/dist/primitives/device-trigger.handler.d.ts.map +1 -1
- package/dist/primitives/device-trigger.handler.js +2 -3
- package/dist/primitives/device-trigger.handler.js.map +1 -1
- package/dist/primitives/device.handler.d.ts +1 -1
- package/dist/primitives/device.handler.d.ts.map +1 -1
- package/dist/primitives/device.handler.js +2 -3
- package/dist/primitives/device.handler.js.map +1 -1
- package/dist/primitives/index.d.ts +1 -1
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +2 -3
- package/dist/primitives/index.js.map +1 -1
- package/dist/primitives/job.handler.d.ts +6 -1
- package/dist/primitives/job.handler.d.ts.map +1 -1
- package/dist/primitives/job.handler.js +9 -3
- package/dist/primitives/job.handler.js.map +1 -1
- package/dist/primitives/mcp-server.handler.d.ts.map +1 -1
- package/dist/primitives/mcp-server.handler.js +2 -2
- package/dist/primitives/mcp-server.handler.js.map +1 -1
- package/dist/primitives/postprocessor.handler.d.ts.map +1 -1
- package/dist/primitives/postprocessor.handler.js.map +1 -1
- package/dist/primitives/preprocessor.handler.d.ts +1 -1
- package/dist/primitives/preprocessor.handler.d.ts.map +1 -1
- package/dist/primitives/preprocessor.handler.js +2 -3
- package/dist/primitives/preprocessor.handler.js.map +1 -1
- package/dist/primitives/skill.handler.d.ts +1 -1
- package/dist/primitives/skill.handler.d.ts.map +1 -1
- package/dist/primitives/skill.handler.js +34 -13
- package/dist/primitives/skill.handler.js.map +1 -1
- package/dist/primitives/types.d.ts +1 -1
- package/dist/primitives/types.d.ts.map +1 -1
- package/dist/primitives/types.js.map +1 -1
- package/dist/primitives/webhook.handler.d.ts +3 -2
- package/dist/primitives/webhook.handler.d.ts.map +1 -1
- package/dist/primitives/webhook.handler.js +9 -4
- package/dist/primitives/webhook.handler.js.map +1 -1
- package/dist/services/analytics.d.ts.map +1 -1
- package/dist/services/analytics.js +4 -5
- package/dist/services/analytics.js.map +1 -1
- package/dist/services/auth.d.ts +9 -1
- package/dist/services/auth.d.ts.map +1 -1
- package/dist/services/auth.js +26 -7
- package/dist/services/auth.js.map +1 -1
- package/dist/services/sandbox.service.d.ts.map +1 -1
- package/dist/services/sandbox.service.js +132 -80
- package/dist/services/sandbox.service.js.map +1 -1
- package/dist/types/api-contracts.d.ts +4 -4
- package/dist/types/api-contracts.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/skill.d.ts +7 -7
- package/dist/types/skill.d.ts.map +1 -1
- package/dist/types/skill.js +2 -2
- package/dist/types/skill.js.map +1 -1
- package/dist/types/tool-validation.js.map +1 -1
- package/dist/types/yaml.types.js +0 -1
- package/dist/types/yaml.types.js.map +1 -1
- package/dist/utils/aliases.d.ts +7 -0
- package/dist/utils/aliases.d.ts.map +1 -0
- package/dist/utils/aliases.js +492 -0
- package/dist/utils/aliases.js.map +1 -0
- package/dist/utils/artifact-loader.d.ts +9 -0
- package/dist/utils/artifact-loader.d.ts.map +1 -1
- package/dist/utils/artifact-loader.js +16 -6
- package/dist/utils/artifact-loader.js.map +1 -1
- package/dist/utils/auth-flows.d.ts.map +1 -1
- package/dist/utils/auth-flows.js +54 -54
- package/dist/utils/auth-flows.js.map +1 -1
- package/dist/utils/backup-helpers.d.ts +24 -0
- package/dist/utils/backup-helpers.d.ts.map +1 -1
- package/dist/utils/backup-helpers.js +102 -22
- package/dist/utils/backup-helpers.js.map +1 -1
- package/dist/utils/bundle-upload.d.ts +42 -0
- package/dist/utils/bundle-upload.d.ts.map +1 -0
- package/dist/utils/bundle-upload.js +90 -0
- package/dist/utils/bundle-upload.js.map +1 -0
- package/dist/utils/chat-attachments.js +1 -1
- package/dist/utils/chat-attachments.js.map +1 -1
- package/dist/utils/cli.d.ts +24 -6
- package/dist/utils/cli.d.ts.map +1 -1
- package/dist/utils/cli.js +26 -14
- package/dist/utils/cli.js.map +1 -1
- package/dist/utils/command-utils.d.ts.map +1 -1
- package/dist/utils/command-utils.js +4 -4
- package/dist/utils/command-utils.js.map +1 -1
- package/dist/utils/deploy-helpers.d.ts.map +1 -1
- package/dist/utils/deploy-helpers.js +13 -13
- package/dist/utils/deploy-helpers.js.map +1 -1
- package/dist/utils/env-loader.utils.d.ts +1 -1
- package/dist/utils/env-loader.utils.d.ts.map +1 -1
- package/dist/utils/env-loader.utils.js +15 -22
- package/dist/utils/env-loader.utils.js.map +1 -1
- package/dist/utils/files.d.ts.map +1 -1
- package/dist/utils/files.js +23 -13
- package/dist/utils/files.js.map +1 -1
- package/dist/utils/hints.d.ts +81 -0
- package/dist/utils/hints.d.ts.map +1 -0
- package/dist/utils/hints.js +81 -0
- package/dist/utils/hints.js.map +1 -0
- package/dist/utils/init-agent.d.ts.map +1 -1
- package/dist/utils/init-agent.js +18 -20
- package/dist/utils/init-agent.js.map +1 -1
- package/dist/utils/init-helpers.d.ts.map +1 -1
- package/dist/utils/init-helpers.js +11 -11
- package/dist/utils/init-helpers.js.map +1 -1
- package/dist/utils/init-prompts.d.ts.map +1 -1
- package/dist/utils/init-prompts.js +34 -36
- package/dist/utils/init-prompts.js.map +1 -1
- package/dist/utils/prompt-handler.js +1 -1
- package/dist/utils/prompt-handler.js.map +1 -1
- package/dist/utils/sandbox-storage.d.ts.map +1 -1
- package/dist/utils/sandbox-storage.js.map +1 -1
- package/dist/utils/sandbox.d.ts +1 -1
- package/dist/utils/sandbox.d.ts.map +1 -1
- package/dist/utils/sandbox.js +107 -106
- package/dist/utils/sandbox.js.map +1 -1
- package/dist/utils/semver.js +1 -1
- package/dist/utils/semver.js.map +1 -1
- package/dist/utils/suggest.d.ts +3 -0
- package/dist/utils/suggest.d.ts.map +1 -0
- package/dist/utils/suggest.js +32 -0
- package/dist/utils/suggest.js.map +1 -0
- package/dist/utils/sync-display.d.ts.map +1 -1
- package/dist/utils/sync-display.js +15 -13
- package/dist/utils/sync-display.js.map +1 -1
- package/dist/utils/sync-fetch.d.ts.map +1 -1
- package/dist/utils/sync-fetch.js +33 -24
- package/dist/utils/sync-fetch.js.map +1 -1
- package/dist/utils/version-check.js +1 -1
- package/dist/utils/version-check.js.map +1 -1
- package/dist/utils/write-info.d.ts +9 -0
- package/dist/utils/write-info.d.ts.map +1 -0
- package/dist/utils/write-info.js +11 -0
- package/dist/utils/write-info.js.map +1 -0
- package/docs/README.md +1 -1
- package/node_modules/@lua/shared-types/dist/index.d.mts +76 -2
- package/node_modules/@lua/shared-types/dist/index.d.ts +76 -2
- package/node_modules/@lua/shared-types/dist/index.js +27 -0
- package/node_modules/@lua/shared-types/dist/index.mjs +24 -0
- package/node_modules/@lua/shared-types/src/ai-generate.types.ts +1 -6
- package/node_modules/@lua/shared-types/src/ai-generate.utils.ts +1 -4
- package/node_modules/@lua/shared-types/src/channel.type.ts +1 -0
- package/node_modules/@lua/shared-types/src/chat-stream.types.ts +11 -0
- package/node_modules/@lua/shared-types/src/client-tools.types.ts +47 -0
- package/node_modules/@lua/shared-types/src/device.types.ts +6 -6
- package/node_modules/@lua/shared-types/src/index.ts +3 -0
- package/node_modules/@lua/shared-types/src/sandbox-contract.ts +26 -5
- package/node_modules/@lua/shared-types/src/vm-execution-log.types.ts +41 -0
- package/package.json +10 -6
- package/scripts/build-vendor.mjs +53 -0
- package/scripts/vendor-entry.mjs +11 -0
- package/template/QUICKSTART.md +33 -33
- package/template/README.md +35 -34
- package/template/examples/README.md +44 -38
- package/template/examples/jobs/AbandonedBasketProcessorJob.ts +30 -31
- package/template/examples/jobs/DailyCleanupJob.ts +17 -18
- package/template/examples/jobs/DataMigrationJob.ts +18 -23
- package/template/examples/jobs/HealthCheckJob.ts +13 -14
- package/template/examples/postprocessors/modifyResponse.ts +14 -15
- package/template/examples/preprocessors/messageMatching.ts +28 -29
- package/template/examples/services/ApiService.ts +68 -64
- package/template/examples/services/GetWeather.ts +39 -33
- package/template/examples/skills/basket.skill.ts +27 -7
- package/template/examples/skills/product.skill.ts +21 -8
- package/template/examples/skills/tools/BasketTool.ts +97 -98
- package/template/examples/skills/tools/CreateInlineJob.ts +38 -36
- package/template/examples/skills/tools/CreatePostTool.ts +27 -28
- package/template/examples/skills/tools/CustomDataTool.ts +72 -67
- package/template/examples/skills/tools/GameScoreTrackerTool.ts +72 -78
- package/template/examples/skills/tools/GetWeatherTool.ts +43 -45
- package/template/examples/skills/tools/OrderTool.ts +58 -58
- package/template/examples/skills/tools/PaymentTool.ts +43 -43
- package/template/examples/skills/tools/PremiumFeatureTool.ts +81 -79
- package/template/examples/skills/tools/ProductsTool.ts +68 -69
- package/template/examples/skills/tools/SmartBasketTool.ts +43 -44
- package/template/examples/skills/tools/UserDataTool.ts +97 -98
- package/template/examples/skills/user.skill.ts +7 -8
- package/template/examples/webhooks/FileUploadWebhook.ts +38 -31
- package/template/examples/webhooks/PaymentWebhook.ts +23 -22
- package/template/examples/webhooks/UserEventWebhook.ts +16 -19
- package/template/lua.skill.yaml +2 -2
- package/template/package.json +1 -1
- package/template/src/index.ts +28 -28
|
@@ -23,8 +23,9 @@ import { safePrompt } from '../utils/prompt-handler.js';
|
|
|
23
23
|
import { initializeCommand } from '../utils/command-utils.js';
|
|
24
24
|
import DeveloperApi from '../api/developer.api.service.js';
|
|
25
25
|
import UnifiedToApi from '../api/unifiedto.api.service.js';
|
|
26
|
-
import { fetchServersCore, activateServerCore, deactivateServerCore
|
|
26
|
+
import { fetchServersCore, activateServerCore, deactivateServerCore } from './mcp.js';
|
|
27
27
|
import { trackEvent } from '../services/analytics.js';
|
|
28
|
+
import { validateOrSuggest } from '../utils/aliases.js';
|
|
28
29
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
29
30
|
// Configuration
|
|
30
31
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
@@ -73,9 +74,7 @@ function startCallbackServer(timeoutMs = 300000) {
|
|
|
73
74
|
resolved = true;
|
|
74
75
|
if (error) {
|
|
75
76
|
// Unified.to redirects to failure_redirect with ?error=<oauth_error>&log_id=<trace_id>
|
|
76
|
-
const logIdHtml = logId
|
|
77
|
-
? `<p style="color: #888; font-size: 0.85em;">Log ID: <code>${logId}</code></p>`
|
|
78
|
-
: '';
|
|
77
|
+
const logIdHtml = logId ? `<p style="color: #888; font-size: 0.85em;">Log ID: <code>${logId}</code></p>` : '';
|
|
79
78
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
80
79
|
res.end(`
|
|
81
80
|
<!DOCTYPE html>
|
|
@@ -145,8 +144,8 @@ export async function integrationsCommand(action, subaction, cmdObj) {
|
|
|
145
144
|
const { agentId, apiKey, userData } = await initializeCommand({ showProgress: false, validateAuth: true });
|
|
146
145
|
const userId = userData?.admin?.userId;
|
|
147
146
|
if (!userId) {
|
|
148
|
-
console.error(
|
|
149
|
-
throw new Error(
|
|
147
|
+
console.error('ā Failed to get user ID from authentication.');
|
|
148
|
+
throw new Error('Failed to get user ID from authentication.');
|
|
150
149
|
}
|
|
151
150
|
const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, agentId);
|
|
152
151
|
const unifiedToApi = new UnifiedToApi(BASE_URLS.API, apiKey);
|
|
@@ -171,13 +170,13 @@ export async function integrationsCommand(action, subaction, cmdObj) {
|
|
|
171
170
|
integration_type: cmdObj?.integration || null,
|
|
172
171
|
non_interactive: !!action,
|
|
173
172
|
});
|
|
174
|
-
},
|
|
173
|
+
}, 'integrations');
|
|
175
174
|
}
|
|
176
175
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
177
176
|
// Non-Interactive Mode
|
|
178
177
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
179
178
|
async function executeNonInteractive(context, action, cmdOptions) {
|
|
180
|
-
const normalizedAction = action
|
|
179
|
+
const normalizedAction = validateOrSuggest('integrations.action', action);
|
|
181
180
|
// Extract typed options
|
|
182
181
|
const options = {
|
|
183
182
|
integration: cmdOptions?.integration,
|
|
@@ -198,9 +197,9 @@ async function executeNonInteractive(context, action, cmdOptions) {
|
|
|
198
197
|
break;
|
|
199
198
|
case 'update':
|
|
200
199
|
if (!options.integration) {
|
|
201
|
-
console.error(
|
|
200
|
+
console.error('ā --integration is required for update');
|
|
202
201
|
console.log("\nš” Run 'lua integrations list' to see connected integrations");
|
|
203
|
-
throw new Error(
|
|
202
|
+
throw new Error('--integration is required for update');
|
|
204
203
|
}
|
|
205
204
|
await updateConnectionFlow(context, options);
|
|
206
205
|
break;
|
|
@@ -215,18 +214,18 @@ async function executeNonInteractive(context, action, cmdOptions) {
|
|
|
215
214
|
// Integration type can be passed as positional arg (info <type>) or as --integration flag
|
|
216
215
|
const infoIntegrationType = options.integration || cmdOptions?._?.[0];
|
|
217
216
|
if (!infoIntegrationType) {
|
|
218
|
-
console.error(
|
|
219
|
-
console.log(
|
|
220
|
-
console.log(
|
|
221
|
-
throw new Error(
|
|
217
|
+
console.error('ā Integration type is required');
|
|
218
|
+
console.log('\nUsage: lua integrations info <type>');
|
|
219
|
+
console.log(' lua integrations info <type> --json');
|
|
220
|
+
throw new Error('Integration type is required');
|
|
222
221
|
}
|
|
223
222
|
await showIntegrationInfo(context, infoIntegrationType, jsonOutput);
|
|
224
223
|
break;
|
|
225
224
|
case 'disconnect':
|
|
226
225
|
if (!options.connectionId) {
|
|
227
|
-
console.error(
|
|
226
|
+
console.error('ā --connection-id is required for disconnect');
|
|
228
227
|
console.log("\nš” Run 'lua integrations list' to see connection IDs");
|
|
229
|
-
throw new Error(
|
|
228
|
+
throw new Error('--connection-id is required for disconnect');
|
|
230
229
|
}
|
|
231
230
|
await disconnectIntegration(context, options.connectionId);
|
|
232
231
|
break;
|
|
@@ -239,7 +238,7 @@ async function executeNonInteractive(context, action, cmdOptions) {
|
|
|
239
238
|
default:
|
|
240
239
|
console.error(`ā Invalid action: "${action}"`);
|
|
241
240
|
showUsage();
|
|
242
|
-
throw new Error(
|
|
241
|
+
throw new Error('Invalid action:');
|
|
243
242
|
}
|
|
244
243
|
}
|
|
245
244
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
@@ -248,9 +247,9 @@ async function executeNonInteractive(context, action, cmdOptions) {
|
|
|
248
247
|
async function interactiveIntegrationsManagement(context) {
|
|
249
248
|
let continueManaging = true;
|
|
250
249
|
while (continueManaging) {
|
|
251
|
-
console.log(
|
|
252
|
-
console.log(
|
|
253
|
-
console.log(
|
|
250
|
+
console.log('\n' + '='.repeat(60));
|
|
251
|
+
console.log('š Integrations');
|
|
252
|
+
console.log('='.repeat(60) + '\n');
|
|
254
253
|
const actionAnswer = await safePrompt([
|
|
255
254
|
{
|
|
256
255
|
type: 'list',
|
|
@@ -264,9 +263,9 @@ async function interactiveIntegrationsManagement(context) {
|
|
|
264
263
|
{ name: 'š Manage triggers', value: 'webhooks' },
|
|
265
264
|
{ name: 'š Manage MCP servers', value: 'mcp' },
|
|
266
265
|
{ name: 'šļø Disconnect an integration', value: 'disconnect' },
|
|
267
|
-
{ name: 'ā Exit', value: 'exit' }
|
|
268
|
-
]
|
|
269
|
-
}
|
|
266
|
+
{ name: 'ā Exit', value: 'exit' },
|
|
267
|
+
],
|
|
268
|
+
},
|
|
270
269
|
]);
|
|
271
270
|
if (!actionAnswer)
|
|
272
271
|
return;
|
|
@@ -295,7 +294,7 @@ async function interactiveIntegrationsManagement(context) {
|
|
|
295
294
|
break;
|
|
296
295
|
case 'exit':
|
|
297
296
|
continueManaging = false;
|
|
298
|
-
console.log(
|
|
297
|
+
console.log('\nš Goodbye!\n');
|
|
299
298
|
break;
|
|
300
299
|
}
|
|
301
300
|
}
|
|
@@ -304,15 +303,15 @@ async function interactiveIntegrationsManagement(context) {
|
|
|
304
303
|
// List Available Integrations
|
|
305
304
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
306
305
|
async function listAvailableIntegrations(context) {
|
|
307
|
-
writeProgress(
|
|
306
|
+
writeProgress('š Fetching available integrations...');
|
|
308
307
|
try {
|
|
309
308
|
const integrations = await fetchAvailableIntegrations(context.unifiedToApi);
|
|
310
|
-
console.log(
|
|
311
|
-
console.log(
|
|
312
|
-
console.log(
|
|
309
|
+
console.log('\n' + '='.repeat(60));
|
|
310
|
+
console.log('š Available Integrations');
|
|
311
|
+
console.log('='.repeat(60) + '\n');
|
|
313
312
|
if (integrations.length === 0) {
|
|
314
|
-
console.log(
|
|
315
|
-
console.log(
|
|
313
|
+
console.log('ā¹ļø No integrations available.');
|
|
314
|
+
console.log('š” Contact support to enable integrations for your workspace.\n');
|
|
316
315
|
return;
|
|
317
316
|
}
|
|
318
317
|
// Group by category
|
|
@@ -325,15 +324,15 @@ async function listAvailableIntegrations(context) {
|
|
|
325
324
|
}
|
|
326
325
|
for (const [category, items] of Object.entries(byCategory)) {
|
|
327
326
|
console.log(`š ${category.toUpperCase()}`);
|
|
328
|
-
items.forEach(i => {
|
|
327
|
+
items.forEach((i) => {
|
|
329
328
|
const authBadge = i.authSupport === 'oauth' ? 'š' : i.authSupport === 'token' ? 'š' : 'šš';
|
|
330
329
|
console.log(` ${authBadge} ${i.name} (${i.value})`);
|
|
331
330
|
});
|
|
332
331
|
console.log();
|
|
333
332
|
}
|
|
334
|
-
console.log(
|
|
333
|
+
console.log('='.repeat(60));
|
|
335
334
|
console.log(`Total: ${integrations.length} integration(s) available`);
|
|
336
|
-
console.log(
|
|
335
|
+
console.log('š = OAuth š = API Key/Token šš = Both\n');
|
|
337
336
|
}
|
|
338
337
|
catch (error) {
|
|
339
338
|
writeError(`ā Failed to fetch integrations: ${error.message}`);
|
|
@@ -350,7 +349,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
350
349
|
try {
|
|
351
350
|
// Fetch integration details
|
|
352
351
|
const integrations = await fetchAvailableIntegrations(context.unifiedToApi);
|
|
353
|
-
const integration = integrations.find(i => i.value === integrationType);
|
|
352
|
+
const integration = integrations.find((i) => i.value === integrationType);
|
|
354
353
|
if (!integration) {
|
|
355
354
|
if (jsonOutput) {
|
|
356
355
|
console.log(JSON.stringify({ error: `Integration not found: ${integrationType}` }));
|
|
@@ -358,9 +357,9 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
358
357
|
else {
|
|
359
358
|
console.error(`ā Integration not found: ${integrationType}`);
|
|
360
359
|
console.log('\nAvailable integrations:');
|
|
361
|
-
integrations.forEach(i => console.log(` - ${i.value} (${i.name})`));
|
|
360
|
+
integrations.forEach((i) => console.log(` - ${i.value} (${i.name})`));
|
|
362
361
|
}
|
|
363
|
-
throw new Error(
|
|
362
|
+
throw new Error('Operation failed');
|
|
364
363
|
}
|
|
365
364
|
// Fetch available webhook events for this integration
|
|
366
365
|
let webhookEvents = [];
|
|
@@ -383,7 +382,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
383
382
|
oauthConfigured: integration.oauthConfigured,
|
|
384
383
|
oauthScopes: integration.oauthScopes || [],
|
|
385
384
|
tokenFields: integration.tokenFields || [],
|
|
386
|
-
webhookEvents: webhookEvents.map(e => ({
|
|
385
|
+
webhookEvents: webhookEvents.map((e) => ({
|
|
387
386
|
trigger: `${e.objectType}.${e.event}`,
|
|
388
387
|
objectType: e.objectType,
|
|
389
388
|
event: e.event,
|
|
@@ -401,9 +400,9 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
401
400
|
}
|
|
402
401
|
else {
|
|
403
402
|
// Human-readable output
|
|
404
|
-
console.log(
|
|
403
|
+
console.log('\n' + '='.repeat(60));
|
|
405
404
|
console.log(`š Integration: ${integration.name}`);
|
|
406
|
-
console.log(
|
|
405
|
+
console.log('='.repeat(60));
|
|
407
406
|
console.log(`\n Type: ${integration.value}`);
|
|
408
407
|
console.log(` Categories: ${integration.categories.join(', ')}`);
|
|
409
408
|
console.log(` Auth Support: ${integration.authSupport}`);
|
|
@@ -411,7 +410,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
411
410
|
// OAuth Scopes
|
|
412
411
|
if (integration.oauthScopes && integration.oauthScopes.length > 0) {
|
|
413
412
|
console.log('\n OAuth Scopes:');
|
|
414
|
-
integration.oauthScopes.forEach(s => {
|
|
413
|
+
integration.oauthScopes.forEach((s) => {
|
|
415
414
|
if (s.friendlyLabel) {
|
|
416
415
|
console.log(` - ${s.friendlyLabel} (${s.unifiedScope})`);
|
|
417
416
|
if (s.friendlyDescription) {
|
|
@@ -426,7 +425,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
426
425
|
// Token Fields
|
|
427
426
|
if (integration.tokenFields && integration.tokenFields.length > 0) {
|
|
428
427
|
console.log('\n Token Fields:');
|
|
429
|
-
integration.tokenFields.forEach(f => {
|
|
428
|
+
integration.tokenFields.forEach((f) => {
|
|
430
429
|
console.log(` - ${f.name}`);
|
|
431
430
|
if (f.instructions) {
|
|
432
431
|
console.log(` š” ${f.instructions}`);
|
|
@@ -436,15 +435,15 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
436
435
|
// Webhook Events/Triggers
|
|
437
436
|
if (webhookEvents.length > 0) {
|
|
438
437
|
console.log('\n Available Triggers:');
|
|
439
|
-
webhookEvents.forEach(e => {
|
|
438
|
+
webhookEvents.forEach((e) => {
|
|
440
439
|
console.log(` - ${e.objectType}.${e.event} [${e.webhookType}] - ${e.friendlyDescription}`);
|
|
441
440
|
});
|
|
442
441
|
}
|
|
443
442
|
else {
|
|
444
443
|
console.log('\n Available Triggers: None');
|
|
445
444
|
}
|
|
446
|
-
console.log(
|
|
447
|
-
console.log(
|
|
445
|
+
console.log('\n' + '='.repeat(60));
|
|
446
|
+
console.log('\nš” Use with non-interactive commands:');
|
|
448
447
|
console.log(` lua integrations connect --integration ${integrationType} --auth-method oauth --scopes all`);
|
|
449
448
|
if (webhookEvents.length > 0) {
|
|
450
449
|
const exampleTrigger = `${webhookEvents[0].objectType}.${webhookEvents[0].event}`;
|
|
@@ -460,7 +459,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
460
459
|
else {
|
|
461
460
|
writeError(`ā Failed to get integration info: ${error.message}`);
|
|
462
461
|
}
|
|
463
|
-
throw new Error(
|
|
462
|
+
throw new Error('Operation failed');
|
|
464
463
|
}
|
|
465
464
|
}
|
|
466
465
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
@@ -468,7 +467,7 @@ async function showIntegrationInfo(context, integrationType, jsonOutput = false)
|
|
|
468
467
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
469
468
|
async function connectIntegrationFlow(context, options = {}) {
|
|
470
469
|
// Step 1: Fetch available integrations (API excludes already-connected types)
|
|
471
|
-
writeProgress(
|
|
470
|
+
writeProgress('š Fetching integrations...');
|
|
472
471
|
let availableIntegrations;
|
|
473
472
|
try {
|
|
474
473
|
availableIntegrations = await fetchAvailableIntegrations(context.unifiedToApi, context.agentId);
|
|
@@ -478,7 +477,7 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
478
477
|
return;
|
|
479
478
|
}
|
|
480
479
|
if (availableIntegrations.length === 0) {
|
|
481
|
-
writeInfo(
|
|
480
|
+
writeInfo('All available integrations are already connected (or none are enabled).');
|
|
482
481
|
console.log("š” Use 'lua integrations update' to change scopes on an existing connection.\n");
|
|
483
482
|
return;
|
|
484
483
|
}
|
|
@@ -486,16 +485,18 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
486
485
|
// Step 2: Select integration (with search/filter support)
|
|
487
486
|
let selectedIntegration;
|
|
488
487
|
if (options.integration) {
|
|
489
|
-
selectedIntegration = availableIntegrations.find(i => i.value === options.integration);
|
|
488
|
+
selectedIntegration = availableIntegrations.find((i) => i.value === options.integration);
|
|
490
489
|
if (!selectedIntegration) {
|
|
491
490
|
// Not in available list ā either already connected or doesn't exist
|
|
492
491
|
console.error(`ā Integration "${options.integration}" not found or already connected.`);
|
|
493
|
-
console.log("š” If already connected, use 'lua integrations update --integration " +
|
|
492
|
+
console.log("š” If already connected, use 'lua integrations update --integration " +
|
|
493
|
+
options.integration +
|
|
494
|
+
"' to change scopes.");
|
|
494
495
|
if (availableIntegrations.length > 0) {
|
|
495
496
|
console.log('\nAvailable integrations to connect:');
|
|
496
|
-
availableIntegrations.forEach(i => console.log(` - ${i.value} (${i.name})`));
|
|
497
|
+
availableIntegrations.forEach((i) => console.log(` - ${i.value} (${i.name})`));
|
|
497
498
|
}
|
|
498
|
-
throw new Error(
|
|
499
|
+
throw new Error('Integration');
|
|
499
500
|
}
|
|
500
501
|
}
|
|
501
502
|
else {
|
|
@@ -505,7 +506,7 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
505
506
|
type: 'input',
|
|
506
507
|
name: 'searchTerm',
|
|
507
508
|
message: 'Search integrations (or press Enter to browse all):',
|
|
508
|
-
}
|
|
509
|
+
},
|
|
509
510
|
]);
|
|
510
511
|
if (!searchAnswer)
|
|
511
512
|
return;
|
|
@@ -513,9 +514,9 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
513
514
|
let filteredIntegrations = availableIntegrations;
|
|
514
515
|
if (searchAnswer.searchTerm.trim()) {
|
|
515
516
|
const searchLower = searchAnswer.searchTerm.toLowerCase().trim();
|
|
516
|
-
filteredIntegrations = availableIntegrations.filter(i => i.name.toLowerCase().includes(searchLower) ||
|
|
517
|
+
filteredIntegrations = availableIntegrations.filter((i) => i.name.toLowerCase().includes(searchLower) ||
|
|
517
518
|
i.value.toLowerCase().includes(searchLower) ||
|
|
518
|
-
i.categories.some(c => c.toLowerCase().includes(searchLower)));
|
|
519
|
+
i.categories.some((c) => c.toLowerCase().includes(searchLower)));
|
|
519
520
|
if (filteredIntegrations.length === 0) {
|
|
520
521
|
writeInfo(`No available integrations found matching "${searchAnswer.searchTerm}"`);
|
|
521
522
|
console.log(`š” If the integration is already connected, use 'lua integrations update' to change scopes.`);
|
|
@@ -525,8 +526,8 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
525
526
|
type: 'confirm',
|
|
526
527
|
name: 'browseAll',
|
|
527
528
|
message: 'Would you like to browse all available integrations?',
|
|
528
|
-
default: true
|
|
529
|
-
}
|
|
529
|
+
default: true,
|
|
530
|
+
},
|
|
530
531
|
]);
|
|
531
532
|
if (!browseAnswer?.browseAll)
|
|
532
533
|
return;
|
|
@@ -542,14 +543,14 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
542
543
|
name: 'integration',
|
|
543
544
|
message: 'Select an integration to connect:',
|
|
544
545
|
pageSize: 15,
|
|
545
|
-
choices: filteredIntegrations.map(i => {
|
|
546
|
+
choices: filteredIntegrations.map((i) => {
|
|
546
547
|
const authBadge = i.authSupport === 'oauth' ? 'š' : i.authSupport === 'token' ? 'š' : 'šš';
|
|
547
548
|
return {
|
|
548
549
|
name: `${authBadge} ${i.name} (${i.categories.join(', ')})`,
|
|
549
|
-
value: i
|
|
550
|
+
value: i,
|
|
550
551
|
};
|
|
551
|
-
})
|
|
552
|
-
}
|
|
552
|
+
}),
|
|
553
|
+
},
|
|
553
554
|
]);
|
|
554
555
|
if (!integrationAnswer)
|
|
555
556
|
return;
|
|
@@ -560,8 +561,7 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
560
561
|
console.log(` Auth Support: ${selectedIntegration.authSupport}`);
|
|
561
562
|
console.log(` OAuth Configured: ${selectedIntegration.oauthConfigured ? 'Yes' : 'No'}`);
|
|
562
563
|
// Step 3: Determine auth method and get scopes
|
|
563
|
-
const canUseOAuth = selectedIntegration.oauthConfigured &&
|
|
564
|
-
['oauth', 'both'].includes(selectedIntegration.authSupport);
|
|
564
|
+
const canUseOAuth = selectedIntegration.oauthConfigured && ['oauth', 'both'].includes(selectedIntegration.authSupport);
|
|
565
565
|
const canUseToken = ['token', 'both'].includes(selectedIntegration.authSupport);
|
|
566
566
|
let authMethod;
|
|
567
567
|
let selectedScopes = [];
|
|
@@ -569,36 +569,38 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
569
569
|
if (options.authMethod) {
|
|
570
570
|
if (!['oauth', 'token'].includes(options.authMethod)) {
|
|
571
571
|
console.error(`ā Invalid --auth-method: "${options.authMethod}". Use 'oauth' or 'token'`);
|
|
572
|
-
throw new Error(
|
|
572
|
+
throw new Error('Invalid --auth-method:');
|
|
573
573
|
}
|
|
574
574
|
if (options.authMethod === 'oauth' && !canUseOAuth) {
|
|
575
575
|
console.error(`ā OAuth is not available for ${selectedIntegration.name}.`);
|
|
576
576
|
if (canUseToken) {
|
|
577
577
|
console.log(`š” Use --auth-method token instead.`);
|
|
578
578
|
}
|
|
579
|
-
throw new Error(
|
|
579
|
+
throw new Error('Operation failed');
|
|
580
580
|
}
|
|
581
581
|
if (options.authMethod === 'token' && !canUseToken) {
|
|
582
582
|
console.error(`ā Token authentication is not available for ${selectedIntegration.name}.`);
|
|
583
583
|
if (canUseOAuth) {
|
|
584
584
|
console.log(`š” Use --auth-method oauth instead.`);
|
|
585
585
|
}
|
|
586
|
-
throw new Error(
|
|
586
|
+
throw new Error('Operation failed');
|
|
587
587
|
}
|
|
588
588
|
authMethod = options.authMethod;
|
|
589
589
|
writeInfo(`Using ${authMethod === 'oauth' ? 'OAuth 2.0' : 'API Token'} authentication`);
|
|
590
590
|
}
|
|
591
591
|
else if (canUseOAuth && canUseToken) {
|
|
592
592
|
// Both available - let user choose interactively
|
|
593
|
-
const authAnswer = await safePrompt([
|
|
593
|
+
const authAnswer = await safePrompt([
|
|
594
|
+
{
|
|
594
595
|
type: 'list',
|
|
595
596
|
name: 'method',
|
|
596
597
|
message: 'Choose authentication method:',
|
|
597
598
|
choices: [
|
|
598
599
|
{ name: 'š OAuth 2.0 (recommended)', value: 'oauth' },
|
|
599
|
-
{ name: 'š API Token / Personal Access Token', value: 'token' }
|
|
600
|
-
]
|
|
601
|
-
}
|
|
600
|
+
{ name: 'š API Token / Personal Access Token', value: 'token' },
|
|
601
|
+
],
|
|
602
|
+
},
|
|
603
|
+
]);
|
|
602
604
|
if (!authAnswer)
|
|
603
605
|
return;
|
|
604
606
|
authMethod = authAnswer.method;
|
|
@@ -619,7 +621,7 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
619
621
|
}
|
|
620
622
|
// Handle OAuth scope selection
|
|
621
623
|
if (authMethod === 'oauth' && selectedIntegration.oauthScopes?.length) {
|
|
622
|
-
const availableScopes = selectedIntegration.oauthScopes.map(s => s.unifiedScope);
|
|
624
|
+
const availableScopes = selectedIntegration.oauthScopes.map((s) => s.unifiedScope);
|
|
623
625
|
if (options.scopes) {
|
|
624
626
|
// Non-interactive: use provided scopes
|
|
625
627
|
if (options.scopes.toLowerCase() === 'all') {
|
|
@@ -628,13 +630,13 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
628
630
|
}
|
|
629
631
|
else {
|
|
630
632
|
// Parse comma-separated scopes
|
|
631
|
-
const requestedScopes = options.scopes.split(',').map(s => s.trim());
|
|
632
|
-
const invalidScopes = requestedScopes.filter(s => !availableScopes.includes(s));
|
|
633
|
+
const requestedScopes = options.scopes.split(',').map((s) => s.trim());
|
|
634
|
+
const invalidScopes = requestedScopes.filter((s) => !availableScopes.includes(s));
|
|
633
635
|
if (invalidScopes.length > 0) {
|
|
634
636
|
console.error(`ā Invalid scopes: ${invalidScopes.join(', ')}`);
|
|
635
637
|
console.log(`\nAvailable scopes for ${selectedIntegration.name}:`);
|
|
636
|
-
availableScopes.forEach(s => console.log(` - ${s}`));
|
|
637
|
-
throw new Error(
|
|
638
|
+
availableScopes.forEach((s) => console.log(` - ${s}`));
|
|
639
|
+
throw new Error('Invalid scopes: ${invalidScopes.join(');
|
|
638
640
|
}
|
|
639
641
|
selectedScopes = requestedScopes;
|
|
640
642
|
writeInfo(`Using ${selectedScopes.length} specified scope(s)`);
|
|
@@ -642,13 +644,14 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
642
644
|
}
|
|
643
645
|
else {
|
|
644
646
|
// Interactive: prompt for scope selection
|
|
645
|
-
const scopeAnswer = await safePrompt([
|
|
647
|
+
const scopeAnswer = await safePrompt([
|
|
648
|
+
{
|
|
646
649
|
type: 'checkbox',
|
|
647
650
|
name: 'scopes',
|
|
648
651
|
message: 'Select OAuth scopes (Space to toggle, Enter to confirm, leave empty for all):',
|
|
649
652
|
pageSize: 15,
|
|
650
653
|
loop: false,
|
|
651
|
-
choices: selectedIntegration.oauthScopes.map(s => {
|
|
654
|
+
choices: selectedIntegration.oauthScopes.map((s) => {
|
|
652
655
|
// Use friendly label if available, otherwise fall back to technical name
|
|
653
656
|
const displayName = s.friendlyLabel || s.unifiedScope;
|
|
654
657
|
const description = s.friendlyDescription
|
|
@@ -657,16 +660,15 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
657
660
|
return {
|
|
658
661
|
name: `${displayName}${description}`,
|
|
659
662
|
value: s.unifiedScope,
|
|
660
|
-
checked: false
|
|
663
|
+
checked: false,
|
|
661
664
|
};
|
|
662
|
-
})
|
|
663
|
-
}
|
|
665
|
+
}),
|
|
666
|
+
},
|
|
667
|
+
]);
|
|
664
668
|
if (!scopeAnswer)
|
|
665
669
|
return;
|
|
666
670
|
// If none selected, request all scopes
|
|
667
|
-
selectedScopes = scopeAnswer.scopes.length > 0
|
|
668
|
-
? scopeAnswer.scopes
|
|
669
|
-
: availableScopes;
|
|
671
|
+
selectedScopes = scopeAnswer.scopes.length > 0 ? scopeAnswer.scopes : availableScopes;
|
|
670
672
|
console.log(`\nā Will request ${selectedScopes.length} scope(s)`);
|
|
671
673
|
}
|
|
672
674
|
}
|
|
@@ -695,12 +697,14 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
695
697
|
}
|
|
696
698
|
else {
|
|
697
699
|
// Interactive: ask user
|
|
698
|
-
const sensitiveAnswer = await safePrompt([
|
|
700
|
+
const sensitiveAnswer = await safePrompt([
|
|
701
|
+
{
|
|
699
702
|
type: 'confirm',
|
|
700
703
|
name: 'hide',
|
|
701
704
|
message: 'Hide sensitive data (PII) from MCP tools?',
|
|
702
|
-
default: false
|
|
703
|
-
}
|
|
705
|
+
default: false,
|
|
706
|
+
},
|
|
707
|
+
]);
|
|
704
708
|
if (sensitiveAnswer) {
|
|
705
709
|
hideSensitive = sensitiveAnswer.hide;
|
|
706
710
|
}
|
|
@@ -722,24 +726,25 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
722
726
|
}
|
|
723
727
|
if (options.triggers) {
|
|
724
728
|
// Non-interactive: parse comma-separated triggers (e.g., 'task_task.created,task_task.updated')
|
|
725
|
-
const requestedTriggers = options.triggers.split(',').map(t => t.trim());
|
|
729
|
+
const requestedTriggers = options.triggers.split(',').map((t) => t.trim());
|
|
726
730
|
for (const trigger of requestedTriggers) {
|
|
727
731
|
const [objectType, event] = trigger.split('.');
|
|
728
|
-
const matchingEvent = availableEvents.find(e => e.objectType === objectType && e.event === event);
|
|
732
|
+
const matchingEvent = availableEvents.find((e) => e.objectType === objectType && e.event === event);
|
|
729
733
|
if (!matchingEvent) {
|
|
730
734
|
console.error(`ā Invalid trigger: ${trigger}`);
|
|
731
735
|
console.log(`\nAvailable triggers for ${selectedIntegration.name}:`);
|
|
732
|
-
availableEvents.forEach(e => {
|
|
736
|
+
availableEvents.forEach((e) => {
|
|
733
737
|
console.log(` - ${e.objectType}.${e.event} [${e.webhookType}] - ${e.friendlyDescription}`);
|
|
734
738
|
});
|
|
735
|
-
throw new Error(
|
|
739
|
+
throw new Error('Invalid trigger: ${trigger}');
|
|
736
740
|
}
|
|
737
741
|
selectedTriggers.push(matchingEvent);
|
|
738
742
|
}
|
|
739
743
|
writeInfo(`Selected ${selectedTriggers.length} trigger(s)`);
|
|
740
744
|
// If custom webhook mode, prompt for URL if not provided
|
|
741
745
|
if (isCustomWebhook && !options.hookUrl) {
|
|
742
|
-
const urlAnswer = await safePrompt([
|
|
746
|
+
const urlAnswer = await safePrompt([
|
|
747
|
+
{
|
|
743
748
|
type: 'input',
|
|
744
749
|
name: 'url',
|
|
745
750
|
message: 'Enter your webhook URL:',
|
|
@@ -751,8 +756,9 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
751
756
|
catch {
|
|
752
757
|
return 'Please enter a valid URL';
|
|
753
758
|
}
|
|
754
|
-
}
|
|
755
|
-
}
|
|
759
|
+
},
|
|
760
|
+
},
|
|
761
|
+
]);
|
|
756
762
|
if (!urlAnswer)
|
|
757
763
|
return;
|
|
758
764
|
webhookUrl = urlAnswer.url;
|
|
@@ -765,46 +771,53 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
765
771
|
console.log('ā'.repeat(60));
|
|
766
772
|
console.log('\nTriggers wake your agent when something happens in the integration.');
|
|
767
773
|
console.log('We recommend adding only what you actually need ā you can always add them later.');
|
|
768
|
-
const wantTriggersAnswer = await safePrompt([
|
|
774
|
+
const wantTriggersAnswer = await safePrompt([
|
|
775
|
+
{
|
|
769
776
|
type: 'confirm',
|
|
770
777
|
name: 'want',
|
|
771
778
|
message: 'Do you want to configure triggers now?',
|
|
772
779
|
default: false,
|
|
773
|
-
}
|
|
780
|
+
},
|
|
781
|
+
]);
|
|
774
782
|
if (!wantTriggersAnswer)
|
|
775
783
|
return;
|
|
776
784
|
if (wantTriggersAnswer.want) {
|
|
777
785
|
console.log('\nSelect the events you actually need:');
|
|
778
786
|
console.log('(Space to toggle, Enter to confirm. Nothing pre-selected.)');
|
|
779
|
-
const triggerAnswer = await safePrompt([
|
|
787
|
+
const triggerAnswer = await safePrompt([
|
|
788
|
+
{
|
|
780
789
|
type: 'checkbox',
|
|
781
790
|
name: 'triggers',
|
|
782
791
|
message: 'Select triggers:',
|
|
783
792
|
pageSize: 15,
|
|
784
793
|
loop: false,
|
|
785
|
-
choices: availableEvents.map(e => ({
|
|
794
|
+
choices: availableEvents.map((e) => ({
|
|
786
795
|
name: `${e.friendlyDescription} [${e.webhookType}]`,
|
|
787
796
|
value: e,
|
|
788
|
-
checked: false // None pre-selected ā user chooses what they need
|
|
789
|
-
}))
|
|
790
|
-
}
|
|
797
|
+
checked: false, // None pre-selected ā user chooses what they need
|
|
798
|
+
})),
|
|
799
|
+
},
|
|
800
|
+
]);
|
|
791
801
|
if (triggerAnswer && triggerAnswer.triggers.length > 0) {
|
|
792
802
|
selectedTriggers = triggerAnswer.triggers;
|
|
793
803
|
// Ask about webhook mode only if triggers are selected
|
|
794
|
-
const modeAnswer = await safePrompt([
|
|
804
|
+
const modeAnswer = await safePrompt([
|
|
805
|
+
{
|
|
795
806
|
type: 'list',
|
|
796
807
|
name: 'mode',
|
|
797
808
|
message: 'How should these events be handled?',
|
|
798
809
|
choices: [
|
|
799
810
|
{ name: 'š¤ Agent Trigger (recommended) - Events wake up your agent', value: 'agent' },
|
|
800
|
-
{ name: 'š Custom URL - Send events to your own webhook URL', value: 'custom' }
|
|
801
|
-
]
|
|
802
|
-
}
|
|
811
|
+
{ name: 'š Custom URL - Send events to your own webhook URL', value: 'custom' },
|
|
812
|
+
],
|
|
813
|
+
},
|
|
814
|
+
]);
|
|
803
815
|
if (!modeAnswer)
|
|
804
816
|
return;
|
|
805
817
|
if (modeAnswer.mode === 'custom') {
|
|
806
818
|
isCustomWebhook = true;
|
|
807
|
-
const urlAnswer = await safePrompt([
|
|
819
|
+
const urlAnswer = await safePrompt([
|
|
820
|
+
{
|
|
808
821
|
type: 'input',
|
|
809
822
|
name: 'url',
|
|
810
823
|
message: 'Enter your webhook URL:',
|
|
@@ -816,8 +829,9 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
816
829
|
catch {
|
|
817
830
|
return 'Please enter a valid URL';
|
|
818
831
|
}
|
|
819
|
-
}
|
|
820
|
-
}
|
|
832
|
+
},
|
|
833
|
+
},
|
|
834
|
+
]);
|
|
821
835
|
if (!urlAnswer)
|
|
822
836
|
return;
|
|
823
837
|
webhookUrl = urlAnswer.url;
|
|
@@ -845,12 +859,12 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
845
859
|
writeInfo(`Note: Could not fetch available triggers (${error.message})`);
|
|
846
860
|
}
|
|
847
861
|
// Step 5: Get authorization URL from Lua API
|
|
848
|
-
writeProgress(
|
|
862
|
+
writeProgress('š Preparing authorization...');
|
|
849
863
|
const state = Buffer.from(JSON.stringify({
|
|
850
864
|
agentId: context.agentId,
|
|
851
865
|
integration: selectedIntegration.value,
|
|
852
866
|
authMethod,
|
|
853
|
-
timestamp: Date.now()
|
|
867
|
+
timestamp: Date.now(),
|
|
854
868
|
})).toString('base64');
|
|
855
869
|
// Encode both agentId and userId in externalXref for the connection
|
|
856
870
|
const externalXref = JSON.stringify({
|
|
@@ -871,9 +885,9 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
871
885
|
// Auth URL is already resolved by the API (redirect wrappers followed server-side)
|
|
872
886
|
const authUrl = authUrlResult.data.authUrl;
|
|
873
887
|
// Step 4: Start callback server and open browser
|
|
874
|
-
console.log(
|
|
875
|
-
console.log(
|
|
876
|
-
console.log(
|
|
888
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
889
|
+
console.log('š Starting OAuth authorization flow...');
|
|
890
|
+
console.log('ā'.repeat(60));
|
|
877
891
|
console.log(`\nIntegration: ${selectedIntegration.name}`);
|
|
878
892
|
console.log(`\nš Authorization URL (copy if browser doesn't open):\n ${authUrl}\n`);
|
|
879
893
|
// Start the callback server
|
|
@@ -881,17 +895,17 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
881
895
|
// Auto-open browser
|
|
882
896
|
try {
|
|
883
897
|
await open(authUrl);
|
|
884
|
-
writeInfo(
|
|
898
|
+
writeInfo('š Browser opened - please complete the authorization');
|
|
885
899
|
}
|
|
886
900
|
catch (error) {
|
|
887
|
-
writeInfo(
|
|
901
|
+
writeInfo('š” Could not open browser automatically. Please open the URL above manually.');
|
|
888
902
|
}
|
|
889
|
-
console.log(
|
|
890
|
-
console.log(
|
|
903
|
+
console.log('\nā³ Waiting for authorization (5 minute timeout)...');
|
|
904
|
+
console.log('š” Complete the authorization in your browser.\n');
|
|
891
905
|
// Wait for callback
|
|
892
906
|
const result = await callbackPromise;
|
|
893
907
|
if (result.success && result.connectionId) {
|
|
894
|
-
writeSuccess(
|
|
908
|
+
writeSuccess('\nā
Authorization successful!');
|
|
895
909
|
// Finalize the connection (sets up MCP server internally and creates webhooks)
|
|
896
910
|
await finalizeConnection(context, selectedIntegration, result.connectionId, selectedScopes, hideSensitive, {
|
|
897
911
|
triggers: selectedTriggers,
|
|
@@ -905,13 +919,15 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
905
919
|
console.log(` Log ID: ${result.logId}`);
|
|
906
920
|
}
|
|
907
921
|
// Report auth failure for observability (fire and forget)
|
|
908
|
-
context.unifiedToApi
|
|
922
|
+
context.unifiedToApi
|
|
923
|
+
.reportAuthFailure({
|
|
909
924
|
integrationType: selectedIntegration.value,
|
|
910
925
|
error: result.error || 'Unknown OAuth failure',
|
|
911
926
|
logId: result.logId,
|
|
912
927
|
agentId: context.agentId,
|
|
913
928
|
source: 'cli',
|
|
914
|
-
})
|
|
929
|
+
})
|
|
930
|
+
.catch(() => { });
|
|
915
931
|
console.log("š” Please try again with 'lua integrations connect'\n");
|
|
916
932
|
}
|
|
917
933
|
}
|
|
@@ -922,7 +938,7 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
922
938
|
async function finalizeConnection(context, integration, connectionId, scopes, hideSensitive = false, webhookConfig = { triggers: [], webhookUrl: '', isCustomWebhook: false }) {
|
|
923
939
|
writeProgress(`š Setting up ${integration.name} connection...`);
|
|
924
940
|
// Build trigger params for the API (include per-trigger hookUrl/interval if set)
|
|
925
|
-
const triggers = webhookConfig.triggers.map(t => ({
|
|
941
|
+
const triggers = webhookConfig.triggers.map((t) => ({
|
|
926
942
|
objectType: t.objectType,
|
|
927
943
|
event: t.event,
|
|
928
944
|
hookUrl: t.hookUrl || (webhookConfig.isCustomWebhook ? webhookConfig.webhookUrl : undefined),
|
|
@@ -944,9 +960,9 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
|
|
|
944
960
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
945
961
|
// Display Results
|
|
946
962
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
947
|
-
console.log(
|
|
948
|
-
console.log(
|
|
949
|
-
console.log(
|
|
963
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
964
|
+
console.log('š Connection Established!');
|
|
965
|
+
console.log('ā'.repeat(60));
|
|
950
966
|
console.log(`\n Integration: ${integration.name}`);
|
|
951
967
|
console.log(` Connection ID: ${connectionId}`);
|
|
952
968
|
// MCP Server status
|
|
@@ -957,8 +973,8 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
|
|
|
957
973
|
// Show requested scopes with friendly labels
|
|
958
974
|
if (scopes.length > 0) {
|
|
959
975
|
console.log(`\n š Permissions (${scopes.length}):`);
|
|
960
|
-
scopes.forEach(scopeName => {
|
|
961
|
-
const scopeInfo = integration.oauthScopes?.find(s => s.unifiedScope === scopeName);
|
|
976
|
+
scopes.forEach((scopeName) => {
|
|
977
|
+
const scopeInfo = integration.oauthScopes?.find((s) => s.unifiedScope === scopeName);
|
|
962
978
|
if (scopeInfo?.friendlyLabel) {
|
|
963
979
|
console.log(` ⢠${scopeInfo.friendlyLabel}`);
|
|
964
980
|
}
|
|
@@ -979,20 +995,20 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
|
|
|
979
995
|
else {
|
|
980
996
|
console.log(` Mode: Agent wake-up`);
|
|
981
997
|
}
|
|
982
|
-
webhooks.forEach(wh => {
|
|
983
|
-
const trigger = webhookConfig.triggers.find(t => t.objectType === wh.objectType && t.event === wh.event);
|
|
998
|
+
webhooks.forEach((wh) => {
|
|
999
|
+
const trigger = webhookConfig.triggers.find((t) => t.objectType === wh.objectType && t.event === wh.event);
|
|
984
1000
|
const desc = trigger?.friendlyDescription || `${wh.objectType}.${wh.event}`;
|
|
985
1001
|
console.log(` ā ${desc}`);
|
|
986
1002
|
});
|
|
987
1003
|
if (failedWebhooks && failedWebhooks.length > 0) {
|
|
988
|
-
failedWebhooks.forEach(t => console.log(` ā ${t.objectType}.${t.event}: ${t.error}`));
|
|
1004
|
+
failedWebhooks.forEach((t) => console.log(` ā ${t.objectType}.${t.event}: ${t.error}`));
|
|
989
1005
|
}
|
|
990
1006
|
}
|
|
991
1007
|
else {
|
|
992
1008
|
console.log(`\n ā” Triggers: none (add later with: lua triggers create --connection ${connectionId})`);
|
|
993
1009
|
}
|
|
994
1010
|
// Summary message
|
|
995
|
-
console.log(
|
|
1011
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
996
1012
|
const capabilities = [];
|
|
997
1013
|
if (mcpServer.active) {
|
|
998
1014
|
capabilities.push('tools via MCP');
|
|
@@ -1020,16 +1036,16 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
|
|
|
1020
1036
|
});
|
|
1021
1037
|
}
|
|
1022
1038
|
async function listConnections(context) {
|
|
1023
|
-
writeProgress(
|
|
1039
|
+
writeProgress('š Loading connections...');
|
|
1024
1040
|
try {
|
|
1025
1041
|
// API now returns connections enriched with MCP server info
|
|
1026
1042
|
const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
|
|
1027
1043
|
const connections = connectionsResult.success ? connectionsResult.data || [] : [];
|
|
1028
|
-
console.log(
|
|
1029
|
-
console.log(
|
|
1030
|
-
console.log(
|
|
1044
|
+
console.log('\n' + '='.repeat(60));
|
|
1045
|
+
console.log('š Connected Integrations');
|
|
1046
|
+
console.log('='.repeat(60) + '\n');
|
|
1031
1047
|
if (connections.length === 0) {
|
|
1032
|
-
console.log(
|
|
1048
|
+
console.log('ā¹ļø No integrations connected yet.');
|
|
1033
1049
|
console.log("š” Run 'lua integrations connect' to connect an integration.\n");
|
|
1034
1050
|
return;
|
|
1035
1051
|
}
|
|
@@ -1063,7 +1079,7 @@ async function listConnections(context) {
|
|
|
1063
1079
|
console.log(` Connected: ${new Date(connection.createdAt).toLocaleDateString()}`);
|
|
1064
1080
|
console.log();
|
|
1065
1081
|
}
|
|
1066
|
-
console.log(
|
|
1082
|
+
console.log('='.repeat(60));
|
|
1067
1083
|
console.log(`Total: ${connections.length} integration(s)\n`);
|
|
1068
1084
|
}
|
|
1069
1085
|
catch (error) {
|
|
@@ -1102,7 +1118,7 @@ async function disconnectIntegrationInteractive(context) {
|
|
|
1102
1118
|
}
|
|
1103
1119
|
const connections = connectionsResult.data || [];
|
|
1104
1120
|
if (connections.length === 0) {
|
|
1105
|
-
console.log(
|
|
1121
|
+
console.log('\nā¹ļø No integrations to disconnect.\n');
|
|
1106
1122
|
return;
|
|
1107
1123
|
}
|
|
1108
1124
|
const connectionAnswer = await safePrompt([
|
|
@@ -1110,25 +1126,25 @@ async function disconnectIntegrationInteractive(context) {
|
|
|
1110
1126
|
type: 'list',
|
|
1111
1127
|
name: 'connection',
|
|
1112
1128
|
message: 'Select an integration to disconnect:',
|
|
1113
|
-
choices: connections.map(c => ({
|
|
1129
|
+
choices: connections.map((c) => ({
|
|
1114
1130
|
name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
|
|
1115
|
-
value: c.id
|
|
1116
|
-
}))
|
|
1117
|
-
}
|
|
1131
|
+
value: c.id,
|
|
1132
|
+
})),
|
|
1133
|
+
},
|
|
1118
1134
|
]);
|
|
1119
1135
|
if (!connectionAnswer?.connection)
|
|
1120
1136
|
return;
|
|
1121
|
-
const selectedConnection = connections.find(c => c.id === connectionAnswer.connection);
|
|
1137
|
+
const selectedConnection = connections.find((c) => c.id === connectionAnswer.connection);
|
|
1122
1138
|
const confirmAnswer = await safePrompt([
|
|
1123
1139
|
{
|
|
1124
1140
|
type: 'confirm',
|
|
1125
1141
|
name: 'confirm',
|
|
1126
1142
|
message: `Disconnect ${selectedConnection?.integrationName || selectedConnection?.integrationType}? Your agent will lose access to this integration.`,
|
|
1127
|
-
default: false
|
|
1128
|
-
}
|
|
1143
|
+
default: false,
|
|
1144
|
+
},
|
|
1129
1145
|
]);
|
|
1130
1146
|
if (!confirmAnswer?.confirm) {
|
|
1131
|
-
console.log(
|
|
1147
|
+
console.log('\nā Cancelled.\n');
|
|
1132
1148
|
return;
|
|
1133
1149
|
}
|
|
1134
1150
|
await disconnectIntegration(context, connectionAnswer.connection);
|
|
@@ -1142,13 +1158,13 @@ async function disconnectIntegrationInteractive(context) {
|
|
|
1142
1158
|
// āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
|
|
1143
1159
|
async function updateConnectionFlow(context, options = {}) {
|
|
1144
1160
|
// Step 1: Fetch existing connections and available integrations
|
|
1145
|
-
writeProgress(
|
|
1161
|
+
writeProgress('š Loading connections...');
|
|
1146
1162
|
let connections = [];
|
|
1147
1163
|
let integrations = [];
|
|
1148
1164
|
try {
|
|
1149
1165
|
const [connectionsResult, integrationsResult] = await Promise.all([
|
|
1150
1166
|
context.unifiedToApi.getConnections(context.agentId),
|
|
1151
|
-
fetchAvailableIntegrations(context.unifiedToApi)
|
|
1167
|
+
fetchAvailableIntegrations(context.unifiedToApi),
|
|
1152
1168
|
]);
|
|
1153
1169
|
connections = connectionsResult.success ? connectionsResult.data || [] : [];
|
|
1154
1170
|
integrations = integrationsResult;
|
|
@@ -1158,7 +1174,7 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1158
1174
|
return;
|
|
1159
1175
|
}
|
|
1160
1176
|
if (connections.length === 0) {
|
|
1161
|
-
writeInfo(
|
|
1177
|
+
writeInfo('No integrations to update.');
|
|
1162
1178
|
console.log("š” Run 'lua integrations connect' to connect an integration.\n");
|
|
1163
1179
|
return;
|
|
1164
1180
|
}
|
|
@@ -1167,14 +1183,14 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1167
1183
|
let selectedIntegration;
|
|
1168
1184
|
if (options.integration) {
|
|
1169
1185
|
// Find connection by integration type
|
|
1170
|
-
selectedConnection = connections.find(c => c.integrationType === options.integration);
|
|
1186
|
+
selectedConnection = connections.find((c) => c.integrationType === options.integration);
|
|
1171
1187
|
if (!selectedConnection) {
|
|
1172
1188
|
console.error(`ā No connection found for integration "${options.integration}".`);
|
|
1173
1189
|
console.log('\nConnected integrations:');
|
|
1174
|
-
connections.forEach(c => console.log(` - ${c.integrationType} (${c.integrationName || c.integrationType})`));
|
|
1175
|
-
throw new Error(
|
|
1190
|
+
connections.forEach((c) => console.log(` - ${c.integrationType} (${c.integrationName || c.integrationType})`));
|
|
1191
|
+
throw new Error('No connection found for integration');
|
|
1176
1192
|
}
|
|
1177
|
-
selectedIntegration = integrations.find(i => i.value === options.integration);
|
|
1193
|
+
selectedIntegration = integrations.find((i) => i.value === options.integration);
|
|
1178
1194
|
}
|
|
1179
1195
|
else {
|
|
1180
1196
|
// Interactive selection
|
|
@@ -1183,16 +1199,16 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1183
1199
|
type: 'list',
|
|
1184
1200
|
name: 'connection',
|
|
1185
1201
|
message: 'Select a connection to update:',
|
|
1186
|
-
choices: connections.map(c => ({
|
|
1202
|
+
choices: connections.map((c) => ({
|
|
1187
1203
|
name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
|
|
1188
|
-
value: c
|
|
1189
|
-
}))
|
|
1190
|
-
}
|
|
1204
|
+
value: c,
|
|
1205
|
+
})),
|
|
1206
|
+
},
|
|
1191
1207
|
]);
|
|
1192
1208
|
if (!connectionAnswer?.connection)
|
|
1193
1209
|
return;
|
|
1194
1210
|
selectedConnection = connectionAnswer.connection;
|
|
1195
|
-
selectedIntegration = integrations.find(i => i.value === selectedConnection.integrationType);
|
|
1211
|
+
selectedIntegration = integrations.find((i) => i.value === selectedConnection.integrationType);
|
|
1196
1212
|
}
|
|
1197
1213
|
if (!selectedIntegration) {
|
|
1198
1214
|
writeError(`ā Integration details not found for ${selectedConnection.integrationType}`);
|
|
@@ -1201,15 +1217,14 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1201
1217
|
console.log(`\nš Updating: ${selectedIntegration.name}`);
|
|
1202
1218
|
console.log(` Current Connection ID: ${selectedConnection.id}`);
|
|
1203
1219
|
// Step 3: Check if OAuth with configurable scopes
|
|
1204
|
-
const canUseOAuth = selectedIntegration.oauthConfigured &&
|
|
1205
|
-
['oauth', 'both'].includes(selectedIntegration.authSupport);
|
|
1220
|
+
const canUseOAuth = selectedIntegration.oauthConfigured && ['oauth', 'both'].includes(selectedIntegration.authSupport);
|
|
1206
1221
|
if (!canUseOAuth || !selectedIntegration.oauthScopes?.length) {
|
|
1207
|
-
writeInfo(
|
|
1208
|
-
console.log(
|
|
1222
|
+
writeInfo('This integration does not have configurable scopes.');
|
|
1223
|
+
console.log('š” To reconnect with different credentials, disconnect and connect again.\n');
|
|
1209
1224
|
return;
|
|
1210
1225
|
}
|
|
1211
1226
|
// Step 4: Select new scopes
|
|
1212
|
-
const availableScopes = selectedIntegration.oauthScopes.map(s => s.unifiedScope);
|
|
1227
|
+
const availableScopes = selectedIntegration.oauthScopes.map((s) => s.unifiedScope);
|
|
1213
1228
|
let selectedScopes = [];
|
|
1214
1229
|
if (options.scopes) {
|
|
1215
1230
|
// Non-interactive: use provided scopes
|
|
@@ -1218,13 +1233,13 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1218
1233
|
writeInfo(`Using all ${selectedScopes.length} available scope(s)`);
|
|
1219
1234
|
}
|
|
1220
1235
|
else {
|
|
1221
|
-
const requestedScopes = options.scopes.split(',').map(s => s.trim());
|
|
1222
|
-
const invalidScopes = requestedScopes.filter(s => !availableScopes.includes(s));
|
|
1236
|
+
const requestedScopes = options.scopes.split(',').map((s) => s.trim());
|
|
1237
|
+
const invalidScopes = requestedScopes.filter((s) => !availableScopes.includes(s));
|
|
1223
1238
|
if (invalidScopes.length > 0) {
|
|
1224
1239
|
console.error(`ā Invalid scopes: ${invalidScopes.join(', ')}`);
|
|
1225
1240
|
console.log(`\nAvailable scopes for ${selectedIntegration.name}:`);
|
|
1226
|
-
availableScopes.forEach(s => console.log(` - ${s}`));
|
|
1227
|
-
throw new Error(
|
|
1241
|
+
availableScopes.forEach((s) => console.log(` - ${s}`));
|
|
1242
|
+
throw new Error('Invalid scopes: ${invalidScopes.join(');
|
|
1228
1243
|
}
|
|
1229
1244
|
selectedScopes = requestedScopes;
|
|
1230
1245
|
writeInfo(`Using ${selectedScopes.length} specified scope(s)`);
|
|
@@ -1232,13 +1247,14 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1232
1247
|
}
|
|
1233
1248
|
else {
|
|
1234
1249
|
// Interactive: prompt for scope selection
|
|
1235
|
-
const scopeAnswer = await safePrompt([
|
|
1250
|
+
const scopeAnswer = await safePrompt([
|
|
1251
|
+
{
|
|
1236
1252
|
type: 'checkbox',
|
|
1237
1253
|
name: 'scopes',
|
|
1238
1254
|
message: 'Select new OAuth scopes (Space to toggle, Enter to confirm, leave empty for all):',
|
|
1239
1255
|
pageSize: 15,
|
|
1240
1256
|
loop: false,
|
|
1241
|
-
choices: selectedIntegration.oauthScopes.map(s => {
|
|
1257
|
+
choices: selectedIntegration.oauthScopes.map((s) => {
|
|
1242
1258
|
// Use friendly label if available, otherwise fall back to technical name
|
|
1243
1259
|
const displayName = s.friendlyLabel || s.unifiedScope;
|
|
1244
1260
|
const description = s.friendlyDescription
|
|
@@ -1247,15 +1263,14 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1247
1263
|
return {
|
|
1248
1264
|
name: `${displayName}${description}`,
|
|
1249
1265
|
value: s.unifiedScope,
|
|
1250
|
-
checked: false
|
|
1266
|
+
checked: false,
|
|
1251
1267
|
};
|
|
1252
|
-
})
|
|
1253
|
-
}
|
|
1268
|
+
}),
|
|
1269
|
+
},
|
|
1270
|
+
]);
|
|
1254
1271
|
if (!scopeAnswer)
|
|
1255
1272
|
return;
|
|
1256
|
-
selectedScopes = scopeAnswer.scopes.length > 0
|
|
1257
|
-
? scopeAnswer.scopes
|
|
1258
|
-
: availableScopes;
|
|
1273
|
+
selectedScopes = scopeAnswer.scopes.length > 0 ? scopeAnswer.scopes : availableScopes;
|
|
1259
1274
|
console.log(`\nā Will request ${selectedScopes.length} scope(s)`);
|
|
1260
1275
|
}
|
|
1261
1276
|
// Determine hide_sensitive setting
|
|
@@ -1265,12 +1280,14 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1265
1280
|
}
|
|
1266
1281
|
else {
|
|
1267
1282
|
// Interactive: ask user
|
|
1268
|
-
const sensitiveAnswer = await safePrompt([
|
|
1283
|
+
const sensitiveAnswer = await safePrompt([
|
|
1284
|
+
{
|
|
1269
1285
|
type: 'confirm',
|
|
1270
1286
|
name: 'hide',
|
|
1271
1287
|
message: 'Hide sensitive data (PII) from MCP tools?',
|
|
1272
|
-
default: false
|
|
1273
|
-
}
|
|
1288
|
+
default: false,
|
|
1289
|
+
},
|
|
1290
|
+
]);
|
|
1274
1291
|
if (sensitiveAnswer) {
|
|
1275
1292
|
hideSensitive = sensitiveAnswer.hide;
|
|
1276
1293
|
}
|
|
@@ -1281,8 +1298,8 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1281
1298
|
const webhooksResult = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
|
|
1282
1299
|
if (webhooksResult.success && webhooksResult.data && webhooksResult.data.length > 0) {
|
|
1283
1300
|
// Filter webhooks to only those belonging to this connection
|
|
1284
|
-
const connectionWebhooks = webhooksResult.data.filter(w => w.connectionId === selectedConnection.id);
|
|
1285
|
-
existingTriggers = connectionWebhooks.map(w => ({
|
|
1301
|
+
const connectionWebhooks = webhooksResult.data.filter((w) => w.connectionId === selectedConnection.id);
|
|
1302
|
+
existingTriggers = connectionWebhooks.map((w) => ({
|
|
1286
1303
|
objectType: w.objectType,
|
|
1287
1304
|
event: w.event,
|
|
1288
1305
|
hookUrl: w.hookUrl,
|
|
@@ -1303,11 +1320,11 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1303
1320
|
type: 'confirm',
|
|
1304
1321
|
name: 'confirm',
|
|
1305
1322
|
message: `Update ${selectedIntegration.name}? This will re-authorize with new scopes.`,
|
|
1306
|
-
default: true
|
|
1307
|
-
}
|
|
1323
|
+
default: true,
|
|
1324
|
+
},
|
|
1308
1325
|
]);
|
|
1309
1326
|
if (!confirmAnswer?.confirm) {
|
|
1310
|
-
console.log(
|
|
1327
|
+
console.log('\nā Cancelled.\n');
|
|
1311
1328
|
return;
|
|
1312
1329
|
}
|
|
1313
1330
|
}
|
|
@@ -1326,7 +1343,7 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1326
1343
|
agentId: context.agentId,
|
|
1327
1344
|
integration: selectedIntegration.value,
|
|
1328
1345
|
authMethod: 'oauth',
|
|
1329
|
-
timestamp: Date.now()
|
|
1346
|
+
timestamp: Date.now(),
|
|
1330
1347
|
})).toString('base64');
|
|
1331
1348
|
const externalXref = JSON.stringify({
|
|
1332
1349
|
agentId: context.agentId,
|
|
@@ -1346,25 +1363,25 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1346
1363
|
// Auth URL is already resolved by the API (redirect wrappers followed server-side)
|
|
1347
1364
|
const authUrl = authUrlResult.data.authUrl;
|
|
1348
1365
|
// Step 9: Open browser and wait for callback
|
|
1349
|
-
console.log(
|
|
1350
|
-
console.log(
|
|
1351
|
-
console.log(
|
|
1366
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
1367
|
+
console.log('š Re-authorizing with new scopes...');
|
|
1368
|
+
console.log('ā'.repeat(60));
|
|
1352
1369
|
console.log(`\nš Authorization URL (copy if browser doesn't open):\n ${authUrl}\n`);
|
|
1353
1370
|
const callbackPromise = startCallbackServer(300000);
|
|
1354
1371
|
try {
|
|
1355
1372
|
await open(authUrl);
|
|
1356
|
-
writeInfo(
|
|
1373
|
+
writeInfo('š Browser opened - please complete the authorization');
|
|
1357
1374
|
}
|
|
1358
1375
|
catch (error) {
|
|
1359
|
-
writeInfo(
|
|
1376
|
+
writeInfo('š” Could not open browser automatically. Please open the URL above manually.');
|
|
1360
1377
|
}
|
|
1361
|
-
console.log(
|
|
1362
|
-
console.log(
|
|
1378
|
+
console.log('\nā³ Waiting for authorization (5 minute timeout)...');
|
|
1379
|
+
console.log('š” Complete the authorization in your browser.\n');
|
|
1363
1380
|
const result = await callbackPromise;
|
|
1364
1381
|
if (result.success && result.connectionId) {
|
|
1365
|
-
writeSuccess(
|
|
1382
|
+
writeSuccess('\nā
Authorization successful!');
|
|
1366
1383
|
// Check if any triggers use custom webhooks
|
|
1367
|
-
const hasCustomWebhook = existingTriggers.some(t => t.hookUrl !== AGENT_WEBHOOK_URL);
|
|
1384
|
+
const hasCustomWebhook = existingTriggers.some((t) => t.hookUrl !== AGENT_WEBHOOK_URL);
|
|
1368
1385
|
// Convert existing triggers to TriggerWithSettings format, preserving per-trigger hookUrl and interval
|
|
1369
1386
|
let triggersToRestore = [];
|
|
1370
1387
|
if (existingTriggers.length > 0) {
|
|
@@ -1372,7 +1389,7 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1372
1389
|
const eventsResult = await context.unifiedToApi.getAvailableWebhookEventsByType(selectedIntegration.value);
|
|
1373
1390
|
if (eventsResult.success && eventsResult.data) {
|
|
1374
1391
|
for (const trigger of existingTriggers) {
|
|
1375
|
-
const matchingEvent = eventsResult.data.find(e => e.objectType === trigger.objectType && e.event === trigger.event);
|
|
1392
|
+
const matchingEvent = eventsResult.data.find((e) => e.objectType === trigger.objectType && e.event === trigger.event);
|
|
1376
1393
|
if (matchingEvent) {
|
|
1377
1394
|
// Preserve per-trigger hookUrl and interval from original webhook
|
|
1378
1395
|
triggersToRestore.push({
|
|
@@ -1403,13 +1420,15 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1403
1420
|
console.log(` Log ID: ${result.logId}`);
|
|
1404
1421
|
}
|
|
1405
1422
|
// Report auth failure for observability (fire and forget)
|
|
1406
|
-
context.unifiedToApi
|
|
1423
|
+
context.unifiedToApi
|
|
1424
|
+
.reportAuthFailure({
|
|
1407
1425
|
integrationType: selectedIntegration.value,
|
|
1408
1426
|
error: result.error || 'Unknown OAuth failure',
|
|
1409
1427
|
logId: result.logId,
|
|
1410
1428
|
agentId: context.agentId,
|
|
1411
1429
|
source: 'cli',
|
|
1412
|
-
})
|
|
1430
|
+
})
|
|
1431
|
+
.catch(() => { });
|
|
1413
1432
|
console.log("š” The old connection was removed. Please reconnect with 'lua integrations connect'\n");
|
|
1414
1433
|
}
|
|
1415
1434
|
}
|
|
@@ -1420,7 +1439,8 @@ async function updateConnectionFlow(context, options = {}) {
|
|
|
1420
1439
|
* Handle webhooks subcommand (non-interactive)
|
|
1421
1440
|
*/
|
|
1422
1441
|
async function webhooksSubcommand(context, cmdOptions) {
|
|
1423
|
-
const
|
|
1442
|
+
const rawSubAction = cmdOptions?._?.[0] || '';
|
|
1443
|
+
const subAction = rawSubAction ? validateOrSuggest('triggers.action', rawSubAction) : '';
|
|
1424
1444
|
const options = {
|
|
1425
1445
|
connectionId: cmdOptions?.connection || cmdOptions?.connectionId,
|
|
1426
1446
|
webhookId: cmdOptions?.webhookId,
|
|
@@ -1441,9 +1461,9 @@ async function webhooksSubcommand(context, cmdOptions) {
|
|
|
1441
1461
|
break;
|
|
1442
1462
|
case 'delete':
|
|
1443
1463
|
if (!options.webhookId) {
|
|
1444
|
-
console.error(
|
|
1464
|
+
console.error('ā --webhook-id is required for delete');
|
|
1445
1465
|
console.log("\nš” Run 'lua integrations webhooks list' to see trigger IDs");
|
|
1446
|
-
throw new Error(
|
|
1466
|
+
throw new Error('--webhook-id is required for delete');
|
|
1447
1467
|
}
|
|
1448
1468
|
await webhooksDeleteFlow(context, options.webhookId);
|
|
1449
1469
|
break;
|
|
@@ -1455,9 +1475,9 @@ async function webhooksSubcommand(context, cmdOptions) {
|
|
|
1455
1475
|
await connectionPauseFlow(context, options.connectionId);
|
|
1456
1476
|
}
|
|
1457
1477
|
else {
|
|
1458
|
-
console.error(
|
|
1478
|
+
console.error('ā --webhook-id or --connection-id is required for pause');
|
|
1459
1479
|
console.log("\nš” Run 'lua integrations webhooks list' to see trigger IDs");
|
|
1460
|
-
throw new Error(
|
|
1480
|
+
throw new Error('--webhook-id or --connection-id is required for pause');
|
|
1461
1481
|
}
|
|
1462
1482
|
break;
|
|
1463
1483
|
case 'resume':
|
|
@@ -1468,9 +1488,9 @@ async function webhooksSubcommand(context, cmdOptions) {
|
|
|
1468
1488
|
await connectionResumeFlow(context, options.connectionId);
|
|
1469
1489
|
}
|
|
1470
1490
|
else {
|
|
1471
|
-
console.error(
|
|
1491
|
+
console.error('ā --webhook-id or --connection-id is required for resume');
|
|
1472
1492
|
console.log("\nš” Run 'lua integrations webhooks list' to see trigger IDs");
|
|
1473
|
-
throw new Error(
|
|
1493
|
+
throw new Error('--webhook-id or --connection-id is required for resume');
|
|
1474
1494
|
}
|
|
1475
1495
|
break;
|
|
1476
1496
|
case 'events':
|
|
@@ -1527,17 +1547,17 @@ async function webhooksEventsFlow(context, options, jsonOutput = false) {
|
|
|
1527
1547
|
console.log(JSON.stringify({ error: 'Either --connection or --integration is required' }));
|
|
1528
1548
|
}
|
|
1529
1549
|
else {
|
|
1530
|
-
console.error(
|
|
1531
|
-
console.log(
|
|
1532
|
-
console.log(
|
|
1533
|
-
console.log(
|
|
1550
|
+
console.error('ā Either --connection <id> or --integration <type> is required');
|
|
1551
|
+
console.log('\nUsage:');
|
|
1552
|
+
console.log(' lua integrations webhooks events --connection <id>');
|
|
1553
|
+
console.log(' lua integrations webhooks events --integration <type>');
|
|
1534
1554
|
}
|
|
1535
|
-
throw new Error(
|
|
1555
|
+
throw new Error('Operation failed');
|
|
1536
1556
|
}
|
|
1537
1557
|
if (jsonOutput) {
|
|
1538
1558
|
const output = {
|
|
1539
1559
|
source: sourceName,
|
|
1540
|
-
events: webhookEvents.map(e => ({
|
|
1560
|
+
events: webhookEvents.map((e) => ({
|
|
1541
1561
|
trigger: `${e.objectType}.${e.event}`,
|
|
1542
1562
|
objectType: e.objectType,
|
|
1543
1563
|
event: e.event,
|
|
@@ -1554,14 +1574,14 @@ async function webhooksEventsFlow(context, options, jsonOutput = false) {
|
|
|
1554
1574
|
console.log(JSON.stringify(output, null, 2));
|
|
1555
1575
|
}
|
|
1556
1576
|
else {
|
|
1557
|
-
console.log(
|
|
1577
|
+
console.log('\n' + '='.repeat(60));
|
|
1558
1578
|
console.log(`š” Available Trigger Events for ${sourceName}`);
|
|
1559
|
-
console.log(
|
|
1579
|
+
console.log('='.repeat(60) + '\n');
|
|
1560
1580
|
if (webhookEvents.length === 0) {
|
|
1561
|
-
console.log(
|
|
1581
|
+
console.log('ā¹ļø No trigger events available for this integration.\n');
|
|
1562
1582
|
}
|
|
1563
1583
|
else {
|
|
1564
|
-
webhookEvents.forEach(e => {
|
|
1584
|
+
webhookEvents.forEach((e) => {
|
|
1565
1585
|
console.log(` ${e.objectType}.${e.event} [${e.webhookType}]`);
|
|
1566
1586
|
console.log(` ${e.friendlyDescription}`);
|
|
1567
1587
|
if (e.availableFilters.length > 0) {
|
|
@@ -1569,10 +1589,13 @@ async function webhooksEventsFlow(context, options, jsonOutput = false) {
|
|
|
1569
1589
|
}
|
|
1570
1590
|
console.log();
|
|
1571
1591
|
});
|
|
1572
|
-
console.log(
|
|
1592
|
+
console.log('ā'.repeat(60));
|
|
1573
1593
|
console.log(`Total: ${webhookEvents.length} event(s) available`);
|
|
1574
|
-
console.log(
|
|
1575
|
-
const exampleTriggers = webhookEvents
|
|
1594
|
+
console.log('\nš” Use with --triggers flag:');
|
|
1595
|
+
const exampleTriggers = webhookEvents
|
|
1596
|
+
.slice(0, 2)
|
|
1597
|
+
.map((e) => `${e.objectType}.${e.event}`)
|
|
1598
|
+
.join(',');
|
|
1576
1599
|
console.log(` lua integrations connect --integration <type> --triggers ${exampleTriggers}\n`);
|
|
1577
1600
|
}
|
|
1578
1601
|
}
|
|
@@ -1584,16 +1607,16 @@ async function webhooksEventsFlow(context, options, jsonOutput = false) {
|
|
|
1584
1607
|
else {
|
|
1585
1608
|
writeError(`ā Failed to get trigger events: ${error.message}`);
|
|
1586
1609
|
}
|
|
1587
|
-
throw new Error(
|
|
1610
|
+
throw new Error('Operation failed');
|
|
1588
1611
|
}
|
|
1589
1612
|
}
|
|
1590
1613
|
/**
|
|
1591
1614
|
* Interactive webhooks menu
|
|
1592
1615
|
*/
|
|
1593
1616
|
async function webhooksInteractiveMenu(context) {
|
|
1594
|
-
console.log(
|
|
1595
|
-
console.log(
|
|
1596
|
-
console.log(
|
|
1617
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
1618
|
+
console.log('š Triggers');
|
|
1619
|
+
console.log('ā'.repeat(60) + '\n');
|
|
1597
1620
|
const actionAnswer = await safePrompt([
|
|
1598
1621
|
{
|
|
1599
1622
|
type: 'list',
|
|
@@ -1607,9 +1630,9 @@ async function webhooksInteractiveMenu(context) {
|
|
|
1607
1630
|
{ name: 'āøļø Pause all triggers for a connection', value: 'pauseConn' },
|
|
1608
1631
|
{ name: 'ā¶ļø Resume all triggers for a connection', value: 'resumeConn' },
|
|
1609
1632
|
{ name: 'šļø Delete a trigger', value: 'delete' },
|
|
1610
|
-
{ name: 'ā Back', value: 'back' }
|
|
1611
|
-
]
|
|
1612
|
-
}
|
|
1633
|
+
{ name: 'ā Back', value: 'back' },
|
|
1634
|
+
],
|
|
1635
|
+
},
|
|
1613
1636
|
]);
|
|
1614
1637
|
if (!actionAnswer || actionAnswer.action === 'back')
|
|
1615
1638
|
return;
|
|
@@ -1641,7 +1664,7 @@ async function webhooksInteractiveMenu(context) {
|
|
|
1641
1664
|
* List all webhook subscriptions
|
|
1642
1665
|
*/
|
|
1643
1666
|
async function webhooksListFlow(context, jsonOutput = false) {
|
|
1644
|
-
writeProgress(
|
|
1667
|
+
writeProgress('š Loading triggers...');
|
|
1645
1668
|
try {
|
|
1646
1669
|
const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
|
|
1647
1670
|
if (!result.success) {
|
|
@@ -1657,7 +1680,7 @@ async function webhooksListFlow(context, jsonOutput = false) {
|
|
|
1657
1680
|
if (jsonOutput) {
|
|
1658
1681
|
// Output as JSON for scripting
|
|
1659
1682
|
console.log(JSON.stringify({
|
|
1660
|
-
triggers: webhooks.map(wh => ({
|
|
1683
|
+
triggers: webhooks.map((wh) => ({
|
|
1661
1684
|
id: wh.id,
|
|
1662
1685
|
integrationType: wh.integrationType,
|
|
1663
1686
|
objectType: wh.objectType,
|
|
@@ -1674,13 +1697,13 @@ async function webhooksListFlow(context, jsonOutput = false) {
|
|
|
1674
1697
|
}, null, 2));
|
|
1675
1698
|
return;
|
|
1676
1699
|
}
|
|
1677
|
-
console.log(
|
|
1678
|
-
console.log(
|
|
1679
|
-
console.log(
|
|
1700
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
1701
|
+
console.log('ā” Triggers / Webhook Subscriptions');
|
|
1702
|
+
console.log('ā'.repeat(60) + '\n');
|
|
1680
1703
|
if (webhooks.length === 0) {
|
|
1681
|
-
console.log(
|
|
1682
|
-
console.log(
|
|
1683
|
-
console.log(
|
|
1704
|
+
console.log('ā¹ļø No triggers configured yet.\n');
|
|
1705
|
+
console.log('š” Add triggers when connecting: lua integrations connect');
|
|
1706
|
+
console.log(' Or add one now: lua integrations webhooks create\n');
|
|
1684
1707
|
return;
|
|
1685
1708
|
}
|
|
1686
1709
|
// Group by integration
|
|
@@ -1726,7 +1749,7 @@ async function webhooksListFlow(context, jsonOutput = false) {
|
|
|
1726
1749
|
}
|
|
1727
1750
|
console.log();
|
|
1728
1751
|
}
|
|
1729
|
-
console.log(
|
|
1752
|
+
console.log('ā'.repeat(60));
|
|
1730
1753
|
console.log(`Total: ${webhooks.length} trigger(s)\n`);
|
|
1731
1754
|
}
|
|
1732
1755
|
catch (error) {
|
|
@@ -1742,7 +1765,7 @@ async function webhooksListFlow(context, jsonOutput = false) {
|
|
|
1742
1765
|
* Pause a single webhook subscription (non-interactive)
|
|
1743
1766
|
*/
|
|
1744
1767
|
async function webhooksPauseFlow(context, webhookId, reason) {
|
|
1745
|
-
writeProgress(
|
|
1768
|
+
writeProgress('š Pausing trigger...');
|
|
1746
1769
|
try {
|
|
1747
1770
|
const result = await context.unifiedToApi.pauseWebhookSubscription(context.agentId, webhookId, reason);
|
|
1748
1771
|
if (result.success) {
|
|
@@ -1764,7 +1787,7 @@ async function webhooksPauseFlow(context, webhookId, reason) {
|
|
|
1764
1787
|
* Resume a single webhook subscription (non-interactive)
|
|
1765
1788
|
*/
|
|
1766
1789
|
async function webhooksResumeFlow(context, webhookId) {
|
|
1767
|
-
writeProgress(
|
|
1790
|
+
writeProgress('š Resuming trigger...');
|
|
1768
1791
|
try {
|
|
1769
1792
|
const result = await context.unifiedToApi.resumeWebhookSubscription(context.agentId, webhookId);
|
|
1770
1793
|
if (result.success) {
|
|
@@ -1790,7 +1813,7 @@ async function webhooksResumeFlow(context, webhookId) {
|
|
|
1790
1813
|
* Pause all triggers for a connection (non-interactive)
|
|
1791
1814
|
*/
|
|
1792
1815
|
async function connectionPauseFlow(context, connectionId) {
|
|
1793
|
-
writeProgress(
|
|
1816
|
+
writeProgress('š Pausing all triggers for connection...');
|
|
1794
1817
|
try {
|
|
1795
1818
|
const result = await context.unifiedToApi.pauseConnection(context.agentId, connectionId);
|
|
1796
1819
|
if (result.success && result.data) {
|
|
@@ -1799,7 +1822,11 @@ async function connectionPauseFlow(context, connectionId) {
|
|
|
1799
1822
|
console.log(` ā ļø ${result.data.failedWebhooks} trigger(s) failed to pause at Unified.to ā check logs.\n`);
|
|
1800
1823
|
}
|
|
1801
1824
|
console.log(`\nš” Resume later with: lua integrations webhooks resume --connection-id ${connectionId}\n`);
|
|
1802
|
-
trackEvent('cli_connection_paused', {
|
|
1825
|
+
trackEvent('cli_connection_paused', {
|
|
1826
|
+
connection_id: connectionId,
|
|
1827
|
+
affected: result.data.affectedWebhooks,
|
|
1828
|
+
failed: result.data.failedWebhooks,
|
|
1829
|
+
});
|
|
1803
1830
|
}
|
|
1804
1831
|
else {
|
|
1805
1832
|
writeError(`ā Failed to pause connection triggers: ${result.error?.message}`);
|
|
@@ -1813,7 +1840,7 @@ async function connectionPauseFlow(context, connectionId) {
|
|
|
1813
1840
|
* Resume all triggers for a connection (non-interactive)
|
|
1814
1841
|
*/
|
|
1815
1842
|
async function connectionResumeFlow(context, connectionId) {
|
|
1816
|
-
writeProgress(
|
|
1843
|
+
writeProgress('š Resuming triggers for connection...');
|
|
1817
1844
|
try {
|
|
1818
1845
|
const result = await context.unifiedToApi.resumeConnection(context.agentId, connectionId);
|
|
1819
1846
|
if (result.success && result.data) {
|
|
@@ -1825,7 +1852,12 @@ async function connectionResumeFlow(context, connectionId) {
|
|
|
1825
1852
|
if (result.data.failedWebhooks > 0) {
|
|
1826
1853
|
console.log(` ā ļø ${result.data.failedWebhooks} trigger(s) failed to resume at Unified.to ā check logs.\n`);
|
|
1827
1854
|
}
|
|
1828
|
-
trackEvent('cli_connection_resumed', {
|
|
1855
|
+
trackEvent('cli_connection_resumed', {
|
|
1856
|
+
connection_id: connectionId,
|
|
1857
|
+
affected: result.data.affectedWebhooks,
|
|
1858
|
+
skipped_credit: result.data.skippedCreditSuspended,
|
|
1859
|
+
failed: result.data.failedWebhooks,
|
|
1860
|
+
});
|
|
1829
1861
|
}
|
|
1830
1862
|
else {
|
|
1831
1863
|
writeError(`ā Failed to resume connection triggers: ${result.error?.message}`);
|
|
@@ -1839,16 +1871,16 @@ async function connectionResumeFlow(context, connectionId) {
|
|
|
1839
1871
|
* Interactive: pause a single trigger
|
|
1840
1872
|
*/
|
|
1841
1873
|
async function webhooksPauseInteractive(context) {
|
|
1842
|
-
writeProgress(
|
|
1874
|
+
writeProgress('š Loading triggers...');
|
|
1843
1875
|
try {
|
|
1844
1876
|
const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
|
|
1845
1877
|
if (!result.success) {
|
|
1846
1878
|
writeError(`ā Failed to load triggers: ${result.error?.message}`);
|
|
1847
1879
|
return;
|
|
1848
1880
|
}
|
|
1849
|
-
const webhooks = (result.data || []).filter(wh => !wh.userPaused && wh.status !== 'unhealthy');
|
|
1881
|
+
const webhooks = (result.data || []).filter((wh) => !wh.userPaused && wh.status !== 'unhealthy');
|
|
1850
1882
|
if (webhooks.length === 0) {
|
|
1851
|
-
console.log(
|
|
1883
|
+
console.log('\nā¹ļø No active triggers to pause.\n');
|
|
1852
1884
|
return;
|
|
1853
1885
|
}
|
|
1854
1886
|
const webhookAnswer = await safePrompt([
|
|
@@ -1856,11 +1888,11 @@ async function webhooksPauseInteractive(context) {
|
|
|
1856
1888
|
type: 'list',
|
|
1857
1889
|
name: 'webhook',
|
|
1858
1890
|
message: 'Select a trigger to pause:',
|
|
1859
|
-
choices: webhooks.map(wh => ({
|
|
1891
|
+
choices: webhooks.map((wh) => ({
|
|
1860
1892
|
name: `${wh.integrationType} ā ${wh.objectType}.${wh.event} (${wh.id.substring(0, 8)}...)`,
|
|
1861
1893
|
value: wh.id,
|
|
1862
|
-
}))
|
|
1863
|
-
}
|
|
1894
|
+
})),
|
|
1895
|
+
},
|
|
1864
1896
|
]);
|
|
1865
1897
|
if (!webhookAnswer?.webhook)
|
|
1866
1898
|
return;
|
|
@@ -1870,10 +1902,10 @@ async function webhooksPauseInteractive(context) {
|
|
|
1870
1902
|
name: 'confirm',
|
|
1871
1903
|
message: `Pause this trigger?`,
|
|
1872
1904
|
default: true,
|
|
1873
|
-
}
|
|
1905
|
+
},
|
|
1874
1906
|
]);
|
|
1875
1907
|
if (!confirmAnswer?.confirm) {
|
|
1876
|
-
console.log(
|
|
1908
|
+
console.log('\nā Cancelled.\n');
|
|
1877
1909
|
return;
|
|
1878
1910
|
}
|
|
1879
1911
|
await webhooksPauseFlow(context, webhookAnswer.webhook);
|
|
@@ -1886,16 +1918,16 @@ async function webhooksPauseInteractive(context) {
|
|
|
1886
1918
|
* Interactive: resume a single trigger
|
|
1887
1919
|
*/
|
|
1888
1920
|
async function webhooksResumeInteractive(context) {
|
|
1889
|
-
writeProgress(
|
|
1921
|
+
writeProgress('š Loading triggers...');
|
|
1890
1922
|
try {
|
|
1891
1923
|
const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
|
|
1892
1924
|
if (!result.success) {
|
|
1893
1925
|
writeError(`ā Failed to load triggers: ${result.error?.message}`);
|
|
1894
1926
|
return;
|
|
1895
1927
|
}
|
|
1896
|
-
const webhooks = (result.data || []).filter(wh => wh.userPaused && !wh.creditSuspended);
|
|
1928
|
+
const webhooks = (result.data || []).filter((wh) => wh.userPaused && !wh.creditSuspended);
|
|
1897
1929
|
if (webhooks.length === 0) {
|
|
1898
|
-
console.log(
|
|
1930
|
+
console.log('\nā¹ļø No user-paused triggers to resume.\n');
|
|
1899
1931
|
return;
|
|
1900
1932
|
}
|
|
1901
1933
|
const webhookAnswer = await safePrompt([
|
|
@@ -1903,11 +1935,11 @@ async function webhooksResumeInteractive(context) {
|
|
|
1903
1935
|
type: 'list',
|
|
1904
1936
|
name: 'webhook',
|
|
1905
1937
|
message: 'Select a trigger to resume:',
|
|
1906
|
-
choices: webhooks.map(wh => ({
|
|
1938
|
+
choices: webhooks.map((wh) => ({
|
|
1907
1939
|
name: `${wh.integrationType} ā ${wh.objectType}.${wh.event} (${wh.id.substring(0, 8)}...)`,
|
|
1908
1940
|
value: wh.id,
|
|
1909
|
-
}))
|
|
1910
|
-
}
|
|
1941
|
+
})),
|
|
1942
|
+
},
|
|
1911
1943
|
]);
|
|
1912
1944
|
if (!webhookAnswer?.webhook)
|
|
1913
1945
|
return;
|
|
@@ -1925,7 +1957,7 @@ async function connectionPauseInteractive(context) {
|
|
|
1925
1957
|
const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
|
|
1926
1958
|
const connections = connectionsResult.success ? connectionsResult.data || [] : [];
|
|
1927
1959
|
if (connections.length === 0) {
|
|
1928
|
-
console.log(
|
|
1960
|
+
console.log('\nā¹ļø No connected integrations.\n');
|
|
1929
1961
|
return;
|
|
1930
1962
|
}
|
|
1931
1963
|
const connectionAnswer = await safePrompt([
|
|
@@ -1933,11 +1965,11 @@ async function connectionPauseInteractive(context) {
|
|
|
1933
1965
|
type: 'list',
|
|
1934
1966
|
name: 'connection',
|
|
1935
1967
|
message: 'Select a connection to pause all triggers:',
|
|
1936
|
-
choices: connections.map(c => ({
|
|
1968
|
+
choices: connections.map((c) => ({
|
|
1937
1969
|
name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)${c.allTriggersPaused ? ' [all triggers paused]' : ''}`,
|
|
1938
1970
|
value: c.id,
|
|
1939
|
-
}))
|
|
1940
|
-
}
|
|
1971
|
+
})),
|
|
1972
|
+
},
|
|
1941
1973
|
]);
|
|
1942
1974
|
if (!connectionAnswer?.connection)
|
|
1943
1975
|
return;
|
|
@@ -1947,10 +1979,10 @@ async function connectionPauseInteractive(context) {
|
|
|
1947
1979
|
name: 'confirm',
|
|
1948
1980
|
message: `Pause all triggers for this connection?`,
|
|
1949
1981
|
default: true,
|
|
1950
|
-
}
|
|
1982
|
+
},
|
|
1951
1983
|
]);
|
|
1952
1984
|
if (!confirmAnswer?.confirm) {
|
|
1953
|
-
console.log(
|
|
1985
|
+
console.log('\nā Cancelled.\n');
|
|
1954
1986
|
return;
|
|
1955
1987
|
}
|
|
1956
1988
|
await connectionPauseFlow(context, connectionAnswer.connection);
|
|
@@ -1967,7 +1999,7 @@ async function connectionResumeInteractive(context) {
|
|
|
1967
1999
|
const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
|
|
1968
2000
|
const connections = connectionsResult.success ? connectionsResult.data || [] : [];
|
|
1969
2001
|
if (connections.length === 0) {
|
|
1970
|
-
console.log(
|
|
2002
|
+
console.log('\nā¹ļø No connected integrations.\n');
|
|
1971
2003
|
return;
|
|
1972
2004
|
}
|
|
1973
2005
|
const connectionAnswer = await safePrompt([
|
|
@@ -1975,11 +2007,11 @@ async function connectionResumeInteractive(context) {
|
|
|
1975
2007
|
type: 'list',
|
|
1976
2008
|
name: 'connection',
|
|
1977
2009
|
message: 'Select a connection to resume triggers:',
|
|
1978
|
-
choices: connections.map(c => ({
|
|
2010
|
+
choices: connections.map((c) => ({
|
|
1979
2011
|
name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
|
|
1980
2012
|
value: c.id,
|
|
1981
|
-
}))
|
|
1982
|
-
}
|
|
2013
|
+
})),
|
|
2014
|
+
},
|
|
1983
2015
|
]);
|
|
1984
2016
|
if (!connectionAnswer?.connection)
|
|
1985
2017
|
return;
|
|
@@ -1994,7 +2026,7 @@ async function connectionResumeInteractive(context) {
|
|
|
1994
2026
|
*/
|
|
1995
2027
|
async function webhooksCreateFlow(context, options) {
|
|
1996
2028
|
// Step 1: Fetch connections
|
|
1997
|
-
writeProgress(
|
|
2029
|
+
writeProgress('š Loading connections...');
|
|
1998
2030
|
let connections = [];
|
|
1999
2031
|
try {
|
|
2000
2032
|
const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
|
|
@@ -2009,19 +2041,19 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2009
2041
|
return;
|
|
2010
2042
|
}
|
|
2011
2043
|
if (connections.length === 0) {
|
|
2012
|
-
writeInfo(
|
|
2044
|
+
writeInfo('No connections available.');
|
|
2013
2045
|
console.log("š” Run 'lua integrations connect' to connect an integration first.\n");
|
|
2014
2046
|
return;
|
|
2015
2047
|
}
|
|
2016
2048
|
// Step 2: Select connection
|
|
2017
2049
|
let selectedConnection;
|
|
2018
2050
|
if (options.connectionId) {
|
|
2019
|
-
selectedConnection = connections.find(c => c.id === options.connectionId);
|
|
2051
|
+
selectedConnection = connections.find((c) => c.id === options.connectionId);
|
|
2020
2052
|
if (!selectedConnection) {
|
|
2021
2053
|
console.error(`ā Connection "${options.connectionId}" not found.`);
|
|
2022
2054
|
console.log('\nAvailable connections:');
|
|
2023
|
-
connections.forEach(c => console.log(` - ${c.id} (${c.integrationName || c.integrationType})`));
|
|
2024
|
-
throw new Error(
|
|
2055
|
+
connections.forEach((c) => console.log(` - ${c.id} (${c.integrationName || c.integrationType})`));
|
|
2056
|
+
throw new Error('Connection');
|
|
2025
2057
|
}
|
|
2026
2058
|
}
|
|
2027
2059
|
else {
|
|
@@ -2030,18 +2062,18 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2030
2062
|
type: 'list',
|
|
2031
2063
|
name: 'connection',
|
|
2032
2064
|
message: 'Select a connection:',
|
|
2033
|
-
choices: connections.map(c => ({
|
|
2065
|
+
choices: connections.map((c) => ({
|
|
2034
2066
|
name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
|
|
2035
|
-
value: c
|
|
2036
|
-
}))
|
|
2037
|
-
}
|
|
2067
|
+
value: c,
|
|
2068
|
+
})),
|
|
2069
|
+
},
|
|
2038
2070
|
]);
|
|
2039
2071
|
if (!connectionAnswer)
|
|
2040
2072
|
return;
|
|
2041
2073
|
selectedConnection = connectionAnswer.connection;
|
|
2042
2074
|
}
|
|
2043
2075
|
// Step 3: Get available events for this connection
|
|
2044
|
-
writeProgress(
|
|
2076
|
+
writeProgress('š Loading available events...');
|
|
2045
2077
|
let availableEvents = [];
|
|
2046
2078
|
try {
|
|
2047
2079
|
const eventsResult = await context.unifiedToApi.getAvailableWebhookEvents(context.agentId, selectedConnection.id);
|
|
@@ -2057,18 +2089,18 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2057
2089
|
}
|
|
2058
2090
|
if (availableEvents.length === 0) {
|
|
2059
2091
|
writeInfo(`No trigger events available for ${selectedConnection.integrationName || selectedConnection.integrationType}.`);
|
|
2060
|
-
console.log(
|
|
2092
|
+
console.log('š” This integration may not support triggers.\n');
|
|
2061
2093
|
return;
|
|
2062
2094
|
}
|
|
2063
2095
|
// Step 4: Select event
|
|
2064
2096
|
let selectedEvent;
|
|
2065
2097
|
if (options.objectType && options.event) {
|
|
2066
|
-
selectedEvent = availableEvents.find(e => e.objectType === options.objectType && e.event === options.event);
|
|
2098
|
+
selectedEvent = availableEvents.find((e) => e.objectType === options.objectType && e.event === options.event);
|
|
2067
2099
|
if (!selectedEvent) {
|
|
2068
2100
|
console.error(`ā Event '${options.objectType}.${options.event}' is not supported.`);
|
|
2069
2101
|
console.log(`\nAvailable events for ${selectedConnection.integrationName || selectedConnection.integrationType}:`);
|
|
2070
|
-
availableEvents.forEach(e => console.log(` - ${e.objectType}.${e.event} [${e.webhookType}]`));
|
|
2071
|
-
throw new Error(
|
|
2102
|
+
availableEvents.forEach((e) => console.log(` - ${e.objectType}.${e.event} [${e.webhookType}]`));
|
|
2103
|
+
throw new Error('Event');
|
|
2072
2104
|
}
|
|
2073
2105
|
}
|
|
2074
2106
|
else {
|
|
@@ -2079,11 +2111,11 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2079
2111
|
name: 'event',
|
|
2080
2112
|
message: 'Select an event to subscribe to:',
|
|
2081
2113
|
pageSize: 15,
|
|
2082
|
-
choices: availableEvents.map(e => ({
|
|
2114
|
+
choices: availableEvents.map((e) => ({
|
|
2083
2115
|
name: `${e.objectTypeDisplay} - ${e.event.charAt(0).toUpperCase() + e.event.slice(1)} [${e.webhookType}]`,
|
|
2084
|
-
value: e
|
|
2085
|
-
}))
|
|
2086
|
-
}
|
|
2116
|
+
value: e,
|
|
2117
|
+
})),
|
|
2118
|
+
},
|
|
2087
2119
|
]);
|
|
2088
2120
|
if (!eventAnswer)
|
|
2089
2121
|
return;
|
|
@@ -2112,7 +2144,7 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2112
2144
|
},
|
|
2113
2145
|
],
|
|
2114
2146
|
default: 'agent',
|
|
2115
|
-
}
|
|
2147
|
+
},
|
|
2116
2148
|
]);
|
|
2117
2149
|
if (!urlModeAnswer)
|
|
2118
2150
|
return;
|
|
@@ -2135,8 +2167,8 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2135
2167
|
catch {
|
|
2136
2168
|
return 'Enter a valid URL (e.g., https://webhook.heylua.ai/myagent/handler)';
|
|
2137
2169
|
}
|
|
2138
|
-
}
|
|
2139
|
-
}
|
|
2170
|
+
},
|
|
2171
|
+
},
|
|
2140
2172
|
]);
|
|
2141
2173
|
if (!webhookAnswer)
|
|
2142
2174
|
return;
|
|
@@ -2171,7 +2203,7 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2171
2203
|
message: 'Select polling interval:',
|
|
2172
2204
|
choices: intervalOptions,
|
|
2173
2205
|
default: 1,
|
|
2174
|
-
}
|
|
2206
|
+
},
|
|
2175
2207
|
]);
|
|
2176
2208
|
if (!intervalAnswer)
|
|
2177
2209
|
return;
|
|
@@ -2180,35 +2212,35 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2180
2212
|
}
|
|
2181
2213
|
// Helper to format interval display
|
|
2182
2214
|
const formatInterval = (minutes) => {
|
|
2183
|
-
const option = intervalOptions.find(o => o.value === minutes);
|
|
2215
|
+
const option = intervalOptions.find((o) => o.value === minutes);
|
|
2184
2216
|
return option ? option.name : `${minutes} minutes`;
|
|
2185
2217
|
};
|
|
2186
2218
|
// Step 7: Confirmation (interactive only)
|
|
2187
2219
|
if (!options.connectionId) {
|
|
2188
|
-
console.log(
|
|
2189
|
-
console.log(
|
|
2190
|
-
console.log(
|
|
2220
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
2221
|
+
console.log('š Trigger Summary');
|
|
2222
|
+
console.log('ā'.repeat(60));
|
|
2191
2223
|
console.log(` Connection: ${selectedConnection.integrationName || selectedConnection.integrationType}`);
|
|
2192
2224
|
console.log(` Event: ${selectedEvent.objectType}.${selectedEvent.event} [${selectedEvent.webhookType}]`);
|
|
2193
2225
|
console.log(` Webhook URL: ${hookUrl}`);
|
|
2194
2226
|
if (interval)
|
|
2195
2227
|
console.log(` Interval: ${formatInterval(interval)}`);
|
|
2196
|
-
console.log(
|
|
2228
|
+
console.log('ā'.repeat(60) + '\n');
|
|
2197
2229
|
const confirmAnswer = await safePrompt([
|
|
2198
2230
|
{
|
|
2199
2231
|
type: 'confirm',
|
|
2200
2232
|
name: 'confirm',
|
|
2201
2233
|
message: 'Create this trigger?',
|
|
2202
|
-
default: true
|
|
2203
|
-
}
|
|
2234
|
+
default: true,
|
|
2235
|
+
},
|
|
2204
2236
|
]);
|
|
2205
2237
|
if (!confirmAnswer?.confirm) {
|
|
2206
|
-
console.log(
|
|
2238
|
+
console.log('\nā Cancelled.\n');
|
|
2207
2239
|
return;
|
|
2208
2240
|
}
|
|
2209
2241
|
}
|
|
2210
2242
|
// Step 8: Create the webhook
|
|
2211
|
-
writeProgress(
|
|
2243
|
+
writeProgress('š Creating trigger...');
|
|
2212
2244
|
try {
|
|
2213
2245
|
const createResult = await context.unifiedToApi.createWebhookSubscription(context.agentId, {
|
|
2214
2246
|
connectionId: selectedConnection.id,
|
|
@@ -2224,9 +2256,9 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2224
2256
|
const webhook = createResult.data;
|
|
2225
2257
|
const isAgentTrigger = webhook.hookUrl.includes('webhook/unifiedto');
|
|
2226
2258
|
const typeLabel = webhook.webhookType === 'native' ? 'push' : 'polling';
|
|
2227
|
-
console.log(
|
|
2228
|
-
writeSuccess(
|
|
2229
|
-
console.log(
|
|
2259
|
+
console.log('\n' + 'ā'.repeat(60));
|
|
2260
|
+
writeSuccess('ā
Trigger created!');
|
|
2261
|
+
console.log('ā'.repeat(60));
|
|
2230
2262
|
console.log(` Integration: ${webhook.integrationType}`);
|
|
2231
2263
|
console.log(` Event: ${webhook.objectType}.${webhook.event}`);
|
|
2232
2264
|
console.log(` Type: ${typeLabel}`);
|
|
@@ -2237,12 +2269,12 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2237
2269
|
if (webhook.interval)
|
|
2238
2270
|
console.log(` Poll interval: ${formatInterval(webhook.interval)}`);
|
|
2239
2271
|
console.log(` Status: ${webhook.status}`);
|
|
2240
|
-
console.log(
|
|
2272
|
+
console.log('ā'.repeat(60) + '\n');
|
|
2241
2273
|
if (isAgentTrigger) {
|
|
2242
|
-
console.log(
|
|
2274
|
+
console.log('š” Your agent will now wake up when this event occurs.\n');
|
|
2243
2275
|
}
|
|
2244
2276
|
else {
|
|
2245
|
-
console.log(
|
|
2277
|
+
console.log('š” Ensure your webhook endpoint is ready to receive events.\n');
|
|
2246
2278
|
}
|
|
2247
2279
|
}
|
|
2248
2280
|
catch (error) {
|
|
@@ -2253,7 +2285,7 @@ async function webhooksCreateFlow(context, options) {
|
|
|
2253
2285
|
* Delete a webhook subscription (interactive)
|
|
2254
2286
|
*/
|
|
2255
2287
|
async function webhooksDeleteInteractive(context) {
|
|
2256
|
-
writeProgress(
|
|
2288
|
+
writeProgress('š Loading triggers...');
|
|
2257
2289
|
try {
|
|
2258
2290
|
const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
|
|
2259
2291
|
if (!result.success) {
|
|
@@ -2262,7 +2294,7 @@ async function webhooksDeleteInteractive(context) {
|
|
|
2262
2294
|
}
|
|
2263
2295
|
const webhooks = result.data || [];
|
|
2264
2296
|
if (webhooks.length === 0) {
|
|
2265
|
-
console.log(
|
|
2297
|
+
console.log('\nā¹ļø No triggers to delete.\n');
|
|
2266
2298
|
return;
|
|
2267
2299
|
}
|
|
2268
2300
|
const webhookAnswer = await safePrompt([
|
|
@@ -2270,30 +2302,30 @@ async function webhooksDeleteInteractive(context) {
|
|
|
2270
2302
|
type: 'list',
|
|
2271
2303
|
name: 'webhook',
|
|
2272
2304
|
message: 'Select a trigger to delete:',
|
|
2273
|
-
choices: webhooks.map(wh => {
|
|
2305
|
+
choices: webhooks.map((wh) => {
|
|
2274
2306
|
// Show last part of URL for readability
|
|
2275
2307
|
const urlParts = (wh.hookUrl || '').split('/');
|
|
2276
2308
|
const shortUrl = urlParts.length > 3 ? '.../' + urlParts.slice(-2).join('/') : wh.hookUrl || '';
|
|
2277
2309
|
return {
|
|
2278
2310
|
name: `${wh.id.substring(0, 8)}... - ${wh.integrationType} ${wh.objectType}.${wh.event} ā ${shortUrl}`,
|
|
2279
|
-
value: wh.id
|
|
2311
|
+
value: wh.id,
|
|
2280
2312
|
};
|
|
2281
|
-
})
|
|
2282
|
-
}
|
|
2313
|
+
}),
|
|
2314
|
+
},
|
|
2283
2315
|
]);
|
|
2284
2316
|
if (!webhookAnswer?.webhook)
|
|
2285
2317
|
return;
|
|
2286
|
-
const selectedWebhook = webhooks.find(wh => wh.id === webhookAnswer.webhook);
|
|
2318
|
+
const selectedWebhook = webhooks.find((wh) => wh.id === webhookAnswer.webhook);
|
|
2287
2319
|
const confirmAnswer = await safePrompt([
|
|
2288
2320
|
{
|
|
2289
2321
|
type: 'confirm',
|
|
2290
2322
|
name: 'confirm',
|
|
2291
2323
|
message: `Delete trigger for ${selectedWebhook?.objectType}.${selectedWebhook?.event}?`,
|
|
2292
|
-
default: false
|
|
2293
|
-
}
|
|
2324
|
+
default: false,
|
|
2325
|
+
},
|
|
2294
2326
|
]);
|
|
2295
2327
|
if (!confirmAnswer?.confirm) {
|
|
2296
|
-
console.log(
|
|
2328
|
+
console.log('\nā Cancelled.\n');
|
|
2297
2329
|
return;
|
|
2298
2330
|
}
|
|
2299
2331
|
await webhooksDeleteFlow(context, webhookAnswer.webhook);
|
|
@@ -2306,7 +2338,7 @@ async function webhooksDeleteInteractive(context) {
|
|
|
2306
2338
|
* Delete a webhook subscription (non-interactive)
|
|
2307
2339
|
*/
|
|
2308
2340
|
async function webhooksDeleteFlow(context, webhookId) {
|
|
2309
|
-
writeProgress(
|
|
2341
|
+
writeProgress('š Deleting trigger...');
|
|
2310
2342
|
try {
|
|
2311
2343
|
const result = await context.unifiedToApi.deleteWebhookSubscription(context.agentId, webhookId);
|
|
2312
2344
|
if (result.success) {
|
|
@@ -2344,7 +2376,7 @@ async function mcpManagementFlow(context, options, subAction) {
|
|
|
2344
2376
|
}
|
|
2345
2377
|
if (subAction === 'activate') {
|
|
2346
2378
|
if (!options.connectionId) {
|
|
2347
|
-
writeError(
|
|
2379
|
+
writeError('ā Missing required option: --connection <id>');
|
|
2348
2380
|
console.log("\nš” Use 'lua integrations mcp list' to see available connection IDs.\n");
|
|
2349
2381
|
return;
|
|
2350
2382
|
}
|
|
@@ -2353,7 +2385,7 @@ async function mcpManagementFlow(context, options, subAction) {
|
|
|
2353
2385
|
}
|
|
2354
2386
|
if (subAction === 'deactivate') {
|
|
2355
2387
|
if (!options.connectionId) {
|
|
2356
|
-
writeError(
|
|
2388
|
+
writeError('ā Missing required option: --connection <id>');
|
|
2357
2389
|
console.log("\nš” Use 'lua integrations mcp list' to see available connection IDs.\n");
|
|
2358
2390
|
return;
|
|
2359
2391
|
}
|
|
@@ -2370,9 +2402,9 @@ async function mcpManagementFlow(context, options, subAction) {
|
|
|
2370
2402
|
{ name: 'š List connections with MCP status', value: 'list' },
|
|
2371
2403
|
{ name: 'ā
Activate MCP server for a connection', value: 'activate' },
|
|
2372
2404
|
{ name: 'āøļø Deactivate MCP server for a connection', value: 'deactivate' },
|
|
2373
|
-
{ name: 'ā Back', value: 'back' }
|
|
2374
|
-
]
|
|
2375
|
-
}
|
|
2405
|
+
{ name: 'ā Back', value: 'back' },
|
|
2406
|
+
],
|
|
2407
|
+
},
|
|
2376
2408
|
]);
|
|
2377
2409
|
if (!actionAnswer || actionAnswer.action === 'back')
|
|
2378
2410
|
return;
|
|
@@ -2392,11 +2424,11 @@ async function mcpManagementFlow(context, options, subAction) {
|
|
|
2392
2424
|
* List all connections with their MCP server status
|
|
2393
2425
|
*/
|
|
2394
2426
|
async function mcpListFlow(context) {
|
|
2395
|
-
writeProgress(
|
|
2427
|
+
writeProgress('š Loading connections and MCP servers...');
|
|
2396
2428
|
try {
|
|
2397
2429
|
const [connectionsResult, mcpServers] = await Promise.all([
|
|
2398
2430
|
context.unifiedToApi.getConnections(context.agentId),
|
|
2399
|
-
fetchServersCore(context)
|
|
2431
|
+
fetchServersCore(context),
|
|
2400
2432
|
]);
|
|
2401
2433
|
if (!connectionsResult.success) {
|
|
2402
2434
|
writeError(`ā Failed to load connections: ${connectionsResult.error?.message}`);
|
|
@@ -2405,7 +2437,7 @@ async function mcpListFlow(context) {
|
|
|
2405
2437
|
if (!mcpServers)
|
|
2406
2438
|
return;
|
|
2407
2439
|
const connections = connectionsResult.data || [];
|
|
2408
|
-
const unifiedServers = mcpServers.filter(s => s.source === 'unifiedto');
|
|
2440
|
+
const unifiedServers = mcpServers.filter((s) => s.source === 'unifiedto');
|
|
2409
2441
|
// Map connection IDs to MCP servers
|
|
2410
2442
|
const serverByConnectionId = new Map();
|
|
2411
2443
|
for (const server of unifiedServers) {
|
|
@@ -2414,12 +2446,12 @@ async function mcpListFlow(context) {
|
|
|
2414
2446
|
serverByConnectionId.set(connectionMatch[1], server);
|
|
2415
2447
|
}
|
|
2416
2448
|
}
|
|
2417
|
-
console.log(
|
|
2418
|
-
console.log(
|
|
2419
|
-
console.log(
|
|
2449
|
+
console.log('\n' + 'ā'.repeat(80));
|
|
2450
|
+
console.log('š MCP Servers for Connections');
|
|
2451
|
+
console.log('ā'.repeat(80) + '\n');
|
|
2420
2452
|
if (connections.length === 0) {
|
|
2421
|
-
console.log(
|
|
2422
|
-
console.log(
|
|
2453
|
+
console.log('ā¹ļø No connections found.\n');
|
|
2454
|
+
console.log('š” Connect an integration with: lua integrations connect\n');
|
|
2423
2455
|
return;
|
|
2424
2456
|
}
|
|
2425
2457
|
for (const conn of connections) {
|
|
@@ -2430,7 +2462,7 @@ async function mcpListFlow(context) {
|
|
|
2430
2462
|
console.log(` Integration: ${conn.integrationName || conn.integrationType}`);
|
|
2431
2463
|
console.log(` MCP Server: ${serverName}`);
|
|
2432
2464
|
console.log(` Status: ${status}`);
|
|
2433
|
-
console.log(
|
|
2465
|
+
console.log('ā'.repeat(80));
|
|
2434
2466
|
}
|
|
2435
2467
|
console.log(`\nTotal: ${connections.length} connection(s)`);
|
|
2436
2468
|
console.log("\nš” Use --connection <id> with 'activate' or 'deactivate' commands.\n");
|
|
@@ -2443,12 +2475,12 @@ async function mcpListFlow(context) {
|
|
|
2443
2475
|
* Activate MCP server for a connection (non-interactive)
|
|
2444
2476
|
*/
|
|
2445
2477
|
async function mcpActivateFlow(context, connectionId) {
|
|
2446
|
-
writeProgress(
|
|
2478
|
+
writeProgress('š Finding MCP server for connection...');
|
|
2447
2479
|
try {
|
|
2448
2480
|
const mcpServers = await fetchServersCore(context);
|
|
2449
2481
|
if (!mcpServers)
|
|
2450
2482
|
return;
|
|
2451
|
-
const mcpServer = mcpServers.find(s => s.source === 'unifiedto' && s.url?.includes(`connection=${connectionId}`));
|
|
2483
|
+
const mcpServer = mcpServers.find((s) => s.source === 'unifiedto' && s.url?.includes(`connection=${connectionId}`));
|
|
2452
2484
|
if (!mcpServer) {
|
|
2453
2485
|
writeError(`ā No MCP server found for connection: ${connectionId}`);
|
|
2454
2486
|
console.log("\nš” Make sure the connection exists. Use 'lua integrations list' to check.\n");
|
|
@@ -2464,12 +2496,12 @@ async function mcpActivateFlow(context, connectionId) {
|
|
|
2464
2496
|
* Deactivate MCP server for a connection (non-interactive)
|
|
2465
2497
|
*/
|
|
2466
2498
|
async function mcpDeactivateFlow(context, connectionId) {
|
|
2467
|
-
writeProgress(
|
|
2499
|
+
writeProgress('š Finding MCP server for connection...');
|
|
2468
2500
|
try {
|
|
2469
2501
|
const mcpServers = await fetchServersCore(context);
|
|
2470
2502
|
if (!mcpServers)
|
|
2471
2503
|
return;
|
|
2472
|
-
const mcpServer = mcpServers.find(s => s.source === 'unifiedto' && s.url?.includes(`connection=${connectionId}`));
|
|
2504
|
+
const mcpServer = mcpServers.find((s) => s.source === 'unifiedto' && s.url?.includes(`connection=${connectionId}`));
|
|
2473
2505
|
if (!mcpServer) {
|
|
2474
2506
|
writeError(`ā No MCP server found for connection: ${connectionId}`);
|
|
2475
2507
|
console.log("\nš” Make sure the connection exists. Use 'lua integrations list' to check.\n");
|
|
@@ -2485,11 +2517,11 @@ async function mcpDeactivateFlow(context, connectionId) {
|
|
|
2485
2517
|
* Interactive flow for activating MCP server
|
|
2486
2518
|
*/
|
|
2487
2519
|
async function mcpActivateInteractive(context) {
|
|
2488
|
-
writeProgress(
|
|
2520
|
+
writeProgress('š Loading connections...');
|
|
2489
2521
|
try {
|
|
2490
2522
|
const [connectionsResult, mcpServers] = await Promise.all([
|
|
2491
2523
|
context.unifiedToApi.getConnections(context.agentId),
|
|
2492
|
-
fetchServersCore(context)
|
|
2524
|
+
fetchServersCore(context),
|
|
2493
2525
|
]);
|
|
2494
2526
|
if (!connectionsResult.success) {
|
|
2495
2527
|
writeError(`ā Failed to load connections: ${connectionsResult.error?.message}`);
|
|
@@ -2509,12 +2541,12 @@ async function mcpActivateInteractive(context) {
|
|
|
2509
2541
|
}
|
|
2510
2542
|
}
|
|
2511
2543
|
// Filter to show only inactive MCP servers
|
|
2512
|
-
const inactiveConnections = connections.filter(conn => {
|
|
2544
|
+
const inactiveConnections = connections.filter((conn) => {
|
|
2513
2545
|
const server = serverByConnectionId.get(conn.id);
|
|
2514
2546
|
return server && !server.active;
|
|
2515
2547
|
});
|
|
2516
2548
|
if (inactiveConnections.length === 0) {
|
|
2517
|
-
writeInfo(
|
|
2549
|
+
writeInfo('ā¹ļø All MCP servers are already active (or no connections found).\n');
|
|
2518
2550
|
return;
|
|
2519
2551
|
}
|
|
2520
2552
|
const connectionAnswer = await safePrompt([
|
|
@@ -2522,11 +2554,11 @@ async function mcpActivateInteractive(context) {
|
|
|
2522
2554
|
type: 'list',
|
|
2523
2555
|
name: 'connectionId',
|
|
2524
2556
|
message: 'Select a connection to activate MCP:',
|
|
2525
|
-
choices: inactiveConnections.map(conn => ({
|
|
2557
|
+
choices: inactiveConnections.map((conn) => ({
|
|
2526
2558
|
name: `${conn.integrationName || conn.integrationType} (${conn.id.substring(0, 12)}...)`,
|
|
2527
|
-
value: conn.id
|
|
2528
|
-
}))
|
|
2529
|
-
}
|
|
2559
|
+
value: conn.id,
|
|
2560
|
+
})),
|
|
2561
|
+
},
|
|
2530
2562
|
]);
|
|
2531
2563
|
if (!connectionAnswer)
|
|
2532
2564
|
return;
|
|
@@ -2540,11 +2572,11 @@ async function mcpActivateInteractive(context) {
|
|
|
2540
2572
|
* Interactive flow for deactivating MCP server
|
|
2541
2573
|
*/
|
|
2542
2574
|
async function mcpDeactivateInteractive(context) {
|
|
2543
|
-
writeProgress(
|
|
2575
|
+
writeProgress('š Loading connections...');
|
|
2544
2576
|
try {
|
|
2545
2577
|
const [connectionsResult, mcpServers] = await Promise.all([
|
|
2546
2578
|
context.unifiedToApi.getConnections(context.agentId),
|
|
2547
|
-
fetchServersCore(context)
|
|
2579
|
+
fetchServersCore(context),
|
|
2548
2580
|
]);
|
|
2549
2581
|
if (!connectionsResult.success) {
|
|
2550
2582
|
writeError(`ā Failed to load connections: ${connectionsResult.error?.message}`);
|
|
@@ -2564,12 +2596,12 @@ async function mcpDeactivateInteractive(context) {
|
|
|
2564
2596
|
}
|
|
2565
2597
|
}
|
|
2566
2598
|
// Filter to show only active MCP servers
|
|
2567
|
-
const activeConnections = connections.filter(conn => {
|
|
2599
|
+
const activeConnections = connections.filter((conn) => {
|
|
2568
2600
|
const server = serverByConnectionId.get(conn.id);
|
|
2569
2601
|
return server && server.active;
|
|
2570
2602
|
});
|
|
2571
2603
|
if (activeConnections.length === 0) {
|
|
2572
|
-
writeInfo(
|
|
2604
|
+
writeInfo('ā¹ļø No active MCP servers found to deactivate.\n');
|
|
2573
2605
|
return;
|
|
2574
2606
|
}
|
|
2575
2607
|
const connectionAnswer = await safePrompt([
|
|
@@ -2577,11 +2609,11 @@ async function mcpDeactivateInteractive(context) {
|
|
|
2577
2609
|
type: 'list',
|
|
2578
2610
|
name: 'connectionId',
|
|
2579
2611
|
message: 'Select a connection to deactivate MCP:',
|
|
2580
|
-
choices: activeConnections.map(conn => ({
|
|
2612
|
+
choices: activeConnections.map((conn) => ({
|
|
2581
2613
|
name: `${conn.integrationName || conn.integrationType} (${conn.id.substring(0, 12)}...)`,
|
|
2582
|
-
value: conn.id
|
|
2583
|
-
}))
|
|
2584
|
-
}
|
|
2614
|
+
value: conn.id,
|
|
2615
|
+
})),
|
|
2616
|
+
},
|
|
2585
2617
|
]);
|
|
2586
2618
|
if (!connectionAnswer)
|
|
2587
2619
|
return;
|