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
@@ -26,10 +26,10 @@
26
26
  * const products = await Products.search('laptop');
27
27
  * ```
28
28
  */
29
- import { LuaSkill, LuaWebhook, LuaJob, PreProcessor, PostProcessor, LuaAgent, env } from "./types/skill.js";
29
+ import { LuaSkill, LuaWebhook, LuaJob, PreProcessor, PostProcessor, LuaAgent, LuaMCPServer, env } from "./types/skill.js";
30
30
  import { BasketStatus } from "./interfaces/baskets.js";
31
31
  import { OrderStatus } from "./interfaces/orders.js";
32
- import { getUserInstance, getDataInstance, getProductsInstance, getBasketsInstance, getOrderInstance, getJobInstance, getChatInstance, } from "./api/lazy-instances.js";
32
+ import { getUserInstance, getDataInstance, getProductsInstance, getBasketsInstance, getOrderInstance, getJobInstance, getChatInstance, getWhatsAppTemplatesInstance, getCdnInstance, } from "./api/lazy-instances.js";
33
33
  import { JobInstance } from "./common/job.instance.js";
34
34
  import ProductInstance from "./common/product.instance.js";
35
35
  import DataEntryInstance from "./common/data.entry.instance.js";
@@ -114,12 +114,13 @@ export const Data = {
114
114
  *
115
115
  * @param collectionName - Name of the collection
116
116
  * @param entryId - ID of the entry to update
117
- * @param data - Updated data
118
- * @returns Promise resolving to updated entry
117
+ * @param data - Updated data fields to merge with existing entry
118
+ * @param searchText - Optional new search text for vector search indexing
119
+ * @returns Promise resolving to update response
119
120
  */
120
- async update(collectionName, entryId, data) {
121
+ async update(collectionName, entryId, data, searchText) {
121
122
  const instance = await getDataInstance();
122
- return instance.update(collectionName, entryId, data);
123
+ return instance.update(collectionName, entryId, data, searchText);
123
124
  },
124
125
  /**
125
126
  * Performs vector search on a collection.
@@ -436,11 +437,10 @@ export const Jobs = {
436
437
  const executeString = config.execute.toString();
437
438
  console.log('Creating Job');
438
439
  // Create the job with initial version and activation in one call
439
- const createResult = await instance.createJobInstance({
440
+ return await instance.createJobInstance({
440
441
  dynamic: true,
441
442
  name: config.name,
442
443
  description: config.description,
443
- context: config.description || '',
444
444
  schedule: config.schedule,
445
445
  timeout: config.timeout,
446
446
  retry: config.retry,
@@ -449,7 +449,6 @@ export const Jobs = {
449
449
  version: {
450
450
  version: '1.0.0',
451
451
  description: config.description,
452
- context: config.description || '',
453
452
  code: '', // Will be set by server
454
453
  executeFunction: executeString,
455
454
  timeout: config.timeout,
@@ -459,17 +458,6 @@ export const Jobs = {
459
458
  // Activate immediately
460
459
  activate: config.activate ?? true
461
460
  });
462
- const jobId = createResult.jobId;
463
- // Server has created the job, version, and activated it
464
- // Return a JobInstance for easy manipulation
465
- return new JobInstance(instance, {
466
- id: jobId,
467
- jobId: jobId,
468
- name: config.name,
469
- schedule: config.schedule,
470
- metadata: config.metadata || {},
471
- active: config.activate ?? true
472
- });
473
461
  },
474
462
  /**
475
463
  * Retrieves a job by its unique identifier
@@ -480,6 +468,25 @@ export const Jobs = {
480
468
  async getJob(jobId) {
481
469
  const instance = await getJobInstance();
482
470
  return instance.getJob(jobId);
471
+ },
472
+ /**
473
+ * Retrieves all jobs for the current agent
474
+ * @param options - Optional configuration
475
+ * @param options.includeDynamic - Include dynamically created jobs (default: false)
476
+ * @returns Promise resolving to an array of JobInstance
477
+ *
478
+ * @example
479
+ * ```typescript
480
+ * // Get all jobs including dynamically created ones
481
+ * const jobs = await Jobs.getAll({ includeDynamic: true });
482
+ * for (const job of jobs) {
483
+ * console.log(job.name, job.data.active ? 'active' : 'inactive');
484
+ * }
485
+ * ```
486
+ */
487
+ async getAll(options = {}) {
488
+ const instance = await getJobInstance();
489
+ return instance.getAll(options);
483
490
  }
484
491
  };
485
492
  // ============================================================================
@@ -543,9 +550,158 @@ export const AI = {
543
550
  }
544
551
  };
545
552
  // ============================================================================
553
+ // TEMPLATES API
554
+ // ============================================================================
555
+ /**
556
+ * Templates API
557
+ *
558
+ * Manage templates across different channel types.
559
+ * Use the appropriate namespace for your template type:
560
+ *
561
+ * - `Templates.whatsapp` - WhatsApp Business templates
562
+ *
563
+ * @example
564
+ * ```typescript
565
+ * // List WhatsApp templates
566
+ * const result = await Templates.whatsapp.list(channelId);
567
+ *
568
+ * // Send a WhatsApp template
569
+ * await Templates.whatsapp.send(channelId, templateId, {
570
+ * phoneNumbers: ['+447551166594'],
571
+ * values: { body: { name: 'John' } }
572
+ * });
573
+ * ```
574
+ */
575
+ export const Templates = {
576
+ /**
577
+ * WhatsApp Templates
578
+ *
579
+ * Pre-approved message formats for WhatsApp Business Accounts.
580
+ * Required for initiating conversations outside the 24-hour messaging window.
581
+ */
582
+ whatsapp: {
583
+ /**
584
+ * Lists WhatsApp templates for a channel with optional pagination and search.
585
+ *
586
+ * @param channelId - The WhatsApp channel identifier
587
+ * @param options - Optional pagination and search options
588
+ * @returns Promise resolving to paginated templates response
589
+ *
590
+ * @example
591
+ * ```typescript
592
+ * const result = await Templates.whatsapp.list(channelId);
593
+ * const filtered = await Templates.whatsapp.list(channelId, { search: 'order' });
594
+ * const paginated = await Templates.whatsapp.list(channelId, { page: 2, limit: 20 });
595
+ * ```
596
+ */
597
+ async list(channelId, options) {
598
+ const instance = await getWhatsAppTemplatesInstance();
599
+ return instance.list(channelId, options);
600
+ },
601
+ /**
602
+ * Gets a specific WhatsApp template by ID.
603
+ *
604
+ * @param channelId - The WhatsApp channel identifier
605
+ * @param templateId - The template identifier
606
+ * @returns Promise resolving to the template
607
+ *
608
+ * @example
609
+ * ```typescript
610
+ * const template = await Templates.whatsapp.get(channelId, 'template_123');
611
+ * ```
612
+ */
613
+ async get(channelId, templateId) {
614
+ const instance = await getWhatsAppTemplatesInstance();
615
+ return instance.get(channelId, templateId);
616
+ },
617
+ /**
618
+ * Sends a WhatsApp template message to one or more phone numbers.
619
+ *
620
+ * @param channelId - The WhatsApp channel identifier
621
+ * @param templateId - The template identifier
622
+ * @param data - Send data including phone numbers and template values
623
+ * @returns Promise resolving to the send response with results and errors
624
+ *
625
+ * @example
626
+ * ```typescript
627
+ * const result = await Templates.whatsapp.send(channelId, 'template_123', {
628
+ * phoneNumbers: ['+447551166594'],
629
+ * values: {
630
+ * body: { first_name: 'John', order_number: '12345' }
631
+ * }
632
+ * });
633
+ * ```
634
+ */
635
+ async send(channelId, templateId, data) {
636
+ const instance = await getWhatsAppTemplatesInstance();
637
+ return instance.send(channelId, templateId, data);
638
+ }
639
+ }
640
+ };
641
+ // ============================================================================
642
+ // CDN API
643
+ // ============================================================================
644
+ /**
645
+ * CDN API
646
+ * Upload and retrieve files from the Lua CDN
647
+ */
648
+ export const CDN = {
649
+ /**
650
+ * Uploads a file to the CDN.
651
+ *
652
+ * @param file - The File object to upload
653
+ * @returns Promise resolving to the file ID
654
+ *
655
+ * @example
656
+ * ```typescript
657
+ * import { CDN } from 'lua-cli';
658
+ * import { readFileSync } from 'fs';
659
+ *
660
+ * const buffer = readFileSync('image.png');
661
+ * const file = new File([buffer], 'image.png', { type: 'image/png' });
662
+ * const fileId = await CDN.upload(file);
663
+ * console.log('Uploaded file ID:', fileId);
664
+ * ```
665
+ */
666
+ async upload(file) {
667
+ const instance = await getCdnInstance();
668
+ return instance.upload(file);
669
+ },
670
+ /**
671
+ * Retrieves a file from the CDN by its ID.
672
+ *
673
+ * @param fileId - The unique identifier of the file
674
+ * @returns Promise resolving to a File object
675
+ *
676
+ * @example
677
+ * ```typescript
678
+ * import { CDN, AI } from 'lua-cli';
679
+ *
680
+ * const file = await CDN.get('abc123-def456');
681
+ * console.log(file.name, file.type, file.size);
682
+ *
683
+ * // Use with AI API for image analysis
684
+ * const buffer = Buffer.from(await file.arrayBuffer());
685
+ * const response = await AI.generate(
686
+ * 'You are an image analysis expert.',
687
+ * [
688
+ * { type: 'text', text: 'What do you see in this image?' },
689
+ * { type: 'image', image: buffer, mediaType: file.type }
690
+ * ]
691
+ * );
692
+ * ```
693
+ */
694
+ async get(fileId) {
695
+ const instance = await getCdnInstance();
696
+ return instance.get(fileId);
697
+ }
698
+ };
699
+ // ============================================================================
546
700
  // EXPORTS
547
701
  // ============================================================================
548
702
  // Export skill classes and utilities
549
- export { LuaSkill, LuaWebhook, LuaJob, PreProcessor, PostProcessor, LuaAgent, BasketStatus, OrderStatus, env };
703
+ export { LuaSkill, LuaWebhook, LuaJob, PreProcessor, PostProcessor, LuaAgent,
704
+ // MCP Server exports
705
+ LuaMCPServer, BasketStatus, OrderStatus, env };
550
706
  // Export instance classes
551
707
  export { JobInstance, UserDataInstance, DataEntryInstance, ProductInstance, BasketInstance, OrderInstance };
@@ -2,7 +2,7 @@
2
2
  * Command Definitions
3
3
  * Centralized command structure for the CLI
4
4
  */
5
- import { configureCommand, initCommand, destroyCommand, apiKeyCommand, compileCommand, testCommand, pushCommand, deployCommand, chatCommand, chatClearCommand, envCommand, personaCommand, productionCommand, resourcesCommand, adminCommand, docsCommand, channelsCommand, logsCommand, completionCommand, skillsCommand, webhooksCommand, jobsCommand, featuresCommand, preprocessorsCommand, postprocessorsCommand, marketplaceCommand } from "../commands/index.js";
5
+ import { configureCommand, initCommand, destroyCommand, apiKeyCommand, compileCommand, testCommand, pushCommand, deployCommand, devCommand, chatCommand, chatClearCommand, envCommand, personaCommand, productionCommand, resourcesCommand, adminCommand, evalsCommand, docsCommand, channelsCommand, logsCommand, completionCommand, skillsCommand, webhooksCommand, jobsCommand, featuresCommand, preprocessorsCommand, postprocessorsCommand, marketplaceCommand, mcpCommand } from "../commands/index.js";
6
6
  /**
7
7
  * Sets up authentication-related commands.
8
8
  *
@@ -70,6 +70,7 @@ export function setupSkillCommands(program) {
70
70
  program
71
71
  .command("init")
72
72
  .description("🚀 Initialize a new Lua skill project")
73
+ .option("--with-examples", "Include example skills, tools, jobs, and webhooks")
73
74
  .action(initCommand);
74
75
  // Development Commands
75
76
  program
@@ -94,12 +95,12 @@ Examples:
94
95
  // Deployment Commands
95
96
  program
96
97
  .command("push [type]")
97
- .description("☁️ Push skill, webhook, job, or persona version to server")
98
+ .description("☁️ Push skill, webhook, job, MCP server, or persona version to server")
98
99
  .option('--force', 'Skip all confirmation prompts (auto-confirm)')
99
100
  .option('--auto-deploy', 'Automatically deploy to production after push')
100
101
  .addHelpText('after', `
