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
@@ -12,24 +12,25 @@ export declare function compressCode(code: string): string;
12
12
  */
13
13
  export declare function findIndexFile(): string;
14
14
  /**
15
- * Resolves import path from module specifier with support for multiple extensions and index files
16
- * @param moduleSpecifier - The import path (e.g., './tools/MyTool' or '../utils')
15
+ * Resolves import path from module specifier with support for multiple extensions and index files.
16
+ * Handles modern TypeScript projects that use .js extensions in imports (Node16/NodeNext resolution).
17
+ * @param moduleSpecifier - The import path (e.g., './tools/MyTool.js' or '../utils')
17
18
  * @param currentFilePath - The file doing the importing
18
19
  * @returns Resolved absolute file path
19
20
  */
20
21
  export declare function resolveImportPath(moduleSpecifier: string, currentFilePath: string): string;
21
- /**
22
- * Creates execute function wrapper from bundled code
23
- */
24
- export declare function createExecuteFunction(bundledCode: string, tool: ToolInfo): string;
25
22
  /**
26
23
  * Evaluates Zod schema code and converts it to JSON Schema
27
24
  */
28
25
  export declare function evaluateZodSchemaToJsonSchema(zodSchemaCode: string): Promise<any>;
29
26
  /**
30
- * Wraps bundled tool code for VM execution
27
+ * Wraps raw bundled tool code for execute function
28
+ */
29
+ export declare function wrapExecuteForVM(bundledCode: string, className: string): string;
30
+ /**
31
+ * Wraps raw bundled tool code for condition evaluation
31
32
  */
32
- export declare function wrapToolForVM(outputPath: string, tool: ToolInfo): Promise<void>;
33
+ export declare function wrapConditionForVM(bundledCode: string, className: string): string;
33
34
  /**
34
35
  * Extracts tool information from a new expression in the AST
35
36
  */
@@ -64,12 +65,12 @@ export declare function extractPostProcessorsMetadata(indexFile: any): any[];
64
65
  export declare function extractLuaAgentMetadata(indexFile: any): {
65
66
  name: string;
66
67
  persona: string;
67
- welcomeMessage?: string;
68
68
  skills: any[];
69
69
  webhooks: any[];
70
70
  jobs: any[];
71
71
  preProcessors: any[];
72
72
  postProcessors: any[];
73
+ mcpServers: any[];
73
74
  } | null;
74
75
  /**
75
76
  * Gets the file paths where skills are defined in a LuaAgent.
@@ -94,10 +95,17 @@ export declare function resolveLuaAgentReferences(agentMetadata: {
94
95
  jobs: any[];
95
96
  preProcessors: any[];
96
97
  postProcessors: any[];
98
+ mcpServers: any[];
97
99
  }, indexFile: any, project: Project): {
98
100
  skills: any[];
99
101
  webhooks: any[];
100
102
  jobs: any[];
101
103
  preProcessors: any[];
102
104
  postProcessors: any[];
105
+ mcpServers: any[];
103
106
  };
107
+ /**
108
+ * Extracts MCP server metadata from a source file.
109
+ * Looks for LuaMCPServer constructor calls.
110
+ */
111
+ export declare function extractMCPServersMetadata(sourceFile: any): any[];
@@ -29,17 +29,24 @@ export function findIndexFile() {
29
29
  throw new Error("index.ts not found in current directory or src/ directory");
30
30
  }
31
31
  /**
32
- * Resolves import path from module specifier with support for multiple extensions and index files
33
- * @param moduleSpecifier - The import path (e.g., './tools/MyTool' or '../utils')
32
+ * Resolves import path from module specifier with support for multiple extensions and index files.
33
+ * Handles modern TypeScript projects that use .js extensions in imports (Node16/NodeNext resolution).
34
+ * @param moduleSpecifier - The import path (e.g., './tools/MyTool.js' or '../utils')
34
35
  * @param currentFilePath - The file doing the importing
35
36
  * @returns Resolved absolute file path
36
37
  */
