lua-cli 2.5.7 → 3.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/api/agent.api.service.d.ts +45 -0
  2. package/dist/api/agent.api.service.js +54 -0
  3. package/dist/api/job.api.service.d.ts +210 -0
  4. package/dist/api/job.api.service.js +200 -0
  5. package/dist/api/lazy-instances.d.ts +24 -0
  6. package/dist/api/lazy-instances.js +48 -0
  7. package/dist/api/postprocessor.api.service.d.ts +98 -0
  8. package/dist/api/postprocessor.api.service.js +76 -0
  9. package/dist/api/preprocessor.api.service.d.ts +98 -0
  10. package/dist/api/preprocessor.api.service.js +76 -0
  11. package/dist/api/user.data.api.service.d.ts +28 -0
  12. package/dist/api/user.data.api.service.js +51 -0
  13. package/dist/api/webhook.api.service.d.ts +151 -0
  14. package/dist/api/webhook.api.service.js +134 -0
  15. package/dist/api-exports.d.ts +156 -41
  16. package/dist/api-exports.js +182 -21
  17. package/dist/cli/command-definitions.js +149 -7
  18. package/dist/commands/compile.js +124 -5
  19. package/dist/commands/completion.d.ts +11 -0
  20. package/dist/commands/completion.js +209 -0
  21. package/dist/commands/env.d.ts +3 -2
  22. package/dist/commands/env.js +42 -17
  23. package/dist/commands/features.d.ts +16 -0
  24. package/dist/commands/features.js +352 -0
  25. package/dist/commands/index.d.ts +7 -0
  26. package/dist/commands/index.js +7 -0
  27. package/dist/commands/init.js +53 -7
  28. package/dist/commands/jobs.d.ts +20 -0
  29. package/dist/commands/jobs.js +533 -0
  30. package/dist/commands/logs.js +2 -5
  31. package/dist/commands/persona.d.ts +3 -2
  32. package/dist/commands/persona.js +43 -18
  33. package/dist/commands/postprocessors.d.ts +8 -0
  34. package/dist/commands/postprocessors.js +431 -0
  35. package/dist/commands/preprocessors.d.ts +8 -0
  36. package/dist/commands/preprocessors.js +431 -0
  37. package/dist/commands/push.d.ts +9 -13
  38. package/dist/commands/push.js +937 -69
  39. package/dist/commands/skills.d.ts +16 -0
  40. package/dist/commands/skills.js +438 -0
  41. package/dist/commands/test.d.ts +9 -18
  42. package/dist/commands/test.js +558 -82
  43. package/dist/commands/webhooks.d.ts +18 -0
  44. package/dist/commands/webhooks.js +424 -0
  45. package/dist/common/data.entry.instance.d.ts +7 -0
  46. package/dist/common/data.entry.instance.js +15 -0
  47. package/dist/common/job.instance.d.ts +77 -0
  48. package/dist/common/job.instance.js +108 -0
  49. package/dist/common/order.instance.d.ts +6 -0
  50. package/dist/common/order.instance.js +14 -0
  51. package/dist/common/product.instance.d.ts +6 -0
  52. package/dist/common/product.instance.js +14 -0
  53. package/dist/common/user.instance.d.ts +15 -0
  54. package/dist/common/user.instance.js +38 -0
  55. package/dist/config/constants.d.ts +2 -2
  56. package/dist/config/constants.js +4 -4
  57. package/dist/index.js +14 -3
  58. package/dist/interfaces/agent.d.ts +33 -1
  59. package/dist/interfaces/chat.d.ts +22 -0
  60. package/dist/interfaces/index.d.ts +10 -0
  61. package/dist/interfaces/index.js +7 -0
  62. package/dist/interfaces/jobs.d.ts +172 -0
  63. package/dist/interfaces/jobs.js +5 -0
  64. package/dist/interfaces/message.d.ts +18 -0
  65. package/dist/interfaces/message.js +1 -0
  66. package/dist/interfaces/postprocessors.d.ts +35 -0
  67. package/dist/interfaces/postprocessors.js +4 -0
  68. package/dist/interfaces/preprocessors.d.ts +35 -0
  69. package/dist/interfaces/preprocessors.js +4 -0
  70. package/dist/interfaces/webhooks.d.ts +104 -0
  71. package/dist/interfaces/webhooks.js +5 -0
  72. package/dist/types/api-contracts.d.ts +14 -0
  73. package/dist/types/api-contracts.js +0 -7
  74. package/dist/types/compile.types.d.ts +49 -0
  75. package/dist/types/index.d.ts +1 -1
  76. package/dist/types/index.js +1 -1
  77. package/dist/types/skill.d.ts +502 -0
  78. package/dist/types/skill.js +477 -0
  79. package/dist/utils/agent-management.d.ts +25 -0
  80. package/dist/utils/agent-management.js +67 -0
  81. package/dist/utils/bundling.d.ts +31 -1
  82. package/dist/utils/bundling.js +653 -10
  83. package/dist/utils/compile.d.ts +63 -0
  84. package/dist/utils/compile.js +691 -36
  85. package/dist/utils/deployment.d.ts +2 -1
  86. package/dist/utils/deployment.js +16 -2
  87. package/dist/utils/init-agent.d.ts +3 -1
  88. package/dist/utils/init-agent.js +6 -4
  89. package/dist/utils/init-prompts.d.ts +2 -1
  90. package/dist/utils/init-prompts.js +14 -9
  91. package/dist/utils/job-management.d.ts +24 -0
  92. package/dist/utils/job-management.js +264 -0
  93. package/dist/utils/postprocessor-management.d.ts +9 -0
  94. package/dist/utils/postprocessor-management.js +118 -0
  95. package/dist/utils/preprocessor-management.d.ts +9 -0
  96. package/dist/utils/preprocessor-management.js +118 -0
  97. package/dist/utils/sandbox.d.ts +61 -1
  98. package/dist/utils/sandbox.js +283 -72
  99. package/dist/utils/tool-detection.d.ts +3 -2
  100. package/dist/utils/tool-detection.js +18 -4
  101. package/dist/utils/webhook-management.d.ts +24 -0
  102. package/dist/utils/webhook-management.js +256 -0
  103. package/dist/web/app.css +152 -736
  104. package/dist/web/app.js +45 -45
  105. package/package.json +2 -2
  106. package/template/AGENT_CONFIGURATION.md +251 -0
  107. package/template/COMPLEX_JOB_EXAMPLES.md +795 -0
  108. package/template/DYNAMIC_JOB_CREATION.md +371 -0
  109. package/template/README.md +30 -2
  110. package/template/WEBHOOKS_JOBS_QUICKSTART.md +318 -0
  111. package/template/WEBHOOK_JOB_EXAMPLES.md +817 -0
  112. package/template/package.json +1 -1
  113. package/template/src/index-agent-example.ts +201 -0
  114. package/template/src/index.ts +39 -0
  115. package/template/src/jobs/AbandonedBasketProcessorJob.ts +139 -0
  116. package/template/src/jobs/DailyCleanupJob.ts +100 -0
  117. package/template/src/jobs/DataMigrationJob.ts +133 -0
  118. package/template/src/jobs/HealthCheckJob.ts +87 -0
  119. package/template/src/postprocessors/ResponseFormatter.ts +151 -0
  120. package/template/src/preprocessors/MessageFilter.ts +91 -0
  121. package/template/src/tools/GameScoreTrackerTool.ts +356 -0
  122. package/template/src/tools/SmartBasketTool.ts +188 -0
  123. package/template/src/webhooks/PaymentWebhook.ts +113 -0
  124. package/template/src/webhooks/UserEventWebhook.ts +77 -0
