lua-cli 1.3.1 → 1.3.2-alpha.2

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.
@@ -5,6 +5,7 @@ import inquirer from 'inquirer';
5
5
  import { compileCommand } from './compile.js';
6
6
  import { checkApiKey, loadApiKey } from '../services/auth.js';
7
7
  import { ApiService } from '../services/api.js';
8
+ import { executeTool, createBroadcastConsole } from '../utils/sandbox.js';
8
9
  import { readSkillConfig, updateSkillYamlPersona } from '../utils/files.js';
9
10
  import { withErrorHandling, clearPromptLines, writeProgress, writeSuccess } from '../utils/cli.js';
10
11
  import keytar from 'keytar';
@@ -190,6 +191,14 @@ function createChatServer(apiKey, agentId, skillId, sandboxId, port = 3000) {
190
191
  res.end(JSON.stringify({ success: false, error: 'Tool not found' }));
191
192
  return;
192
193
  }
194
+ // Extract environment variables from YAML config
195
+ const config = readSkillConfig();
196
+ const envVars = {};
197
+ if (config?.skill?.env) {
198
+ for (const [key, value] of Object.entries(config.skill.env)) {
199
+ envVars[key] = value;
200
+ }
201
+ }
193
202
  // Decompress and execute the tool
194
203
  const { gunzipSync } = await import('zlib');
195
204
  const { Buffer } = await import('buffer');
@@ -200,64 +209,22 @@ function createChatServer(apiKey, agentId, skillId, sandboxId, port = 3000) {
200
209
  return gunzipSync(buffer).toString('utf8');
201
210
  }
202
211
  const toolCode = decompressCode(tool.execute);
203
- // Create a CommonJS context for execution
204
- const require = createRequire(process.cwd() + '/package.json');
205
- // Create a sandbox context
206
- const sandbox = {
207
- require,
208
- console,
209
- Buffer,
210
- setTimeout,
211
- setInterval,
212
- clearTimeout,
213
- clearInterval,
214
- process,
215
- global: globalThis,
216
- __dirname: process.cwd(),
217
- __filename: path.join(process.cwd(), 'index.ts'),
218
- module: { exports: {} },
219
- exports: {},
220
- // Web APIs
221
- fetch: globalThis.fetch,
222
- URLSearchParams: globalThis.URLSearchParams,
223
- URL: globalThis.URL,
224
- Headers: globalThis.Headers,
225
- Request: globalThis.Request,
226
- Response: globalThis.Response,
227
- // Additional globals
228
- Object,
229
- Array,
230
- String,
231
- Number,
232
- Boolean,
233
- Date,
234
- Math,
235
- JSON,
236
- Error,
237
- TypeError,
238
- ReferenceError,
239
- SyntaxError,
240
- globalThis,
241
- undefined: undefined,
242
- null: null,
243
- Infinity: Infinity,
244
- NaN: NaN
245
- };
246
- // Create the CommonJS wrapper code
247
- const commonJsWrapper = `
248
- const executeFunction = ${toolCode};
249
-
250
- // Export the function for testing
251
- module.exports = async (input) => {
252
- return await executeFunction(input);
253
- };
254
- `;
255
- // Execute the code in the sandbox
256
- const context = vm.createContext(sandbox);
257
- vm.runInContext(commonJsWrapper, context);
258
- // Get the exported function and execute it
259
- const executeFunction = context.module.exports;
260
- const result = await executeFunction(inputs);
212
+ // Create custom console that captures output and sends via WebSocket
213
+ const customConsole = createBroadcastConsole((logData) => {
214
+ wss.clients.forEach((client) => {
215
+ if (client.readyState === 1) { // WebSocket.OPEN
216
+ client.send(JSON.stringify(logData));
217
+ }
218
+ });
219
+ });
220
+ // Execute the tool using the common utility
221
+ const result = await executeTool({
222
+ toolCode,
223
+ inputs,
224
+ apiKey,
225
+ agentId,
226
+ customConsole
227
+ });
261
228
  res.writeHead(200, { 'Content-Type': 'application/json' });
