lua-cli 3.1.0-alpha.3 → 3.1.0-alpha.5

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 (125) hide show
  1. package/README.md +0 -4
  2. package/dist/api/cdn.api.service.d.ts +18 -0
  3. package/dist/api/cdn.api.service.js +43 -0
  4. package/dist/api/custom.data.api.service.d.ts +4 -3
  5. package/dist/api/custom.data.api.service.js +4 -3
  6. package/dist/api/developer.api.service.d.ts +54 -1
  7. package/dist/api/developer.api.service.js +89 -0
  8. package/dist/api/job.api.service.d.ts +33 -100
  9. package/dist/api/job.api.service.js +27 -11
  10. package/dist/api/lazy-instances.d.ts +16 -0
  11. package/dist/api/lazy-instances.js +32 -0
  12. package/dist/api/postprocessor.api.service.d.ts +3 -13
  13. package/dist/api/postprocessor.api.service.js +2 -4
  14. package/dist/api/preprocessor.api.service.d.ts +1 -8
  15. package/dist/api/preprocessor.api.service.js +1 -2
  16. package/dist/api/webhook.api.service.d.ts +1 -3
  17. package/dist/api/webhook.api.service.js +1 -1
  18. package/dist/api/whatsapp-templates.api.service.d.ts +40 -0
  19. package/dist/api/whatsapp-templates.api.service.js +78 -0
  20. package/dist/api-exports.d.ts +153 -6
  21. package/dist/api-exports.js +177 -21
  22. package/dist/cli/command-definitions.js +34 -7
  23. package/dist/commands/admin.js +1 -1
  24. package/dist/commands/channels.js +1 -1
  25. package/dist/commands/chat.js +2 -4
  26. package/dist/commands/compile.js +23 -4
  27. package/dist/commands/evals.d.ts +8 -0
  28. package/dist/commands/evals.js +41 -0
  29. package/dist/commands/index.d.ts +2 -0
  30. package/dist/commands/index.js +2 -0
  31. package/dist/commands/init.d.ts +10 -1
  32. package/dist/commands/init.js +23 -46
  33. package/dist/commands/jobs.js +5 -5
  34. package/dist/commands/mcp.d.ts +18 -0
  35. package/dist/commands/mcp.js +393 -0
  36. package/dist/commands/push.js +174 -23
  37. package/dist/common/data.entry.instance.d.ts +1 -1
  38. package/dist/common/data.entry.instance.js +4 -4
  39. package/dist/common/job.instance.d.ts +59 -7
  40. package/dist/common/job.instance.js +84 -19
  41. package/dist/config/constants.d.ts +1 -0
  42. package/dist/config/constants.js +1 -0
  43. package/dist/index.js +1 -0
  44. package/dist/interfaces/agent.d.ts +0 -3
  45. package/dist/interfaces/cdn.d.ts +24 -0
  46. package/dist/interfaces/cdn.js +5 -0
  47. package/dist/interfaces/compile.d.ts +1 -0
  48. package/dist/interfaces/custom.data.d.ts +3 -3
  49. package/dist/interfaces/index.d.ts +2 -1
  50. package/dist/interfaces/init.d.ts +0 -1
  51. package/dist/interfaces/jobs.d.ts +88 -132
  52. package/dist/interfaces/jobs.js +1 -1
  53. package/dist/interfaces/mcp.d.ts +64 -0
  54. package/dist/interfaces/mcp.js +5 -0
  55. package/dist/interfaces/postprocessors.d.ts +0 -3
  56. package/dist/interfaces/preprocessors.d.ts +0 -3
  57. package/dist/interfaces/webhooks.d.ts +0 -5
  58. package/dist/interfaces/whatsapp-templates.d.ts +104 -0
  59. package/dist/interfaces/whatsapp-templates.js +5 -0
  60. package/dist/types/api-contracts.d.ts +68 -14
  61. package/dist/types/compile.types.d.ts +5 -6
  62. package/dist/types/index.d.ts +2 -2
  63. package/dist/types/index.js +3 -1
  64. package/dist/types/skill.d.ts +181 -103
  65. package/dist/types/skill.js +123 -91
  66. package/dist/utils/agent-management.d.ts +3 -5
  67. package/dist/utils/agent-management.js +6 -8
  68. package/dist/utils/bundling.d.ts +4 -11
  69. package/dist/utils/bundling.js +24 -33
  70. package/dist/utils/compile.d.ts +17 -9
  71. package/dist/utils/compile.js +72 -88
  72. package/dist/utils/deployment.js +13 -7
  73. package/dist/utils/dev-api.js +1 -4
  74. package/dist/utils/dev-server.js +1 -1
  75. package/dist/utils/files.d.ts +11 -4
  76. package/dist/utils/files.js +17 -14
  77. package/dist/utils/init-agent.d.ts +1 -2
  78. package/dist/utils/init-agent.js +4 -6
  79. package/dist/utils/init-helpers.d.ts +4 -4
  80. package/dist/utils/init-helpers.js +10 -11
  81. package/dist/utils/job-management.js +0 -2
  82. package/dist/utils/mcp-server-management.d.ts +23 -0
  83. package/dist/utils/mcp-server-management.js +212 -0
  84. package/dist/utils/postprocessor-management.js +2 -4
  85. package/dist/utils/preprocessor-management.js +2 -4
  86. package/dist/utils/sandbox.d.ts +4 -2
  87. package/dist/utils/sandbox.js +38 -9
  88. package/dist/utils/webhook-management.js +1 -3
  89. package/dist/web/app.css +1505 -14
  90. package/dist/web/app.js +79 -64
  91. package/package.json +2 -6
  92. package/template/QUICKSTART.md +57 -774
  93. package/template/README.md +80 -907
  94. package/template/examples/README.md +106 -0
  95. package/template/{src → examples}/jobs/AbandonedBasketProcessorJob.ts +67 -14
  96. package/template/{src → examples}/jobs/DailyCleanupJob.ts +0 -3
  97. package/template/{src → examples}/jobs/DataMigrationJob.ts +0 -3
  98. package/template/{src → examples}/jobs/HealthCheckJob.ts +0 -3
  99. package/template/{src → examples}/postprocessors/modifyResponse.ts +3 -4
  100. package/template/examples/preprocessors/messageMatching.ts +35 -0
  101. package/template/{src → examples}/skills/basket.skill.ts +0 -1
  102. package/template/{src → examples}/skills/product.skill.ts +0 -1
  103. package/template/{src → examples}/skills/tools/GameScoreTrackerTool.ts +11 -15
  104. package/template/{src → examples}/skills/tools/OrderTool.ts +25 -0
  105. package/template/examples/skills/tools/PremiumFeatureTool.ts +98 -0
  106. package/template/{src → examples}/skills/tools/UserDataTool.ts +34 -0
  107. package/template/{src → examples}/skills/user.skill.ts +0 -1
  108. package/template/examples/webhooks/FileUploadWebhook.ts +86 -0
  109. package/template/{src → examples}/webhooks/PaymentWebhook.ts +12 -9
  110. package/template/examples/webhooks/UserEventWebhook.ts +105 -0
  111. package/template/package-lock.json +7895 -0
  112. package/template/package.json +1 -1
  113. package/template/src/index.ts +40 -22
  114. package/template/src/preprocessors/messageMatching.ts +0 -22
  115. package/template/src/webhooks/UserEventWebhook.ts +0 -77
  116. /package/template/{src → examples}/services/ApiService.ts +0 -0
  117. /package/template/{src → examples}/services/GetWeather.ts +0 -0
  118. /package/template/{src → examples}/skills/tools/BasketTool.ts +0 -0
  119. /package/template/{src → examples}/skills/tools/CreateInlineJob.ts +0 -0
  120. /package/template/{src → examples}/skills/tools/CreatePostTool.ts +0 -0
  121. /package/template/{src → examples}/skills/tools/CustomDataTool.ts +0 -0
  122. /package/template/{src → examples}/skills/tools/GetWeatherTool.ts +0 -0
  123. /package/template/{src → examples}/skills/tools/PaymentTool.ts +0 -0
  124. /package/template/{src → examples}/skills/tools/ProductsTool.ts +0 -0
  125. /package/template/{src → examples}/skills/tools/SmartBasketTool.ts +0 -0