37
38
  export function resolveImportPath(moduleSpecifier, currentFilePath) {
38
39
  const extensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js'];
39
- if (moduleSpecifier.startsWith('./') || moduleSpecifier.startsWith('../')) {
40
+ // Handle modern TS projects using .js extensions in imports (Node16/NodeNext module resolution)
41
+ // Strip the extension so we can properly resolve to the .ts source file
42
+ let normalizedSpecifier = moduleSpecifier;
43
+ if (moduleSpecifier.endsWith('.js')) {
44
+ normalizedSpecifier = moduleSpecifier.slice(0, -3);
45
+ }
46
+ if (normalizedSpecifier.startsWith('./') || normalizedSpecifier.startsWith('../')) {
40
47
  // Relative import - resolve relative to current file
41
48
  const currentDir = path.dirname(currentFilePath);
42
- const basePath = path.resolve(currentDir, moduleSpecifier);
49
+ const basePath = path.resolve(currentDir, normalizedSpecifier);
43
50
  // Try each extension in order
44
51
  for (const ext of extensions) {
45
52
  const fullPath = ext.startsWith('/') ? path.join(basePath, ext) : basePath + ext;
@@ -52,7 +59,7 @@ export function resolveImportPath(moduleSpecifier, currentFilePath) {
52
59
  }
53
60
  else {
54
61
  // Absolute import - check in src/ directory
55
- const srcBase = path.resolve(process.cwd(), 'src', moduleSpecifier);
62
+ const srcBase = path.resolve(process.cwd(), 'src', normalizedSpecifier);
56
63
  for (const ext of extensions) {
57
64
  const fullPath = ext.startsWith('/') ? path.join(srcBase, ext) : srcBase + ext;
58
65
  if (fs.existsSync(fullPath)) {
@@ -60,17 +67,9 @@ export function resolveImportPath(moduleSpecifier, currentFilePath) {
60
67
  }
61
68
  }
62
69
  // Fallback: return .ts in src/ (original behavior)
63
- return path.resolve(process.cwd(), 'src', moduleSpecifier + '.ts');
70
+ return path.resolve(process.cwd(), 'src', normalizedSpecifier + '.ts');
64
71
  }
65
72
  }
66
- /**
67
- * Creates execute function wrapper from bundled code
68
- */
69
- export function createExecuteFunction(bundledCode, tool) {
70
- // The bundled code is already wrapped for VM execution by wrapToolForVM
71
- // Just return it directly since it's already an async function
72
- return bundledCode;
73
- }
74
73
  /**
75
74
  * Evaluates Zod schema code and converts it to JSON Schema
76
75
  */
@@ -109,25 +108,28 @@ export async function evaluateZodSchemaToJsonSchema(zodSchemaCode) {
109
108
  }
110
109
  }
111
110
  /**
112
- * Wraps bundled tool code for VM execution
111
+ * Wraps raw bundled tool code for execute function
113
112
  */
114
- export async function wrapToolForVM(outputPath, tool) {
115
- const bundledCode = fs.readFileSync(outputPath, 'utf8');
116
- // Create a wrapper that's compatible with the existing sandbox.ts VM system
117
- // The sandbox expects: const executeFunction = ${toolCode}; module.exports = async (input) => { return await executeFunction(input); };
118
- const wrappedCode = `async (input) => {
119
-
120
- // Execute the bundled tool code
113
+ export function wrapExecuteForVM(bundledCode, className) {
114
+ return `async (input) => {
121
115
  ${bundledCode}
122
116
 
123
- // Get the tool class from exports
124
- const ToolClass = module.exports.default || module.exports.${tool.className} || module.exports;
125
-
126
- // Create and execute the tool
117
+ const ToolClass = module.exports.default || module.exports.${className} || module.exports;
127
118
  const toolInstance = new ToolClass();
128
119
  return await toolInstance.execute(input);
129
120
  }`;
130
- fs.writeFileSync(outputPath, wrappedCode);
121
+ }
122
+ /**
123
+ * Wraps raw bundled tool code for condition evaluation
124
+ */
125
+ export function wrapConditionForVM(bundledCode, className) {
126
+ return `async () => {
127
+ ${bundledCode}
128
+
129
+ const ToolClass = module.exports.default || module.exports.${className} || module.exports;
130
+ const toolInstance = new ToolClass();
131
+ return await toolInstance.condition() === true;
132
+ }`;
131
133
  }
132
134
  /**
133
135
  * Extracts tool information from a new expression in the AST
@@ -235,7 +237,6 @@ export function extractSkillsMetadata(indexFile) {
235
237
  if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
236
238
  const configObj = args[0];
237
239
  let skillName = '';
238
- let skillVersion = '';
239
240
  let description = '';
240
241
  let context = '';
241
242
  let constructorTools = [];
@@ -247,9 +248,6 @@ export function extractSkillsMetadata(indexFile) {
247
248
  if (name === 'name' && value) {
248
249
  skillName = value.getText().replace(/['"]/g, '');
249
250
  }
250
- else if (name === 'version' && value) {
251
- skillVersion = value.getText().replace(/['"]/g, '');
252
- }
253
251
  else if (name === 'description' && value) {
254
252
  description = value.getText().replace(/['"]/g, '');
255
253
  }
@@ -271,7 +269,6 @@ export function extractSkillsMetadata(indexFile) {
271
269
  if (skillName) {
272
270
  skills.push({
273
271
  name: skillName,
274
- version: skillVersion || '1.0.0',
275
272
  description,
276
273
  context,
277
274
  constructorTools
@@ -297,9 +294,7 @@ export function extractWebhooksMetadata(indexFile) {
297
294
  if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
298
295
  const configObj = args[0];
299
296
  let webhookName = '';
300
- let webhookVersion = '';
301
297
  let description = '';
302
- let context = '';
303
298
  // Extract properties
304
299
  configObj.getProperties().forEach((prop) => {
305
300
  if (Node.isPropertyAssignment(prop)) {
@@ -308,23 +303,15 @@ export function extractWebhooksMetadata(indexFile) {
308
303
  if (name === 'name' && value) {
309
304
  webhookName = value.getText().replace(/['"]/g, '');
310
305
  }
311
- else if (name === 'version' && value) {
312
- webhookVersion = value.getText().replace(/['"]/g, '');
313
- }
314
306
  else if (name === 'description' && value) {
315
307
  description = value.getText().replace(/['"]/g, '');
316
308
  }
317
- else if (name === 'context' && value) {
318
- context = value.getText().replace(/['"]/g, '');
319
- }
320
309
  }
321
310
  });
322
311
  if (webhookName) {
323
312
  webhooks.push({
324
313
  name: webhookName,
325
- version: webhookVersion || '1.0.0',
326
- description,
327
- context
314
+ description
328
315
  });
329
316
  }
330
317
  }
@@ -347,9 +334,7 @@ export function extractJobsMetadata(indexFile) {
347
334
  if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
348
335
  const configObj = args[0];
349
336
  let jobName = '';
350
- let jobVersion = '';
351
337
  let description = '';
352
- let context = '';
353
338
  let schedule = null;
354
339
  let timeout;
355
340
  let retry = undefined;
@@ -362,15 +347,9 @@ export function extractJobsMetadata(indexFile) {
362
347
  if (name === 'name' && value) {
363
348
  jobName = value.getText().replace(/['"]/g, '');
364
349
  }
365
- else if (name === 'version' && value) {
366
- jobVersion = value.getText().replace(/['"]/g, '');
367
- }
368
350
  else if (name === 'description' && value) {
369
351
  description = value.getText().replace(/['"]/g, '');
370
352
  }
371
- else if (name === 'context' && value) {
372
- context = value.getText().replace(/['"]/g, '');
373
- }
374
353
  else if (name === 'schedule' && value) {
375
354
  // Extract schedule configuration
376
355
  try {
@@ -412,9 +391,7 @@ export function extractJobsMetadata(indexFile) {
412
391
  if (jobName) {
413
392
  jobs.push({
414
393
  name: jobName,
415
- version: jobVersion || '1.0.0',
416
394
  description,
417
- context,
418
395
  schedule,
419
396
  timeout,
420
397
  retry,
@@ -441,9 +418,7 @@ export function extractPreProcessorsMetadata(indexFile) {
441
418
  if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
442
419
  const configObj = args[0];
443
420
  let name = '';
444
- let version = '';
445
421
  let description = '';
446
- let context = '';
447
422
  let asyncMode = false;
448
423
  configObj.getProperties().forEach((prop) => {
449
424
  if (Node.isPropertyAssignment(prop)) {
@@ -452,15 +427,9 @@ export function extractPreProcessorsMetadata(indexFile) {
452
427
  if (propName === 'name' && value) {
453
428
  name = value.getText().replace(/['"]/g, '');
454
429
  }
455
- else if (propName === 'version' && value) {
456
- version = value.getText().replace(/['"]/g, '');
457
- }
458
430
  else if (propName === 'description' && value) {
459
431
  description = value.getText().replace(/['"]/g, '');
460
432
  }
461
- else if (propName === 'context' && value) {
462
- context = value.getText().replace(/['"]/g, '');
463
- }
464
433
  else if (propName === 'async' && value) {
465
434
  // Properly extract boolean value by checking node kind
466
435
  const nodeKind = value.getKind();
@@ -471,9 +440,7 @@ export function extractPreProcessorsMetadata(indexFile) {
471
440
  if (name) {
472
441
  preprocessors.push({
473
442
  name,
474
- version: version || '1.0.0',
475
443
  description,
476
- context,
477
444
  async: asyncMode
478
445
  });
479
446
  }
@@ -497,10 +464,7 @@ export function extractPostProcessorsMetadata(indexFile) {
497
464
  if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
498
465
  const configObj = args[0];
499
466
  let name = '';
500
- let version = '';
501
467
  let description = '';
502
- let context = '';
503
- let asyncMode = false;
504
468
  configObj.getProperties().forEach((prop) => {
505
469
  if (Node.isPropertyAssignment(prop)) {
506
470
  const propName = prop.getName();
@@ -508,29 +472,15 @@ export function extractPostProcessorsMetadata(indexFile) {
508
472
  if (propName === 'name' && value) {
509
473
  name = value.getText().replace(/['"]/g, '');
510
474
  }
511
- else if (propName === 'version' && value) {
512
- version = value.getText().replace(/['"]/g, '');
513
- }
514
475
  else if (propName === 'description' && value) {
515
476
  description = value.getText().replace(/['"]/g, '');
516
477
  }
517
- else if (propName === 'context' && value) {
518
- context = value.getText().replace(/['"]/g, '');
519
- }
520
- else if (propName === 'async' && value) {
521
- // Properly extract boolean value by checking node kind
522
- const nodeKind = value.getKind();
523
- asyncMode = nodeKind === 110; // TrueKeyword = 110, FalseKeyword = 95
524
- }
525
478
  }
526
479
  });
527
480
  if (name) {
528
481
  postprocessors.push({
529
482
  name,
530
- version: version || '1.0.0',
531
- description,
532
- context,
533
- async: asyncMode
483
+ description
534
484
  });
535
485
  }
536
486
  }
@@ -558,12 +508,12 @@ export function extractLuaAgentMetadata(indexFile) {
558
508
  const configObj = args[0];
559
509
  let name = '';
560
510
  let persona = '';
561
- let welcomeMessage = '';
562
511
  const skills = [];
563
512
  const webhooks = [];
564
513
  const jobs = [];
565
514
  const preProcessors = [];
566
515
  const postProcessors = [];
516
+ const mcpServers = [];
567
517
  // Extract properties from LuaAgent config
568
518
  configObj.getProperties().forEach((prop) => {
569
519
  if (Node.isPropertyAssignment(prop)) {
@@ -581,9 +531,6 @@ export function extractLuaAgentMetadata(indexFile) {
581
531
  .replace(/\\n/g, '\n')
582
532
  .trim();
583
533
  }
584
- else if (propName === 'welcomeMessage' && value) {
585
- welcomeMessage = value.getText().replace(/['"]/g, '');
586
- }
587
534
  else if (propName === 'skills' && value && Node.isArrayLiteralExpression(value)) {
588
535
  // Extract skill references from the array
589
536
  value.getElements().forEach((element) => {
@@ -657,18 +604,34 @@ export function extractLuaAgentMetadata(indexFile) {
657
604
  }
658
605
  });
659
606
  }
607
+ else if (propName === 'mcpServers' && value && Node.isArrayLiteralExpression(value)) {
608
+ // Extract MCP server references from the array
609
+ value.getElements().forEach((element) => {
610
+ if (Node.isIdentifier(element)) {
611
+ mcpServers.push({ ref: element.getText() });
612
+ }
613
+ else if (Node.isNewExpression(element)) {
614
+ // Extract inline MCP server metadata
615
+ const mcpArgs = element.getArguments();
616
+ if (mcpArgs.length > 0 && Node.isObjectLiteralExpression(mcpArgs[0])) {
617
+ const mcpConfig = extractConfigFromObjectLiteral(mcpArgs[0]);
618
+ mcpServers.push(mcpConfig);
619
+ }
620
+ }
621
+ });
622
+ }
660
623
  }
661
624
  });
662
625
  if (name && persona) {
663
626
  agentMetadata = {
664
627
  name,
665
628
  persona,
666
- welcomeMessage: welcomeMessage || undefined,
667
629
  skills,
668
630
  webhooks,
669
631
  jobs,
670
632
  preProcessors,
671
- postProcessors
633
+ postProcessors,
634
+ mcpServers
672
635
  };
673
636
  }
674
637
  }
@@ -838,9 +801,30 @@ export function resolveLuaAgentReferences(agentMetadata, indexFile, project) {
838
801
  webhooks: resolveArrayReferences(agentMetadata.webhooks, extractWebhooksMetadata),
839
802
  jobs: resolveArrayReferences(agentMetadata.jobs, extractJobsMetadata),
840
803
  preProcessors: resolveArrayReferences(agentMetadata.preProcessors, extractPreProcessorsMetadata),
841
- postProcessors: resolveArrayReferences(agentMetadata.postProcessors, extractPostProcessorsMetadata)
804
+ postProcessors: resolveArrayReferences(agentMetadata.postProcessors, extractPostProcessorsMetadata),
805
+ mcpServers: resolveArrayReferences(agentMetadata.mcpServers, extractMCPServersMetadata)
842
806
  };
843
807
  }
808
+ /**
809
+ * Extracts MCP server metadata from a source file.
810
+ * Looks for LuaMCPServer constructor calls.
811
+ */
812
+ export function extractMCPServersMetadata(sourceFile) {
813
+ const mcpServers = [];
814
+ sourceFile.forEachDescendant((node) => {
815
+ if (Node.isNewExpression(node)) {
816
+ const expression = node.getExpression();
817
+ if (expression.getText() === 'LuaMCPServer') {
818
+ const args = node.getArguments();
819
+ if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
820
+ const config = extractConfigFromObjectLiteral(args[0]);
821
+ mcpServers.push(config);
822
+ }
823
+ }
824
+ }
825
+ });
826
+ return mcpServers;
827
+ }
844
828
  /**
845
829
  * Finds a variable declaration in a source file by name.
846
830
  */
@@ -152,15 +152,21 @@ function buildSkillsArray(skillsMetadata, skillToTools, tools) {
152
152
  }
153
153
  return {
154
154
  name: skillMeta.name,
155
- version: skillMeta.version,
156
155
  description: skillMeta.description,
157
156
  context: skillMeta.context,
158
- tools: skillTools.map(tool => ({
159
- name: tool.name,
160
- description: tool.description || '',
161
- inputSchema: tool.inputSchema || DEFAULT_INPUT_SCHEMA,
162
- execute: compressCode(tool.executeCode || '')
163
- }))
157
+ tools: skillTools.map(tool => {
158
+ const toolData = {
159
+ name: tool.name,
160
+ description: tool.description || '',
161
+ inputSchema: tool.inputSchema || DEFAULT_INPUT_SCHEMA,
162
+ execute: compressCode(tool.executeCode || '')
163
+ };
164
+ // Include condition if tool has one
165
+ if (tool.conditionCode) {
166
+ toolData.condition = compressCode(tool.conditionCode);
167
+ }
168
+ return toolData;
169
+ })
164
170
  };
165
171
  });
166
172
  }
@@ -290,7 +290,6 @@ export async function pushSinglePreProcessorToSandbox(apiKey, agentId, preproces
290
290
  name: preprocessorName,
291
291
  version: sandboxVersion,
292
292
  description: preprocessorData.description,
293
- context: preprocessorData.context,
294
293
  code: preprocessorData.code,
295
294
  executeFunction: preprocessorData.executeFunction,
296
295
  async: Boolean(preprocessorData.async ?? false)
@@ -349,10 +348,8 @@ export async function pushSinglePostProcessorToSandbox(apiKey, agentId, postproc
349
348
  name: postprocessorName,
350
349
  version: sandboxVersion,
351
350
  description: postprocessorData.description,
352
- context: postprocessorData.context,
353
351
  code: postprocessorData.code,
354
- executeFunction: postprocessorData.executeFunction,
355
- async: Boolean(postprocessorData.async ?? false)
352
+ executeFunction: postprocessorData.executeFunction
356
353
  };
357
354
  if (sandboxPostProcessorId) {
358
355
  // Try to update existing sandbox version
@@ -792,7 +792,7 @@ async function handleCustomDataEndpoint(req, res, apiKey, agentId) {
792
792
  req.on('end', () => resolve(data));
793
793
  });
794
794
  const updateData = JSON.parse(body);
795
- result = await customDataApi.update(collectionName, entryId, updateData);
795
+ result = await customDataApi.update(collectionName, entryId, updateData.data, updateData.searchText);
796
796
  res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
797
797
  res.end(JSON.stringify({ success: true, data: result }));
798
798
  }
@@ -1,9 +1,16 @@
1
- export declare function copyTemplateFiles(templateDir: string, targetDir: string): void;
2
- export declare function createSkillYaml(agentId: string, orgId: string, skillName?: string, skillId?: string, persona?: string, welcomeMessage?: string): void;
1
+ /**
2
+ * Copies template files to target directory.
3
+ *
4
+ * @param templateDir - Source template directory
5
+ * @param targetDir - Target directory to copy to
6
+ * @param includeExamples - Whether to include the examples/ directory (default: false)
7
+ */
8
+ export declare function copyTemplateFiles(templateDir: string, targetDir: string, includeExamples?: boolean): void;
9
+ export declare function createSkillYaml(agentId: string, orgId: string, skillName?: string, skillId?: string, persona?: string): void;
3
10
  export declare function readSkillYaml(): any;
4
11
  export declare function readSkillConfig(): any;
5
12
  /**
6
13
  * Update only the agent information in an existing YAML file
7
14
  */
8
- export declare function updateYamlAgent(agentId: string, orgId: string, persona?: string, welcomeMessage?: string): void;
9
- export declare function updateSkillYamlPersona(persona: string, welcomeMessage?: string): void;
15
+ export declare function updateYamlAgent(agentId: string, orgId: string, persona?: string): void;
16
+ export declare function updateSkillYamlPersona(persona: string): void;
@@ -2,18 +2,29 @@ import * as fs from "fs";
2
2
  import * as path from "path";
3
3
  import pkg from 'js-yaml';
4
4
  const { load, dump } = pkg;
5
- export function copyTemplateFiles(templateDir, targetDir) {
5
+ /**
6
+ * Copies template files to target directory.
7
+ *
8
+ * @param templateDir - Source template directory
9
+ * @param targetDir - Target directory to copy to
10
+ * @param includeExamples - Whether to include the examples/ directory (default: false)
11
+ */
12
+ export function copyTemplateFiles(templateDir, targetDir, includeExamples = false) {
6
13
  const files = fs.readdirSync(templateDir);
7
14
  for (const file of files) {
8
15
  // Skip node_modules and package-lock.json to avoid circular dependencies
9
16
  if (file === 'node_modules' || file === 'package-lock.json') {
10
17
  continue;
11
18
  }
19
+ // Skip examples/ by default (user can include with --with-examples flag)
20
+ if (file === 'examples' && !includeExamples) {
21
+ continue;
22
+ }
12
23
  const srcPath = path.join(templateDir, file);
13
24
  const destPath = path.join(targetDir, file);
14
25
  if (fs.statSync(srcPath).isDirectory()) {
15
26
  fs.mkdirSync(destPath, { recursive: true });
16
- copyTemplateFiles(srcPath, destPath);
27
+ copyTemplateFiles(srcPath, destPath, includeExamples);
17
28
  }
18
29
  else if (file === 'package.json') {
19
30
  // Special handling for package.json to update lua-cli version
@@ -53,14 +64,13 @@ function updatePackageJson(srcPath, destPath) {
53
64
  // Write the updated package.json
54
65
  fs.writeFileSync(destPath, JSON.stringify(templatePackageJson, null, 2) + '\n');
55
66
  }
56
- export function createSkillYaml(agentId, orgId, skillName, skillId, persona, welcomeMessage) {
67
+ export function createSkillYaml(agentId, orgId, skillName, skillId, persona) {
57
68
  // Handle multiline strings properly for YAML
58
69
  const personaSection = persona ? ` persona: |\n${persona.split('\n').map(line => ` ${line}`).join('\n')}\n` : '';
59
- const welcomeMessageSection = welcomeMessage ? ` welcomeMessage: "${welcomeMessage}"\n` : '';
60
70
  const yamlContent = `agent:
61
71
  agentId: "${agentId}"
62
72
  orgId: "${orgId}"
63
- ${personaSection}${welcomeMessageSection}
73
+ ${personaSection}
64
74
  skills:
65
75
  # Skills will be auto-generated during compilation
66
76
  `;
@@ -81,7 +91,7 @@ export function readSkillConfig() {
81
91
  /**
82
92
  * Update only the agent information in an existing YAML file
83
93
  */
84
- export function updateYamlAgent(agentId, orgId, persona, welcomeMessage) {
94
+ export function updateYamlAgent(agentId, orgId, persona) {
85
95
  const yamlPath = path.join(process.cwd(), 'lua.skill.yaml');
86
96
  if (!fs.existsSync(yamlPath)) {
87
97
  throw new Error('lua.skill.yaml not found');
@@ -94,9 +104,6 @@ export function updateYamlAgent(agentId, orgId, persona, welcomeMessage) {
94
104
  if (persona) {
95
105
  config.agent.persona = persona;
96
106
  }
97
- if (welcomeMessage) {
98
- config.agent.welcomeMessage = welcomeMessage;
99
- }
100
107
  // Write back to file
101
108
  const yamlContent = dump(config, {
102
109
  indent: 2,
@@ -105,7 +112,7 @@ export function updateYamlAgent(agentId, orgId, persona, welcomeMessage) {
105
112
  });
106
113
  fs.writeFileSync(yamlPath, yamlContent);
107
114
  }
108
- export function updateSkillYamlPersona(persona, welcomeMessage) {
115
+ export function updateSkillYamlPersona(persona) {
109
116
  const yamlPath = path.join(process.cwd(), 'lua.skill.yaml');
110
117
  if (!fs.existsSync(yamlPath)) {
111
118
  console.error('❌ No lua.skill.yaml found. Please run this command from a skill directory.');
@@ -118,10 +125,6 @@ export function updateSkillYamlPersona(persona, welcomeMessage) {
118
125
  data.agent = {};
119
126
  }
120
127
  data.agent.persona = persona;
121
- // Update welcome message if provided
122
- if (welcomeMessage) {
123
- data.agent.welcomeMessage = welcomeMessage;
124
- }
125
128
  // Use yaml.dump to properly handle both old and new formats
126
129
  const updatedYamlContent = dump(data, {
127
130
  indent: 2,
@@ -40,10 +40,9 @@ export declare function createNewAgent(apiKey: string, agentType: AgentType, bus
40
40
  *
41
41
  * @param apiKey - User's API key
42
42
  * @param agentId - Agent ID to fetch
43
- * @returns Agent details including persona and welcome message
43
+ * @returns Agent details including persona
44
44
  * @throws Error if fetch fails
45
45
  */
46
46
  export declare function fetchExistingAgentDetails(apiKey: string, agentId: string): Promise<{
47
47
  persona?: string;
48
- welcomeMessage?: string;
49
48
  }>;
@@ -98,8 +98,7 @@ export async function createNewAgent(apiKey, agentType, businessConfig, metadata
98
98
  org: {
99
99
  id: orgId
100
100
  },
101
- persona: agentDetails.persona,
102
- welcomeMessage: agentDetails.welcomeMessage
101
+ persona: agentDetails.persona
103
102
  };
104
103
  }
105
104
  /**
@@ -114,7 +113,7 @@ async function waitForAgentReady() {
114
113
  *
115
114
  * @param agentApi - Agent API instance
116
115
  * @param agentId - Agent ID to fetch
117
- * @returns Agent details including persona and welcome message
116
+ * @returns Agent details including persona
118
117
  * @throws Error if fetch fails
119
118
  */
120
119
  async function fetchAgentDetails(agentApi, agentId) {
@@ -125,8 +124,7 @@ async function fetchAgentDetails(agentApi, agentId) {
125
124
  }
126
125
  writeProgress("✅ Agent details loaded");
127
126
  return {
128
- persona: agentDetailsResult.data.persona,
129
- welcomeMessage: agentDetailsResult.data.welcomeMessage
127
+ persona: agentDetailsResult.data.persona
130
128
  };
131
129
  }
132
130
  /**
@@ -135,7 +133,7 @@ async function fetchAgentDetails(agentApi, agentId) {
135
133
  *
136
134
  * @param apiKey - User's API key
137
135
  * @param agentId - Agent ID to fetch
138
- * @returns Agent details including persona and welcome message
136
+ * @returns Agent details including persona
139
137
  * @throws Error if fetch fails
140
138
  */
141
139
  export async function fetchExistingAgentDetails(apiKey, agentId) {