262
229
  res.end(JSON.stringify({
263
230
  success: true,
@@ -328,22 +295,44 @@ module.exports = async (input) => {
328
295
  res.writeHead(404);
329
296
  res.end('Not Found');
330
297
  });
331
- // Create WebSocket server for live reload
298
+ // Create WebSocket server for log streaming
332
299
  const wss = new WebSocketServer({ server });
333
300
  wss.on('connection', (ws) => {
334
- console.log('WebSocket client connected for live reload');
301
+ console.log('WebSocket client connected for log streaming');
335
302
  ws.on('close', () => {
336
303
  console.log('WebSocket client disconnected');
337
304
  });
338
305
  ws.on('error', (error) => {
339
306
  console.error('WebSocket error:', error);
340
307
  });
308
+ // Send initial connection message
309
+ ws.send(JSON.stringify({
310
+ type: 'log',
311
+ subType: 'info',
312
+ message: 'Connected to CLI dev server',
313
+ timestamp: new Date().toISOString()
314
+ }));
341
315
  });
342
316
  server.listen(port, () => {
343
317
  console.log('Chat interface available at: http://localhost:' + port);
344
- console.log('Live reload WebSocket available at: ws://localhost:' + port);
318
+ console.log('Log streaming WebSocket available at: ws://localhost:' + port);
345
319
  });
346
- return { server, wss };
320
+ // Function to broadcast logs to all connected clients
321
+ const broadcastLog = (message, subType = 'info') => {
322
+ const logMessage = {
323
+ type: 'log',
324
+ subType,
325
+ message,
326
+ timestamp: new Date().toISOString(),
327
+ id: Date.now().toString()
328
+ };
329
+ wss.clients.forEach((client) => {
330
+ if (client.readyState === 1) { // WebSocket.OPEN
331
+ client.send(JSON.stringify(logMessage));
332
+ }
333
+ });
334
+ };
335
+ return { server, wss, broadcastLog };
347
336
  }
348
337
  // Function to update existing sandbox version
349
338
  export async function updateDevVersion(apiKey, agentId, skillId, sandboxVersionId, versionData) {
@@ -415,10 +404,6 @@ export async function pushDevVersion(apiKey, agentId, skillId, versionData) {
415
404
  };
416
405
  }
417
406
  }
