lua-cli 3.11.0 → 3.12.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 +12 -0
- package/dist/api/unifiedto.api.service.d.ts +18 -1
- package/dist/api/unifiedto.api.service.d.ts.map +1 -1
- package/dist/api/unifiedto.api.service.js +26 -0
- package/dist/api/unifiedto.api.service.js.map +1 -1
- package/dist/cli/command-definitions.d.ts.map +1 -1
- package/dist/cli/command-definitions.js +43 -2
- package/dist/cli/command-definitions.js.map +1 -1
- package/dist/commands/integrations.d.ts.map +1 -1
- package/dist/commands/integrations.js +456 -80
- package/dist/commands/integrations.js.map +1 -1
- package/dist/commands/push.js +18 -24
- package/dist/commands/push.js.map +1 -1
- package/dist/compiler/compiler.d.ts.map +1 -1
- package/dist/compiler/compiler.js +13 -0
- package/dist/compiler/compiler.js.map +1 -1
- package/dist/compiler/plugins/base.d.ts +28 -0
- package/dist/compiler/plugins/base.d.ts.map +1 -1
- package/dist/compiler/plugins/base.js.map +1 -1
- package/dist/compiler/plugins/skill.plugin.d.ts +7 -3
- package/dist/compiler/plugins/skill.plugin.d.ts.map +1 -1
- package/dist/compiler/plugins/skill.plugin.js +22 -4
- package/dist/compiler/plugins/skill.plugin.js.map +1 -1
- package/dist/interfaces/unifiedto.d.ts +19 -0
- package/dist/interfaces/unifiedto.d.ts.map +1 -1
- package/dist/primitives/base.handler.d.ts +76 -3
- package/dist/primitives/base.handler.d.ts.map +1 -1
- package/dist/primitives/base.handler.js +99 -8
- package/dist/primitives/base.handler.js.map +1 -1
- package/dist/primitives/mcp-server.handler.d.ts +46 -22
- package/dist/primitives/mcp-server.handler.d.ts.map +1 -1
- package/dist/primitives/mcp-server.handler.js +52 -21
- package/dist/primitives/mcp-server.handler.js.map +1 -1
- package/docs/README.md +1 -1
- package/package.json +1 -1
- package/template/package.json +1 -1
|
@@ -759,69 +759,83 @@ async function connectIntegrationFlow(context, options = {}) {
|
|
|
759
759
|
}
|
|
760
760
|
}
|
|
761
761
|
else {
|
|
762
|
-
// Interactive:
|
|
762
|
+
// Interactive: opt-in gate — ask before showing trigger selector
|
|
763
763
|
console.log('\n' + '─'.repeat(60));
|
|
764
|
-
console.log('📡 Webhook Triggers');
|
|
764
|
+
console.log('📡 Webhook Triggers (Optional)');
|
|
765
765
|
console.log('─'.repeat(60));
|
|
766
|
-
console.log('\
|
|
767
|
-
console.log('
|
|
768
|
-
const
|
|
769
|
-
type: '
|
|
770
|
-
name: '
|
|
771
|
-
message: '
|
|
772
|
-
|
|
773
|
-
loop: false,
|
|
774
|
-
choices: availableEvents.map(e => ({
|
|
775
|
-
name: `${e.friendlyDescription} [${e.webhookType}]`,
|
|
776
|
-
value: e,
|
|
777
|
-
checked: true // Pre-select all by default
|
|
778
|
-
}))
|
|
766
|
+
console.log('\nTriggers wake your agent when something happens in the integration.');
|
|
767
|
+
console.log('We recommend adding only what you actually need — you can always add them later.');
|
|
768
|
+
const wantTriggersAnswer = await safePrompt([{
|
|
769
|
+
type: 'confirm',
|
|
770
|
+
name: 'want',
|
|
771
|
+
message: 'Do you want to configure triggers now?',
|
|
772
|
+
default: false,
|
|
779
773
|
}]);
|
|
780
|
-
if (
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
774
|
+
if (!wantTriggersAnswer)
|
|
775
|
+
return;
|
|
776
|
+
if (wantTriggersAnswer.want) {
|
|
777
|
+
console.log('\nSelect the events you actually need:');
|
|
778
|
+
console.log('(Space to toggle, Enter to confirm. Nothing pre-selected.)');
|
|
779
|
+
const triggerAnswer = await safePrompt([{
|
|
780
|
+
type: 'checkbox',
|
|
781
|
+
name: 'triggers',
|
|
782
|
+
message: 'Select triggers:',
|
|
783
|
+
pageSize: 15,
|
|
784
|
+
loop: false,
|
|
785
|
+
choices: availableEvents.map(e => ({
|
|
786
|
+
name: `${e.friendlyDescription} [${e.webhookType}]`,
|
|
787
|
+
value: e,
|
|
788
|
+
checked: false // None pre-selected — user chooses what they need
|
|
789
|
+
}))
|
|
791
790
|
}]);
|
|
792
|
-
if (
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
return true;
|
|
804
|
-
}
|
|
805
|
-
catch {
|
|
806
|
-
return 'Please enter a valid URL';
|
|
807
|
-
}
|
|
808
|
-
}
|
|
791
|
+
if (triggerAnswer && triggerAnswer.triggers.length > 0) {
|
|
792
|
+
selectedTriggers = triggerAnswer.triggers;
|
|
793
|
+
// Ask about webhook mode only if triggers are selected
|
|
794
|
+
const modeAnswer = await safePrompt([{
|
|
795
|
+
type: 'list',
|
|
796
|
+
name: 'mode',
|
|
797
|
+
message: 'How should these events be handled?',
|
|
798
|
+
choices: [
|
|
799
|
+
{ 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
|
+
]
|
|
809
802
|
}]);
|
|
810
|
-
if (!
|
|
803
|
+
if (!modeAnswer)
|
|
811
804
|
return;
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
805
|
+
if (modeAnswer.mode === 'custom') {
|
|
806
|
+
isCustomWebhook = true;
|
|
807
|
+
const urlAnswer = await safePrompt([{
|
|
808
|
+
type: 'input',
|
|
809
|
+
name: 'url',
|
|
810
|
+
message: 'Enter your webhook URL:',
|
|
811
|
+
validate: (input) => {
|
|
812
|
+
try {
|
|
813
|
+
new URL(input);
|
|
814
|
+
return true;
|
|
815
|
+
}
|
|
816
|
+
catch {
|
|
817
|
+
return 'Please enter a valid URL';
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
}]);
|
|
821
|
+
if (!urlAnswer)
|
|
822
|
+
return;
|
|
823
|
+
webhookUrl = urlAnswer.url;
|
|
824
|
+
}
|
|
825
|
+
console.log(`\n✓ ${selectedTriggers.length} trigger(s) selected`);
|
|
826
|
+
if (isCustomWebhook) {
|
|
827
|
+
console.log(` → Events will be sent to: ${webhookUrl}`);
|
|
828
|
+
}
|
|
829
|
+
else {
|
|
830
|
+
console.log(` → Events will wake up your agent`);
|
|
831
|
+
}
|
|
817
832
|
}
|
|
818
833
|
else {
|
|
819
|
-
console.log(
|
|
834
|
+
console.log(`\n⏭️ No triggers selected`);
|
|
820
835
|
}
|
|
821
836
|
}
|
|
822
837
|
else {
|
|
823
|
-
console.log(`\n⏭️
|
|
824
|
-
console.log(` You can add triggers later with: lua integrations webhooks create`);
|
|
838
|
+
console.log(`\n⏭️ Skipping triggers — your agent will use manual invocation only`);
|
|
825
839
|
}
|
|
826
840
|
}
|
|
827
841
|
}
|
|
@@ -974,6 +988,9 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
|
|
|
974
988
|
failedWebhooks.forEach(t => console.log(` ✗ ${t.objectType}.${t.event}: ${t.error}`));
|
|
975
989
|
}
|
|
976
990
|
}
|
|
991
|
+
else {
|
|
992
|
+
console.log(`\n ⚡ Triggers: none (add later with: lua triggers create --connection ${connectionId})`);
|
|
993
|
+
}
|
|
977
994
|
// Summary message
|
|
978
995
|
console.log("\n" + "─".repeat(60));
|
|
979
996
|
const capabilities = [];
|
|
@@ -999,6 +1016,7 @@ async function finalizeConnection(context, integration, connectionId, scopes, hi
|
|
|
999
1016
|
integration_name: integration.name,
|
|
1000
1017
|
mcp_server_active: mcpServer.active,
|
|
1001
1018
|
webhooks_count: webhooks.length,
|
|
1019
|
+
triggers_skipped_at_connect: webhooks.length === 0,
|
|
1002
1020
|
});
|
|
1003
1021
|
}
|
|
1004
1022
|
async function listConnections(context) {
|
|
@@ -1411,6 +1429,7 @@ async function webhooksSubcommand(context, cmdOptions) {
|
|
|
1411
1429
|
hookUrl: cmdOptions?.hookUrl,
|
|
1412
1430
|
interval: cmdOptions?.interval ? parseInt(cmdOptions.interval, 10) : undefined,
|
|
1413
1431
|
integration: cmdOptions?.integration,
|
|
1432
|
+
reason: cmdOptions?.reason,
|
|
1414
1433
|
};
|
|
1415
1434
|
const jsonOutput = cmdOptions?.json === true;
|
|
1416
1435
|
switch (subAction) {
|
|
@@ -1428,12 +1447,43 @@ async function webhooksSubcommand(context, cmdOptions) {
|
|
|
1428
1447
|
}
|
|
1429
1448
|
await webhooksDeleteFlow(context, options.webhookId);
|
|
1430
1449
|
break;
|
|
1450
|
+
case 'pause':
|
|
1451
|
+
if (options.webhookId) {
|
|
1452
|
+
await webhooksPauseFlow(context, options.webhookId, options.reason);
|
|
1453
|
+
}
|
|
1454
|
+
else if (options.connectionId) {
|
|
1455
|
+
await connectionPauseFlow(context, options.connectionId);
|
|
1456
|
+
}
|
|
1457
|
+
else {
|
|
1458
|
+
console.error("❌ --webhook-id or --connection-id is required for pause");
|
|
1459
|
+
console.log("\n💡 Run 'lua integrations webhooks list' to see trigger IDs");
|
|
1460
|
+
throw new Error("--webhook-id or --connection-id is required for pause");
|
|
1461
|
+
}
|
|
1462
|
+
break;
|
|
1463
|
+
case 'resume':
|
|
1464
|
+
if (options.webhookId) {
|
|
1465
|
+
await webhooksResumeFlow(context, options.webhookId);
|
|
1466
|
+
}
|
|
1467
|
+
else if (options.connectionId) {
|
|
1468
|
+
await connectionResumeFlow(context, options.connectionId);
|
|
1469
|
+
}
|
|
1470
|
+
else {
|
|
1471
|
+
console.error("❌ --webhook-id or --connection-id is required for resume");
|
|
1472
|
+
console.log("\n💡 Run 'lua integrations webhooks list' to see trigger IDs");
|
|
1473
|
+
throw new Error("--webhook-id or --connection-id is required for resume");
|
|
1474
|
+
}
|
|
1475
|
+
break;
|
|
1431
1476
|
case 'events':
|
|
1432
1477
|
// New: List available webhook events for a connection or integration type
|
|
1433
1478
|
await webhooksEventsFlow(context, options, jsonOutput);
|
|
1434
1479
|
break;
|
|
1480
|
+
case '':
|
|
1481
|
+
// No sub-action: open interactive trigger management menu
|
|
1482
|
+
// (covers `lua triggers` and `lua integrations webhooks` run bare)
|
|
1483
|
+
await webhooksInteractiveMenu(context);
|
|
1484
|
+
break;
|
|
1435
1485
|
default:
|
|
1436
|
-
console.error(`❌ Invalid webhooks action: "${subAction
|
|
1486
|
+
console.error(`❌ Invalid webhooks action: "${subAction}"`);
|
|
1437
1487
|
console.log('\nUsage:');
|
|
1438
1488
|
console.log(' lua integrations webhooks list List triggers');
|
|
1439
1489
|
console.log(' lua integrations webhooks events --connection <id> List available events for a connection');
|
|
@@ -1441,7 +1491,11 @@ async function webhooksSubcommand(context, cmdOptions) {
|
|
|
1441
1491
|
console.log(' lua integrations webhooks create Create trigger (interactive)');
|
|
1442
1492
|
console.log(' lua integrations webhooks create --connection <id> --object <type> --event <event> --hook-url <url>');
|
|
1443
1493
|
console.log(' lua integrations webhooks delete --webhook-id <id> Delete trigger');
|
|
1444
|
-
|
|
1494
|
+
console.log(' lua integrations webhooks pause --webhook-id <id> Pause a trigger');
|
|
1495
|
+
console.log(' lua integrations webhooks pause --connection-id <id> Pause all triggers for a connection');
|
|
1496
|
+
console.log(' lua integrations webhooks resume --webhook-id <id> Resume a trigger');
|
|
1497
|
+
console.log(' lua integrations webhooks resume --connection-id <id> Resume all triggers for a connection');
|
|
1498
|
+
throw new Error(`Invalid webhooks action: ${subAction}`);
|
|
1445
1499
|
}
|
|
1446
1500
|
}
|
|
1447
1501
|
/**
|
|
@@ -1547,8 +1601,12 @@ async function webhooksInteractiveMenu(context) {
|
|
|
1547
1601
|
message: 'What would you like to do?',
|
|
1548
1602
|
choices: [
|
|
1549
1603
|
{ name: '📋 List triggers', value: 'list' },
|
|
1550
|
-
{ name: '➕ Create new
|
|
1551
|
-
{ name: '
|
|
1604
|
+
{ name: '➕ Create new trigger', value: 'create' },
|
|
1605
|
+
{ name: '⏸️ Pause a trigger', value: 'pause' },
|
|
1606
|
+
{ name: '▶️ Resume a trigger', value: 'resume' },
|
|
1607
|
+
{ name: '⏸️ Pause all triggers for a connection', value: 'pauseConn' },
|
|
1608
|
+
{ name: '▶️ Resume all triggers for a connection', value: 'resumeConn' },
|
|
1609
|
+
{ name: '🗑️ Delete a trigger', value: 'delete' },
|
|
1552
1610
|
{ name: '← Back', value: 'back' }
|
|
1553
1611
|
]
|
|
1554
1612
|
}
|
|
@@ -1562,6 +1620,18 @@ async function webhooksInteractiveMenu(context) {
|
|
|
1562
1620
|
case 'create':
|
|
1563
1621
|
await webhooksCreateFlow(context, {});
|
|
1564
1622
|
break;
|
|
1623
|
+
case 'pause':
|
|
1624
|
+
await webhooksPauseInteractive(context);
|
|
1625
|
+
break;
|
|
1626
|
+
case 'resume':
|
|
1627
|
+
await webhooksResumeInteractive(context);
|
|
1628
|
+
break;
|
|
1629
|
+
case 'pauseConn':
|
|
1630
|
+
await connectionPauseInteractive(context);
|
|
1631
|
+
break;
|
|
1632
|
+
case 'resumeConn':
|
|
1633
|
+
await connectionResumeInteractive(context);
|
|
1634
|
+
break;
|
|
1565
1635
|
case 'delete':
|
|
1566
1636
|
await webhooksDeleteInteractive(context);
|
|
1567
1637
|
break;
|
|
@@ -1595,6 +1665,8 @@ async function webhooksListFlow(context, jsonOutput = false) {
|
|
|
1595
1665
|
webhookType: wh.webhookType,
|
|
1596
1666
|
hookUrl: wh.hookUrl,
|
|
1597
1667
|
status: wh.status,
|
|
1668
|
+
userPaused: wh.userPaused ?? false,
|
|
1669
|
+
creditSuspended: wh.creditSuspended ?? false,
|
|
1598
1670
|
interval: wh.interval,
|
|
1599
1671
|
connectionId: wh.connectionId,
|
|
1600
1672
|
})),
|
|
@@ -1607,8 +1679,8 @@ async function webhooksListFlow(context, jsonOutput = false) {
|
|
|
1607
1679
|
console.log("─".repeat(60) + "\n");
|
|
1608
1680
|
if (webhooks.length === 0) {
|
|
1609
1681
|
console.log("ℹ️ No triggers configured yet.\n");
|
|
1610
|
-
console.log("💡 Add triggers when connecting: lua integrations connect
|
|
1611
|
-
console.log(" Or
|
|
1682
|
+
console.log("💡 Add triggers when connecting: lua integrations connect");
|
|
1683
|
+
console.log(" Or add one now: lua integrations webhooks create\n");
|
|
1612
1684
|
return;
|
|
1613
1685
|
}
|
|
1614
1686
|
// Group by integration
|
|
@@ -1622,12 +1694,31 @@ async function webhooksListFlow(context, jsonOutput = false) {
|
|
|
1622
1694
|
for (const [integration, integrationWebhooks] of byIntegration) {
|
|
1623
1695
|
console.log(`📦 ${integration}`);
|
|
1624
1696
|
for (const wh of integrationWebhooks) {
|
|
1625
|
-
const statusIcon = wh.status === 'active' ? '✅' : '⚪';
|
|
1626
|
-
const typeLabel = wh.webhookType === 'native' ? 'push' : 'poll';
|
|
1627
1697
|
const isAgentTrigger = wh.hookUrl.includes('webhook/unifiedto');
|
|
1628
1698
|
const mode = isAgentTrigger ? 'agent trigger' : 'custom URL';
|
|
1629
|
-
|
|
1630
|
-
|
|
1699
|
+
const typeLabel = wh.webhookType === 'native' ? 'push' : 'poll';
|
|
1700
|
+
// Determine display icon + status badge
|
|
1701
|
+
let statusIcon;
|
|
1702
|
+
let statusBadge = '';
|
|
1703
|
+
if (wh.creditSuspended) {
|
|
1704
|
+
statusIcon = '💳';
|
|
1705
|
+
statusBadge = ' (credit-suspended)';
|
|
1706
|
+
}
|
|
1707
|
+
else if (wh.userPaused) {
|
|
1708
|
+
statusIcon = '⏸️';
|
|
1709
|
+
statusBadge = ' (paused by you)';
|
|
1710
|
+
}
|
|
1711
|
+
else if (wh.status === 'active') {
|
|
1712
|
+
statusIcon = '✅';
|
|
1713
|
+
}
|
|
1714
|
+
else if (wh.status === 'unhealthy') {
|
|
1715
|
+
statusIcon = '🔴';
|
|
1716
|
+
statusBadge = ' (unhealthy)';
|
|
1717
|
+
}
|
|
1718
|
+
else {
|
|
1719
|
+
statusIcon = '⚪';
|
|
1720
|
+
}
|
|
1721
|
+
console.log(` ${statusIcon} ${wh.objectType}.${wh.event}${statusBadge} (${typeLabel}, ${mode})`);
|
|
1631
1722
|
console.log(` ID: ${wh.id}`);
|
|
1632
1723
|
if (!isAgentTrigger) {
|
|
1633
1724
|
console.log(` URL: ${wh.hookUrl}`);
|
|
@@ -1647,6 +1738,257 @@ async function webhooksListFlow(context, jsonOutput = false) {
|
|
|
1647
1738
|
}
|
|
1648
1739
|
}
|
|
1649
1740
|
}
|
|
1741
|
+
/**
|
|
1742
|
+
* Pause a single webhook subscription (non-interactive)
|
|
1743
|
+
*/
|
|
1744
|
+
async function webhooksPauseFlow(context, webhookId, reason) {
|
|
1745
|
+
writeProgress("🔄 Pausing trigger...");
|
|
1746
|
+
try {
|
|
1747
|
+
const result = await context.unifiedToApi.pauseWebhookSubscription(context.agentId, webhookId, reason);
|
|
1748
|
+
if (result.success) {
|
|
1749
|
+
writeSuccess(`⏸️ Trigger paused: ${webhookId}\n`);
|
|
1750
|
+
if (reason)
|
|
1751
|
+
console.log(` Reason: ${reason}`);
|
|
1752
|
+
console.log(`\n💡 Resume later with: lua integrations webhooks resume --webhook-id ${webhookId}\n`);
|
|
1753
|
+
trackEvent('cli_trigger_paused', { webhook_id: webhookId });
|
|
1754
|
+
}
|
|
1755
|
+
else {
|
|
1756
|
+
writeError(`❌ Failed to pause trigger: ${result.error?.message}`);
|
|
1757
|
+
}
|
|
1758
|
+
}
|
|
1759
|
+
catch (error) {
|
|
1760
|
+
writeError(`❌ Error: ${error.message}`);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
/**
|
|
1764
|
+
* Resume a single webhook subscription (non-interactive)
|
|
1765
|
+
*/
|
|
1766
|
+
async function webhooksResumeFlow(context, webhookId) {
|
|
1767
|
+
writeProgress("🔄 Resuming trigger...");
|
|
1768
|
+
try {
|
|
1769
|
+
const result = await context.unifiedToApi.resumeWebhookSubscription(context.agentId, webhookId);
|
|
1770
|
+
if (result.success) {
|
|
1771
|
+
writeSuccess(`▶️ Trigger resumed: ${webhookId}\n`);
|
|
1772
|
+
trackEvent('cli_trigger_resumed', { webhook_id: webhookId });
|
|
1773
|
+
}
|
|
1774
|
+
else {
|
|
1775
|
+
const code = result.error?.code;
|
|
1776
|
+
if (code === 'CREDIT_SUSPENDED') {
|
|
1777
|
+
writeError(`❌ Cannot resume: this trigger is suspended due to credit depletion.`);
|
|
1778
|
+
console.log(` Add credits to your account to re-enable webhook triggers.\n`);
|
|
1779
|
+
}
|
|
1780
|
+
else {
|
|
1781
|
+
writeError(`❌ Failed to resume trigger: ${result.error?.message}`);
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}
|
|
1785
|
+
catch (error) {
|
|
1786
|
+
writeError(`❌ Error: ${error.message}`);
|
|
1787
|
+
}
|
|
1788
|
+
}
|
|
1789
|
+
/**
|
|
1790
|
+
* Pause all triggers for a connection (non-interactive)
|
|
1791
|
+
*/
|
|
1792
|
+
async function connectionPauseFlow(context, connectionId) {
|
|
1793
|
+
writeProgress("🔄 Pausing all triggers for connection...");
|
|
1794
|
+
try {
|
|
1795
|
+
const result = await context.unifiedToApi.pauseConnection(context.agentId, connectionId);
|
|
1796
|
+
if (result.success && result.data) {
|
|
1797
|
+
writeSuccess(`⏸️ Paused ${result.data.affectedWebhooks} trigger(s) for connection ${connectionId}\n`);
|
|
1798
|
+
if (result.data.failedWebhooks > 0) {
|
|
1799
|
+
console.log(` ⚠️ ${result.data.failedWebhooks} trigger(s) failed to pause at Unified.to — check logs.\n`);
|
|
1800
|
+
}
|
|
1801
|
+
console.log(`\n💡 Resume later with: lua integrations webhooks resume --connection-id ${connectionId}\n`);
|
|
1802
|
+
trackEvent('cli_connection_paused', { connection_id: connectionId, affected: result.data.affectedWebhooks, failed: result.data.failedWebhooks });
|
|
1803
|
+
}
|
|
1804
|
+
else {
|
|
1805
|
+
writeError(`❌ Failed to pause connection triggers: ${result.error?.message}`);
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
catch (error) {
|
|
1809
|
+
writeError(`❌ Error: ${error.message}`);
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
/**
|
|
1813
|
+
* Resume all triggers for a connection (non-interactive)
|
|
1814
|
+
*/
|
|
1815
|
+
async function connectionResumeFlow(context, connectionId) {
|
|
1816
|
+
writeProgress("🔄 Resuming triggers for connection...");
|
|
1817
|
+
try {
|
|
1818
|
+
const result = await context.unifiedToApi.resumeConnection(context.agentId, connectionId);
|
|
1819
|
+
if (result.success && result.data) {
|
|
1820
|
+
writeSuccess(`▶️ Resumed ${result.data.affectedWebhooks} trigger(s) for connection ${connectionId}\n`);
|
|
1821
|
+
if (result.data.skippedCreditSuspended > 0) {
|
|
1822
|
+
console.log(` ⚠️ ${result.data.skippedCreditSuspended} trigger(s) skipped — suspended due to credit depletion.`);
|
|
1823
|
+
console.log(` Add credits to your account to re-enable them.\n`);
|
|
1824
|
+
}
|
|
1825
|
+
if (result.data.failedWebhooks > 0) {
|
|
1826
|
+
console.log(` ⚠️ ${result.data.failedWebhooks} trigger(s) failed to resume at Unified.to — check logs.\n`);
|
|
1827
|
+
}
|
|
1828
|
+
trackEvent('cli_connection_resumed', { connection_id: connectionId, affected: result.data.affectedWebhooks, skipped_credit: result.data.skippedCreditSuspended, failed: result.data.failedWebhooks });
|
|
1829
|
+
}
|
|
1830
|
+
else {
|
|
1831
|
+
writeError(`❌ Failed to resume connection triggers: ${result.error?.message}`);
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
catch (error) {
|
|
1835
|
+
writeError(`❌ Error: ${error.message}`);
|
|
1836
|
+
}
|
|
1837
|
+
}
|
|
1838
|
+
/**
|
|
1839
|
+
* Interactive: pause a single trigger
|
|
1840
|
+
*/
|
|
1841
|
+
async function webhooksPauseInteractive(context) {
|
|
1842
|
+
writeProgress("🔄 Loading triggers...");
|
|
1843
|
+
try {
|
|
1844
|
+
const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
|
|
1845
|
+
if (!result.success) {
|
|
1846
|
+
writeError(`❌ Failed to load triggers: ${result.error?.message}`);
|
|
1847
|
+
return;
|
|
1848
|
+
}
|
|
1849
|
+
const webhooks = (result.data || []).filter(wh => !wh.userPaused && wh.status !== 'unhealthy');
|
|
1850
|
+
if (webhooks.length === 0) {
|
|
1851
|
+
console.log("\nℹ️ No active triggers to pause.\n");
|
|
1852
|
+
return;
|
|
1853
|
+
}
|
|
1854
|
+
const webhookAnswer = await safePrompt([
|
|
1855
|
+
{
|
|
1856
|
+
type: 'list',
|
|
1857
|
+
name: 'webhook',
|
|
1858
|
+
message: 'Select a trigger to pause:',
|
|
1859
|
+
choices: webhooks.map(wh => ({
|
|
1860
|
+
name: `${wh.integrationType} — ${wh.objectType}.${wh.event} (${wh.id.substring(0, 8)}...)`,
|
|
1861
|
+
value: wh.id,
|
|
1862
|
+
}))
|
|
1863
|
+
}
|
|
1864
|
+
]);
|
|
1865
|
+
if (!webhookAnswer?.webhook)
|
|
1866
|
+
return;
|
|
1867
|
+
const confirmAnswer = await safePrompt([
|
|
1868
|
+
{
|
|
1869
|
+
type: 'confirm',
|
|
1870
|
+
name: 'confirm',
|
|
1871
|
+
message: `Pause this trigger?`,
|
|
1872
|
+
default: true,
|
|
1873
|
+
}
|
|
1874
|
+
]);
|
|
1875
|
+
if (!confirmAnswer?.confirm) {
|
|
1876
|
+
console.log("\n❌ Cancelled.\n");
|
|
1877
|
+
return;
|
|
1878
|
+
}
|
|
1879
|
+
await webhooksPauseFlow(context, webhookAnswer.webhook);
|
|
1880
|
+
}
|
|
1881
|
+
catch (error) {
|
|
1882
|
+
writeError(`❌ Error: ${error.message}`);
|
|
1883
|
+
}
|
|
1884
|
+
}
|
|
1885
|
+
/**
|
|
1886
|
+
* Interactive: resume a single trigger
|
|
1887
|
+
*/
|
|
1888
|
+
async function webhooksResumeInteractive(context) {
|
|
1889
|
+
writeProgress("🔄 Loading triggers...");
|
|
1890
|
+
try {
|
|
1891
|
+
const result = await context.unifiedToApi.getWebhookSubscriptions(context.agentId);
|
|
1892
|
+
if (!result.success) {
|
|
1893
|
+
writeError(`❌ Failed to load triggers: ${result.error?.message}`);
|
|
1894
|
+
return;
|
|
1895
|
+
}
|
|
1896
|
+
const webhooks = (result.data || []).filter(wh => wh.userPaused && !wh.creditSuspended);
|
|
1897
|
+
if (webhooks.length === 0) {
|
|
1898
|
+
console.log("\nℹ️ No user-paused triggers to resume.\n");
|
|
1899
|
+
return;
|
|
1900
|
+
}
|
|
1901
|
+
const webhookAnswer = await safePrompt([
|
|
1902
|
+
{
|
|
1903
|
+
type: 'list',
|
|
1904
|
+
name: 'webhook',
|
|
1905
|
+
message: 'Select a trigger to resume:',
|
|
1906
|
+
choices: webhooks.map(wh => ({
|
|
1907
|
+
name: `${wh.integrationType} — ${wh.objectType}.${wh.event} (${wh.id.substring(0, 8)}...)`,
|
|
1908
|
+
value: wh.id,
|
|
1909
|
+
}))
|
|
1910
|
+
}
|
|
1911
|
+
]);
|
|
1912
|
+
if (!webhookAnswer?.webhook)
|
|
1913
|
+
return;
|
|
1914
|
+
await webhooksResumeFlow(context, webhookAnswer.webhook);
|
|
1915
|
+
}
|
|
1916
|
+
catch (error) {
|
|
1917
|
+
writeError(`❌ Error: ${error.message}`);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
/**
|
|
1921
|
+
* Interactive: pause all triggers for a connection
|
|
1922
|
+
*/
|
|
1923
|
+
async function connectionPauseInteractive(context) {
|
|
1924
|
+
try {
|
|
1925
|
+
const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
|
|
1926
|
+
const connections = connectionsResult.success ? connectionsResult.data || [] : [];
|
|
1927
|
+
if (connections.length === 0) {
|
|
1928
|
+
console.log("\nℹ️ No connected integrations.\n");
|
|
1929
|
+
return;
|
|
1930
|
+
}
|
|
1931
|
+
const connectionAnswer = await safePrompt([
|
|
1932
|
+
{
|
|
1933
|
+
type: 'list',
|
|
1934
|
+
name: 'connection',
|
|
1935
|
+
message: 'Select a connection to pause all triggers:',
|
|
1936
|
+
choices: connections.map(c => ({
|
|
1937
|
+
name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)${c.allTriggersPaused ? ' [all triggers paused]' : ''}`,
|
|
1938
|
+
value: c.id,
|
|
1939
|
+
}))
|
|
1940
|
+
}
|
|
1941
|
+
]);
|
|
1942
|
+
if (!connectionAnswer?.connection)
|
|
1943
|
+
return;
|
|
1944
|
+
const confirmAnswer = await safePrompt([
|
|
1945
|
+
{
|
|
1946
|
+
type: 'confirm',
|
|
1947
|
+
name: 'confirm',
|
|
1948
|
+
message: `Pause all triggers for this connection?`,
|
|
1949
|
+
default: true,
|
|
1950
|
+
}
|
|
1951
|
+
]);
|
|
1952
|
+
if (!confirmAnswer?.confirm) {
|
|
1953
|
+
console.log("\n❌ Cancelled.\n");
|
|
1954
|
+
return;
|
|
1955
|
+
}
|
|
1956
|
+
await connectionPauseFlow(context, connectionAnswer.connection);
|
|
1957
|
+
}
|
|
1958
|
+
catch (error) {
|
|
1959
|
+
writeError(`❌ Error: ${error.message}`);
|
|
1960
|
+
}
|
|
1961
|
+
}
|
|
1962
|
+
/**
|
|
1963
|
+
* Interactive: resume all triggers for a connection
|
|
1964
|
+
*/
|
|
1965
|
+
async function connectionResumeInteractive(context) {
|
|
1966
|
+
try {
|
|
1967
|
+
const connectionsResult = await context.unifiedToApi.getConnections(context.agentId);
|
|
1968
|
+
const connections = connectionsResult.success ? connectionsResult.data || [] : [];
|
|
1969
|
+
if (connections.length === 0) {
|
|
1970
|
+
console.log("\nℹ️ No connected integrations.\n");
|
|
1971
|
+
return;
|
|
1972
|
+
}
|
|
1973
|
+
const connectionAnswer = await safePrompt([
|
|
1974
|
+
{
|
|
1975
|
+
type: 'list',
|
|
1976
|
+
name: 'connection',
|
|
1977
|
+
message: 'Select a connection to resume triggers:',
|
|
1978
|
+
choices: connections.map(c => ({
|
|
1979
|
+
name: `${c.integrationName || c.integrationType} (${c.id.substring(0, 8)}...)`,
|
|
1980
|
+
value: c.id,
|
|
1981
|
+
}))
|
|
1982
|
+
}
|
|
1983
|
+
]);
|
|
1984
|
+
if (!connectionAnswer?.connection)
|
|
1985
|
+
return;
|
|
1986
|
+
await connectionResumeFlow(context, connectionAnswer.connection);
|
|
1987
|
+
}
|
|
1988
|
+
catch (error) {
|
|
1989
|
+
writeError(`❌ Error: ${error.message}`);
|
|
1990
|
+
}
|
|
1991
|
+
}
|
|
1650
1992
|
/**
|
|
1651
1993
|
* Create a webhook subscription
|
|
1652
1994
|
*/
|
|
@@ -1753,27 +2095,53 @@ async function webhooksCreateFlow(context, options) {
|
|
|
1753
2095
|
hookUrl = options.hookUrl;
|
|
1754
2096
|
}
|
|
1755
2097
|
else {
|
|
1756
|
-
|
|
2098
|
+
// Ask the user whether to use the built-in agent URL or a custom endpoint.
|
|
2099
|
+
const urlModeAnswer = await safePrompt([
|
|
1757
2100
|
{
|
|
1758
|
-
type: '
|
|
1759
|
-
name: '
|
|
1760
|
-
message: '
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
2101
|
+
type: 'list',
|
|
2102
|
+
name: 'urlMode',
|
|
2103
|
+
message: 'Where should events be sent?',
|
|
2104
|
+
choices: [
|
|
2105
|
+
{
|
|
2106
|
+
name: '🤖 Wake up my Lua agent (recommended)',
|
|
2107
|
+
value: 'agent',
|
|
2108
|
+
},
|
|
2109
|
+
{
|
|
2110
|
+
name: '🔗 Custom webhook URL',
|
|
2111
|
+
value: 'custom',
|
|
2112
|
+
},
|
|
2113
|
+
],
|
|
2114
|
+
default: 'agent',
|
|
1772
2115
|
}
|
|
1773
2116
|
]);
|
|
1774
|
-
if (!
|
|
2117
|
+
if (!urlModeAnswer)
|
|
1775
2118
|
return;
|
|
1776
|
-
|
|
2119
|
+
if (urlModeAnswer.urlMode === 'agent') {
|
|
2120
|
+
hookUrl = AGENT_WEBHOOK_URL;
|
|
2121
|
+
}
|
|
2122
|
+
else {
|
|
2123
|
+
const webhookAnswer = await safePrompt([
|
|
2124
|
+
{
|
|
2125
|
+
type: 'input',
|
|
2126
|
+
name: 'hookUrl',
|
|
2127
|
+
message: 'Enter the full webhook URL to receive events:',
|
|
2128
|
+
validate: (input) => {
|
|
2129
|
+
if (!input.trim())
|
|
2130
|
+
return 'Webhook URL is required';
|
|
2131
|
+
try {
|
|
2132
|
+
new URL(input);
|
|
2133
|
+
return true;
|
|
2134
|
+
}
|
|
2135
|
+
catch {
|
|
2136
|
+
return 'Enter a valid URL (e.g., https://webhook.heylua.ai/myagent/handler)';
|
|
2137
|
+
}
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
]);
|
|
2141
|
+
if (!webhookAnswer)
|
|
2142
|
+
return;
|
|
2143
|
+
hookUrl = webhookAnswer.hookUrl.trim();
|
|
2144
|
+
}
|
|
1777
2145
|
}
|
|
1778
2146
|
// Step 6: Get interval for virtual webhooks
|
|
1779
2147
|
let interval;
|
|
@@ -2239,20 +2607,28 @@ function showUsage() {
|
|
|
2239
2607
|
console.log(' lua integrations info <type> Show integration details (scopes, triggers)');
|
|
2240
2608
|
console.log(' lua integrations info <type> --json Output as JSON for scripting');
|
|
2241
2609
|
console.log(' lua integrations disconnect --connection-id <id> Disconnect an integration');
|
|
2242
|
-
console.log('\nTriggers:');
|
|
2610
|
+
console.log('\nTriggers (also available as: lua triggers <action>):');
|
|
2243
2611
|
console.log(' lua integrations webhooks list List all triggers');
|
|
2612
|
+
console.log(' lua integrations webhooks list --json Output as JSON');
|
|
2244
2613
|
console.log(' lua integrations webhooks events --connection <id> List available events for a connection');
|
|
2245
2614
|
console.log(' lua integrations webhooks events --integration <type> List available events for an integration');
|
|
2246
2615
|
console.log(' lua integrations webhooks create Create trigger (interactive)');
|
|
2247
2616
|
console.log(' lua integrations webhooks create --connection <id> --object <type> --event <event> --hook-url <url>');
|
|
2248
2617
|
console.log(' lua integrations webhooks delete --webhook-id <id> Delete a trigger');
|
|
2618
|
+
console.log(' lua integrations webhooks pause --webhook-id <id> Pause a trigger');
|
|
2619
|
+
console.log(' lua integrations webhooks pause --connection-id <id> Pause all triggers for a connection');
|
|
2620
|
+
console.log(' lua integrations webhooks resume --webhook-id <id> Resume a trigger');
|
|
2621
|
+
console.log(' lua integrations webhooks resume --connection-id <id> Resume all triggers for a connection');
|
|
2249
2622
|
console.log('\nMCP Server Management:');
|
|
2250
2623
|
console.log(' lua integrations mcp list List connections with MCP status');
|
|
2251
2624
|
console.log(' lua integrations mcp activate --connection <id> Activate MCP server');
|
|
2252
2625
|
console.log(' lua integrations mcp deactivate --connection <id> Deactivate MCP server');
|
|
2253
2626
|
console.log('\nTrigger Options (use with connect):');
|
|
2254
2627
|
console.log(' --triggers <events> Comma-separated triggers (e.g., task_task.created,task_task.updated)');
|
|
2628
|
+
console.log(' Omit to skip triggers and add them later');
|
|
2255
2629
|
console.log(' --custom-webhook Use custom URL instead of agent trigger');
|
|
2256
2630
|
console.log(' --hook-url <url> Custom URL for triggers');
|
|
2631
|
+
console.log('\nPause Options (use with webhooks pause):');
|
|
2632
|
+
console.log(' --reason <text> Optional reason for pausing (informational)');
|
|
2257
2633
|
}
|
|
2258
2634
|
//# sourceMappingURL=integrations.js.map
|