@@ -0,0 +1,424 @@
1
+ /**
2
+ * Webhooks Command
3
+ * Manages agent webhooks for sandbox and production environments
4
+ */
5
+ import { loadApiKey, checkApiKey } from '../services/auth.js';
6
+ import { readSkillConfig } from '../utils/files.js';
7
+ import { withErrorHandling, writeProgress, writeSuccess, writeInfo } from '../utils/cli.js';
8
+ import { BASE_URLS } from '../config/constants.js';
9
+ import { safePrompt } from '../utils/prompt-handler.js';
10
+ import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
11
+ import WebhookApi from '../api/webhook.api.service.js';
12
+ /**
13
+ * Main webhooks command - manages agent webhooks
14
+ *
15
+ * Features:
16
+ * - View deployed webhooks
17
+ * - View webhook versions
18
+ * - Deploy webhook versions to production
19
+ * - Activate/deactivate webhooks
20
+ *
21
+ * Note: For local testing, use `lua test webhook`
22
+ *
23
+ * @returns Promise that resolves when command completes
24
+ */
25
+ export async function webhooksCommand() {
26
+ return withErrorHandling(async () => {
27
+ // Step 1: Load configuration first (to get agentId)
28
+ const config = readSkillConfig();
29
+ validateConfig(config);
30
+ validateAgentConfig(config);
31
+ const agentId = config.agent.agentId;
32
+ // Step 2: Authenticate
33
+ const apiKey = await loadApiKey();
34
+ if (!apiKey) {
35
+ console.error("❌ No API key found. Please run 'lua auth configure' to set up your API key.");
36
+ process.exit(1);
37
+ }
38
+ await checkApiKey(apiKey);
39
+ writeProgress("✅ Authenticated");
40
+ const context = {
41
+ environment: 'production',
42
+ agentId,
43
+ apiKey,
44
+ };
45
+ // Start webhook management
46
+ await manageProductionWebhooks(context, config);
47
+ }, "webhooks");
48
+ }
49
+ /**
50
+ * Manage production webhooks - view and deploy versions
51
+ */
52
+ async function manageProductionWebhooks(context, config) {
53
+ let continueManaging = true;
54
+ while (continueManaging) {
55
+ console.log("\n" + "=".repeat(60));
56
+ console.log("🚀 Production Webhooks");
57
+ console.log("=".repeat(60) + "\n");
58
+ const actionAnswer = await safePrompt([
59
+ {
60
+ type: 'list',
61
+ name: 'action',
62
+ message: 'What would you like to do?',
63
+ choices: [
64
+ { name: '👁️ View deployed webhooks', value: 'view' },
65
+ { name: '📜 View webhook versions', value: 'versions' },
66
+ { name: '🚀 Deploy a version', value: 'deploy' },
67
+ { name: '✅ Activate a webhook', value: 'activate' },
68
+ { name: '🚫 Deactivate a webhook', value: 'deactivate' },
69
+ { name: '❌ Exit', value: 'exit' }
70
+ ]
71
+ }
72
+ ]);
73
+ if (!actionAnswer)
74
+ return;
75
+ const { action } = actionAnswer;
76
+ switch (action) {
77
+ case 'view':
78
+ await viewDeployedWebhooks(context, config);
79
+ break;
80
+ case 'versions':
81
+ await viewWebhookVersions(context, config);
82
+ break;
83
+ case 'deploy':
84
+ await deployWebhookVersion(context, config);
85
+ break;
86
+ case 'activate':
87
+ await activateWebhook(context, config);
88
+ break;
89
+ case 'deactivate':
90
+ await deactivateWebhook(context, config);
91
+ break;
92
+ case 'exit':
93
+ continueManaging = false;
94
+ console.log("\n👋 Goodbye!\n");
95
+ break;
96
+ }
97
+ }
98
+ }
99
+ /**
100
+ * View deployed webhooks in production
101
+ */
102
+ async function viewDeployedWebhooks(context, config) {
103
+ writeProgress("🔄 Loading webhook information...");
104
+ try {
105
+ const webhooks = config.webhooks || [];
106
+ if (webhooks.length === 0) {
107
+ console.log("\nℹ️ No webhooks found in configuration.\n");
108
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
109
+ return;
110
+ }
111
+ console.log("\n" + "=".repeat(60));
112
+ console.log("⚙️ Production Webhooks");
113
+ console.log("=".repeat(60) + "\n");
114
+ const webhookApi = new WebhookApi(BASE_URLS.API, context.apiKey, context.agentId);
115
+ // Fetch version info for each webhook
116
+ for (const webhook of webhooks) {
117
+ try {
118
+ const response = await webhookApi.getWebhookVersions(webhook.webhookId);
119
+ if (response.success && response.data) {
120
+ const versions = response.data.versions || [];
121
+ const activeVersionId = response.data.activeVersionId;
122
+ // Find active version
123
+ const activeVersion = versions.find((v) => v.webhookId === activeVersionId);
124
+ console.log(`🪝 ${webhook.name}`);
125
+ console.log(` Webhook ID: ${webhook.webhookId}`);
126
+ if (activeVersion) {
127
+ console.log(` Deployed Version: ${activeVersion.version} ⭐`);
128
+ const date = new Date(activeVersion.createdAt);
129
+ console.log(` Deployed: ${date.toLocaleString()}`);
130
+ }
131
+ else {
132
+ console.log(` Deployed Version: Not deployed`);
133
+ }
134
+ console.log(` Total Versions: ${versions.length}`);
135
+ console.log();
136
+ }
137
+ else {
138
+ console.log(`🪝 ${webhook.name}`);
139
+ console.log(` Webhook ID: ${webhook.webhookId}`);
140
+ console.log(` Status: Unable to fetch version info`);
141
+ console.log();
142
+ }
143
+ }
144
+ catch (error) {
145
+ console.log(`🪝 ${webhook.name}`);
146
+ console.log(` Webhook ID: ${webhook.webhookId}`);
147
+ console.log(` Status: Error loading versions`);
148
+ console.log();
149
+ }
150
+ }
151
+ console.log("=".repeat(60) + "\n");
152
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
153
+ }
154
+ catch (error) {
155
+ console.error('❌ Error loading webhook information:', error);
156
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
157
+ }
158
+ }
159
+ /**
160
+ * View versions for a specific webhook
161
+ */
162
+ async function viewWebhookVersions(context, config) {
163
+ const webhooks = config.webhooks || [];
164
+ if (webhooks.length === 0) {
165
+ console.log("\nℹ️ No webhooks found in configuration.\n");
166
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
167
+ return;
168
+ }
169
+ // Prompt to select a webhook
170
+ const webhookAnswer = await safePrompt([
171
+ {
172
+ type: 'list',
173
+ name: 'selectedWebhook',
174
+ message: 'Select a webhook to view versions:',
175
+ choices: webhooks.map((webhook) => ({
176
+ name: `${webhook.name} (${webhook.webhookId})`,
177
+ value: webhook
178
+ }))
179
+ }
180
+ ]);
181
+ if (!webhookAnswer)
182
+ return;
183
+ const selectedWebhook = webhookAnswer.selectedWebhook;
184
+ writeProgress(`🔄 Loading versions for ${selectedWebhook.name}...`);
185
+ try {
186
+ const response = await fetch(`${BASE_URLS.API}/developer/webhooks/${context.agentId}/${selectedWebhook.webhookId}/versions`, {
187
+ method: 'GET',
188
+ headers: {
189
+ 'Authorization': `Bearer ${context.apiKey}`,
190
+ 'Content-Type': 'application/json'
191
+ }
192
+ });
193
+ if (!response.ok) {
194
+ throw new Error(`HTTP error! status: ${response.status}`);
195
+ }
196
+ const data = await response.json();
197
+ const versions = data.data?.versions || data.versions || [];
198
+ const activeVersionId = data.data?.activeVersionId || data.activeVersionId;
199
+ if (versions.length === 0) {
200
+ console.log(`\nℹ️ No versions found for ${selectedWebhook.name}.\n`);
201
+ console.log("💡 Push a version first using 'lua push webhook'.\n");
202
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
203
+ return;
204
+ }
205
+ console.log("\n" + "=".repeat(60));
206
+ console.log(`📜 Versions for ${selectedWebhook.name}`);
207
+ console.log("=".repeat(60) + "\n");
208
+ // Sort versions by date (newest first)
209
+ const sortedVersions = versions.sort((a, b) => {
210
+ const dateA = new Date(a.createdAt).getTime();
211
+ const dateB = new Date(b.createdAt).getTime();
212
+ return dateB - dateA;
213
+ });
214
+ sortedVersions.forEach((version, index) => {
215
+ const isActive = version.webhookId === activeVersionId;
216
+ const date = new Date(version.createdAt);
217
+ console.log(`${index + 1}. Version ${version.version}${isActive ? ' ⭐ DEPLOYED' : ''}`);
218
+ console.log(` Created: ${date.toLocaleString()}`);
219
+ console.log(` Version ID: ${version.webhookId}`);
220
+ console.log();
221
+ });
222
+ console.log("=".repeat(60) + "\n");
223
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
224
+ }
225
+ catch (error) {
226
+ console.error('❌ Error loading versions:', error);
227
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
228
+ }
229
+ }
230
+ /**
231
+ * Deploy a webhook version to production
232
+ */
233
+ async function deployWebhookVersion(context, config) {
234
+ const webhooks = config.webhooks || [];
235
+ if (webhooks.length === 0) {
236
+ console.log("\nℹ️ No webhooks found in configuration.\n");
237
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
238
+ return;
239
+ }
240
+ // Prompt to select a webhook
241
+ const webhookAnswer = await safePrompt([
242
+ {
243
+ type: 'list',
244
+ name: 'selectedWebhook',
245
+ message: 'Select a webhook to deploy:',
246
+ choices: webhooks.map((webhook) => ({
247
+ name: `${webhook.name} (${webhook.webhookId})`,
248
+ value: webhook
249
+ }))
250
+ }
251
+ ]);
252
+ if (!webhookAnswer)
253
+ return;
254
+ const selectedWebhook = webhookAnswer.selectedWebhook;
255
+ writeProgress(`🔄 Loading versions for ${selectedWebhook.name}...`);
256
+ try {
257
+ const webhookApi = new WebhookApi(BASE_URLS.API, context.apiKey, context.agentId);
258
+ const response = await webhookApi.getWebhookVersions(selectedWebhook.webhookId);
259
+ if (!response.success || !response.data) {
260
+ throw new Error(response.error?.message || 'Failed to fetch versions');
261
+ }
262
+ const versions = response.data.versions || [];
263
+ const activeVersionId = response.data.activeVersionId;
264
+ if (versions.length === 0) {
265
+ console.log(`\nℹ️ No versions found for ${selectedWebhook.name}.\n`);
266
+ console.log("💡 Push a version first using 'lua push webhook'.\n");
267
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
268
+ return;
269
+ }
270
+ // Sort versions by date (newest first)
271
+ const sortedVersions = versions.sort((a, b) => {
272
+ const dateA = new Date(a.createdAt).getTime();
273
+ const dateB = new Date(b.createdAt).getTime();
274
+ return dateB - dateA;
275
+ });
276
+ // Prompt to select a version
277
+ const versionAnswer = await safePrompt([
278
+ {
279
+ type: 'list',
280
+ name: 'selectedVersion',
281
+ message: 'Select a version to deploy:',
282
+ choices: sortedVersions.map((version) => {
283
+ const isActive = version.webhookId === activeVersionId;
284
+ const date = new Date(version.createdAt);
285
+ return {
286
+ name: `Version ${version.version} (${date.toLocaleDateString()})${isActive ? ' ⭐ CURRENT' : ''}`,
287
+ value: version
288
+ };
289
+ })
290
+ }
291
+ ]);
292
+ if (!versionAnswer)
293
+ return;
294
+ const selectedVersion = versionAnswer.selectedVersion;
295
+ // Show warning
296
+ console.log("\n⚠️ WARNING: You are about to deploy to PRODUCTION!");
297
+ console.log("⚠️ This will affect ALL users immediately.\n");
298
+ console.log(`Webhook: ${selectedWebhook.name}`);
299
+ console.log(`Version: ${selectedVersion.version}\n`);
300
+ const confirmAnswer = await safePrompt([
301
+ {
302
+ type: 'confirm',
303
+ name: 'confirm',
304
+ message: 'Are you absolutely sure you want to deploy this version?',
305
+ default: false
306
+ }
307
+ ]);
308
+ if (!confirmAnswer || !confirmAnswer.confirm) {
309
+ console.log("\n❌ Deployment cancelled.\n");
310
+ return;
311
+ }
312
+ writeProgress("🔄 Deploying version...");
313
+ // Reuse the same webhookApi instance
314
+ const deployResponse = await webhookApi.publishWebhookVersion(selectedWebhook.webhookId, selectedVersion.version);
315
+ if (!deployResponse.success) {
316
+ console.error(`\n❌ Deploy Error: ${deployResponse.error?.message || 'Unknown error'}\n`);
317
+ throw new Error(deployResponse.error?.message || 'Failed to publish webhook version');
318
+ }
319
+ writeSuccess(`\n✅ Version ${selectedVersion.version} of "${selectedWebhook.name}" deployed successfully to production\n`);
320
+ writeInfo("💡 The new version is now active for all users.");
321
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
322
+ }
323
+ catch (error) {
324
+ console.error('\n❌ Error deploying version:', error);
325
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
326
+ }
327
+ }
328
+ /**
329
+ * Activate a webhook
330
+ */
331
+ async function activateWebhook(context, config) {
332
+ const webhooks = config.webhooks || [];
333
+ if (webhooks.length === 0) {
334
+ console.log("\nℹ️ No webhooks found in configuration.\n");
335
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
336
+ return;
337
+ }
338
+ // Prompt to select a webhook
339
+ const webhookAnswer = await safePrompt([
340
+ {
341
+ type: 'list',
342
+ name: 'selectedWebhook',
343
+ message: 'Select a webhook to activate:',
344
+ choices: webhooks.map((webhook) => ({
345
+ name: `${webhook.name} (${webhook.webhookId})`,
346
+ value: webhook
347
+ }))
348
+ }
349
+ ]);
350
+ if (!webhookAnswer)
351
+ return;
352
+ const selectedWebhook = webhookAnswer.selectedWebhook;
353
+ writeProgress(`🔄 Activating webhook "${selectedWebhook.name}"...`);
354
+ try {
355
+ const webhookApi = new WebhookApi(BASE_URLS.API, context.apiKey, context.agentId);
356
+ const response = await webhookApi.activateWebhook(selectedWebhook.webhookId);
357
+ if (!response.success) {
358
+ console.error(`\n❌ Error: ${response.error?.message || 'Unknown error'}\n`);
359
+ throw new Error(response.error?.message || 'Failed to activate webhook');
360
+ }
361
+ writeSuccess(`\n✅ Webhook "${selectedWebhook.name}" activated successfully\n`);
362
+ writeInfo("💡 The webhook is now enabled and can receive requests.");
363
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
364
+ }
365
+ catch (error) {
366
+ console.error('\n❌ Error activating webhook:', error);
367
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
368
+ }
369
+ }
370
+ /**
371
+ * Deactivate a webhook
372
+ */
373
+ async function deactivateWebhook(context, config) {
374
+ const webhooks = config.webhooks || [];
375
+ if (webhooks.length === 0) {
376
+ console.log("\nℹ️ No webhooks found in configuration.\n");
377
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
378
+ return;
379
+ }
380
+ // Prompt to select a webhook
381
+ const webhookAnswer = await safePrompt([
382
+ {
383
+ type: 'list',
384
+ name: 'selectedWebhook',
385
+ message: 'Select a webhook to deactivate:',
386
+ choices: webhooks.map((webhook) => ({
387
+ name: `${webhook.name} (${webhook.webhookId})`,
388
+ value: webhook
389
+ }))
390
+ }
391
+ ]);
392
+ if (!webhookAnswer)
393
+ return;
394
+ const selectedWebhook = webhookAnswer.selectedWebhook;
395
+ // Confirm deactivation
396
+ const confirmAnswer = await safePrompt([
397
+ {
398
+ type: 'confirm',
399
+ name: 'confirm',
400
+ message: `Are you sure you want to deactivate "${selectedWebhook.name}"? It will stop receiving requests.`,
401
+ default: false
402
+ }
403
+ ]);
404
+ if (!confirmAnswer || !confirmAnswer.confirm) {
405
+ console.log("\n❌ Deactivation cancelled.\n");
406
+ return;
407
+ }
408
+ writeProgress(`🔄 Deactivating webhook "${selectedWebhook.name}"...`);
409
+ try {
410
+ const webhookApi = new WebhookApi(BASE_URLS.API, context.apiKey, context.agentId);
411
+ const response = await webhookApi.deactivateWebhook(selectedWebhook.webhookId);
412
+ if (!response.success) {
413
+ console.error(`\n❌ Error: ${response.error?.message || 'Unknown error'}\n`);
414
+ throw new Error(response.error?.message || 'Failed to deactivate webhook');
415
+ }
416
+ writeSuccess(`\n✅ Webhook "${selectedWebhook.name}" deactivated successfully\n`);
417
+ writeInfo("💡 The webhook is now disabled and will not receive requests.");
418
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
419
+ }
420
+ catch (error) {
421
+ console.error('\n❌ Error deactivating webhook:', error);
422
+ await safePrompt([{ type: 'input', name: 'continue', message: 'Press Enter to continue...' }]);
423
+ }
424
+ }
@@ -39,4 +39,11 @@ export default class DataEntryInstance {
39
39
  * @throws Error if the deletion fails
40
40
  */
41
41
  delete(): Promise<boolean>;
42
+ /**
43
+ * Saves the data entry
44
+ * @param searchText - Optional search text for vector search indexing
45
+ * @returns Promise resolving to true if saving was successful
46
+ * @throws Error if the save operation fails
47
+ */
48
+ save(searchText?: string): Promise<boolean>;
42
49
  }
