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
@@ -29,10 +29,13 @@ import { readSkillYaml, updateYamlAgent } from "../utils/files.js";
29
29
  * - Feature configuration
30
30
  * - Automatic project scaffolding
31
31
  * - Dependency installation
32
+ * - Optional example code with --with-examples flag
32
33
  *
34
+ * @param options - Command options including --with-examples
33
35
  * @returns Promise that resolves when initialization is complete
34
36
  */
35
- export async function initCommand() {
37
+ export async function initCommand(options = {}) {
38
+ const withExamples = options.withExamples ?? false;
36
39
  return withErrorHandling(async () => {
37
40
  // Step 1: Authenticate
38
41
  const apiKey = await loadApiKey();
@@ -111,7 +114,6 @@ export async function initCommand() {
111
114
  let selectedAgent;
112
115
  let selectedOrg;
113
116
  let persona;
114
- let welcomeMessage;
115
117
  let skipProjectInit = false;
116
118
  if (agentChoice === "existing") {
117
119
  // Step 4a: Select existing agent
@@ -119,7 +121,6 @@ export async function initCommand() {
119
121
  selectedAgent = result.agent;
120
122
  selectedOrg = result.org;
121
123
  persona = result.persona;
122
- welcomeMessage = result.welcomeMessage;
123
124
  }
124
125
  else {
125
126
  // Step 4b: Create new agent
@@ -127,35 +128,41 @@ export async function initCommand() {
127
128
  selectedAgent = result.agent;
128
129
  selectedOrg = result.org;
129
130
  persona = result.persona;
130
- welcomeMessage = result.welcomeMessage;
131
131
  }
132
132
  // Step 5: Initialize or update project
133
133
  if (yamlExists) {
134
134
  // Update existing YAML and LuaAgent in index.ts
135
135
  writeInfo("šŸ“ Updating existing lua.skill.yaml with new agent...");
136
- updateYamlAgent(selectedAgent.agentId, selectedOrg.id, persona, welcomeMessage);
136
+ updateYamlAgent(selectedAgent.agentId, selectedOrg.id, persona);
137
137
  // Also update LuaAgent in index.ts if it exists
138
138
  const { updateLuaAgentInIndexFile } = await import("../utils/init-helpers.js");
139
- updateLuaAgentInIndexFile(process.cwd(), selectedAgent.name, persona, welcomeMessage);
139
+ updateLuaAgentInIndexFile(process.cwd(), selectedAgent.name, persona);
140
140
  writeSuccess("āœ… lua.skill.yaml updated successfully!");
141
141
  writeSuccess("āœ… LuaAgent configuration updated!");
142
142
  }
143
143
  else {
144
144
  // Full project initialization
145
- const currentDir = initializeProject(selectedAgent.agentId, selectedOrg.id, persona, welcomeMessage, selectedAgent.name);
145
+ const currentDir = initializeProject(selectedAgent.agentId, selectedOrg.id, persona, selectedAgent.name, withExamples);
146
146
  // Step 6: Install dependencies
147
147
  await installDependencies(currentDir);
148
- writeSuccess("āœ… Lua skill project initialized successfully!");
148
+ if (withExamples) {
149
+ writeSuccess("āœ… Lua skill project initialized with examples!");
150
+ writeInfo("šŸ’” Check the examples/ folder for sample skills, tools, jobs, and webhooks");
151
+ }
152
+ else {
153
+ writeSuccess("āœ… Lua skill project initialized successfully!");
154
+ writeInfo("šŸ’” Tip: Use `lua init --with-examples` to include example code");
155
+ }
149
156
  }
150
157
  }, "initialization");
151
158
  }
152
159
  /**
153
160
  * Handles the flow for selecting an existing agent.
154
- * Fetches the agent details from the server to get persona and welcomeMessage.
161
+ * Fetches the agent details from the server to get persona.
155
162
  *
156
163
  * @param userData - User's data
157
164
  * @param apiKey - User's API key
158
- * @returns Selected agent, organization, and optional persona/welcome message
165
+ * @returns Selected agent, organization, and optional persona
159
166
  */
160
167
  async function selectExistingAgent(userData, apiKey) {
161
168
  // Extract organizations
@@ -167,13 +174,12 @@ async function selectExistingAgent(userData, apiKey) {
167
174
  const selectedOrg = await promptOrganizationSelection(orgs);
168
175
  // Select agent from organization
169
176
  const selectedAgent = await promptAgentSelection(selectedOrg);
170
- // Fetch agent details to get persona and welcomeMessage
177
+ // Fetch agent details to get persona
171
178
  const agentDetails = await fetchExistingAgentDetails(apiKey, selectedAgent.agentId);
172
179
  return {
173
180
  agent: selectedAgent,
174
181
  org: selectedOrg,
175
- persona: agentDetails.persona,
176
- welcomeMessage: agentDetails.welcomeMessage
182
+ persona: agentDetails.persona
177
183
  };
178
184
  }
179
185
  /**
@@ -181,7 +187,7 @@ async function selectExistingAgent(userData, apiKey) {
181
187
  *
182
188
  * @param apiKey - User's API key
183
189
  * @param userData - User data containing organizations
184
- * @returns Created agent, organization, and optional persona/welcome message
190
+ * @returns Created agent, organization, and optional persona
185
191
  */
186
192
  async function createNewAgentFlow(apiKey, userData) {
187
193
  // Fetch and select agent type
@@ -275,14 +281,12 @@ async function handleAgentSwitch(userData, apiKey, existingYaml) {
275
281
  let selectedAgent;
276
282
  let selectedOrg;
277
283
  let persona;
278
- let welcomeMessage;
279
284
  if (agentChoice === "existing") {
280
285
  // Select existing agent
281
286
  const result = await selectExistingAgent(userData, apiKey);
282
287
  selectedAgent = result.agent;
283
288
  selectedOrg = result.org;
284
289
  persona = result.persona;
285
- welcomeMessage = result.welcomeMessage;
286
290
  }
287
291
  else {
288
292
  // Create new agent
@@ -290,17 +294,15 @@ async function handleAgentSwitch(userData, apiKey, existingYaml) {
290
294
  selectedAgent = result.agent;
291
295
  selectedOrg = result.org;
292
296
  persona = result.persona;
293
- welcomeMessage = result.welcomeMessage;
294
297
  }
295
- // Ask about persona and welcome message
298
+ // Ask about persona
296
299
  const finalPersona = await promptPersonaReplacement(existingYaml, persona);
297
- const finalWelcomeMessage = await promptWelcomeMessageReplacement(existingYaml, welcomeMessage);
298
300
  // Update existing YAML file with new agent
299
301
  writeInfo("\nšŸ“ Updating lua.skill.yaml with new agent...");
300
- updateYamlAgent(selectedAgent.agentId, selectedOrg.id, finalPersona, finalWelcomeMessage);
302
+ updateYamlAgent(selectedAgent.agentId, selectedOrg.id, finalPersona);
301
303
  // Also update LuaAgent in index.ts if it exists
302
304
  const { updateLuaAgentInIndexFile } = await import("../utils/init-helpers.js");
303
- updateLuaAgentInIndexFile(process.cwd(), selectedAgent.name, finalPersona, finalWelcomeMessage);
305
+ updateLuaAgentInIndexFile(process.cwd(), selectedAgent.name, finalPersona);
304
306
  writeSuccess("āœ… lua.skill.yaml updated successfully!");
305
307
  writeSuccess("āœ… LuaAgent configuration updated!");
306
308
  writeInfo("\nšŸ’” Your project now uses the new agent. Run 'lua compile' to update your skills.\n");
@@ -331,28 +333,3 @@ async function promptPersonaReplacement(existingYaml, newPersona) {
331
333
  ]);
332
334
  return replacePersona ? newPersona : existingPersona;
333
335
  }
334
- /**
335
- * Prompt user about replacing existing welcome message
336
- */
337
- async function promptWelcomeMessageReplacement(existingYaml, newWelcomeMessage) {
338
- const existingWelcomeMessage = existingYaml?.agent?.welcomeMessage;
339
- // If no existing welcome message, use new one
340
- if (!existingWelcomeMessage) {
341
- return newWelcomeMessage;
342
- }
343
- // If no new welcome message, keep existing
344
- if (!newWelcomeMessage) {
345
- return existingWelcomeMessage;
346
- }
347
- // Both exist - ask user
348
- writeInfo(" Existing welcome message found in project");
349
- const { replaceWelcomeMessage } = await inquirer.prompt([
350
- {
351
- type: 'confirm',
352
- name: 'replaceWelcomeMessage',
353
- message: 'Replace existing welcome message with the new agent\'s welcome message?',
354
- default: false
355
- }
356
- ]);
357
- return replaceWelcomeMessage ? newWelcomeMessage : existingWelcomeMessage;
358
- }
@@ -203,8 +203,8 @@ async function viewJobVersions(context, config) {
203
203
  if (!response.success || !response.data) {
204
204
  throw new Error(response.error?.message || 'Failed to fetch versions');
205
205
  }
206
- const versions = response.data.versions || [];
207
- const activeVersionId = response.data.activeVersionId;
206
+ const versions = response.data;
207
+ const activeVersionId = selectedJob.activeVersionId;
208
208
  if (versions.length === 0) {
209
209
  console.log(`\nā„¹ļø No versions found for ${selectedJob.name}.\n`);
210
210
  console.log("šŸ’” Push a version first using 'lua push job'.\n");
@@ -270,8 +270,8 @@ async function deployJobVersion(context, config) {
270
270
  if (!response.success || !response.data) {
271
271
  throw new Error(response.error?.message || 'Failed to fetch versions');
272
272
  }
273
- const versions = response.data.versions || [];
274
- const activeVersionId = response.data.activeVersionId;
273
+ const versions = response.data;
274
+ const activeVersionId = selectedJob.activeVersionId;
275
275
  if (versions.length === 0) {
276
276
  console.log(`\nā„¹ļø No versions found for ${selectedJob.name}.\n`);
277
277
  console.log("šŸ’” Push a version first using 'lua push job'.\n");
@@ -434,7 +434,7 @@ async function triggerJob(context, config) {
434
434
  const response = await jobApi.triggerJob(jobAnswer.selectedJob.jobId);
435
435
  if (response.success && response.data) {
436
436
  writeSuccess(`āœ… Job "${jobAnswer.selectedJob.name}" triggered successfully`);
437
- writeInfo(`šŸ“‹ Execution ID: ${response.data.executionId || 'N/A'}`);
437
+ writeInfo(`šŸ“‹ Execution ID: ${response.data.id || 'N/A'}`);
438
438
  }
439
439
  else {
440
440
  console.error(`āŒ Failed to trigger job: ${response.error?.message || 'Unknown error'}`);
@@ -0,0 +1,18 @@
1
+ /**
2
+ * MCP Command
3
+ * Manages Model Context Protocol (MCP) servers for agents
4
+ */
5
+ /**
6
+ * Main MCP command - manages MCP servers
7
+ *
8
+ * Subcommands:
9
+ * - lua mcp list - List all MCP servers
10
+ * - lua mcp activate - Activate an MCP server
11
+ * - lua mcp deactivate - Deactivate an MCP server
12
+ * - lua mcp delete - Delete an MCP server
13
+ *
14
+ * @param action - Optional action ('list', 'activate', 'deactivate', 'delete')
15
+ * @param serverName - Optional server name for actions
16
+ * @returns Promise that resolves when command completes
17
+ */
18
+ export declare function mcpCommand(action?: string, serverName?: string): Promise<void>;
@@ -0,0 +1,393 @@
1
+ /**
2
+ * MCP Command
3
+ * Manages Model Context Protocol (MCP) servers for agents
4
+ */
5
+ import { loadApiKey, checkApiKey } from '../services/auth.js';
6
+ import { readSkillConfig } from '../utils/files.js';
7
+ import { withErrorHandling, writeProgress, writeSuccess, writeInfo } from '../utils/cli.js';
8
+ import { BASE_URLS } from '../config/constants.js';
9
+ import { safePrompt } from '../utils/prompt-handler.js';
10
+ import { validateConfig, validateAgentConfig, } from '../utils/dev-helpers.js';
11
+ import DeveloperApi from '../api/developer.api.service.js';
12
+ /**
13
+ * Main MCP command - manages MCP servers
14
+ *
15
+ * Subcommands:
16
+ * - lua mcp list - List all MCP servers
17
+ * - lua mcp activate - Activate an MCP server
18
+ * - lua mcp deactivate - Deactivate an MCP server
19
+ * - lua mcp delete - Delete an MCP server
20
+ *
21
+ * @param action - Optional action ('list', 'activate', 'deactivate', 'delete')
22
+ * @param serverName - Optional server name for actions
23
+ * @returns Promise that resolves when command completes
24
+ */
25
+ export async function mcpCommand(action, serverName) {
26
+ return withErrorHandling(async () => {
27
+ // Step 1: Load configuration
28
+ const config = readSkillConfig();
29
+ validateConfig(config);
30
+ validateAgentConfig(config);
31
+ const agentId = config.agent.agentId;
32
+ // Step 2: Authenticate
33
+ const apiKey = await loadApiKey();
34
+ if (!apiKey) {
35
+ console.error("āŒ No API key found. Please run 'lua auth configure' to set up your API key.");
36
+ process.exit(1);
37
+ }
38
+ await checkApiKey(apiKey);
39
+ writeProgress("āœ… Authenticated");
40
+ const developerApi = new DeveloperApi(BASE_URLS.API, apiKey, agentId);
41
+ const context = {
42
+ agentId,
43
+ apiKey,
44
+ developerApi,
45
+ };
46
+ // Step 3: Handle action or show interactive menu
47
+ if (action) {
48
+ const normalizedAction = action.toLowerCase();
49
+ switch (normalizedAction) {
50
+ case 'list':
51
+ case 'ls':
52
+ await listMCPServers(context);
53
+ break;
54
+ case 'activate':
55
+ case 'enable':
56
+ await activateMCPServer(context, serverName);
57
+ break;
58
+ case 'deactivate':
59
+ case 'disable':
60
+ await deactivateMCPServer(context, serverName);
61
+ break;
62
+ case 'delete':
63
+ case 'rm':
64
+ await deleteMCPServer(context, serverName);
65
+ break;
66
+ default:
67
+ console.error(`āŒ Unknown action: "${action}"`);
68
+ showUsage();
69
+ process.exit(1);
70
+ }
71
+ }
72
+ else {
73
+ // Interactive mode
74
+ await interactiveMCPManagement(context);
75
+ }
76
+ }, "mcp");
77
+ }
78
+ /**
79
+ * Show usage information
80
+ */
81
+ function showUsage() {
82
+ console.log('\nUsage:');
83
+ console.log(' lua mcp - Interactive MCP server management');
84
+ console.log(' lua mcp list - List all MCP servers');
85
+ console.log(' lua mcp activate [name] - Activate an MCP server');
86
+ console.log(' lua mcp deactivate [name] - Deactivate an MCP server');
87
+ console.log(' lua mcp delete [name] - Delete an MCP server');
88
+ console.log('\nAliases:');
89
+ console.log(' list → ls');
90
+ console.log(' activate → enable');
91
+ console.log(' deactivate → disable');
92
+ console.log(' delete → rm');
93
+ }
94
+ /**
95
+ * Interactive MCP management
96
+ */
97
+ async function interactiveMCPManagement(context) {
98
+ let continueManaging = true;
99
+ while (continueManaging) {
100
+ console.log("\n" + "=".repeat(60));
101
+ console.log("šŸ”Œ MCP Server Management");
102
+ console.log("=".repeat(60) + "\n");
103
+ const actionAnswer = await safePrompt([
104
+ {
105
+ type: 'list',
106
+ name: 'action',
107
+ message: 'What would you like to do?',
108
+ choices: [
109
+ { name: 'šŸ“‹ List MCP servers', value: 'list' },
110
+ { name: 'āœ… Activate a server', value: 'activate' },
111
+ { name: 'āøļø Deactivate a server', value: 'deactivate' },
112
+ { name: 'šŸ—‘ļø Delete a server', value: 'delete' },
113
+ { name: 'āŒ Exit', value: 'exit' }
114
+ ]
115
+ }
116
+ ]);
117
+ if (!actionAnswer)
118
+ return;
119
+ const { action } = actionAnswer;
120
+ switch (action) {
121
+ case 'list':
122
+ await listMCPServers(context);
123
+ break;
124
+ case 'activate':
125
+ await activateMCPServer(context);
126
+ break;
127
+ case 'deactivate':
128
+ await deactivateMCPServer(context);
129
+ break;
130
+ case 'delete':
131
+ await deleteMCPServer(context);
132
+ break;
133
+ case 'exit':
134
+ continueManaging = false;
135
+ console.log("\nšŸ‘‹ Goodbye!\n");
136
+ break;
137
+ }
138
+ }
139
+ }
140
+ /**
141
+ * List all MCP servers
142
+ */
143
+ async function listMCPServers(context) {
144
+ writeProgress("šŸ”„ Loading MCP servers...");
145
+ try {
146
+ const result = await context.developerApi.getMCPServers();
147
+ if (!result.success) {
148
+ console.error(`\nāŒ Failed to load MCP servers: ${result.error?.message}\n`);
149
+ return;
150
+ }
151
+ const servers = result.data || [];
152
+ console.log("\n" + "=".repeat(60));
153
+ console.log("šŸ”Œ MCP Servers");
154
+ console.log("=".repeat(60) + "\n");
155
+ if (servers.length === 0) {
156
+ console.log("ā„¹ļø No MCP servers found.");
157
+ console.log("šŸ’” Define MCP servers in your LuaAgent configuration and run 'lua push all'.\n");
158
+ return;
159
+ }
160
+ // Separate active and inactive servers
161
+ const activeServers = servers.filter((s) => s.active);
162
+ const inactiveServers = servers.filter((s) => !s.active);
163
+ if (activeServers.length > 0) {
164
+ console.log("āœ… Active Servers:\n");
165
+ activeServers.forEach((server) => {
166
+ printServerInfo(server);
167
+ });
168
+ }
169
+ if (inactiveServers.length > 0) {
170
+ if (activeServers.length > 0)
171
+ console.log("─".repeat(40) + "\n");
172
+ console.log("āøļø Inactive Servers:\n");
173
+ inactiveServers.forEach((server) => {
174
+ printServerInfo(server);
175
+ });
176
+ }
177
+ console.log("=".repeat(60) + "\n");
178
+ }
179
+ catch (error) {
180
+ console.error('\nāŒ Error loading MCP servers:', error.message);
181
+ }
182
+ }
183
+ /**
184
+ * Print server information
185
+ */
186
+ function printServerInfo(server) {
187
+ const statusIcon = server.active ? '🟢' : '⚪';
188
+ console.log(`${statusIcon} ${server.name}`);
189
+ console.log(` Transport: ${server.transport}`);
190
+ if (server.transport === 'stdio') {
191
+ console.log(` Command: ${server.command} ${(server.args || []).join(' ')}`);
192
+ }
193
+ else {
194
+ console.log(` URL: ${server.url}`);
195
+ }
196
+ console.log(` ID: ${server.id}`);
197
+ console.log();
198
+ }
199
+ /**
200
+ * Activate an MCP server
201
+ */
202
+ async function activateMCPServer(context, serverName) {
203
+ try {
204
+ // Get all servers
205
+ const result = await context.developerApi.getMCPServers();
206
+ if (!result.success) {
207
+ console.error(`\nāŒ Failed to load MCP servers: ${result.error?.message}\n`);
208
+ return;
209
+ }
210
+ const servers = result.data || [];
211
+ const inactiveServers = servers.filter((s) => !s.active);
212
+ if (inactiveServers.length === 0) {
213
+ console.log("\nā„¹ļø All MCP servers are already active.\n");
214
+ return;
215
+ }
216
+ let serverToActivate;
217
+ if (serverName) {
218
+ // Find by name
219
+ const server = inactiveServers.find((s) => s.name.toLowerCase() === serverName.toLowerCase());
220
+ if (!server) {
221
+ console.error(`\nāŒ Inactive MCP server "${serverName}" not found.\n`);
222
+ console.log("Available inactive servers:");
223
+ inactiveServers.forEach((s) => console.log(` - ${s.name}`));
224
+ return;
225
+ }
226
+ serverToActivate = server;
227
+ }
228
+ else {
229
+ // Prompt for selection
230
+ const answer = await safePrompt([
231
+ {
232
+ type: 'list',
233
+ name: 'server',
234
+ message: 'Select an MCP server to activate:',
235
+ choices: inactiveServers.map((s) => ({
236
+ name: `${s.name} (${s.transport})`,
237
+ value: s
238
+ }))
239
+ }
240
+ ]);
241
+ if (!answer)
242
+ return;
243
+ serverToActivate = answer.server;
244
+ }
245
+ writeProgress(`šŸ”„ Activating ${serverToActivate.name}...`);
246
+ const activateResult = await context.developerApi.activateMCPServer(serverToActivate.id);
247
+ if (activateResult.success) {
248
+ writeSuccess(`\nāœ… MCP server "${serverToActivate.name}" activated successfully!\n`);
249
+ writeInfo("šŸ’” The server's tools are now available to your agent.");
250
+ }
251
+ else {
252
+ console.error(`\nāŒ Failed to activate: ${activateResult.error?.message}\n`);
253
+ }
254
+ }
255
+ catch (error) {
256
+ console.error('\nāŒ Error activating MCP server:', error.message);
257
+ }
258
+ }
259
+ /**
260
+ * Deactivate an MCP server
261
+ */
262
+ async function deactivateMCPServer(context, serverName) {
263
+ try {
264
+ // Get all servers
265
+ const result = await context.developerApi.getMCPServers();
266
+ if (!result.success) {
267
+ console.error(`\nāŒ Failed to load MCP servers: ${result.error?.message}\n`);
268
+ return;
269
+ }
270
+ const servers = result.data || [];
271
+ const activeServers = servers.filter((s) => s.active);
272
+ if (activeServers.length === 0) {
273
+ console.log("\nā„¹ļø No active MCP servers to deactivate.\n");
274
+ return;
275
+ }
276
+ let serverToDeactivate;
277
+ if (serverName) {
278
+ // Find by name
279
+ const server = activeServers.find((s) => s.name.toLowerCase() === serverName.toLowerCase());
280
+ if (!server) {
281
+ console.error(`\nāŒ Active MCP server "${serverName}" not found.\n`);
282
+ console.log("Available active servers:");
283
+ activeServers.forEach((s) => console.log(` - ${s.name}`));
284
+ return;
285
+ }
286
+ serverToDeactivate = server;
287
+ }
288
+ else {
289
+ // Prompt for selection
290
+ const answer = await safePrompt([
291
+ {
292
+ type: 'list',
293
+ name: 'server',
294
+ message: 'Select an MCP server to deactivate:',
295
+ choices: activeServers.map((s) => ({
296
+ name: `${s.name} (${s.transport})`,
297
+ value: s
298
+ }))
299
+ }
300
+ ]);
301
+ if (!answer)
302
+ return;
303
+ serverToDeactivate = answer.server;
304
+ }
305
+ writeProgress(`šŸ”„ Deactivating ${serverToDeactivate.name}...`);
306
+ const deactivateResult = await context.developerApi.deactivateMCPServer(serverToDeactivate.id);
307
+ if (deactivateResult.success) {
308
+ writeSuccess(`\nāœ… MCP server "${serverToDeactivate.name}" deactivated successfully!\n`);
309
+ writeInfo("šŸ’” The server's tools are no longer available to your agent.");
310
+ }
311
+ else {
312
+ console.error(`\nāŒ Failed to deactivate: ${deactivateResult.error?.message}\n`);
313
+ }
314
+ }
315
+ catch (error) {
316
+ console.error('\nāŒ Error deactivating MCP server:', error.message);
317
+ }
318
+ }
319
+ /**
320
+ * Delete an MCP server
321
+ */
322
+ async function deleteMCPServer(context, serverName) {
323
+ try {
324
+ // Get all servers
325
+ const result = await context.developerApi.getMCPServers();
326
+ if (!result.success) {
327
+ console.error(`\nāŒ Failed to load MCP servers: ${result.error?.message}\n`);
328
+ return;
329
+ }
330
+ const servers = result.data || [];
331
+ if (servers.length === 0) {
332
+ console.log("\nā„¹ļø No MCP servers to delete.\n");
333
+ return;
334
+ }
335
+ let serverToDelete;
336
+ if (serverName) {
337
+ // Find by name
338
+ const server = servers.find((s) => s.name.toLowerCase() === serverName.toLowerCase());
339
+ if (!server) {
340
+ console.error(`\nāŒ MCP server "${serverName}" not found.\n`);
341
+ console.log("Available servers:");
342
+ servers.forEach((s) => console.log(` - ${s.name}`));
343
+ return;
344
+ }
345
+ serverToDelete = server;
346
+ }
347
+ else {
348
+ // Prompt for selection
349
+ const answer = await safePrompt([
350
+ {
351
+ type: 'list',
352
+ name: 'server',
353
+ message: 'Select an MCP server to delete:',
354
+ choices: servers.map((s) => ({
355
+ name: `${s.name} (${s.transport}) ${s.active ? '🟢' : '⚪'}`,
356
+ value: s
357
+ }))
358
+ }
359
+ ]);
360
+ if (!answer)
361
+ return;
362
+ serverToDelete = answer.server;
363
+ }
364
+ // Confirm deletion
365
+ console.log(`\nāš ļø You are about to delete MCP server: ${serverToDelete.name}`);
366
+ if (serverToDelete.active) {
367
+ console.log("āš ļø WARNING: This server is currently ACTIVE!");
368
+ }
369
+ const confirmAnswer = await safePrompt([
370
+ {
371
+ type: 'confirm',
372
+ name: 'confirm',
373
+ message: 'Are you sure you want to delete this MCP server?',
374
+ default: false
375
+ }
376
+ ]);
377
+ if (!confirmAnswer || !confirmAnswer.confirm) {
378
+ console.log("\nāŒ Deletion cancelled.\n");
379
+ return;
380
+ }
381
+ writeProgress(`šŸ”„ Deleting ${serverToDelete.name}...`);
382
+ const deleteResult = await context.developerApi.deleteMCPServer(serverToDelete.id);
383
+ if (deleteResult.success) {
384
+ writeSuccess(`\nāœ… MCP server "${serverToDelete.name}" deleted successfully!\n`);
385
+ }
386
+ else {
387
+ console.error(`\nāŒ Failed to delete: ${deleteResult.error?.message}\n`);
388
+ }
389
+ }
390
+ catch (error) {
391
+ console.error('\nāŒ Error deleting MCP server:', error.message);
392
+ }
393
+ }