101
102
  Arguments:
102
- type Optional: 'skill', 'webhook', 'job', 'preprocessor', 'postprocessor', 'persona', or 'all' (prompts if not provided)
103
+ type Optional: 'skill', 'webhook', 'job', 'preprocessor', 'postprocessor', 'mcp', 'persona', or 'all' (prompts if not provided)
103
104
 
104
105
  Options:
105
106
  --force Skip all confirmation prompts
@@ -110,6 +111,7 @@ Examples:
110
111
  $ lua push skill Push a skill directly
111
112
  $ lua push webhook Push a webhook directly
112
113
  $ lua push job Push a job directly
114
+ $ lua push mcp Push an MCP server directly
113
115
  $ lua push all --force Push all components from YAML without prompts
114
116
  $ lua push all --force --auto-deploy Push and deploy all to production
115
117
  `)
@@ -119,10 +121,10 @@ Examples:
119
121
  .description("🚀 Deploy version to production")
120
122
  .action(deployCommand);
121
123
  // Temporarily disabled - will be released later
122
- // program
123
- // .command("dev")
124
- // .description("🔧 Development mode with live reload")
125
- // .action(devCommand);
124
+ program
125
+ .command("dev")
126
+ .description("🔧 Development mode with live reload")
127
+ .action(devCommand);
126
128
  // Chat Commands
127
129
  const chatCmd = program
128
130
  .command("chat")
@@ -178,6 +180,10 @@ Examples:
178
180
  .command("admin")
179
181
  .description("🔧 Open Lua Admin Dashboard in browser")
180
182
  .action(adminCommand);
183
+ program
184
+ .command("evals")
185
+ .description("📊 Open Lua Evaluations Dashboard in browser")
186
+ .action(evalsCommand);
181
187
  program
182
188
  .command("docs")
183
189
  .description("📖 Open Lua documentation in browser")
@@ -276,6 +282,27 @@ Examples:
276
282
  $ lua postprocessors Manage production postprocessors
277
283
  `)
