lua-cli 2.5.8 → 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 (98) hide show
  1. package/dist/api/job.api.service.d.ts +210 -0
  2. package/dist/api/job.api.service.js +200 -0
  3. package/dist/api/lazy-instances.d.ts +24 -0
  4. package/dist/api/lazy-instances.js +48 -0
  5. package/dist/api/postprocessor.api.service.d.ts +98 -0
  6. package/dist/api/postprocessor.api.service.js +76 -0
  7. package/dist/api/preprocessor.api.service.d.ts +98 -0
  8. package/dist/api/preprocessor.api.service.js +76 -0
  9. package/dist/api/user.data.api.service.d.ts +13 -0
  10. package/dist/api/user.data.api.service.js +20 -0
  11. package/dist/api/webhook.api.service.d.ts +151 -0
  12. package/dist/api/webhook.api.service.js +134 -0
  13. package/dist/api-exports.d.ts +156 -41
  14. package/dist/api-exports.js +182 -21
  15. package/dist/cli/command-definitions.js +75 -5
  16. package/dist/commands/compile.js +124 -5
  17. package/dist/commands/index.d.ts +4 -0
  18. package/dist/commands/index.js +4 -0
  19. package/dist/commands/init.js +53 -7
  20. package/dist/commands/jobs.d.ts +20 -0
  21. package/dist/commands/jobs.js +533 -0
  22. package/dist/commands/logs.js +2 -5
  23. package/dist/commands/postprocessors.d.ts +8 -0
  24. package/dist/commands/postprocessors.js +431 -0
  25. package/dist/commands/preprocessors.d.ts +8 -0
  26. package/dist/commands/preprocessors.js +431 -0
  27. package/dist/commands/push.js +684 -5
  28. package/dist/commands/test.d.ts +9 -18
  29. package/dist/commands/test.js +558 -82
  30. package/dist/commands/webhooks.d.ts +18 -0
  31. package/dist/commands/webhooks.js +424 -0
  32. package/dist/common/job.instance.d.ts +77 -0
  33. package/dist/common/job.instance.js +108 -0
  34. package/dist/common/user.instance.d.ts +1 -0
  35. package/dist/common/user.instance.js +9 -0
  36. package/dist/config/constants.d.ts +2 -2
  37. package/dist/config/constants.js +4 -4
  38. package/dist/interfaces/agent.d.ts +2 -1
  39. package/dist/interfaces/chat.d.ts +22 -0
  40. package/dist/interfaces/index.d.ts +10 -0
  41. package/dist/interfaces/index.js +7 -0
  42. package/dist/interfaces/jobs.d.ts +172 -0
  43. package/dist/interfaces/jobs.js +5 -0
  44. package/dist/interfaces/postprocessors.d.ts +35 -0
  45. package/dist/interfaces/postprocessors.js +4 -0
  46. package/dist/interfaces/preprocessors.d.ts +35 -0
  47. package/dist/interfaces/preprocessors.js +4 -0
  48. package/dist/interfaces/webhooks.d.ts +104 -0
  49. package/dist/interfaces/webhooks.js +5 -0
  50. package/dist/types/api-contracts.d.ts +5 -0
  51. package/dist/types/compile.types.d.ts +49 -0
  52. package/dist/types/index.d.ts +1 -1
  53. package/dist/types/index.js +1 -1
  54. package/dist/types/skill.d.ts +502 -0
  55. package/dist/types/skill.js +477 -0
  56. package/dist/utils/agent-management.d.ts +25 -0
  57. package/dist/utils/agent-management.js +67 -0
  58. package/dist/utils/bundling.d.ts +31 -1
  59. package/dist/utils/bundling.js +653 -10
  60. package/dist/utils/compile.d.ts +63 -0
  61. package/dist/utils/compile.js +691 -36
  62. package/dist/utils/deployment.d.ts +2 -1
  63. package/dist/utils/deployment.js +16 -2
  64. package/dist/utils/init-agent.d.ts +3 -1
  65. package/dist/utils/init-agent.js +6 -4
  66. package/dist/utils/init-prompts.d.ts +2 -1
  67. package/dist/utils/init-prompts.js +14 -9
  68. package/dist/utils/job-management.d.ts +24 -0
  69. package/dist/utils/job-management.js +264 -0
  70. package/dist/utils/postprocessor-management.d.ts +9 -0
  71. package/dist/utils/postprocessor-management.js +118 -0
  72. package/dist/utils/preprocessor-management.d.ts +9 -0
  73. package/dist/utils/preprocessor-management.js +118 -0
  74. package/dist/utils/sandbox.d.ts +61 -1
  75. package/dist/utils/sandbox.js +283 -72
  76. package/dist/utils/tool-detection.d.ts +3 -2
  77. package/dist/utils/tool-detection.js +18 -4
  78. package/dist/utils/webhook-management.d.ts +24 -0
  79. package/dist/utils/webhook-management.js +256 -0
  80. package/package.json +1 -1
  81. package/template/AGENT_CONFIGURATION.md +251 -0
  82. package/template/COMPLEX_JOB_EXAMPLES.md +795 -0
  83. package/template/DYNAMIC_JOB_CREATION.md +371 -0
  84. package/template/README.md +30 -2
  85. package/template/WEBHOOKS_JOBS_QUICKSTART.md +318 -0
  86. package/template/WEBHOOK_JOB_EXAMPLES.md +817 -0
  87. package/template/src/index-agent-example.ts +201 -0
  88. package/template/src/index.ts +39 -0
  89. package/template/src/jobs/AbandonedBasketProcessorJob.ts +139 -0
  90. package/template/src/jobs/DailyCleanupJob.ts +100 -0
  91. package/template/src/jobs/DataMigrationJob.ts +133 -0
  92. package/template/src/jobs/HealthCheckJob.ts +87 -0
  93. package/template/src/postprocessors/ResponseFormatter.ts +151 -0
  94. package/template/src/preprocessors/MessageFilter.ts +91 -0
  95. package/template/src/tools/GameScoreTrackerTool.ts +356 -0
  96. package/template/src/tools/SmartBasketTool.ts +188 -0
  97. package/template/src/webhooks/PaymentWebhook.ts +113 -0
  98. package/template/src/webhooks/UserEventWebhook.ts +77 -0
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Smart Basket Tool Example
3
+ *
4
+ * This tool creates a basket AND schedules a follow-up job to check if it was abandoned.
5
+ * Demonstrates: Dynamic job creation, basket management, and automated follow-ups.
6
+ *
7
+ * Use case: E-commerce abandoned cart recovery
8
+ */
9
+
10
+ import { LuaTool, Baskets, Jobs, Data } from "lua-cli";
11
+ import { z } from "zod";
12
+
13
+ export class CreateSmartBasketTool implements LuaTool {
14
+ name = "create_smart_basket";
15
+ description = "Creates a basket with automatic abandoned cart reminder";
16
+
17
+ inputSchema = z.object({
18
+ currency: z.string().default('USD')
19
+ });
20
+
21
+ async execute(input: { currency: string }) {
22
+ console.log('🛒 Creating smart basket with auto-reminder...');
23
+
24
+ // Step 1: Create the basket
25
+ const basketData = {
26
+ currency: input.currency,
27
+ metadata: {
28
+ createdBy: 'smart-basket-tool',
29
+ reminderScheduled: true,
30
+ createdAt: new Date().toISOString()
31
+ }
32
+ };
33
+
34
+ const basketInstance = await Baskets.create(basketData);
35
+ const basketInfo = await basketInstance.getData();
36
+
37
+ console.log(`✅ Basket created: ${basketInfo.id}`);
38
+
39
+ // Step 2: Schedule a one-time job to check the basket in 3 hours
40
+ const checkTime = new Date(Date.now() + 3 * 60 * 60 * 1000); // 3 hours from now
41
+
42
+ // Capture basketId in closure for the job
43
+ const basketId = basketInfo.id;
44
+
45
+ // Create a dynamic one-time job using the Jobs API!
46
+
47
+ const job = await Jobs.create({
48
+ name: `check-basket-${basketId}`,
49
+ description: `Check if basket ${basketId} was checked out`,
50
+
51
+ // One-time job that runs in 3 hours
52
+ schedule: {
53
+ type: 'once',
54
+ executeAt: checkTime
55
+ },
56
+
57
+ timeout: 60, // 1 minute timeout
58
+
59
+ // Write normal TypeScript code! It will be compiled automatically
60
+ execute: async () => {
61
+ console.log(`⏰ Checking basket ${basketId}...`);
62
+
63
+ const basketInstance = await Baskets.getById(basketId);
64
+ const basket = await basketInstance.getData();
65
+
66
+ if (basket.status === 'active' || basket.status === 'pending') {
67
+ // Basket is still active - it was abandoned!
68
+ console.log(`🛒 Basket ${basketId} was abandoned`);
69
+
70
+ await Data.create('abandoned-baskets', {
71
+ basketId: basketId,
72
+ currency: basket.currency,
73
+ itemCount: basket.items?.length || 0,
74
+ totalValue: basket.total || 0,
75
+ abandonedAt: new Date().toISOString()
76
+ });
77
+
78
+ console.log('📧 Sending abandoned cart reminder email...');
79
+ // TODO: Integrate with email service
80
+ // await sendEmail({
81
+ // to: userEmail,
82
+ // template: 'abandoned-cart',
83
+ // data: { basket }
84
+ // });
85
+
86
+ return {
87
+ abandoned: true,
88
+ basketId: basketId,
89
+ reminderSent: true
90
+ };
91
+ }
92
+
93
+ console.log(`✅ Basket ${basketId} was checked out`);
94
+ return {
95
+ abandoned: false,
96
+ basketId: basketId,
97
+ status: basket.status
98
+ };
99
+ }
100
+ });
101
+
102
+ console.log(`⏰ One-time job created: ${job.jobId}`);
103
+ console.log(`📅 Will execute at: ${checkTime.toLocaleString()}`);
104
+
105
+ // Return basket info with job details
106
+ return {
107
+ success: true,
108
+ basket: {
109
+ id: basketInfo.id,
110
+ currency: basketInfo.currency,
111
+ status: basketInfo.status
112
+ },
113
+ scheduledJob: {
114
+ jobId: job.jobId,
115
+ name: job.name,
116
+ scheduledFor: checkTime.toISOString(),
117
+ message: 'One-time job will check basket in 3 hours'
118
+ }
119
+ };
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Check Abandoned Baskets Tool
125
+ *
126
+ * This tool can be called manually or by a recurring job to check for abandoned baskets.
127
+ */
128
+ export class CheckAbandonedBasketsTool implements LuaTool {
129
+ name = "check_abandoned_baskets";
130
+ description = "Checks for abandoned baskets and sends reminders";
131
+
132
+ inputSchema = z.object({
133
+ basketId: z.string().optional()
134
+ });
135
+
136
+ async execute(input: { basketId?: string }) {
137
+ console.log('🔍 Checking for abandoned baskets...');
138
+
139
+ // Get all abandoned baskets from data collection
140
+ const abandonedBasketsData = await Data.get('abandoned-baskets', {}, 1, 100);
141
+ const abandonedBaskets = abandonedBasketsData.data || [];
142
+
143
+ if (input.basketId) {
144
+ // Check specific basket
145
+ const specific = abandonedBaskets.find((ab: any) => ab.data.basketId === input.basketId);
146
+
147
+ if (specific) {
148
+ return {
149
+ basketId: input.basketId,
150
+ abandoned: true,
151
+ abandonedAt: specific.data.abandonedAt,
152
+ itemCount: specific.data.itemCount,
153
+ totalValue: specific.data.totalValue
154
+ };
155
+ }
156
+
157
+ // Not in abandoned list - check current status
158
+ const basketInstance = await Baskets.getById(input.basketId);
159
+ const basket = await basketInstance.getData();
160
+
161
+ return {
162
+ basketId: input.basketId,
163
+ abandoned: false,
164
+ status: basket.status,
165
+ itemCount: basket.items?.length || 0
166
+ };
167
+ }
168
+
169
+ // Return all abandoned baskets summary
170
+ const summary = abandonedBaskets.map((ab: any) => ({
171
+ basketId: ab.data.basketId,
172
+ currency: ab.data.currency,
173
+ itemCount: ab.data.itemCount,
174
+ totalValue: ab.data.totalValue,
175
+ abandonedAt: ab.data.abandonedAt
176
+ }));
177
+
178
+ console.log(`🛒 Found ${abandonedBaskets.length} abandoned baskets`);
179
+
180
+ return {
181
+ success: true,
182
+ abandonedCount: abandonedBaskets.length,
183
+ abandonedBaskets: summary,
184
+ timestamp: new Date().toISOString()
185
+ };
186
+ }
187
+ }
188
+
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Payment Webhook Example
3
+ *
4
+ * This webhook receives payment notifications from payment providers (Stripe, PayPal, etc.).
5
+ * It validates signatures, processes payment events, and updates order status.
6
+ *
7
+ * Common use case: Stripe webhook for payment confirmations
8
+ */
9
+
10
+ import { LuaWebhook, Orders, Data } from "lua-cli";
11
+ import { z } from "zod";
12
+
13
+ const paymentWebhook = new LuaWebhook({
14
+ name: "payment-notifications",
15
+ version: "1.0.0",
16
+ description: "Receives payment notifications from payment providers",
17
+ context: "This webhook processes payment confirmation events from Stripe or other providers. " +
18
+ "It validates the payment, updates order status, and logs the transaction.",
19
+
20
+ // Headers typically include webhook signature for verification
21
+ headerSchema: z.object({
22
+ 'stripe-signature': z.string().optional(),
23
+ 'content-type': z.string()
24
+ }),
25
+
26
+ // Payment event body
27
+ bodySchema: z.object({
28
+ type: z.string(), // e.g., 'payment_intent.succeeded'
29
+ data: z.object({
30
+ object: z.object({
31
+ id: z.string(),
32
+ amount: z.number(),
33
+ currency: z.string(),
34
+ status: z.string(),
35
+ metadata: z.object({
36
+ orderId: z.string().optional(),
37
+ customerId: z.string().optional()
38
+ }).optional()
39
+ })
40
+ })
41
+ }),
42
+
43
+ execute: async ({ headers, body }) => {
44
+ console.log(`💳 Payment event received:`, body.type);
45
+
46
+ // In production: Verify Stripe signature
47
+ // const signature = headers['stripe-signature'];
48
+ // const isValid = verifyStripeSignature(body, signature);
49
+ // if (!isValid) throw new Error('Invalid signature');
50
+
51
+ const payment = body.data.object;
52
+ const eventType = body.type;
53
+
54
+ // Handle payment success
55
+ if (eventType === 'payment_intent.succeeded') {
56
+ console.log(`✅ Payment successful: ${payment.amount} ${payment.currency}`);
57
+
58
+ // Update order if we have orderId in metadata
59
+ if (payment.metadata?.orderId) {
60
+ try {
61
+ await Orders.updateStatus('confirmed', payment.metadata.orderId);
62
+ console.log(`📦 Order ${payment.metadata.orderId} marked as confirmed`);
63
+ } catch (error) {
64
+ console.error('Failed to update order:', error);
65
+ }
66
+ }
67
+
68
+ // Log the transaction
69
+ await Data.create('payment-logs', {
70
+ paymentId: payment.id,
71
+ amount: payment.amount,
72
+ currency: payment.currency,
73
+ orderId: payment.metadata?.orderId,
74
+ customerId: payment.metadata?.customerId,
75
+ status: 'succeeded',
76
+ receivedAt: new Date().toISOString()
77
+ });
78
+
79
+ return {
80
+ success: true,
81
+ paymentId: payment.id,
82
+ orderId: payment.metadata?.orderId,
83
+ message: 'Payment processed successfully'
84
+ };
85
+ }
86
+
87
+ // Handle payment failure
88
+ if (eventType === 'payment_intent.payment_failed') {
89
+ console.log(`❌ Payment failed: ${payment.id}`);
90
+
91
+ await Data.create('payment-logs', {
92
+ paymentId: payment.id,
93
+ status: 'failed',
94
+ receivedAt: new Date().toISOString()
95
+ });
96
+
97
+ return {
98
+ success: true,
99
+ paymentId: payment.id,
100
+ message: 'Payment failure logged'
101
+ };
102
+ }
103
+
104
+ // Other event types
105
+ return {
106
+ success: true,
107
+ message: `Event ${eventType} received`
108
+ };
109
+ }
110
+ });
111
+
112
+ export default paymentWebhook;
113
+
@@ -0,0 +1,77 @@
1
+ /**
2
+ * User Event Webhook Example
3
+ *
4
+ * This webhook receives user events from external systems (e.g., CRM, marketing tools).
5
+ * It validates incoming data and stores events for processing.
6
+ *
7
+ * Webhook URL: {API_URL}/webhooks/{agentId}/{webhookId}
8
+ */
9
+
10
+ import { LuaWebhook, Data } from "lua-cli";
11
+ import { z } from "zod";
12
+
13
+ const userEventWebhook = new LuaWebhook({
14
+ name: "user-events",
15
+ version: "1.0.0",
16
+ description: "Receives user events from external systems",
17
+ context: "This webhook handles user registration, profile updates, and deletion events. " +
18
+ "It validates the incoming data, stores events in the database, and can trigger follow-up actions.",
19
+
20
+ // Validate query parameters (optional source tracking)
21
+ querySchema: z.object({
22
+ source: z.string().optional(),
23
+ version: z.string().optional()
24
+ }),
25
+
26
+ // Validate headers (require API key for security)
27
+ headerSchema: z.object({
28
+ 'x-api-key': z.string(),
29
+ 'content-type': z.string().optional()
30
+ }),
31
+
32
+ // Validate request body
33
+ bodySchema: z.object({
34
+ eventType: z.enum(['signup', 'update', 'delete']),
35
+ userId: z.string(),
36
+ email: z.string().email(),
37
+ name: z.string().optional(),
38
+ metadata: z.record(z.any()).optional(),
39
+ timestamp: z.string()
40
+ }),
41
+
42
+ execute: async ({ query, headers, body }) => {
43
+ console.log(`📥 Received ${body.eventType} event for user:`, body.email);
44
+ console.log(`📍 Source:`, query?.source || 'unknown');
45
+
46
+ // Security: Validate API key (in production, use env variable)
47
+ const expectedKey = process.env.WEBHOOK_API_KEY || 'your-secret-key';
48
+ if (headers['x-api-key'] !== expectedKey) {
49
+ throw new Error('Invalid API key');
50
+ }
51
+
52
+ // Store the event in custom data collection
53
+ const eventData = {
54
+ ...body,
55
+ source: query?.source,
56
+ receivedAt: new Date().toISOString(),
57
+ processed: false
58
+ };
59
+
60
+ const result = await Data.create('user-events', eventData,
61
+ `${body.eventType} ${body.email} ${body.name || ''}`
62
+ );
63
+
64
+ console.log('✅ Event stored successfully:', result.id);
65
+
66
+ // Return success response
67
+ return {
68
+ success: true,
69
+ eventId: result.id,
70
+ userId: body.userId,
71
+ timestamp: new Date().toISOString()
72
+ };
73
+ }
74
+ });
75
+
76
+ export default userEventWebhook;
77
+