lua-cli 1.1.1 → 1.1.3
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.
- package/README.md +1 -1
- package/dist/commands/agents.d.ts +1 -0
- package/dist/commands/apiKey.d.ts +1 -0
- package/dist/commands/configure.d.ts +1 -0
- package/dist/commands/deploy.d.ts +1 -0
- package/dist/commands/deploy.js +534 -0
- package/dist/commands/destroy.d.ts +1 -0
- package/dist/commands/index.d.ts +7 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +1 -0
- package/dist/commands/test.d.ts +1 -0
- package/dist/commands/test.js +141 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +9 -1
- package/dist/services/auth.d.ts +8 -0
- package/dist/skill.d.ts +9 -0
- package/dist/skill.js +18 -0
- package/dist/types/index.d.ts +69 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.js +2 -0
- package/dist/utils/files.d.ts +2 -0
- package/dist/utils/files.js +25 -0
- package/package.json +21 -9
- package/template/package.json +0 -12
package/README.md
CHANGED
|
@@ -169,7 +169,7 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
169
169
|
## Support
|
|
170
170
|
|
|
171
171
|
For support and questions:
|
|
172
|
-
- Create an issue on [GitHub](https://github.com/
|
|
172
|
+
- Create an issue on [GitHub](https://github.com/lua-ai-global/lua-cli/issues)
|
|
173
173
|
- Contact: stefan@heylua.ai
|
|
174
174
|
|
|
175
175
|
## Changelog
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function agentsCommand(): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function apiKeyCommand(): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function configureCommand(): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deployCommand(): Promise<void>;
|
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export async function deployCommand() {
|
|
4
|
+
try {
|
|
5
|
+
console.log("🔨 Compiling Lua skill...");
|
|
6
|
+
// Read package.json to get version and name
|
|
7
|
+
const packageJsonPath = path.join(process.cwd(), "package.json");
|
|
8
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
9
|
+
throw new Error("package.json not found in current directory");
|
|
10
|
+
}
|
|
11
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
12
|
+
const version = packageJson.version || "1.0.0";
|
|
13
|
+
const skillsName = packageJson.name || "lua-skill";
|
|
14
|
+
// Read index.ts file
|
|
15
|
+
const indexPath = path.join(process.cwd(), "index.ts");
|
|
16
|
+
if (!fs.existsSync(indexPath)) {
|
|
17
|
+
throw new Error("index.ts not found in current directory");
|
|
18
|
+
}
|
|
19
|
+
const indexContent = fs.readFileSync(indexPath, "utf8");
|
|
20
|
+
// Extract skill information
|
|
21
|
+
const skillInfo = await extractSkillInfo(indexContent);
|
|
22
|
+
// Create deployment data
|
|
23
|
+
const deployData = {
|
|
24
|
+
version,
|
|
25
|
+
skillsName,
|
|
26
|
+
tools: skillInfo
|
|
27
|
+
};
|
|
28
|
+
// Create .lua directory
|
|
29
|
+
const luaDir = path.join(process.cwd(), ".lua");
|
|
30
|
+
if (!fs.existsSync(luaDir)) {
|
|
31
|
+
fs.mkdirSync(luaDir, { recursive: true });
|
|
32
|
+
}
|
|
33
|
+
// Write JSON output to .lua directory
|
|
34
|
+
const jsonOutputPath = path.join(luaDir, "deploy.json");
|
|
35
|
+
fs.writeFileSync(jsonOutputPath, JSON.stringify(deployData, null, 2));
|
|
36
|
+
// Write individual tool files to .lua directory
|
|
37
|
+
for (const tool of skillInfo) {
|
|
38
|
+
const toolFilePath = path.join(luaDir, `${tool.name}.js`);
|
|
39
|
+
fs.writeFileSync(toolFilePath, tool.execute);
|
|
40
|
+
}
|
|
41
|
+
console.log(`📁 Compiled files written to: ${luaDir}`);
|
|
42
|
+
console.log(`📄 JSON output: ${jsonOutputPath}`);
|
|
43
|
+
console.log(`🔧 Tool files: ${skillInfo.map(t => `${t.name}.js`).join(', ')}`);
|
|
44
|
+
console.log("✅ Skill compilation completed successfully!");
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error("❌ Compilation failed:", error.message);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function extractSkillInfo(indexContent) {
|
|
52
|
+
const tools = [];
|
|
53
|
+
// Find all addTool calls
|
|
54
|
+
const addToolRegex = /skill\.addTool\(\s*\{([\s\S]*?)\}\s*\)/g;
|
|
55
|
+
let match;
|
|
56
|
+
while ((match = addToolRegex.exec(indexContent)) !== null) {
|
|
57
|
+
const toolContent = match[1];
|
|
58
|
+
// Extract tool properties
|
|
59
|
+
const nameMatch = toolContent.match(/name:\s*["']([^"']+)["']/);
|
|
60
|
+
const descriptionMatch = toolContent.match(/description:\s*["']([^"']+)["']/);
|
|
61
|
+
const inputSchemaMatch = toolContent.match(/inputSchema:\s*(\w+)/);
|
|
62
|
+
const outputSchemaMatch = toolContent.match(/outputSchema:\s*(\w+)/);
|
|
63
|
+
const executeMatch = toolContent.match(/execute:\s*async\s*\([^)]*\)\s*=>\s*\{([\s\S]*?)\}/);
|
|
64
|
+
if (nameMatch && descriptionMatch && inputSchemaMatch && outputSchemaMatch && executeMatch) {
|
|
65
|
+
const toolName = nameMatch[1];
|
|
66
|
+
const toolDescription = descriptionMatch[1];
|
|
67
|
+
const inputSchemaVar = inputSchemaMatch[1];
|
|
68
|
+
const outputSchemaVar = outputSchemaMatch[1];
|
|
69
|
+
const executeBody = executeMatch[1];
|
|
70
|
+
// Convert schemas to JSON Schema format
|
|
71
|
+
const inputSchema = convertSchemaToJSON(inputSchemaVar, indexContent);
|
|
72
|
+
const outputSchema = convertSchemaToJSON(outputSchemaVar, indexContent);
|
|
73
|
+
// Create self-contained execute function
|
|
74
|
+
const selfContainedExecute = await createSelfContainedExecute(executeBody, indexContent);
|
|
75
|
+
tools.push({
|
|
76
|
+
name: toolName,
|
|
77
|
+
description: toolDescription,
|
|
78
|
+
inputSchema,
|
|
79
|
+
outputSchema,
|
|
80
|
+
execute: selfContainedExecute
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
return tools;
|
|
85
|
+
}
|
|
86
|
+
function convertSchemaToJSON(schemaVar, indexContent) {
|
|
87
|
+
// Find the schema definition
|
|
88
|
+
const schemaRegex = new RegExp(`const\\s+${schemaVar}\\s*=\\s*z\\.object\\(\\{([\\s\\S]*?)\\}\\\);`, 'g');
|
|
89
|
+
const match = schemaRegex.exec(indexContent);
|
|
90
|
+
if (match) {
|
|
91
|
+
const schemaContent = match[1];
|
|
92
|
+
// Convert Zod schema to JSON Schema format
|
|
93
|
+
return {
|
|
94
|
+
type: "object",
|
|
95
|
+
properties: parseZodProperties(schemaContent),
|
|
96
|
+
required: extractRequiredFields(schemaContent)
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// If no match found, return empty schema
|
|
100
|
+
return { type: "object", properties: {} };
|
|
101
|
+
}
|
|
102
|
+
function parseZodProperties(schemaContent) {
|
|
103
|
+
const properties = {};
|
|
104
|
+
// Simple regex to find z.string(), z.number(), etc.
|
|
105
|
+
const fieldRegex = /(\w+):\s*z\.(\w+)\(\)/g;
|
|
106
|
+
let match;
|
|
107
|
+
while ((match = fieldRegex.exec(schemaContent)) !== null) {
|
|
108
|
+
const fieldName = match[1];
|
|
109
|
+
const fieldType = match[2];
|
|
110
|
+
switch (fieldType) {
|
|
111
|
+
case 'string':
|
|
112
|
+
properties[fieldName] = { type: 'string' };
|
|
113
|
+
break;
|
|
114
|
+
case 'number':
|
|
115
|
+
properties[fieldName] = { type: 'number' };
|
|
116
|
+
break;
|
|
117
|
+
case 'boolean':
|
|
118
|
+
properties[fieldName] = { type: 'boolean' };
|
|
119
|
+
break;
|
|
120
|
+
default:
|
|
121
|
+
properties[fieldName] = { type: 'string' };
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return properties;
|
|
125
|
+
}
|
|
126
|
+
function extractRequiredFields(schemaContent) {
|
|
127
|
+
const required = [];
|
|
128
|
+
const fieldRegex = /(\w+):\s*z\.(\w+)\(\)/g;
|
|
129
|
+
let match;
|
|
130
|
+
while ((match = fieldRegex.exec(schemaContent)) !== null) {
|
|
131
|
+
required.push(match[1]);
|
|
132
|
+
}
|
|
133
|
+
return required;
|
|
134
|
+
}
|
|
135
|
+
async function createSelfContainedExecute(executeBody, indexContent) {
|
|
136
|
+
const dependencies = [];
|
|
137
|
+
const bundledPackages = new Set();
|
|
138
|
+
// 1. Parse external package imports and bundle their code
|
|
139
|
+
const allImportRegex = /import\s+(?:(?:\{([^}]+)\})|(\w+))\s+from\s+["']([^"']+)["']/g;
|
|
140
|
+
let importMatch;
|
|
141
|
+
while ((importMatch = allImportRegex.exec(indexContent)) !== null) {
|
|
142
|
+
const namedImports = importMatch[1]; // Named imports like { z }
|
|
143
|
+
const defaultImport = importMatch[2]; // Default import like axios
|
|
144
|
+
const packagePath = importMatch[3];
|
|
145
|
+
// Skip local imports (relative paths)
|
|
146
|
+
if (packagePath.startsWith('./') || packagePath.startsWith('../')) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
// Skip lua-cli imports (these are handled separately)
|
|
150
|
+
if (packagePath.startsWith('lua-cli')) {
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
153
|
+
// Skip zod - assume it's always available on target machine
|
|
154
|
+
if (packagePath === 'zod') {
|
|
155
|
+
// Add require statement for zod instead of bundling
|
|
156
|
+
if (namedImports) {
|
|
157
|
+
const importsList = namedImports.split(',').map(imp => imp.trim());
|
|
158
|
+
const usedImports = importsList.filter(imp => executeBody.includes(imp) || indexContent.includes(`${imp}.`));
|
|
159
|
+
if (usedImports.length > 0) {
|
|
160
|
+
const requireStatement = usedImports.length === 1
|
|
161
|
+
? `const { ${usedImports[0]} } = require('zod');`
|
|
162
|
+
: `const { ${usedImports.join(', ')} } = require('zod');`;
|
|
163
|
+
bundledPackages.add(requireStatement);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
else if (defaultImport) {
|
|
167
|
+
bundledPackages.add(`const ${defaultImport} = require('zod');`);
|
|
168
|
+
}
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
// Bundle other external packages
|
|
172
|
+
if (namedImports || defaultImport) {
|
|
173
|
+
const packageCode = await bundlePackageCode(packagePath, namedImports, defaultImport);
|
|
174
|
+
if (packageCode) {
|
|
175
|
+
bundledPackages.add(packageCode);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// 2. Extract class definitions with proper brace matching
|
|
180
|
+
const classRegex = /class\s+(\w+)(?:\s+extends\s+\w+)?\s*\{/g;
|
|
181
|
+
let classMatch;
|
|
182
|
+
while ((classMatch = classRegex.exec(indexContent)) !== null) {
|
|
183
|
+
const className = classMatch[1];
|
|
184
|
+
const classStart = classMatch.index;
|
|
185
|
+
// Find the matching closing brace
|
|
186
|
+
let braceCount = 0;
|
|
187
|
+
let classEnd = classStart;
|
|
188
|
+
let found = false;
|
|
189
|
+
for (let i = classStart; i < indexContent.length; i++) {
|
|
190
|
+
if (indexContent[i] === '{') {
|
|
191
|
+
braceCount++;
|
|
192
|
+
}
|
|
193
|
+
else if (indexContent[i] === '}') {
|
|
194
|
+
braceCount--;
|
|
195
|
+
if (braceCount === 0) {
|
|
196
|
+
classEnd = i;
|
|
197
|
+
found = true;
|
|
198
|
+
break;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
if (found) {
|
|
203
|
+
const fullClass = indexContent.substring(classStart, classEnd + 1);
|
|
204
|
+
// Check if this class is used in the execute function
|
|
205
|
+
let isUsed = false;
|
|
206
|
+
// Direct usage in execute body
|
|
207
|
+
if (executeBody.includes(`new ${className}`) ||
|
|
208
|
+
executeBody.includes(`${className}.`) ||
|
|
209
|
+
executeBody.includes(`${className}(`)) {
|
|
210
|
+
isUsed = true;
|
|
211
|
+
}
|
|
212
|
+
// Check if any variable that uses this class is referenced in execute body
|
|
213
|
+
const variableRegex = new RegExp(`(?:const|let|var)\\s+(\\w+)\\s*=\\s*new\\s+${className}\\s*\\([^)]*\\);`, 'g');
|
|
214
|
+
let varMatch;
|
|
215
|
+
while ((varMatch = variableRegex.exec(indexContent)) !== null) {
|
|
216
|
+
const varName = varMatch[1];
|
|
217
|
+
if (executeBody.includes(varName)) {
|
|
218
|
+
isUsed = true;
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
if (isUsed) {
|
|
223
|
+
dependencies.push(fullClass);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
// 3. Extract function definitions
|
|
228
|
+
const functionRegex = /(?:async\s+)?function\s+(\w+)\s*\([^)]*\)\s*\{([\s\S]*?)\n\}/g;
|
|
229
|
+
let functionMatch;
|
|
230
|
+
while ((functionMatch = functionRegex.exec(indexContent)) !== null) {
|
|
231
|
+
const functionName = functionMatch[1];
|
|
232
|
+
const functionBody = functionMatch[2];
|
|
233
|
+
if (executeBody.includes(functionName)) {
|
|
234
|
+
dependencies.push(`function ${functionName}() {\n${functionBody}\n}`);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
// 4. Extract const/let/var declarations (avoid duplicates)
|
|
238
|
+
const varRegex = /(?:const|let|var)\s+(\w+)\s*=\s*([^;]+);/g;
|
|
239
|
+
const declaredVars = new Set();
|
|
240
|
+
let varMatch;
|
|
241
|
+
while ((varMatch = varRegex.exec(indexContent)) !== null) {
|
|
242
|
+
const varName = varMatch[1];
|
|
243
|
+
const varValue = varMatch[2];
|
|
244
|
+
// Skip if it's a class instantiation (we'll handle that separately)
|
|
245
|
+
if (varValue.includes('new ') && varValue.includes('()')) {
|
|
246
|
+
continue;
|
|
247
|
+
}
|
|
248
|
+
// Skip if already declared
|
|
249
|
+
if (declaredVars.has(varName)) {
|
|
250
|
+
continue;
|
|
251
|
+
}
|
|
252
|
+
if (executeBody.includes(varName)) {
|
|
253
|
+
declaredVars.add(varName);
|
|
254
|
+
dependencies.push(`const ${varName} = ${varValue};`);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
// 5. Extract class instantiations (avoid duplicates)
|
|
258
|
+
const instantiationRegex = /(?:const|let|var)\s+(\w+)\s*=\s*new\s+(\w+)\([^)]*\);/g;
|
|
259
|
+
let instantiationMatch;
|
|
260
|
+
while ((instantiationMatch = instantiationRegex.exec(indexContent)) !== null) {
|
|
261
|
+
const instanceName = instantiationMatch[1];
|
|
262
|
+
const className = instantiationMatch[2];
|
|
263
|
+
// Skip if already declared
|
|
264
|
+
if (declaredVars.has(instanceName)) {
|
|
265
|
+
continue;
|
|
266
|
+
}
|
|
267
|
+
if (executeBody.includes(instanceName)) {
|
|
268
|
+
declaredVars.add(instanceName);
|
|
269
|
+
dependencies.push(`const ${instanceName} = new ${className}();`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
// 6. Create the self-contained execute function
|
|
273
|
+
const allDependencies = [...Array.from(bundledPackages), ...dependencies];
|
|
274
|
+
const dependencyCode = allDependencies.join('\n');
|
|
275
|
+
// Strip TypeScript type annotations for JavaScript compatibility (only for local code)
|
|
276
|
+
const cleanDependencyCode = allDependencies.map(dep => {
|
|
277
|
+
// Only strip TypeScript from local dependencies, not bundled packages
|
|
278
|
+
if (dep.includes('require(') || dep.includes('import ')) {
|
|
279
|
+
return dep; // Skip bundled packages
|
|
280
|
+
}
|
|
281
|
+
return dep
|
|
282
|
+
.replace(/:\s*string/g, '') // Remove : string
|
|
283
|
+
.replace(/:\s*number/g, '') // Remove : number
|
|
284
|
+
.replace(/:\s*boolean/g, '') // Remove : boolean
|
|
285
|
+
.replace(/:\s*any/g, '') // Remove : any
|
|
286
|
+
.replace(/:\s*void/g, '') // Remove : void
|
|
287
|
+
.replace(/:\s*object/g, '') // Remove : object
|
|
288
|
+
.replace(/:\s*Array<[^>]+>/g, '') // Remove : Array<Type>
|
|
289
|
+
.replace(/:\s*Promise<[^>]+>/g, '') // Remove : Promise<Type>
|
|
290
|
+
.replace(/:\s*Record<[^>]+>/g, ''); // Remove : Record<Type>
|
|
291
|
+
}).join('\n');
|
|
292
|
+
const cleanExecuteBody = executeBody
|
|
293
|
+
.replace(/:\s*string/g, '') // Remove : string
|
|
294
|
+
.replace(/:\s*number/g, '') // Remove : number
|
|
295
|
+
.replace(/:\s*boolean/g, '') // Remove : boolean
|
|
296
|
+
.replace(/:\s*any/g, '') // Remove : any
|
|
297
|
+
.replace(/:\s*void/g, '') // Remove : void
|
|
298
|
+
.replace(/:\s*object/g, '') // Remove : object
|
|
299
|
+
.replace(/:\s*Array<[^>]+>/g, '') // Remove : Array<Type>
|
|
300
|
+
.replace(/:\s*Promise<[^>]+>/g, '') // Remove : Promise<Type>
|
|
301
|
+
.replace(/:\s*Record<[^>]+>/g, ''); // Remove : Record<Type>
|
|
302
|
+
const selfContainedExecute = `async (input) => {
|
|
303
|
+
${cleanDependencyCode ? ` ${cleanDependencyCode.split('\n').join('\n ')}\n` : ''} ${cleanExecuteBody.trim()}
|
|
304
|
+
}`;
|
|
305
|
+
return selfContainedExecute;
|
|
306
|
+
}
|
|
307
|
+
async function bundlePackageCode(packagePath, namedImports, defaultImport) {
|
|
308
|
+
try {
|
|
309
|
+
const { build } = await import('esbuild');
|
|
310
|
+
// Create a temporary entry file for esbuild in .lua directory
|
|
311
|
+
const luaDir = path.join(process.cwd(), '.lua');
|
|
312
|
+
if (!fs.existsSync(luaDir)) {
|
|
313
|
+
fs.mkdirSync(luaDir, { recursive: true });
|
|
314
|
+
}
|
|
315
|
+
const entryFile = path.join(luaDir, `${packagePath}-entry.js`);
|
|
316
|
+
const outputFile = path.join(luaDir, `${packagePath}-bundle.js`);
|
|
317
|
+
// Create entry file based on import type
|
|
318
|
+
let entryContent = '';
|
|
319
|
+
if (defaultImport) {
|
|
320
|
+
// For default imports like `import axios from 'axios'`
|
|
321
|
+
entryContent = `import ${defaultImport} from '${packagePath}';\nmodule.exports = ${defaultImport};`;
|
|
322
|
+
}
|
|
323
|
+
else if (namedImports) {
|
|
324
|
+
// For named imports like `import { z } from 'zod'`
|
|
325
|
+
const importsList = namedImports.split(',').map(imp => imp.trim());
|
|
326
|
+
entryContent = `import { ${importsList.join(', ')} } from '${packagePath}';\nmodule.exports = { ${importsList.join(', ')} };`;
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
// Fallback - import everything
|
|
330
|
+
entryContent = `import * as ${packagePath.replace(/[^a-zA-Z0-9]/g, '_')} from '${packagePath}';\nmodule.exports = ${packagePath.replace(/[^a-zA-Z0-9]/g, '_')};`;
|
|
331
|
+
}
|
|
332
|
+
// Write entry file
|
|
333
|
+
fs.writeFileSync(entryFile, entryContent);
|
|
334
|
+
// Bundle with esbuild
|
|
335
|
+
const result = await build({
|
|
336
|
+
entryPoints: [entryFile],
|
|
337
|
+
bundle: true,
|
|
338
|
+
format: 'cjs', // CommonJS format
|
|
339
|
+
platform: 'node',
|
|
340
|
+
target: 'node16',
|
|
341
|
+
outfile: outputFile,
|
|
342
|
+
external: [], // Bundle everything
|
|
343
|
+
minify: false, // Keep readable for debugging
|
|
344
|
+
sourcemap: false,
|
|
345
|
+
write: true,
|
|
346
|
+
resolveExtensions: ['.js', '.ts', '.json'],
|
|
347
|
+
mainFields: ['main', 'module', 'browser'],
|
|
348
|
+
conditions: ['node'],
|
|
349
|
+
nodePaths: [
|
|
350
|
+
path.join(process.cwd(), 'node_modules'),
|
|
351
|
+
path.join(process.cwd(), '..', 'node_modules'),
|
|
352
|
+
path.join(process.cwd(), '..', '..', 'node_modules')
|
|
353
|
+
],
|
|
354
|
+
absWorkingDir: process.cwd(),
|
|
355
|
+
});
|
|
356
|
+
if (result.errors.length > 0) {
|
|
357
|
+
console.warn(`Warning: esbuild errors for package ${packagePath}:`, result.errors);
|
|
358
|
+
return null;
|
|
359
|
+
}
|
|
360
|
+
// Read the bundled output
|
|
361
|
+
if (!fs.existsSync(outputFile)) {
|
|
362
|
+
console.warn(`Warning: Bundle output not found for package ${packagePath}`);
|
|
363
|
+
return null;
|
|
364
|
+
}
|
|
365
|
+
const bundledContent = fs.readFileSync(outputFile, 'utf8');
|
|
366
|
+
// Clean up temporary files
|
|
367
|
+
try {
|
|
368
|
+
fs.unlinkSync(entryFile);
|
|
369
|
+
fs.unlinkSync(outputFile);
|
|
370
|
+
}
|
|
371
|
+
catch (cleanupError) {
|
|
372
|
+
// Ignore cleanup errors
|
|
373
|
+
}
|
|
374
|
+
// Create the final bundled code
|
|
375
|
+
let finalCode = '';
|
|
376
|
+
if (defaultImport) {
|
|
377
|
+
finalCode = `const ${defaultImport} = (function() {\n${bundledContent}\n return module.exports;\n})();\n`;
|
|
378
|
+
}
|
|
379
|
+
else if (namedImports) {
|
|
380
|
+
const importsList = namedImports.split(',').map(imp => imp.trim());
|
|
381
|
+
finalCode = `(function() {\n${bundledContent}\n})();\n`;
|
|
382
|
+
finalCode += `const { ${importsList.join(', ')} } = module.exports;\n`;
|
|
383
|
+
}
|
|
384
|
+
else {
|
|
385
|
+
finalCode = `(function() {\n${bundledContent}\n})();\n`;
|
|
386
|
+
}
|
|
387
|
+
return finalCode;
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
console.warn(`Warning: Could not bundle package ${packagePath} with esbuild:`, error);
|
|
391
|
+
// For test environments or when esbuild fails, provide a fallback
|
|
392
|
+
if (packagePath === 'axios') {
|
|
393
|
+
return createWorkingAxiosImplementation();
|
|
394
|
+
}
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
function createWorkingAxiosImplementation() {
|
|
399
|
+
return `
|
|
400
|
+
// Working axios implementation using native fetch (for test environments)
|
|
401
|
+
const axios = {
|
|
402
|
+
get: async (url, config = {}) => {
|
|
403
|
+
const searchParams = new URLSearchParams(config.params || {});
|
|
404
|
+
const fullUrl = searchParams.toString() ? \`\${url}?\${searchParams}\` : url;
|
|
405
|
+
|
|
406
|
+
const response = await fetch(fullUrl, {
|
|
407
|
+
method: 'GET',
|
|
408
|
+
headers: {
|
|
409
|
+
'Content-Type': 'application/json',
|
|
410
|
+
...config.headers
|
|
411
|
+
}
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
if (!response.ok) {
|
|
415
|
+
const error = new Error(\`Request failed with status \${response.status}\`);
|
|
416
|
+
error.response = { status: response.status, statusText: response.statusText };
|
|
417
|
+
throw error;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
const data = await response.json();
|
|
421
|
+
return {
|
|
422
|
+
data,
|
|
423
|
+
status: response.status,
|
|
424
|
+
statusText: response.statusText,
|
|
425
|
+
headers: response.headers,
|
|
426
|
+
config: config
|
|
427
|
+
};
|
|
428
|
+
},
|
|
429
|
+
|
|
430
|
+
post: async (url, data, config = {}) => {
|
|
431
|
+
const response = await fetch(url, {
|
|
432
|
+
method: 'POST',
|
|
433
|
+
headers: {
|
|
434
|
+
'Content-Type': 'application/json',
|
|
435
|
+
...config.headers
|
|
436
|
+
},
|
|
437
|
+
body: JSON.stringify(data)
|
|
438
|
+
});
|
|
439
|
+
|
|
440
|
+
if (!response.ok) {
|
|
441
|
+
const error = new Error(\`Request failed with status \${response.status}\`);
|
|
442
|
+
error.response = { status: response.status, statusText: response.statusText };
|
|
443
|
+
throw error;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
const responseData = await response.json();
|
|
447
|
+
return {
|
|
448
|
+
data: responseData,
|
|
449
|
+
status: response.status,
|
|
450
|
+
statusText: response.statusText,
|
|
451
|
+
headers: response.headers,
|
|
452
|
+
config: config
|
|
453
|
+
};
|
|
454
|
+
},
|
|
455
|
+
|
|
456
|
+
put: async (url, data, config = {}) => {
|
|
457
|
+
const response = await fetch(url, {
|
|
458
|
+
method: 'PUT',
|
|
459
|
+
headers: {
|
|
460
|
+
'Content-Type': 'application/json',
|
|
461
|
+
...config.headers
|
|
462
|
+
},
|
|
463
|
+
body: JSON.stringify(data)
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
if (!response.ok) {
|
|
467
|
+
const error = new Error(\`Request failed with status \${response.status}\`);
|
|
468
|
+
error.response = { status: response.status, statusText: response.statusText };
|
|
469
|
+
throw error;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
const responseData = await response.json();
|
|
473
|
+
return {
|
|
474
|
+
data: responseData,
|
|
475
|
+
status: response.status,
|
|
476
|
+
statusText: response.statusText,
|
|
477
|
+
headers: response.headers,
|
|
478
|
+
config: config
|
|
479
|
+
};
|
|
480
|
+
},
|
|
481
|
+
|
|
482
|
+
delete: async (url, config = {}) => {
|
|
483
|
+
const response = await fetch(url, {
|
|
484
|
+
method: 'DELETE',
|
|
485
|
+
headers: {
|
|
486
|
+
'Content-Type': 'application/json',
|
|
487
|
+
...config.headers
|
|
488
|
+
}
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
if (!response.ok) {
|
|
492
|
+
const error = new Error(\`Request failed with status \${response.status}\`);
|
|
493
|
+
error.response = { status: response.status, statusText: response.statusText };
|
|
494
|
+
throw error;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
const responseData = await response.json();
|
|
498
|
+
return {
|
|
499
|
+
data: responseData,
|
|
500
|
+
status: response.status,
|
|
501
|
+
statusText: response.statusText,
|
|
502
|
+
headers: response.headers,
|
|
503
|
+
config: config
|
|
504
|
+
};
|
|
505
|
+
},
|
|
506
|
+
|
|
507
|
+
patch: async (url, data, config = {}) => {
|
|
508
|
+
const response = await fetch(url, {
|
|
509
|
+
method: 'PATCH',
|
|
510
|
+
headers: {
|
|
511
|
+
'Content-Type': 'application/json',
|
|
512
|
+
...config.headers
|
|
513
|
+
},
|
|
514
|
+
body: JSON.stringify(data)
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
if (!response.ok) {
|
|
518
|
+
const error = new Error(\`Request failed with status \${response.status}\`);
|
|
519
|
+
error.response = { status: response.status, statusText: response.statusText };
|
|
520
|
+
throw error;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
const responseData = await response.json();
|
|
524
|
+
return {
|
|
525
|
+
data: responseData,
|
|
526
|
+
status: response.status,
|
|
527
|
+
statusText: response.statusText,
|
|
528
|
+
headers: response.headers,
|
|
529
|
+
config: config
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
`;
|
|
534
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function destroyCommand(): Promise<void>;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { configureCommand } from "./configure.js";
|
|
2
|
+
export { initCommand } from "./init.js";
|
|
3
|
+
export { destroyCommand } from "./destroy.js";
|
|
4
|
+
export { apiKeyCommand } from "./apiKey.js";
|
|
5
|
+
export { agentsCommand } from "./agents.js";
|
|
6
|
+
export { deployCommand } from "./deploy.js";
|
|
7
|
+
export { testCommand } from "./test.js";
|
package/dist/commands/index.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function initCommand(): Promise<void>;
|
package/dist/commands/init.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function testCommand(): Promise<void>;
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import inquirer from "inquirer";
|
|
4
|
+
import { deployCommand } from "./deploy.js";
|
|
5
|
+
export async function testCommand() {
|
|
6
|
+
try {
|
|
7
|
+
console.log("🧪 Testing Lua skill...");
|
|
8
|
+
// First, compile the code
|
|
9
|
+
console.log("📦 Compiling code first...");
|
|
10
|
+
await deployCommand();
|
|
11
|
+
// Check if .lua directory exists
|
|
12
|
+
const luaDir = path.join(process.cwd(), ".lua");
|
|
13
|
+
if (!fs.existsSync(luaDir)) {
|
|
14
|
+
throw new Error(".lua directory not found. Run 'lua compile' first.");
|
|
15
|
+
}
|
|
16
|
+
// Read deploy.json
|
|
17
|
+
const deployJsonPath = path.join(luaDir, "deploy.json");
|
|
18
|
+
if (!fs.existsSync(deployJsonPath)) {
|
|
19
|
+
throw new Error("deploy.json not found. Run 'lua compile' first.");
|
|
20
|
+
}
|
|
21
|
+
const deployData = JSON.parse(fs.readFileSync(deployJsonPath, "utf8"));
|
|
22
|
+
if (!deployData.tools || deployData.tools.length === 0) {
|
|
23
|
+
throw new Error("No tools found in deploy.json");
|
|
24
|
+
}
|
|
25
|
+
// Let user select a tool using picker
|
|
26
|
+
const toolChoices = deployData.tools.map((tool) => ({
|
|
27
|
+
name: `${tool.name} - ${tool.description}`,
|
|
28
|
+
value: tool
|
|
29
|
+
}));
|
|
30
|
+
const { selectedTool } = await inquirer.prompt([
|
|
31
|
+
{
|
|
32
|
+
type: 'list',
|
|
33
|
+
name: 'selectedTool',
|
|
34
|
+
message: '🔧 Select a tool to test:',
|
|
35
|
+
choices: toolChoices,
|
|
36
|
+
pageSize: 10
|
|
37
|
+
}
|
|
38
|
+
]);
|
|
39
|
+
console.log(`\n✅ Selected tool: ${selectedTool.name}`);
|
|
40
|
+
// Get input values for each required parameter using inquirer
|
|
41
|
+
const inputValues = {};
|
|
42
|
+
const inputSchema = selectedTool.inputSchema;
|
|
43
|
+
if (inputSchema.properties) {
|
|
44
|
+
console.log("\n📝 Enter input values:");
|
|
45
|
+
const inputPrompts = [];
|
|
46
|
+
for (const [key, value] of Object.entries(inputSchema.properties)) {
|
|
47
|
+
const property = value;
|
|
48
|
+
const isRequired = inputSchema.required?.includes(key) || false;
|
|
49
|
+
let promptType = 'input';
|
|
50
|
+
let validate = undefined;
|
|
51
|
+
// Set up validation and input type based on schema
|
|
52
|
+
switch (property.type) {
|
|
53
|
+
case "string":
|
|
54
|
+
if (isRequired) {
|
|
55
|
+
validate = (input) => input.trim() !== "" || `${key} is required`;
|
|
56
|
+
}
|
|
57
|
+
break;
|
|
58
|
+
case "number":
|
|
59
|
+
promptType = 'number';
|
|
60
|
+
if (isRequired) {
|
|
61
|
+
validate = (input) => !isNaN(input) || `${key} must be a valid number`;
|
|
62
|
+
}
|
|
63
|
+
break;
|
|
64
|
+
case "boolean":
|
|
65
|
+
promptType = 'confirm';
|
|
66
|
+
break;
|
|
67
|
+
default:
|
|
68
|
+
if (isRequired) {
|
|
69
|
+
validate = (input) => input.trim() !== "" || `${key} is required`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
inputPrompts.push({
|
|
73
|
+
type: promptType,
|
|
74
|
+
name: key,
|
|
75
|
+
message: `${key}${isRequired ? " (required)" : " (optional)"}:`,
|
|
76
|
+
validate: validate,
|
|
77
|
+
when: isRequired ? true : (answers) => {
|
|
78
|
+
// For optional fields, ask if user wants to provide a value
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const answers = await inquirer.prompt(inputPrompts);
|
|
84
|
+
// Convert answers to proper types
|
|
85
|
+
for (const [key, value] of Object.entries(answers)) {
|
|
86
|
+
const property = inputSchema.properties[key];
|
|
87
|
+
switch (property.type) {
|
|
88
|
+
case "string":
|
|
89
|
+
inputValues[key] = value;
|
|
90
|
+
break;
|
|
91
|
+
case "number":
|
|
92
|
+
inputValues[key] = parseFloat(value);
|
|
93
|
+
break;
|
|
94
|
+
case "boolean":
|
|
95
|
+
inputValues[key] = value;
|
|
96
|
+
break;
|
|
97
|
+
default:
|
|
98
|
+
inputValues[key] = value;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
console.log("\n🚀 Executing tool...");
|
|
103
|
+
console.log(`Input: ${JSON.stringify(inputValues, null, 2)}`);
|
|
104
|
+
// Get the execute function string directly from the selected tool
|
|
105
|
+
const toolCode = selectedTool.execute;
|
|
106
|
+
// Execute the tool
|
|
107
|
+
try {
|
|
108
|
+
// Create a temporary CommonJS file to run the tool
|
|
109
|
+
const tempFile = path.join(luaDir, `temp-${selectedTool.name}.cjs`);
|
|
110
|
+
const commonJsWrapper = `
|
|
111
|
+
const executeFunction = ${toolCode};
|
|
112
|
+
|
|
113
|
+
// Export the function for testing
|
|
114
|
+
module.exports = async (input) => {
|
|
115
|
+
return await executeFunction(input);
|
|
116
|
+
};
|
|
117
|
+
`;
|
|
118
|
+
fs.writeFileSync(tempFile, commonJsWrapper);
|
|
119
|
+
// Import and execute the CommonJS module
|
|
120
|
+
const { createRequire } = await import('module');
|
|
121
|
+
const require = createRequire(import.meta.url);
|
|
122
|
+
const executeFunction = require(tempFile);
|
|
123
|
+
const result = await executeFunction(inputValues);
|
|
124
|
+
// Clean up temp file
|
|
125
|
+
fs.unlinkSync(tempFile);
|
|
126
|
+
console.log("\n✅ Tool execution successful!");
|
|
127
|
+
console.log(`Output: ${JSON.stringify(result, null, 2)}`);
|
|
128
|
+
}
|
|
129
|
+
catch (executionError) {
|
|
130
|
+
console.error("\n❌ Tool execution failed:");
|
|
131
|
+
console.error(executionError.message);
|
|
132
|
+
if (executionError.stack) {
|
|
133
|
+
console.error(executionError.stack);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.error("❌ Test failed:", error.message);
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from "commander";
|
|
3
|
-
import { configureCommand, initCommand, destroyCommand, apiKeyCommand, agentsCommand } from "./commands/index.js";
|
|
3
|
+
import { configureCommand, initCommand, destroyCommand, apiKeyCommand, agentsCommand, deployCommand, testCommand } from "./commands/index.js";
|
|
4
4
|
const program = new Command();
|
|
5
5
|
program
|
|
6
6
|
.command("init")
|
|
@@ -22,4 +22,12 @@ program
|
|
|
22
22
|
.command("agents")
|
|
23
23
|
.description("Fetch agents from HeyLua API")
|
|
24
24
|
.action(agentsCommand);
|
|
25
|
+
program
|
|
26
|
+
.command("compile")
|
|
27
|
+
.description("Compile Lua skill to generate deployable format")
|
|
28
|
+
.action(deployCommand);
|
|
29
|
+
program
|
|
30
|
+
.command("test")
|
|
31
|
+
.description("Test Lua skill tools interactively")
|
|
32
|
+
.action(testCommand);
|
|
25
33
|
program.parse(process.argv);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { UserData } from "../types/index.js";
|
|
2
|
+
export declare function saveApiKey(apiKey: string): Promise<void>;
|
|
3
|
+
export declare function loadApiKey(): Promise<string | null>;
|
|
4
|
+
export declare function deleteApiKey(): Promise<boolean>;
|
|
5
|
+
export declare function checkApiKey(apiKey: string): Promise<UserData>;
|
|
6
|
+
export declare function requestEmailOTP(email: string): Promise<boolean>;
|
|
7
|
+
export declare function verifyOTPAndGetToken(email: string, pin: string): Promise<string | null>;
|
|
8
|
+
export declare function generateApiKey(signInToken: string): Promise<string | null>;
|
package/dist/skill.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ZodType } from "zod";
|
|
2
|
+
import { LuaTool } from "./types/index.js";
|
|
3
|
+
export declare class LuaSkill {
|
|
4
|
+
private readonly apiKey;
|
|
5
|
+
private readonly tools;
|
|
6
|
+
constructor(apiKey: string);
|
|
7
|
+
addTool<TInput extends ZodType, TOutput extends ZodType>(tool: LuaTool<TInput, TOutput>): void;
|
|
8
|
+
run(input: Record<string, any>): Promise<any>;
|
|
9
|
+
}
|
package/dist/skill.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export class LuaSkill {
|
|
2
|
+
constructor(apiKey) {
|
|
3
|
+
this.apiKey = apiKey;
|
|
4
|
+
this.tools = [];
|
|
5
|
+
}
|
|
6
|
+
addTool(tool) {
|
|
7
|
+
this.tools.push(tool);
|
|
8
|
+
}
|
|
9
|
+
async run(input) {
|
|
10
|
+
const tool = this.tools.find(tool => tool.name === input.tool);
|
|
11
|
+
if (!tool) {
|
|
12
|
+
throw new Error(`Tool ${input.tool} not found`);
|
|
13
|
+
}
|
|
14
|
+
// Validate input against the tool's schema
|
|
15
|
+
const validatedInput = tool.inputSchema.parse(input);
|
|
16
|
+
return tool.execute(validatedInput);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
export interface UserData {
|
|
2
|
+
uid: string;
|
|
3
|
+
email: string;
|
|
4
|
+
emailVerified: boolean;
|
|
5
|
+
fullName: string;
|
|
6
|
+
mobileNumbers: any[];
|
|
7
|
+
emailAddresses: EmailAddress[];
|
|
8
|
+
country: Country;
|
|
9
|
+
admin: Admin;
|
|
10
|
+
channels: Record<string, any>;
|
|
11
|
+
rights: Record<string, any>;
|
|
12
|
+
setupPersona: Record<string, any>;
|
|
13
|
+
notifications: Record<string, any>;
|
|
14
|
+
}
|
|
15
|
+
export interface EmailAddress {
|
|
16
|
+
address: string;
|
|
17
|
+
validated: boolean;
|
|
18
|
+
validatedAt: number;
|
|
19
|
+
_id: string;
|
|
20
|
+
}
|
|
21
|
+
export interface Country {
|
|
22
|
+
code: string;
|
|
23
|
+
name: string;
|
|
24
|
+
}
|
|
25
|
+
export interface Admin {
|
|
26
|
+
userId: string;
|
|
27
|
+
orgs: Organization[];
|
|
28
|
+
id: string;
|
|
29
|
+
createdAt: number;
|
|
30
|
+
__v: number;
|
|
31
|
+
}
|
|
32
|
+
export interface Organization {
|
|
33
|
+
id: string;
|
|
34
|
+
rights?: string[];
|
|
35
|
+
agents: Agent[];
|
|
36
|
+
registeredName: string;
|
|
37
|
+
country: string;
|
|
38
|
+
phoneNumber?: string | null;
|
|
39
|
+
type: string;
|
|
40
|
+
}
|
|
41
|
+
export interface Agent {
|
|
42
|
+
agentId: string;
|
|
43
|
+
rights: string[];
|
|
44
|
+
name: string;
|
|
45
|
+
}
|
|
46
|
+
export interface OTPResponse {
|
|
47
|
+
signInToken: string;
|
|
48
|
+
}
|
|
49
|
+
export interface ApiKeyResponse {
|
|
50
|
+
message: string;
|
|
51
|
+
userId: string;
|
|
52
|
+
apiKey: string;
|
|
53
|
+
apiId: string;
|
|
54
|
+
}
|
|
55
|
+
import { ZodType } from "zod";
|
|
56
|
+
export interface LuaTool<TInput extends ZodType = ZodType, TOutput extends ZodType = ZodType> {
|
|
57
|
+
name: string;
|
|
58
|
+
description: string;
|
|
59
|
+
inputSchema: TInput;
|
|
60
|
+
outputSchema: TOutput;
|
|
61
|
+
execute: (input: any) => Promise<any>;
|
|
62
|
+
}
|
|
63
|
+
export declare class LuaSkill {
|
|
64
|
+
private readonly apiKey;
|
|
65
|
+
private readonly tools;
|
|
66
|
+
constructor(apiKey: string);
|
|
67
|
+
addTool<TInput extends ZodType, TOutput extends ZodType>(tool: LuaTool<TInput, TOutput>): void;
|
|
68
|
+
run(input: Record<string, any>): Promise<any>;
|
|
69
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./types/index.js";
|
package/dist/types.js
ADDED
package/dist/utils/files.js
CHANGED
|
@@ -1,19 +1,44 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
3
4
|
export function copyTemplateFiles(templateDir, targetDir) {
|
|
4
5
|
const files = fs.readdirSync(templateDir);
|
|
5
6
|
for (const file of files) {
|
|
7
|
+
// Skip node_modules and package-lock.json to avoid circular dependencies
|
|
8
|
+
if (file === 'node_modules' || file === 'package-lock.json') {
|
|
9
|
+
continue;
|
|
10
|
+
}
|
|
6
11
|
const srcPath = path.join(templateDir, file);
|
|
7
12
|
const destPath = path.join(targetDir, file);
|
|
8
13
|
if (fs.statSync(srcPath).isDirectory()) {
|
|
9
14
|
fs.mkdirSync(destPath, { recursive: true });
|
|
10
15
|
copyTemplateFiles(srcPath, destPath);
|
|
11
16
|
}
|
|
17
|
+
else if (file === 'package.json') {
|
|
18
|
+
// Special handling for package.json to update lua-cli version
|
|
19
|
+
updatePackageJson(srcPath, destPath);
|
|
20
|
+
}
|
|
12
21
|
else {
|
|
13
22
|
fs.copyFileSync(srcPath, destPath);
|
|
14
23
|
}
|
|
15
24
|
}
|
|
16
25
|
}
|
|
26
|
+
function updatePackageJson(srcPath, destPath) {
|
|
27
|
+
// Read the template package.json
|
|
28
|
+
const templatePackageJson = JSON.parse(fs.readFileSync(srcPath, 'utf8'));
|
|
29
|
+
// Get the current CLI version from the main package.json
|
|
30
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
31
|
+
const __dirname = path.dirname(__filename);
|
|
32
|
+
const mainPackageJsonPath = path.join(__dirname, '..', '..', 'package.json');
|
|
33
|
+
const mainPackageJson = JSON.parse(fs.readFileSync(mainPackageJsonPath, 'utf8'));
|
|
34
|
+
const currentCliVersion = mainPackageJson.version;
|
|
35
|
+
// Update the lua-cli dependency version
|
|
36
|
+
if (templatePackageJson.dependencies && templatePackageJson.dependencies['lua-cli']) {
|
|
37
|
+
templatePackageJson.dependencies['lua-cli'] = `^${currentCliVersion}`;
|
|
38
|
+
}
|
|
39
|
+
// Write the updated package.json
|
|
40
|
+
fs.writeFileSync(destPath, JSON.stringify(templatePackageJson, null, 2) + '\n');
|
|
41
|
+
}
|
|
17
42
|
export function createSkillToml(agentId, orgId, skillName, skillDescription) {
|
|
18
43
|
const tomlContent = `[agent]
|
|
19
44
|
agentId = "${agentId}"
|
package/package.json
CHANGED
|
@@ -1,13 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lua-cli",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Command-line interface for Lua AI platform - manage agents, organizations, and skills",
|
|
5
5
|
"readmeFilename": "README.md",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": "./dist/index.js",
|
|
9
|
+
"./types": "./dist/types.js",
|
|
10
|
+
"./skill": "./dist/skill.js"
|
|
11
|
+
},
|
|
7
12
|
"scripts": {
|
|
8
|
-
"
|
|
13
|
+
"clean": "rm -rf dist",
|
|
14
|
+
"build": "npm run clean && tsc",
|
|
9
15
|
"prepublishOnly": "npm run build",
|
|
10
|
-
"test": "
|
|
16
|
+
"test": "jest",
|
|
17
|
+
"test:watch": "jest --watch",
|
|
18
|
+
"test:coverage": "jest --coverage"
|
|
11
19
|
},
|
|
12
20
|
"keywords": [
|
|
13
21
|
"lua",
|
|
@@ -24,19 +32,18 @@
|
|
|
24
32
|
"type": "module",
|
|
25
33
|
"repository": {
|
|
26
34
|
"type": "git",
|
|
27
|
-
"url": "https://github.com/
|
|
35
|
+
"url": "https://github.com/lua-ai-global/lua-cli.git"
|
|
28
36
|
},
|
|
29
|
-
"homepage": "https://github.com/
|
|
37
|
+
"homepage": "https://github.com/lua-ai-global/lua-cli#readme",
|
|
30
38
|
"readme": "README.md",
|
|
31
39
|
"bugs": {
|
|
32
|
-
"url": "https://github.com/
|
|
40
|
+
"url": "https://github.com/lua-ai-global/lua-cli/issues"
|
|
33
41
|
},
|
|
34
42
|
"engines": {
|
|
35
43
|
"node": ">=16.0.0"
|
|
36
44
|
},
|
|
37
45
|
"files": [
|
|
38
46
|
"dist/**/*",
|
|
39
|
-
"template/**/*",
|
|
40
47
|
"README.md",
|
|
41
48
|
"CHANGELOG.md",
|
|
42
49
|
"LICENSE"
|
|
@@ -45,16 +52,21 @@
|
|
|
45
52
|
"commander": "^14.0.1",
|
|
46
53
|
"inquirer": "^12.9.6",
|
|
47
54
|
"keytar": "^7.9.0",
|
|
48
|
-
"node-fetch": "^3.3.2"
|
|
55
|
+
"node-fetch": "^3.3.2",
|
|
56
|
+
"zod": "^4.1.9"
|
|
49
57
|
},
|
|
50
58
|
"devDependencies": {
|
|
51
59
|
"@types/inquirer": "^9.0.9",
|
|
60
|
+
"@types/jest": "^29.5.8",
|
|
52
61
|
"@types/node": "^24.5.1",
|
|
53
62
|
"@types/node-fetch": "^2.6.13",
|
|
63
|
+
"esbuild": "^0.25.10",
|
|
64
|
+
"jest": "^29.7.0",
|
|
65
|
+
"ts-jest": "^29.1.1",
|
|
54
66
|
"ts-node": "^10.9.2",
|
|
55
67
|
"typescript": "^5.9.2"
|
|
56
68
|
},
|
|
57
69
|
"bin": {
|
|
58
70
|
"lua": "dist/index.js"
|
|
59
71
|
}
|
|
60
|
-
}
|
|
72
|
+
}
|
package/template/package.json
DELETED