278
284
  .action(postprocessorsCommand);
285
+ program
286
+ .command("mcp [action] [name]")
287
+ .description("🔌 Manage MCP (Model Context Protocol) servers")
288
+ .addHelpText('after', `
289
+ Arguments:
290
+ action Optional: 'list', 'activate', 'deactivate', or 'delete'
291
+ name Optional: server name (for activate/deactivate/delete)
292
+
293
+ Features:
294
+ • List all MCP servers and their status
295
+ • Activate/deactivate MCP servers
296
+ • Delete MCP servers
297
+
298
+ Examples:
299
+ $ lua mcp Interactive management
300
+ $ lua mcp list List all MCP servers
301
+ $ lua mcp activate filesystem Activate a specific server
302
+ $ lua mcp deactivate api-server Deactivate a specific server
303
+ $ lua mcp delete old-server Delete a server
304
+ `)
305
+ .action(mcpCommand);
279
306
  program
280
307
  .command("completion [shell]")
281
308
  .description("🎯 Generate shell completion script")
@@ -51,7 +51,7 @@ export async function adminCommand() {
51
51
  }
52
52
  // Construct the admin dashboard URL
53
53
  // This URL authenticates with the API key and redirects to the usage page
54
- const adminUrl = `https://admin.heylua.ai/validate-token/${apiKey}?redirect=/admin/usage?&agentId=${agentId}&orgId=${orgId}&hideToolBar=true`;
54
+ const adminUrl = `https://admin.heylua.ai/validate-token/${apiKey}?redirect=/admin/usage?&agentId=${agentId}&orgId=${orgId}`;
55
55
  // Open the URL in the default browser