@@ -14,10 +14,11 @@ export declare function getTemplateDir(): string;
14
14
  * @param agentId - Agent ID for configuration
15
15
  * @param orgId - Organization ID for configuration
16
16
  * @param persona - Optional persona configuration
17
- * @param welcomeMessage - Optional welcome message
17
+ * @param agentName - Optional agent name
18
+ * @param withExamples - Whether to include example skills, tools, jobs, etc. (default: false)
18
19
  * @returns Current working directory
19
20
  */
20
- export declare function initializeProject(agentId: string, orgId: string, persona?: string, welcomeMessage?: string, agentName?: string): string;
21
+ export declare function initializeProject(agentId: string, orgId: string, persona?: string, agentName?: string, withExamples?: boolean): string;
21
22
  /**
22
23
  * Installs npm dependencies for the project.
23
24
  *
@@ -45,6 +46,5 @@ export declare function clearLinesIfNeeded(lineCount: number): void;
45
46
  * @param projectDir - Project directory containing src/index.ts
46
47
  * @param agentName - Name of the agent
47
48
  * @param persona - Agent persona
48
- * @param welcomeMessage - Welcome message
49
49
  */
50
- export declare function updateLuaAgentInIndexFile(projectDir: string, agentName?: string, persona?: string, welcomeMessage?: string): void;
50
+ export declare function updateLuaAgentInIndexFile(projectDir: string, agentName?: string, persona?: string): void;
@@ -24,18 +24,22 @@ export function getTemplateDir() {
24
24
  * @param agentId - Agent ID for configuration
25
25
  * @param orgId - Organization ID for configuration
26
26
  * @param persona - Optional persona configuration
27
- * @param welcomeMessage - Optional welcome message
27
+ * @param agentName - Optional agent name
28
+ * @param withExamples - Whether to include example skills, tools, jobs, etc. (default: false)
28
29
  * @returns Current working directory
29
30
  */
30
- export function initializeProject(agentId, orgId, persona, welcomeMessage, agentName) {
31
+ export function initializeProject(agentId, orgId, persona, agentName, withExamples = false) {
31
32
  const templateDir = getTemplateDir();
32
33
  const currentDir = process.cwd();
33
- copyTemplateFiles(templateDir, currentDir);
34
- createSkillYaml(agentId, orgId, undefined, undefined, persona, welcomeMessage);
34
+ copyTemplateFiles(templateDir, currentDir, withExamples);
35
+ createSkillYaml(agentId, orgId, undefined, undefined, persona);
35
36
  // Update LuaAgent in index.ts with agent configuration
36
- updateLuaAgentInIndexFile(currentDir, agentName, persona, welcomeMessage);
37
+ updateLuaAgentInIndexFile(currentDir, agentName, persona);
37
38
  writeProgress("✅ Created lua.skill.yaml");
38
39
  writeProgress("✅ Copied template files");
40
+ if (withExamples) {
41
+ writeProgress("✅ Included example skills, tools, jobs, and webhooks");
42
+ }
39
43
  writeProgress("✅ Updated LuaAgent configuration");
40
44
  return currentDir;
41
45
  }
@@ -81,9 +85,8 @@ export function clearLinesIfNeeded(lineCount) {
81
85
  * @param projectDir - Project directory containing src/index.ts
82
86
  * @param agentName - Name of the agent
83
87
  * @param persona - Agent persona
84
- * @param welcomeMessage - Welcome message
85
88
  */
86
- export function updateLuaAgentInIndexFile(projectDir, agentName, persona, welcomeMessage) {
89
+ export function updateLuaAgentInIndexFile(projectDir, agentName, persona) {
87
90
  const indexPath = path.join(projectDir, 'src', 'index.ts');
88
91
  if (!fs.existsSync(indexPath)) {
89
92
  // If no index.ts, skip (might be an old template structure)
@@ -103,10 +106,6 @@ export function updateLuaAgentInIndexFile(projectDir, agentName, persona, welcom
103
106
  if (persona) {
104
107
  content = content.replace(/(persona:\s*['"`])[\s\S]*?(['"`])/, `$1${persona.replace(/'/g, "\\'").replace(/`/g, '\\`')}$2`);
105
108
  }
106
- // Update welcome message
107
- if (welcomeMessage) {
108
- content = content.replace(/(welcomeMessage:\s*['"])[\s\S]*?(['"])/, `$1${welcomeMessage.replace(/'/g, "\\'")}$2`);
109
- }
110
109
  fs.writeFileSync(indexPath, content);
111
110
  }
112
111
  catch (error) {
@@ -82,7 +82,6 @@ async function createJobViaApi(job, config, existingJobs, existingJob) {
82
82
  const jobPayload = {
83
83
  name: job.name,
84
84
  description: job.description || `A Lua job for ${job.name}`,
85
- context: job.context || '',
86
85
  schedule: job.schedule || { type: 'cron', expression: '0 0 * * *' },
87
86
  timeout: job.timeout,
88
87
  retry: job.retry,
@@ -96,7 +95,6 @@ async function createJobViaApi(job, config, existingJobs, existingJob) {
96
95
  if (!existingJob) {
97
96
  existingJobs.push({
98
97
  name: job.name || '',
99
- version: job.version || SKILL_DEFAULTS.VERSION,
100
98
  jobId: newJobId,
101
99
  schedule: job.schedule
102
100
  });
@@ -0,0 +1,23 @@
1
+ /**
2
+ * MCP Server Management Utilities
3
+ * Handles MCP server configuration in lua.skill.yaml
4
+ */
5
+ import { YamlConfig } from '../types/compile.types.js';
6
+ /**
7
+ * Ensures all detected MCP servers exist in the YAML config and database.
8
+ * Uses upsert to create or update servers via API during compile (like skills).
9
+ * YAML only tracks name and ID - the full configuration stays in source code.
10
+ *
11
+ * @param mcpServersArray - Array of MCP servers detected from source code (with full config)
12
+ * @param config - The skill configuration from lua.skill.yaml
13
+ * @returns Updated MCP servers array with IDs assigned
14
+ */
15
+ export declare function ensureMCPServersExistInYaml(mcpServersArray: any[], config: YamlConfig): Promise<any[]>;
16
+ /**
17
+ * Syncs the server MCP servers with the YAML configuration.
18
+ * Deletes MCP servers from the server that aren't in YAML (removed from source code).
19
+ *
20
+ * @param config - The skill configuration from lua.skill.yaml
21
+ * @returns Array of messages about sync operations
22
+ */
23
+ export declare function syncServerMCPServersWithYaml(config: YamlConfig): Promise<string[]>;
@@ -0,0 +1,212 @@
1
+ /**
2
+ * MCP Server Management Utilities
3
+ * Handles MCP server configuration in lua.skill.yaml
4
+ */
5
+ import fs from "fs";
6
+ import path from "path";
7
+ import yaml from "js-yaml";
8
+ import { COMPILE_FILES, YAML_FORMAT, } from '../config/compile.constants.js';
9
+ import { loadApiKey } from '../services/auth.js';
10
+ import { BASE_URLS } from '../config/constants.js';
11
+ import DeveloperApi from '../api/developer.api.service.js';
12
+ /**
13
+ * Ensures all detected MCP servers exist in the YAML config and database.
14
+ * Uses upsert to create or update servers via API during compile (like skills).
15
+ * YAML only tracks name and ID - the full configuration stays in source code.
16
+ *
17
+ * @param mcpServersArray - Array of MCP servers detected from source code (with full config)
18
+ * @param config - The skill configuration from lua.skill.yaml
19
+ * @returns Updated MCP servers array with IDs assigned
20
+ */
21
+ export async function ensureMCPServersExistInYaml(mcpServersArray, config) {
22
+ const existingServers = config?.mcpServers || [];
23
+ const existingServersMap = createMCPServersMap(existingServers);
24
+ const updatedServersArray = [];
25
+ let yamlUpdated = false;
26
+ // Process each detected MCP server from source code
27
+ for (const server of mcpServersArray) {
28
+ const existingServer = existingServersMap.get(server.name);
29
+ if (existingServer && existingServer.mcpServerId && existingServer.mcpServerId !== '') {
30
+ // Server exists with valid ID - reuse it
31
+ updatedServersArray.push({
32
+ ...server, // Full config from source code
33
+ mcpServerId: existingServer.mcpServerId // ID from YAML
34
+ });
35
+ }
36
+ else {
37
+ // Server doesn't exist or missing ID - upsert via API
38
+ const upsertedServer = await upsertMCPServerViaApi(server, config, existingServers, existingServer);
39
+ updatedServersArray.push(upsertedServer);
40
+ yamlUpdated = true;
41
+ }
42
+ }
43
+ // Update YAML file with tracking info (name + ID only)
44
+ if (yamlUpdated) {
45
+ await updateYamlWithMCPServers(updatedServersArray, config);
46
+ }
47
+ return updatedServersArray;
48
+ }
49
+ /**
50
+ * Creates a map of existing MCP servers for quick lookup by name.
51
+ */
52
+ function createMCPServersMap(existingServers) {
53
+ const map = new Map();
54
+ existingServers.forEach((server) => {
55
+ map.set(server.name, server);
56
+ });
57
+ return map;
58
+ }
59
+ /**
60
+ * Creates or updates an MCP server via the Lua API (upsert by name).
61
+ *
62
+ * @param server - The MCP server to upsert (with full config)
63
+ * @param config - The skill configuration
64
+ * @param existingServers - Array of existing servers (mutated)
65
+ * @param existingServer - The existing server entry if one exists (may be without ID)
66
+ * @returns The server with its ID
67
+ */
68
+ async function upsertMCPServerViaApi(server, config, existingServers, existingServer) {
69
+ try {
70
+ // Validate prerequisites
71
+ const apiKey = await loadApiKey();
72
+ if (!apiKey) {
73
+ throw new Error("No API key found. Run 'lua auth configure' first.");
74
+ }
75
+ const agentId = config?.agent?.agentId;
76
+ if (!agentId) {
77
+ throw new Error("No agent ID found in lua.skill.yaml. Run 'lua init' first.");
78
+ }
79
+ // Prepare server data for upsert
80
+ const serverData = {
81
+ name: server.name,
82
+ transport: server.transport,
83
+ timeout: server.timeout,
84
+ ...(server.transport === 'stdio' ? {
85
+ command: server.command,
86
+ args: server.args,
87
+ env: server.env
88
+ } : {
89
+ url: server.url,
90
+ headers: server.headers
91
+ })
92
+ };
93
+ // Upsert server via API (creates if new, updates if exists by name)
94
+ const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, agentId);
95
+ const result = await developerApi.upsertMCPServer(serverData);
96
+ if (!result.success || !result.data?.id) {
97
+ throw new Error(result.error?.message || 'Failed to upsert MCP server');
98
+ }
99
+ const mcpServerId = result.data.id;
100
+ // Update or add to existing servers array
101
+ if (existingServer) {
102
+ existingServer.mcpServerId = mcpServerId;
103
+ }
104
+ else {
105
+ existingServers.push({
106
+ name: server.name,
107
+ mcpServerId: mcpServerId
108
+ });
109
+ }
110
+ console.log(` ✅ Synced MCP server "${server.name}" with ID: ${mcpServerId}`);
111
+ return {
112
+ ...server,
113
+ mcpServerId: mcpServerId
114
+ };
115
+ }
116
+ catch (error) {
117
+ console.error(` ❌ Failed to sync MCP server "${server.name}":`, error.message);
118
+ throw error;
119
+ }
120
+ }
121
+ /**
122
+ * Updates the lua.skill.yaml file with MCP server tracking (name and ID only).
123
+ * IDs are assigned during compile via API (like skills).
124
+ * The full server configuration remains in the source code as the single source of truth.
125
+ */
126
+ async function updateYamlWithMCPServers(mcpServers, config) {
127
+ const yamlPath = path.join(process.cwd(), COMPILE_FILES.LUA_SKILL_YAML);
128
+ // Read existing content
129
+ let existingConfig = {};
130
+ if (fs.existsSync(yamlPath)) {
131
+ const yamlContent = fs.readFileSync(yamlPath, 'utf8');
132
+ existingConfig = yaml.load(yamlContent);
133
+ }
134
+ // Update MCP servers section - only track name and ID (like skills)
135
+ existingConfig.mcpServers = mcpServers.map(server => ({
136
+ name: server.name,
137
+ mcpServerId: server.mcpServerId // Always present after upsert during compile
138
+ }));
139
+ // Write updated YAML
140
+ const yamlContent = yaml.dump(existingConfig, {
141
+ indent: YAML_FORMAT.INDENT,
142
+ lineWidth: YAML_FORMAT.LINE_WIDTH,
143
+ noRefs: YAML_FORMAT.NO_REFS
144
+ });
145
+ fs.writeFileSync(yamlPath, yamlContent);
146
+ }
147
+ /**
148
+ * Syncs the server MCP servers with the YAML configuration.
149
+ * Deletes MCP servers from the server that aren't in YAML (removed from source code).
150
+ *
151
+ * @param config - The skill configuration from lua.skill.yaml
152
+ * @returns Array of messages about sync operations
153
+ */
154
+ export async function syncServerMCPServersWithYaml(config) {
155
+ const messages = [];
156
+ try {
157
+ // Validate prerequisites
158
+ const apiKey = await loadApiKey();
159
+ if (!apiKey) {
160
+ console.warn("⚠️ No API key found. Skipping server MCP server sync.");
161
+ return messages;
162
+ }
163
+ const agentId = config?.agent?.agentId;
164
+ if (!agentId) {
165
+ console.warn("⚠️ No agent ID found in lua.skill.yaml. Skipping server MCP server sync.");
166
+ return messages;
167
+ }
168
+ // Get MCP servers from server
169
+ const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, agentId);
170
+ const serverMCPServersResponse = await developerApi.getMCPServers();
171
+ if (!serverMCPServersResponse.success || !serverMCPServersResponse.data) {
172
+ console.warn("⚠️ Could not retrieve server MCP servers. Skipping server MCP server sync.");
173
+ return messages;
174
+ }
175
+ const serverMCPServers = serverMCPServersResponse.data;
176
+ const yamlMCPServers = config?.mcpServers || [];
177
+ // Create map of YAML MCP servers by ID for efficient lookup
178
+ const yamlMCPServersMap = new Map(yamlMCPServers
179
+ .filter((server) => server.mcpServerId)
180
+ .map((server) => [server.mcpServerId, server]));
181
+ // Find MCP servers on server that aren't in YAML (removed from source code)
182
+ const serversToDelete = serverMCPServers.filter(serverMCP => !yamlMCPServersMap.has(serverMCP.id));
183
+ // Delete servers that are no longer in YAML
184
+ for (const server of serversToDelete) {
185
+ try {
186
+ const deleteResponse = await developerApi.deleteMCPServer(server.id);
187
+ if (deleteResponse.success) {
188
+ const msg = `✅ Deleted MCP server "${server.name}" from server (removed from source code)`;
189
+ messages.push(msg);
190
+ console.log(msg);
191
+ }
192
+ else {
193
+ const msg = `❌ Failed to delete MCP server "${server.name}": ${deleteResponse.error?.message || 'Unknown error'}`;
194
+ messages.push(msg);
195
+ console.error(msg);
196
+ }
197
+ }
198
+ catch (error) {
199
+ const msg = `❌ Error deleting MCP server "${server.name}": ${error}`;
200
+ messages.push(msg);
201
+ console.error(msg);
202
+ }
203
+ }
204
+ if (serversToDelete.length === 0) {
205
+ console.log("✅ Server MCP servers and YAML are fully in sync");
206
+ }
207
+ }
208
+ catch (error) {
209
+ console.error("❌ Error syncing server MCP servers:", error);
210
+ }
211
+ return messages;
212
+ }
@@ -7,7 +7,7 @@ import yaml from "js-yaml";
7
7
  import PostProcessorApi from '../api/postprocessor.api.service.js';
8
8
  import { BASE_URLS } from '../config/constants.js';
9
9
  import { loadApiKey } from '../services/auth.js';
10
- import { SKILL_DEFAULTS, YAML_FORMAT } from '../config/compile.constants.js';
10
+ import { YAML_FORMAT } from '../config/compile.constants.js';
11
11
  /**
12
12
  * Ensures all detected postprocessors exist in the YAML config with valid IDs.
13
13
  */
@@ -45,8 +45,7 @@ async function createPostProcessorViaApi(postprocessor, config, existingPostProc
45
45
  throw new Error("No agent ID found in lua.skill.yaml. Run 'lua init' first.");
46
46
  const payload = {
47
47
  name: postprocessor.name,
48
- description: postprocessor.description || `A Lua postprocessor for ${postprocessor.name}`,
49
- context: postprocessor.context || ''
48
+ description: postprocessor.description || `A Lua postprocessor for ${postprocessor.name}`
50
49
  };
51
50
  const api = new PostProcessorApi(BASE_URLS.API, apiKey, agentId);
52
51
  const result = await api.createPostProcessor(payload);
@@ -55,7 +54,6 @@ async function createPostProcessorViaApi(postprocessor, config, existingPostProc
55
54
  if (!existingPostProcessor) {
56
55
  existingPostProcessors.push({
57
56
  name: postprocessor.name || '',
58
- version: postprocessor.version || SKILL_DEFAULTS.VERSION,
59
57
  postprocessorId: newId
60
58
  });
61
59
  }
@@ -7,7 +7,7 @@ import yaml from "js-yaml";
7
7
  import PreProcessorApi from '../api/preprocessor.api.service.js';
8
8
  import { BASE_URLS } from '../config/constants.js';
9
9
  import { loadApiKey } from '../services/auth.js';
10
- import { SKILL_DEFAULTS, YAML_FORMAT } from '../config/compile.constants.js';
10
+ import { YAML_FORMAT } from '../config/compile.constants.js';
11
11
  /**
12
12
  * Ensures all detected preprocessors exist in the YAML config with valid IDs.
13
13
  */
@@ -45,8 +45,7 @@ async function createPreProcessorViaApi(preprocessor, config, existingPreProcess
45
45
  throw new Error("No agent ID found in lua.skill.yaml. Run 'lua init' first.");
46
46
  const payload = {
47
47
  name: preprocessor.name,
48
- description: preprocessor.description || `A Lua preprocessor for ${preprocessor.name}`,
49
- context: preprocessor.context || ''
48
+ description: preprocessor.description || `A Lua preprocessor for ${preprocessor.name}`
50
49
  };
51
50
  const api = new PreProcessorApi(BASE_URLS.API, apiKey, agentId);
52
51
  const result = await api.createPreProcessor(payload);
@@ -55,7 +54,6 @@ async function createPreProcessorViaApi(preprocessor, config, existingPreProcess
55
54
  if (!existingPreProcessor) {
56
55
  existingPreProcessors.push({
57
56
  name: preprocessor.name || '',
58
- version: preprocessor.version || SKILL_DEFAULTS.VERSION,
59
57
  preprocessorId: newId
60
58
  });
61
59
  }
@@ -45,8 +45,10 @@ export declare function loadEnvironmentVariables(): Record<string, string>;
45
45
  * - Data: Custom data collections API
46
46
  * - Baskets: Shopping basket API
47
47
  * - Orders: Order management API
48
- * - Webhooks: Webhook management API (new)
49
- * - Jobs: Job scheduling API (new)
48
+ * - Templates: Template APIs (whatsapp)
49
+ * - CDN: File upload/retrieval API
50
+ * - Jobs: Job scheduling API
51
+ * - AI: AI generation API
50
52
  * - env(): Environment variable access function
51
53
  * - console, fetch, and other standard globals
52
54
  */
@@ -11,6 +11,8 @@ import OrderApiService from "../api/order.api.service.js";
11
11
  import CustomDataApiService from "../api/custom.data.api.service.js";
12
12
  import WebhookApi from "../api/webhook.api.service.js";
13
13
  import JobApi from "../api/job.api.service.js";
14
+ import WhatsAppTemplatesApiService from "../api/whatsapp-templates.api.service.js";
15
+ import CdnApiService from "../api/cdn.api.service.js";
14
16
  import { BasketStatus } from "../interfaces/baskets.js";
15
17
  import { OrderStatus } from "../interfaces/orders.js";
16
18
  import { compressCode } from "./compile.js";
@@ -67,8 +69,10 @@ export function loadEnvironmentVariables() {
67
69
  * - Data: Custom data collections API
68
70
  * - Baskets: Shopping basket API
69
71
  * - Orders: Order management API
70
- * - Webhooks: Webhook management API (new)
71
- * - Jobs: Job scheduling API (new)
72
+ * - Templates: Template APIs (whatsapp)
73
+ * - CDN: File upload/retrieval API
74
+ * - Jobs: Job scheduling API
75
+ * - AI: AI generation API
72
76
  * - env(): Environment variable access function
73
77
  * - console, fetch, and other standard globals
74
78
  */
@@ -88,6 +92,8 @@ export function createSandbox(options) {
88
92
  const orderService = new OrderApiService(BASE_URLS.API, apiKey, agentId);
89
93
  const webhookService = new WebhookApi(BASE_URLS.API, apiKey, agentId);
90
94
  const jobService = new JobApi(BASE_URLS.API, apiKey, agentId);
95
+ const whatsAppTemplatesService = new WhatsAppTemplatesApiService(BASE_URLS.API, apiKey, agentId);
96
+ const cdnService = new CdnApiService(BASE_URLS.CDN, apiKey);
91
97
  // Override User service methods if needed
92
98
  // Example: Override the update method
93
99
  // const originalUpdate = userService.update.bind(userService);
@@ -195,6 +201,8 @@ export function createSandbox(options) {
195
201
  Headers: globalThis.Headers,
196
202
  Request: globalThis.Request,
197
203
  Response: globalThis.Response,
204
+ File: globalThis.File,
205
+ Blob: globalThis.Blob,
198
206
  FormData: polyfills.FormData,
199
207
  AbortController: polyfills.AbortController,
200
208
  TextEncoder: polyfills.TextEncoder,
@@ -224,6 +232,12 @@ export function createSandbox(options) {
224
232
  Baskets: basketsService,
225
233
  compressCode: compressCode,
226
234
  Orders: orderService,
235
+ // Templates API with namespaces for different template types
236
+ Templates: {
237
+ whatsapp: whatsAppTemplatesService
238
+ },
239
+ // CDN API
240
+ CDN: cdnService,
227
241
  // Jobs API
228
242
  Jobs: {
229
243
  create: async (config) => {
@@ -235,7 +249,6 @@ export function createSandbox(options) {
235
249
  return await jobService.createJobInstance({
236
250
  name: config.name + '_' + Date.now(),
237
251
  description: config.description,
238
- context: config.description || '',
239
252
  schedule: config.schedule,
240
253
  timeout: config.timeout,
241
254
  retry: config.retry,
@@ -244,7 +257,6 @@ export function createSandbox(options) {
244
257
  version: {
245
258
  version: '1.0.0',
246
259
  description: config.description,
247
- context: config.description || '',
248
260
  code: '',
249
261
  executeFunction: executeString,
250
262
  timeout: config.timeout,
@@ -254,7 +266,8 @@ export function createSandbox(options) {
254
266
  activate: config.activate ?? true
255
267
  });
256
268
  },
257
- get: async (jobId) => jobService.getJob(jobId)
269
+ getJob: async (jobId) => jobService.getJob(jobId),
270
+ getAll: async (options = {}) => jobService.getAll(options)
258
271
  },
259
272
  // Environment variables function
260
273
  env: (key) => envVars[key],
@@ -323,6 +336,8 @@ try{
323
336
  global.Response = Response;
324
337
  global.URL = URL;
325
338
  global.URLSearchParams = URLSearchParams;
339
+ global.File = File;
340
+ global.Blob = Blob;
326
341
  }
327
342
  `, context);
328
343
  vm.runInContext(commonJsWrapper, context);
@@ -345,9 +360,9 @@ export async function executeWebhook(options) {
345
360
  const executeFunction = ${webhookCode};
346
361
 
347
362
  // Export the function for testing
348
- module.exports = async (query, headers, body) => {
363
+ module.exports = async (event) => {
349
364
  try{
350
- return await executeFunction(query, headers, body);
365
+ return await executeFunction(event);
351
366
  }catch(e){
352
367
  console.error(e);
353
368
  return { status: 'error', error: e.message };
@@ -370,12 +385,20 @@ try{
370
385
  global.Response = Response;
371
386
  global.URL = URL;
372
387
  global.URLSearchParams = URLSearchParams;
388
+ global.File = File;
389
+ global.Blob = Blob;
373
390
  }
374
391
  `, context);
375
392
  vm.runInContext(commonJsWrapper, context);
376
- // Get the exported function and execute with webhook input structure
393
+ // Get the exported function and execute with unified event object
377
394
  const executeFunction = context.module.exports;
378
- return await executeFunction({ query, headers, body });
395
+ const event = {
396
+ query: query ?? {},
397
+ headers: headers ?? {},
398
+ body,
399
+ timestamp: new Date().toISOString()
400
+ };
401
+ return await executeFunction(event);
379
402
  }
380
403
  /**
381
404
  * Executes a job in a sandboxed environment.
@@ -439,6 +462,8 @@ try{
439
462
  global.Response = Response;
440
463
  global.URL = URL;
441
464
  global.URLSearchParams = URLSearchParams;
465
+ global.File = File;
466
+ global.Blob = Blob;
442
467
  }
443
468
  `, context);
444
469
  vm.runInContext(commonJsWrapper, context);
@@ -491,6 +516,8 @@ try{
491
516
  global.Response = Response;
492
517
  global.URL = URL;
493
518
  global.URLSearchParams = URLSearchParams;
519
+ global.File = File;
520
+ global.Blob = Blob;
494
521
  }
495
522
  `, context);
496
523
  vm.runInContext(commonJsWrapper, context);
@@ -543,6 +570,8 @@ try{
543
570
  global.Response = Response;
544
571
  global.URL = URL;
545
572
  global.URLSearchParams = URLSearchParams;
573
+ global.File = File;
574
+ global.Blob = Blob;
546
575
  }
547
576
  `, context);
548
577
  vm.runInContext(commonJsWrapper, context);
@@ -81,8 +81,7 @@ async function createWebhookViaApi(webhook, config, existingWebhooks, existingWe
81
81
  // Create webhook via API
82
82
  const webhookPayload = {
83
83
  name: webhook.name,
84
- description: webhook.description || `A Lua webhook for ${webhook.name}`,
85
- context: webhook.context || ''
84
+ description: webhook.description || `A Lua webhook for ${webhook.name}`
86
85
  };
87
86
  const webhookApi = new WebhookApi(BASE_URLS.API, apiKey, agentId);
88
87
  const result = await webhookApi.createWebhook(webhookPayload);
@@ -92,7 +91,6 @@ async function createWebhookViaApi(webhook, config, existingWebhooks, existingWe
92
91
  if (!existingWebhook) {
93
92
  existingWebhooks.push({
94
93
  name: webhook.name || '',
95
- version: webhook.version || SKILL_DEFAULTS.VERSION,
96
94
  webhookId: newWebhookId
97
95
  });
98
96
  }