418
- function readConfigSkillName() {
419
- const config = readSkillConfig();
420
- return config?.skill?.name || null;
421
- }
422
407
  function readConfigVersion() {
423
408
  const config = readSkillConfig();
424
409
  return config?.skill?.version || null;
@@ -434,18 +419,21 @@ function readDeployJson() {
434
419
  // Function to push to sandbox (extracted for reuse)
435
420
  async function pushToSandbox(apiKey, agentId, skillId, deployData, isInitial = false) {
436
421
  const sandboxSkillId = await getSandboxSkillId();
437
- // Read skill name from config and add to payload
438
- const skillName = readConfigSkillName();
439
- const payloadWithName = {
422
+ // Read skill name and environment variables from config
423
+ const config = readSkillConfig();
424
+ const skillName = config?.skill?.name || deployData.name || 'Unknown Skill';
425
+ const envVars = config?.skill?.env || {};
426
+ const payloadWithNameAndEnv = {
440
427
  ...deployData,
441
- name: skillName || deployData.name || 'Unknown Skill'
428
+ name: skillName,
429
+ env: envVars
442
430
  };
443
431
  if (sandboxSkillId) {
444
432
  // Try to update existing sandbox version
445
433
  if (!isInitial) {
446
434
  writeProgress("šŸ”„ Updating existing sandbox version...");
447
435
  }
448
- const updateResult = await updateDevVersion(apiKey, agentId, skillId, sandboxSkillId, payloadWithName);
436
+ const updateResult = await updateDevVersion(apiKey, agentId, skillId, sandboxSkillId, payloadWithNameAndEnv);
449
437
  if (updateResult.success && updateResult.data) {
450
438
  if (!isInitial) {
451
439
  writeSuccess(`āœ… Version ${updateResult.data.version} updated in sandbox successfully`);
@@ -468,7 +456,7 @@ async function pushToSandbox(apiKey, agentId, skillId, deployData, isInitial = f
468
456
  if (!isInitial) {
469
457
  writeProgress("šŸ”„ Creating new sandbox version...");
470
458
  }
471
- const result = await pushDevVersion(apiKey, agentId, skillId, payloadWithName);
459
+ const result = await pushDevVersion(apiKey, agentId, skillId, payloadWithNameAndEnv);
472
460
  if (result.success && result.data) {
473
461
  // Store the new sandbox skill ID
474
462
  await setSandboxSkillId(result.data.skillId);
@@ -571,26 +559,37 @@ export async function devCommand() {
571
559
  }
572
560
  // Start web server for chat interface
573
561
  const chatPort = 3000;
574
- const { server, wss } = createChatServer(apiKey, agentId, skillId, sandboxSkillId, chatPort);
562
+ const { server, wss, broadcastLog } = createChatServer(apiKey, agentId, skillId, sandboxSkillId, chatPort);
575
563
  // Open browser to chat interface
576
564
  try {
577
565
  await open(`http://localhost:${chatPort}`);
578
566
  writeSuccess("🌐 Chat interface opened in your browser");
567
+ broadcastLog("🌐 Chat interface opened in your browser", 'info');
579
568
  }
580
569
  catch (error) {
581
570
  writeSuccess(`🌐 Chat interface available at: http://localhost:${chatPort}`);
571
+ broadcastLog(`🌐 Chat interface available at: http://localhost:${chatPort}`, 'info');
582
572
  }
583
573
  // Start file watching
584
574
  writeSuccess("šŸ” Watching for file changes... (Press Ctrl+C to stop)");
575
+ broadcastLog("šŸ” Watching for file changes... (Press Ctrl+C to stop)", 'info');
585
576
  let isCompiling = false;
586
577
  let pendingCompile = false;
578
+ let compileTimeout = null;
587
579
  const watcher = watch(process.cwd(), { recursive: true }, async (eventType, filename) => {
588
580
  // Ignore changes in .lua directory and other build artifacts
589
581
  if (filename && (filename.includes('.lua/') ||
582
+ filename.includes('.lua\\') ||
590
583
  filename.includes('node_modules/') ||
584
+ filename.includes('node_modules\\') ||
591
585
  filename.includes('.git/') ||
586
+ filename.includes('.git\\') ||
592
587
  filename.endsWith('.log') ||
593
- filename.endsWith('.tmp'))) {
588
+ filename.endsWith('.tmp') ||
589
+ filename.endsWith('.js') ||
590
+ filename.endsWith('.map') ||
591
+ filename.includes('dist/') ||
592
+ filename.includes('dist\\'))) {
594
593
  return;
595
594
  }
596
595
  // Debounce rapid changes
@@ -598,55 +597,59 @@ export async function devCommand() {
598
597
  pendingCompile = true;
599
598
  return;
600
599
  }
601
- isCompiling = true;
602
- pendingCompile = false;
603
- try {
604
- writeProgress(`šŸ”„ File changed: ${filename} - Compiling and pushing...`);
605
- // Compile the skill
606
- await compileCommand();
607
- // Read updated deploy.json
608
- const updatedDeployData = readDeployJson();
609
- if (!updatedDeployData) {
610
- writeProgress("āŒ Compilation failed, skipping push");
611
- return;
612
- }
613
- // Verify version matches
614
- if (updatedDeployData.version !== version) {
615
- writeProgress("āŒ Version mismatch, skipping push");
600
+ // Clear any existing timeout
601
+ if (compileTimeout) {
602
+ clearTimeout(compileTimeout);
603
+ }
604
+ // Debounce file changes with a 500ms delay
605
+ compileTimeout = setTimeout(async () => {
606
+ if (isCompiling) {
616
607
  return;
617
608
  }
618
- // Push to sandbox
619
- const pushSuccess = await pushToSandbox(apiKey, agentId, skillId, updatedDeployData, false);
620
- if (!pushSuccess) {
621
- writeProgress("āŒ Failed to push to sandbox, will retry on next change");
609
+ isCompiling = true;
610
+ pendingCompile = false;
611
+ try {
612
+ writeProgress(`šŸ”„ File changed: ${filename} - Compiling and pushing...`);
613
+ broadcastLog(`šŸ”„ File changed: ${filename} - Compiling and pushing...`, 'info');
614
+ // Compile the skill
615
+ await compileCommand();
616
+ broadcastLog("āœ… Compilation completed", 'info');
617
+ // Read updated deploy.json
618
+ const updatedDeployData = readDeployJson();
619
+ if (!updatedDeployData) {
620
+ writeProgress("āŒ Compilation failed, skipping push");
621
+ return;
622
+ }
623
+ // Verify version matches
624
+ if (updatedDeployData.version !== version) {
625
+ writeProgress("āŒ Version mismatch, skipping push");
626
+ return;
627
+ }
628
+ // Push to sandbox
629
+ const pushSuccess = await pushToSandbox(apiKey, agentId, skillId, updatedDeployData, false);
630
+ if (!pushSuccess) {
631
+ writeProgress("āŒ Failed to push to sandbox, will retry on next change");
632
+ broadcastLog("āŒ Failed to push to sandbox, will retry on next change", 'error');
633
+ }
634
+ else {
635
+ writeProgress("āœ… Successfully pushed to sandbox");
636
+ broadcastLog("āœ… Successfully pushed to sandbox", 'info');
637
+ }
622
638
  }
623
- else {
624
- // Broadcast reload message to all connected WebSocket clients
625
- wss.clients.forEach((client) => {
626
- if (client.readyState === 1) { // WebSocket.OPEN
627
- client.send(JSON.stringify({ type: 'reload', message: 'Files changed, reloading...' }));
628
- }
629
- });
639
+ catch (error) {
640
+ writeProgress(`āŒ Error during auto-compile: ${error instanceof Error ? error.message : 'Unknown error'}`);
630
641
  }
631
- }
632
- catch (error) {
633
- writeProgress(`āŒ Error during auto-compile: ${error instanceof Error ? error.message : 'Unknown error'}`);
634
- }
635
- finally {
636
- isCompiling = false;
637
- // Handle any pending compile
638
- if (pendingCompile) {
639
- setTimeout(() => {
640
- if (!isCompiling) {
641
- watcher.emit('change', 'pending', 'pending');
642
- }
643
- }, 100);
642
+ finally {
643
+ isCompiling = false;
644
644
  }
645
- }
645
+ }, 500); // 500ms debounce delay
646
646
  });
647
647
  // Handle graceful shutdown
648
648
  process.on('SIGINT', () => {
649
649
  writeSuccess("\nšŸ›‘ Stopping file watcher...");
650
+ if (compileTimeout) {
651
+ clearTimeout(compileTimeout);
652
+ }
650
653
  watcher.close();
651
654
  process.exit(0);
652
655
  });
@@ -4,9 +4,10 @@ import inquirer from "inquirer";
4
4
  import { compileCommand } from "./compile.js";
5
5
  import { gunzipSync } from "zlib";
6
6
  import { Buffer } from "buffer";
7
- import { createRequire } from "module";
8
- import vm from "vm";
9
7
  import { withErrorHandling, clearPromptLines, writeProgress, writeSuccess } from "../utils/cli.js";
8
+ import { loadApiKey } from "../services/auth.js";
9
+ import { executeTool } from "../utils/sandbox.js";
10
+ import { readSkillConfig } from "../utils/files.js";
10
11
  // Decompression utility
11
12
  function decompressCode(compressedCode) {
12
13
  const buffer = Buffer.from(compressedCode, 'base64');
@@ -32,6 +33,24 @@ export async function testCommand() {
32
33
  if (!deployData.tools || deployData.tools.length === 0) {
33
34
  throw new Error("No tools found in deploy.json");
34
35
  }
36
+ // Get API key from keystore and agent ID from YAML
37
+ const apiKey = await loadApiKey();
38
+ if (!apiKey) {
39
+ throw new Error("No API key found. Please run 'lua auth configure' first.");
40
+ }
41
+ // Extract environment variables from YAML config
42
+ const config = readSkillConfig();
43
+ const agentId = config?.agent?.agentId;
44
+ if (!agentId) {
45
+ throw new Error("No agent ID found in lua.skill.yaml. Please run 'lua skill init' first.");
46
+ }
47
+ // Extract environment variables from YAML config
48
+ const envVars = {};
49
+ if (config?.skill?.env) {
50
+ for (const [key, value] of Object.entries(config.skill.env)) {
51
+ envVars[key] = value;
52
+ }
53
+ }
35
54
  // Let user select a tool using picker
36
55
  const toolChoices = deployData.tools.map((tool) => ({
37
56
  name: `${tool.name} - ${tool.description}`,
@@ -50,66 +69,122 @@ export async function testCommand() {
50
69
  clearPromptLines(2);
51
70
  writeProgress(`āœ… Selected tool: ${selectedTool.name}`);
52
71
  // Get input values for each required parameter using inquirer
53
- const inputValues = {};
72
+ let inputValues = {};
54
73
  const inputSchema = selectedTool.inputSchema;
55
74
  if (inputSchema.properties) {
56
75
  writeProgress("\nšŸ“ Enter input values:");
57
- const inputPrompts = [];
58
- for (const [key, value] of Object.entries(inputSchema.properties)) {
59
- const property = value;
60
- const isRequired = inputSchema.required?.includes(key) || false;
61
- let promptType = 'input';
62
- let validate = undefined;
63
- // Set up validation and input type based on schema
64
- switch (property.type) {
65
- case "string":
66
- if (isRequired) {
67
- validate = (input) => input.trim() !== "" || `${key} is required`;
76
+ // Recursive function to generate prompts for nested objects
77
+ async function generatePromptsForObject(schema, prefix = '', required = []) {
78
+ const prompts = [];
79
+ const result = {};
80
+ for (const [key, value] of Object.entries(schema.properties || {})) {
81
+ const property = value;
82
+ const fullKey = prefix ? `${prefix}.${key}` : key;
83
+ const isRequired = required.includes(key);
84
+ if (property.type === "object" && property.properties) {
85
+ // Handle nested object - use fullKey to maintain proper prompt names
86
+ writeProgress(`\nšŸ“‹ Entering values for ${key}:`);
87
+ const nestedResult = await generatePromptsForObject(property, fullKey, property.required || []);
88
+ // Extract the nested values from the nested result
89
+ result[key] = nestedResult[key] || nestedResult;
90
+ }
91
+ else {
92
+ // Handle primitive types
93
+ let promptType = 'input';
94
+ let validate = undefined;
95
+ switch (property.type) {
96
+ case "string":
97
+ if (isRequired) {
98
+ validate = (input) => input.trim() !== "" || `${key} is required`;
99
+ }
100
+ break;
101
+ case "number":
102
+ promptType = 'number';
103
+ if (isRequired) {
104
+ validate = (input) => !isNaN(input) || `${key} must be a valid number`;
105
+ }
106
+ break;
107
+ case "boolean":
108
+ promptType = 'confirm';
109
+ break;
110
+ default:
111
+ if (isRequired) {
112
+ validate = (input) => input.trim() !== "" || `${key} is required`;
113
+ }
68
114
  }
69
- break;
70
- case "number":
71
- promptType = 'number';
72
- if (isRequired) {
73
- validate = (input) => !isNaN(input) || `${key} must be a valid number`;
115
+ const prompt = {
116
+ type: promptType,
117
+ name: fullKey,
118
+ message: `${key}${isRequired ? " (required)" : " (optional)"}:`,
119
+ validate: validate,
120
+ };
121
+ prompts.push(prompt);
122
+ }
123
+ }
124
+ if (prompts.length > 0) {
125
+ const answers = await inquirer.prompt(prompts);
126
+ // Convert answers to proper types and structure
127
+ for (const [key, value] of Object.entries(answers)) {
128
+ const keyParts = key.split('.');
129
+ const propertyKey = keyParts[keyParts.length - 1];
130
+ // For nested properties, we need to find the property in the original schema
131
+ let currentSchema = inputSchema; // Use the original inputSchema
132
+ let currentProperty = null;
133
+ // Navigate through nested schemas to find the property
134
+ for (let i = 0; i < keyParts.length; i++) {
135
+ const part = keyParts[i];
136
+ if (currentSchema.properties && currentSchema.properties[part]) {
137
+ currentProperty = currentSchema.properties[part];
138
+ if (i < keyParts.length - 1) {
139
+ // Move to nested schema
140
+ currentSchema = currentProperty;
141
+ }
142
+ }
74
143
  }
75
- break;
76
- case "boolean":
77
- promptType = 'confirm';
78
- break;
79
- default:
80
- if (isRequired) {
81
- validate = (input) => input.trim() !== "" || `${key} is required`;
144
+ if (currentProperty) {
145
+ let convertedValue = value;
146
+ switch (currentProperty.type) {
147
+ case "number":
148
+ convertedValue = parseFloat(value);
149
+ break;
150
+ case "boolean":
151
+ convertedValue = value;
152
+ break;
153
+ default:
154
+ convertedValue = value;
155
+ }
156
+ // Check if field is optional and value is empty - skip if so
157
+ // For nested properties, check the parent schema's required fields
158
+ const parentSchema = keyParts.length > 1 ? currentSchema : schema;
159
+ const isOptional = !parentSchema.required || !parentSchema.required.includes(propertyKey);
160
+ const isEmpty = convertedValue === '' || convertedValue === null || convertedValue === undefined;
161
+ if (isOptional && isEmpty) {
162
+ // Skip optional empty fields
163
+ continue;
164
+ }
165
+ // Build nested structure
166
+ if (keyParts.length === 1) {
167
+ // Top-level property
168
+ result[propertyKey] = convertedValue;
169
+ }
170
+ else {
171
+ // Nested property - build the nested structure
172
+ let current = result;
173
+ for (let i = 0; i < keyParts.length - 1; i++) {
174
+ const part = keyParts[i];
175
+ if (!current[part]) {
176
+ current[part] = {};
177
+ }
178
+ current = current[part];
179
+ }
180
+ current[propertyKey] = convertedValue;
181
+ }
82
182
  }
83
- }
84
- inputPrompts.push({
85
- type: promptType,
86
- name: key,
87
- message: `${key}${isRequired ? " (required)" : " (optional)"}:`,
88
- validate: validate,
89
- when: isRequired ? true : (answers) => {
90
- // For optional fields, ask if user wants to provide a value
91
- return true;
92
183
  }
93
- });
94
- }
95
- const answers = await inquirer.prompt(inputPrompts);
96
- // Convert answers to proper types
97
- for (const [key, value] of Object.entries(answers)) {
98
- const property = inputSchema.properties[key];
99
- switch (property.type) {
100
- case "string":
101
- inputValues[key] = value;
102
- break;
103
- case "number":
104
- inputValues[key] = parseFloat(value);
105
- break;
106
- case "boolean":
107
- inputValues[key] = value;
108
- break;
109
- default:
110
- inputValues[key] = value;
111
184
  }
185
+ return result;
112
186
  }
187
+ inputValues = await generatePromptsForObject(inputSchema, '', inputSchema.required || []);
113
188
  }
114
189
  writeProgress("\nšŸš€ Executing tool...");
115
190
  writeProgress(`Input: ${JSON.stringify(inputValues, null, 2)}`);
@@ -117,66 +192,12 @@ export async function testCommand() {
117
192
  const toolCode = decompressCode(selectedTool.execute);
118
193
  // Execute the tool
119
194
  try {
120
- // Create a CommonJS context for execution
121
- const require = createRequire(process.cwd() + '/package.json');
122
- // Create a sandbox context with require and other necessary globals
123
- const sandbox = {
124
- require,
125
- console,
126
- Buffer,
127
- setTimeout,
128
- setInterval,
129
- clearTimeout,
130
- clearInterval,
131
- process,
132
- global: globalThis,
133
- __dirname: process.cwd(),
134
- __filename: path.join(process.cwd(), 'index.ts'),
135
- module: { exports: {} },
136
- exports: {},
137
- // Web APIs
138
- fetch: globalThis.fetch,
139
- URLSearchParams: globalThis.URLSearchParams,
140
- URL: globalThis.URL,
141
- Headers: globalThis.Headers,
142
- Request: globalThis.Request,
143
- Response: globalThis.Response,
144
- // Additional Node.js globals that might be needed
145
- Object,
146
- Array,
147
- String,
148
- Number,
149
- Boolean,
150
- Date,
151
- Math,
152
- JSON,
153
- Error,
154
- TypeError,
155
- ReferenceError,
156
- SyntaxError,
157
- // Node.js specific globals
158
- globalThis,
159
- // Additional globals that might be referenced
160
- undefined: undefined,
161
- null: null,
162
- Infinity: Infinity,
163
- NaN: NaN
164
- };
165
- // Create the CommonJS wrapper code
166
- const commonJsWrapper = `
167
- const executeFunction = ${toolCode};
168
-
169
- // Export the function for testing
170
- module.exports = async (input) => {
171
- return await executeFunction(input);
172
- };
173
- `;
174
- // Execute the code in the sandbox
175
- const context = vm.createContext(sandbox);
176
- vm.runInContext(commonJsWrapper, context);
177
- // Get the exported function
178
- const executeFunction = context.module.exports;
179
- const result = await executeFunction(inputValues);
195
+ const result = await executeTool({
196
+ toolCode,
197
+ inputs: inputValues,
198
+ apiKey,
199
+ agentId
200
+ });
180
201
  writeSuccess("āœ… Tool execution successful!");
181
202
  console.log(`Output: ${JSON.stringify(result, null, 2)}`);
182
203
  }
package/dist/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  #!/usr/bin/env node
2
- export { user, createUserDataAPI, UserDataAPI } from './user-data-api.js';
2
+ export { user, UserDataAPI } from './user-data-api.js';
package/dist/index.js CHANGED
@@ -46,4 +46,4 @@ skillCommand
46
46
  .action(devCommand);
47
47
  program.parse(process.argv);
48
48
  // Export user data API for use in projects
49
- export { user, createUserDataAPI, UserDataAPI } from './user-data-api.js';
49
+ export { user, UserDataAPI } from './user-data-api.js';
@@ -183,6 +183,12 @@ export declare class ToolApi {
183
183
  static deleteTool(url: string, apiKey: string): Promise<ApiResponse<any>>;
184
184
  static patchTool(url: string, data: any, apiKey: string): Promise<ApiResponse<any>>;
185
185
  }
186
+ export declare class UserDataApi {
187
+ static getUserData(apiKey: string, agentId: string): Promise<any>;
188
+ static createUserData(apiKey: string, agentId: string, data: any): Promise<any>;
189
+ static updateUserData(apiKey: string, agentId: string, data: any): Promise<ApiResponse<any>>;
190
+ static deleteUserData(apiKey: string, agentId: string): Promise<ApiResponse<any>>;
191
+ }
186
192
  /**
187
193
  * Main API service that exports all API classes
188
194
  */