56
56
  await open(adminUrl);
57
57
  writeSuccess('Lua Admin Dashboard opened in your browser');
@@ -77,7 +77,7 @@ async function openAdminDashboard(apiKey, config) {
77
77
  throw new Error('No orgId found in lua.skill.yaml. Please ensure your configuration is valid.');
78
78
  }
79
79
  // Construct the admin dashboard URL
80
- const adminUrl = `https://admin.heylua.ai/validate-token/${apiKey}?redirect=/admin/usage?&agentId=${agentId}&orgId=${orgId}&hideToolBar=true`;
80
+ const adminUrl = `https://admin.heylua.ai/validate-token/${apiKey}?redirect=/admin/usage?&agentId=${agentId}&orgId=${orgId}`;
81
81
  // Open the URL in the default browser
82
82
  await open(adminUrl);
83
83
  writeSuccess('✅ Lua Admin Dashboard opened in your browser');
@@ -123,10 +123,8 @@ async function startChatLoop(chatEnv) {
123
123
  console.log(`Environment: ${chatEnv.type === 'sandbox' ? '🔧 Sandbox' : '🚀 Production'}`);
124
124
  console.log("Press Ctrl+C to exit");
125
125
  console.log("=".repeat(60) + "\n");
126
- // Welcome message from config or default
127
- const config = readSkillConfig();
128
- const welcomeMessage = config?.agent?.welcomeMessage || "Hi there! How can I help you today?";
129
- console.log(`🌙 Assistant: ${welcomeMessage}\n`);
126
+ // Welcome message
127
+ console.log("🌙 Assistant: Hi there! How can I help you today?\n");
130
128
  // Create readline interface
131
129
  const rl = readline.createInterface({
132
130
  input: process.stdin,
@@ -6,15 +6,16 @@ import fs from "fs";
6
6
  import path from "path";
7
7
  import { Project } from "ts-morph";
8
8
  import { withErrorHandling, writeProgress, writeSuccess } from "../utils/cli.js";
9
- import { findIndexFile, extractWebhooksMetadata, extractJobsMetadata, extractPreProcessorsMetadata, extractPostProcessorsMetadata } from '../utils/compile.js';
9
+ import { findIndexFile, extractWebhooksMetadata, extractJobsMetadata, extractPreProcessorsMetadata, extractPostProcessorsMetadata, extractMCPServersMetadata } from '../utils/compile.js';
10
10
  import { detectTools } from '../utils/tool-detection.js';
11
- import { bundleTool, bundleMainIndex, extractExecuteCode, bundleWebhook, bundleJob, bundlePreProcessor, bundlePostProcessor } from '../utils/bundling.js';
11
+ import { bundleTool, bundleMainIndex, extractToolCode, bundleWebhook, bundleJob, bundlePreProcessor, bundlePostProcessor } from '../utils/bundling.js';
12
12
  import { createDeploymentData, createLegacyDeploymentData } from '../utils/deployment.js';
13
13
  import { syncYamlWithDeployJson, syncServerSkillsWithYaml } from '../utils/skill-management.js';
14
14
  import { ensureWebhooksExistInYaml, syncServerWebhooksWithYaml } from '../utils/webhook-management.js';
15
15
  import { ensureJobsExistInYaml, syncServerJobsWithYaml } from '../utils/job-management.js';
16
16
  import { ensurePreProcessorsExistInYaml, syncServerPreProcessorsWithYaml } from '../utils/preprocessor-management.js';
17
17
  import { ensurePostProcessorsExistInYaml, syncServerPostProcessorsWithYaml } from '../utils/postprocessor-management.js';
18
+ import { ensureMCPServersExistInYaml, syncServerMCPServersWithYaml } from '../utils/mcp-server-management.js';
18
19
  import { readSkillConfig } from '../utils/files.js';
19
20
  import { COMPILE_DIRS, COMPILE_FILES } from '../config/compile.constants.js';
20
21
  import { syncAgentPersonaWithYaml } from '../utils/agent-management.js';
@@ -95,7 +96,7 @@ export async function compileCommand(options) {
95
96
  resolvedAgentData = resolveLuaAgentReferences(agentMetadata, indexFile, project);
96
97
  // Get file paths where skills are defined so we can scan them for tools
97
98
  skillFilePaths = getSkillFilePaths(agentMetadata, indexFile);
98
- writeProgress(`📦 Agent contains: ${resolvedAgentData?.skills?.length || 0} skill(s), ${resolvedAgentData?.webhooks?.length || 0} webhook(s), ${resolvedAgentData?.jobs?.length || 0} job(s), ${resolvedAgentData?.preProcessors?.length || 0} preprocessor(s), ${resolvedAgentData?.postProcessors?.length || 0} postprocessor(s)`);
99
+ writeProgress(`📦 Agent contains: ${resolvedAgentData?.skills?.length || 0} skill(s), ${resolvedAgentData?.webhooks?.length || 0} webhook(s), ${resolvedAgentData?.jobs?.length || 0} job(s), ${resolvedAgentData?.preProcessors?.length || 0} preprocessor(s), ${resolvedAgentData?.postProcessors?.length || 0} postprocessor(s), ${resolvedAgentData?.mcpServers?.length || 0} MCP server(s)`);
99
100
  }
100
101
  else {
101
102
  writeProgress(`ℹ️ No LuaAgent found, using legacy detection for individual components`);
@@ -132,7 +133,7 @@ export async function compileCommand(options) {
132
133
  }
133
134
  }
134
135
  // Step 3d: Extract execute code
135
- await extractExecuteCode(tool, project, distDir);
136
+ await extractToolCode(tool, project);
136
137
  if (debugMode) {
137
138
  const toolTime = Date.now() - toolStartTime;
138
139
  const bundledPath = path.join(distDir, 'tools', `${tool.className}.js`);
@@ -258,6 +259,22 @@ export async function compileCommand(options) {
258
259
  await syncServerPostProcessorsWithYaml(postprocessorConfig);
259
260
  fs.writeFileSync(path.join(distDir, 'postprocessors.json'), JSON.stringify(bundledPostProcessors, null, 2));
260
261
  }
262
+ // Step 12: Detect and process MCP servers
263
+ writeProgress("🔍 Detecting MCP servers...");
264
+ // Use resolved agent MCP servers if available
265
+ let mcpServersMetadata = resolvedAgentData?.mcpServers || extractMCPServersMetadata(indexFile);
266
+ if (mcpServersMetadata.length > 0) {
267
+ writeProgress(`📦 Found ${mcpServersMetadata.length} MCP server(s)...`);
268
+ // Ensure MCP servers exist in YAML
269
+ const configForMCP = readSkillConfig();
270
+ await ensureMCPServersExistInYaml(mcpServersMetadata, configForMCP);
271
+ // Sync server MCP servers with YAML
272
+ writeProgress("🔄 Syncing server MCP servers with YAML...");
273
+ const mcpServerConfig = readSkillConfig();
274
+ await syncServerMCPServersWithYaml(mcpServerConfig);
275
+ // Write MCP servers to file for reference
276
+ fs.writeFileSync(path.join(distDir, 'mcp-servers.json'), JSON.stringify(mcpServersMetadata, null, 2));
277
+ }
261
278
  // Build compilation summary
262
279
  const summaryParts = [`${tools.length} tools bundled`];
263
280
  if (webhooksMetadata.length > 0)
@@ -268,6 +285,8 @@ export async function compileCommand(options) {
268
285
  summaryParts.push(`${preprocessorsMetadata.length} preprocessor(s) registered`);
269
286
  if (postprocessorsMetadata.length > 0)
270
287
  summaryParts.push(`${postprocessorsMetadata.length} postprocessor(s) registered`);
288
+ if (mcpServersMetadata.length > 0)
289
+ summaryParts.push(`${mcpServersMetadata.length} MCP server(s) registered`);
271
290
  // Check for empty bundles (potential failures)
272
291
  const emptyBundles = [];
273
292
  for (const tool of tools) {
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Evals Command
3
+ * Opens the Lua Evaluations Dashboard in the user's default browser
4
+ */
5
+ /**
6
+ * Evals command - opens the Lua evaluations dashboard in the browser.
7
+ */
8
+ export declare function evalsCommand(): Promise<void>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Evals Command
3
+ * Opens the Lua Evaluations Dashboard in the user's default browser
4
+ */
5
+ import open from 'open';
6
+ import { loadApiKey } from '../services/auth.js';
7
+ import { readSkillConfig } from '../utils/files.js';
8
+ import { withErrorHandling, writeSuccess, writeProgress } from '../utils/cli.js';
9
+ /**
10
+ * Evals command - opens the Lua evaluations dashboard in the browser.
11
+ */
12
+ export async function evalsCommand() {
13
+ return withErrorHandling(async () => {
14
+ writeProgress('Opening Lua Evaluations Dashboard...');
15
+ // Load API key from secure storage
16
+ const apiKey = await loadApiKey();
17
+ if (!apiKey) {
18
+ throw new Error('No API key found. Please run "lua auth configure" first.');
19
+ }
20
+ // Read skill configuration
21
+ let config;
22
+ try {
23
+ config = readSkillConfig();
24
+ }
25
+ catch (error) {
26
+ throw new Error('Could not read lua.skill.yaml. Please ensure you are in a Lua agent directory, or run "lua init" to create a new agent.');
27
+ }
28
+ // Extract agentId from config
29
+ const agentId = config?.agent?.agentId;
30
+ if (!agentId) {
31
+ throw new Error('No agentId found in lua.skill.yaml. Please ensure your configuration is valid.');
32
+ }
33
+ // Construct the evals dashboard URL
34
+ const evalsUrl = `https://evals.heylua.ai?apiKey=${apiKey}&agentID=${agentId}`;
35
+ // Open the URL in the default browser
36
+ await open(evalsUrl);
37
+ writeSuccess('Lua Evaluations Dashboard opened in your browser');
38
+ console.log(`\n Dashboard URL: https://evals.heylua.ai`);
39
+ console.log(` Agent ID: ${agentId}\n`);
40
+ }, 'evals');
41
+ }
@@ -14,6 +14,7 @@ export { personaCommand } from "./persona.js";
14
14
  export { productionCommand } from "./production.js";
15
15
  export { resourcesCommand } from "./resources.js";
16
16
  export { adminCommand } from "./admin.js";
17
+ export { evalsCommand } from "./evals.js";
17
18
  export { docsCommand } from "./docs.js";
18
19
  export { channelsCommand } from "./channels.js";
19
20
  export { logsCommand } from "./logs.js";
@@ -25,3 +26,4 @@ export { featuresCommand } from "./features.js";
25
26
  export { preprocessorsCommand } from "./preprocessors.js";
26
27
  export { postprocessorsCommand } from "./postprocessors.js";
27
28
  export { marketplaceCommand } from "./marketplace.js";
29
+ export { mcpCommand } from "./mcp.js";
@@ -14,6 +14,7 @@ export { personaCommand } from "./persona.js";
14
14
  export { productionCommand } from "./production.js";
15
15
  export { resourcesCommand } from "./resources.js";
16
16
  export { adminCommand } from "./admin.js";
17
+ export { evalsCommand } from "./evals.js";
17
18
  export { docsCommand } from "./docs.js";
18
19
  export { channelsCommand } from "./channels.js";
19
20
  export { logsCommand } from "./logs.js";
@@ -25,3 +26,4 @@ export { featuresCommand } from "./features.js";
25
26
  export { preprocessorsCommand } from "./preprocessors.js";
26
27
  export { postprocessorsCommand } from "./postprocessors.js";
27
28
  export { marketplaceCommand } from "./marketplace.js";
29
+ export { mcpCommand } from "./mcp.js";
@@ -2,6 +2,12 @@
2
2
  * Init Command
3
3
  * Orchestrates the initialization of a new Lua skill project
4
4
  */
5
+ /**
6
+ * Options for the init command
7
+ */
8
+ interface InitCommandOptions {
9
+ withExamples?: boolean;
10
+ }
5
11
  /**
6
12
  * Main init command - initializes a new Lua skill project.
7
13
  *
@@ -22,7 +28,10 @@
22
28
  * - Feature configuration
23
29
  * - Automatic project scaffolding
24
30
  * - Dependency installation
31
+ * - Optional example code with --with-examples flag
25
32
  *
33
+ * @param options - Command options including --with-examples
26
34
  * @returns Promise that resolves when initialization is complete
27
35
  */
28
- export declare function initCommand(): Promise<void>;
36
+ export declare function initCommand(options?: InitCommandOptions): Promise<void>;
37
+ export {};