@@ -144,4 +144,19 @@ export default class DataEntryInstance {
144
144
  throw new Error('Failed to clear user data');
145
145
  }
146
146
  }
147
+ /**
148
+ * Saves the data entry
149
+ * @param searchText - Optional search text for vector search indexing
150
+ * @returns Promise resolving to true if saving was successful
151
+ * @throws Error if the save operation fails
152
+ */
153
+ async save(searchText) {
154
+ try {
155
+ await this.customDataAPI.update(this.collectionName, this.id, { data: this.data, searchText: searchText });
156
+ return true;
157
+ }
158
+ catch (error) {
159
+ throw new Error('Failed to save data entry');
160
+ }
161
+ }
147
162
  }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Job Instance
3
+ * Provides a convenient interface for interacting with a job
4
+ */
5
+ import JobApi from '../api/job.api.service.js';
6
+ /**
7
+ * Job Instance class.
8
+ * Represents a single job with helper methods for common operations.
9
+ *
10
+ * This class provides:
11
+ * - Direct property access to job data via Proxy
12
+ * - Helper methods for job operations (delete, updateMetadata)
13
+ * - Metadata access and modification
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const job = await Jobs.create({
18
+ * name: 'my-job',
19
+ * schedule: { type: 'once', executeAt: new Date() },
20
+ * execute: async (job) => {
21
+ * // Access metadata
22
+ * console.log(job.metadata);
23
+ *
24
+ * // Update metadata
25
+ * await job.updateMetadata({ processed: true });
26
+ *
27
+ * // Delete job when done
28
+ * await job.delete();
29
+ * }
30
+ * });
31
+ * ```
32
+ */
33
+ export declare class JobInstance {
34
+ private jobApi;
35
+ private _data;
36
+ readonly id: string;
37
+ readonly name: string;
38
+ readonly jobId: string;
39
+ readonly schedule: any;
40
+ metadata: Record<string, any>;
41
+ constructor(jobApi: JobApi, jobData: any);
42
+ /**
43
+ * Gets the full job data.
44
+ */
45
+ get data(): any;
46
+ /**
47
+ * Updates the job's metadata.
48
+ *
49
+ * @param metadata - The new metadata to set
50
+ * @returns Promise resolving when update is complete
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * await job.updateMetadata({
55
+ * lastProcessed: new Date().toISOString(),
56
+ * status: 'completed'
57
+ * });
58
+ * ```
59
+ */
60
+ updateMetadata(metadata: Record<string, any>): Promise<void>;
61
+ /**
62
+ * Deletes the job from the backend.
63
+ *
64
+ * @returns Promise resolving when deletion is complete
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * // Delete a one-time job after it completes
69
+ * await job.delete();
70
+ * ```
71
+ */
72
+ delete(): Promise<void>;
73
+ /**
74
+ * Converts the job instance to JSON.
75
+ */
76
+ toJSON(): any;
77
+ }
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Job Instance
3
+ * Provides a convenient interface for interacting with a job
4
+ */
5
+ /**
6
+ * Job Instance class.
7
+ * Represents a single job with helper methods for common operations.
8
+ *
9
+ * This class provides:
10
+ * - Direct property access to job data via Proxy
11
+ * - Helper methods for job operations (delete, updateMetadata)
12
+ * - Metadata access and modification
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * const job = await Jobs.create({
17
+ * name: 'my-job',
18
+ * schedule: { type: 'once', executeAt: new Date() },
19
+ * execute: async (job) => {
20
+ * // Access metadata
21
+ * console.log(job.metadata);
22
+ *
23
+ * // Update metadata
24
+ * await job.updateMetadata({ processed: true });
25
+ *
26
+ * // Delete job when done
27
+ * await job.delete();
28
+ * }
29
+ * });
30
+ * ```
31
+ */
32
+ export class JobInstance {
33
+ constructor(jobApi, jobData) {
34
+ this.jobApi = jobApi;
35
+ this._data = jobData;
36
+ this.id = jobData.id || jobData.jobId;
37
+ this.jobId = jobData.id || jobData.jobId;
38
+ this.name = jobData.name;
39
+ this.schedule = jobData.schedule;
40
+ this.metadata = jobData.metadata || {};
41
+ }
42
+ /**
43
+ * Gets the full job data.
44
+ */
45
+ get data() {
46
+ return this._data;
47
+ }
48
+ /**
49
+ * Updates the job's metadata.
50
+ *
51
+ * @param metadata - The new metadata to set
52
+ * @returns Promise resolving when update is complete
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * await job.updateMetadata({
57
+ * lastProcessed: new Date().toISOString(),
58
+ * status: 'completed'
59
+ * });
60
+ * ```
61
+ */
62
+ async updateMetadata(metadata) {
63
+ this.metadata = { ...this.metadata, ...metadata };
64
+ const result = await this.jobApi.updateMetadata(this.jobId, this.metadata);
65
+ if (!result.success) {
66
+ throw new Error(result.error?.message || 'Failed to update job metadata');
67
+ }
68
+ return result.data;
69
+ // Update metadata on the server if the job has versions
70
+ // Note: Metadata updates may require updating the active version
71
+ // For now, we just update the local instance
72
+ // In the future, this could call an API endpoint to update job metadata
73
+ console.warn('Note: Job metadata updates are stored locally. Deploy a new version to persist changes.');
74
+ }
75
+ /**
76
+ * Deletes the job from the backend.
77
+ *
78
+ * @returns Promise resolving when deletion is complete
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * // Delete a one-time job after it completes
83
+ * await job.delete();
84
+ * ```
85
+ */
86
+ async delete() {
87
+ const result = await this.jobApi.deleteJob(this.jobId);
88
+ if (!result.success) {
89
+ throw new Error(result.error?.message || 'Failed to delete job');
90
+ }
91
+ if (result.data?.deactivated) {
92
+ console.warn(`Job "${this.name}" has versions and was deactivated instead of deleted.`);
93
+ }
94
+ }
95
+ /**
96
+ * Converts the job instance to JSON.
97
+ */
98
+ toJSON() {
99
+ return {
100
+ id: this.id,
101
+ jobId: this.jobId,
102
+ name: this.name,
103
+ schedule: this.schedule,
104
+ metadata: this.metadata,
105
+ ...this._data
106
+ };
107
+ }
108
+ }
@@ -40,4 +40,10 @@ export default class OrderInstance {
40
40
  * @throws Error if the data update fails
41
41
  */
42
42
  update(data: Record<string, any>): Promise<any>;
43
+ /**
44
+ * Saves the order's data
45
+ * @returns Promise resolving to true if saving was successful
46
+ * @throws Error if the save operation fails
47
+ */
48
+ save(): Promise<boolean>;
43
49
  }
@@ -170,4 +170,18 @@ export default class OrderInstance {
170
170
  id: this.id
171
171
  };
172
172
  }
173
+ /**
174
+ * Saves the order's data
175
+ * @returns Promise resolving to true if saving was successful
176
+ * @throws Error if the save operation fails
177
+ */
178
+ async save() {
179
+ try {
180
+ await this.orderAPI.updateData(this.data, this.id);
181
+ return true;
182
+ }
183
+ catch (error) {
184
+ throw new Error('Failed to save order data');
185
+ }
186
+ }
173
187
  }
@@ -33,4 +33,10 @@ export default class ProductInstance {
33
33
  * @throws Error if the deletion fails or the product is not found
34
34
  */
35
35
  delete(): Promise<Product>;
36
+ /**
37
+ * Saves the product's data
38
+ * @returns Promise resolving to true if saving was successful
39
+ * @throws Error if the save operation fails
40
+ */
41
+ save(): Promise<boolean>;
36
42
  }