lua-cli 3.1.0-alpha.4 → 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.
- package/dist/api/cdn.api.service.d.ts +18 -0
- package/dist/api/cdn.api.service.js +43 -0
- package/dist/api/custom.data.api.service.d.ts +4 -3
- package/dist/api/custom.data.api.service.js +4 -3
- package/dist/api/developer.api.service.d.ts +54 -1
- package/dist/api/developer.api.service.js +89 -0
- package/dist/api/job.api.service.d.ts +10 -0
- package/dist/api/job.api.service.js +14 -0
- package/dist/api/lazy-instances.d.ts +8 -0
- package/dist/api/lazy-instances.js +16 -0
- package/dist/api/postprocessor.api.service.d.ts +3 -6
- package/dist/api/postprocessor.api.service.js +2 -3
- package/dist/api-exports.d.ts +74 -6
- package/dist/api-exports.js +87 -7
- package/dist/cli/command-definitions.js +34 -7
- package/dist/commands/admin.js +1 -1
- package/dist/commands/channels.js +1 -1
- package/dist/commands/compile.js +23 -4
- package/dist/commands/evals.d.ts +8 -0
- package/dist/commands/evals.js +41 -0
- package/dist/commands/index.d.ts +2 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/init.d.ts +10 -1
- package/dist/commands/init.js +13 -3
- package/dist/commands/mcp.d.ts +18 -0
- package/dist/commands/mcp.js +393 -0
- package/dist/commands/push.js +172 -14
- package/dist/common/data.entry.instance.d.ts +1 -1
- package/dist/common/data.entry.instance.js +4 -4
- package/dist/common/job.instance.d.ts +24 -0
- package/dist/common/job.instance.js +38 -0
- package/dist/config/constants.d.ts +1 -0
- package/dist/config/constants.js +1 -0
- package/dist/index.js +1 -0
- package/dist/interfaces/cdn.d.ts +24 -0
- package/dist/interfaces/cdn.js +5 -0
- package/dist/interfaces/compile.d.ts +1 -0
- package/dist/interfaces/custom.data.d.ts +3 -3
- package/dist/interfaces/index.d.ts +1 -0
- package/dist/interfaces/mcp.d.ts +64 -0
- package/dist/interfaces/mcp.js +5 -0
- package/dist/types/api-contracts.d.ts +36 -14
- package/dist/types/compile.types.d.ts +5 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +3 -1
- package/dist/types/skill.d.ts +120 -13
- package/dist/types/skill.js +95 -5
- package/dist/utils/bundling.d.ts +4 -11
- package/dist/utils/bundling.js +19 -27
- package/dist/utils/compile.d.ts +17 -8
- package/dist/utils/compile.js +71 -37
- package/dist/utils/deployment.js +13 -6
- package/dist/utils/dev-api.js +1 -2
- package/dist/utils/dev-server.js +1 -1
- package/dist/utils/files.d.ts +8 -1
- package/dist/utils/files.js +13 -2
- package/dist/utils/init-helpers.d.ts +3 -1
- package/dist/utils/init-helpers.js +7 -2
- package/dist/utils/mcp-server-management.d.ts +23 -0
- package/dist/utils/mcp-server-management.js +212 -0
- package/dist/utils/sandbox.d.ts +4 -2
- package/dist/utils/sandbox.js +22 -3
- package/dist/web/app.css +1505 -14
- package/dist/web/app.js +79 -64
- package/package.json +2 -6
- package/template/QUICKSTART.md +57 -761
- package/template/README.md +80 -906
- package/template/examples/README.md +106 -0
- package/template/{src → examples}/jobs/AbandonedBasketProcessorJob.ts +67 -11
- package/template/{src → examples}/postprocessors/modifyResponse.ts +3 -3
- package/template/{src → examples}/skills/tools/GameScoreTrackerTool.ts +11 -15
- package/template/{src → examples}/skills/tools/OrderTool.ts +25 -0
- package/template/examples/skills/tools/PremiumFeatureTool.ts +98 -0
- package/template/{src → examples}/skills/tools/UserDataTool.ts +34 -0
- package/template/examples/webhooks/FileUploadWebhook.ts +86 -0
- package/template/package-lock.json +7895 -0
- package/template/package.json +1 -1
- package/template/src/index.ts +40 -22
- /package/template/{src → examples}/jobs/DailyCleanupJob.ts +0 -0
- /package/template/{src → examples}/jobs/DataMigrationJob.ts +0 -0
- /package/template/{src → examples}/jobs/HealthCheckJob.ts +0 -0
- /package/template/{src → examples}/preprocessors/messageMatching.ts +0 -0
- /package/template/{src → examples}/services/ApiService.ts +0 -0
- /package/template/{src → examples}/services/GetWeather.ts +0 -0
- /package/template/{src → examples}/skills/basket.skill.ts +0 -0
- /package/template/{src → examples}/skills/product.skill.ts +0 -0
- /package/template/{src → examples}/skills/tools/BasketTool.ts +0 -0
- /package/template/{src → examples}/skills/tools/CreateInlineJob.ts +0 -0
- /package/template/{src → examples}/skills/tools/CreatePostTool.ts +0 -0
- /package/template/{src → examples}/skills/tools/CustomDataTool.ts +0 -0
- /package/template/{src → examples}/skills/tools/GetWeatherTool.ts +0 -0
- /package/template/{src → examples}/skills/tools/PaymentTool.ts +0 -0
- /package/template/{src → examples}/skills/tools/ProductsTool.ts +0 -0
- /package/template/{src → examples}/skills/tools/SmartBasketTool.ts +0 -0
- /package/template/{src → examples}/skills/user.skill.ts +0 -0
- /package/template/{src → examples}/webhooks/PaymentWebhook.ts +0 -0
- /package/template/{src → examples}/webhooks/UserEventWebhook.ts +0 -0
package/dist/types/skill.js
CHANGED
|
@@ -459,7 +459,7 @@ export class PreProcessor {
|
|
|
459
459
|
* name: 'response-formatter',
|
|
460
460
|
* description: 'Formats responses with branding',
|
|
461
461
|
* execute: async (user, message, response, channel) => {
|
|
462
|
-
* return response + '\n\n---\nPowered by Acme Corp';
|
|
462
|
+
* return { modifiedResponse: response + '\n\n---\nPowered by Acme Corp' };
|
|
463
463
|
* }
|
|
464
464
|
* });
|
|
465
465
|
* ```
|
|
@@ -468,7 +468,6 @@ export class PostProcessor {
|
|
|
468
468
|
constructor(config) {
|
|
469
469
|
this.name = config.name || 'unnamed-postprocessor';
|
|
470
470
|
this.description = config.description;
|
|
471
|
-
this.asyncMode = config.async ?? false; // Default to synchronous
|
|
472
471
|
this.executeFunction = config.execute;
|
|
473
472
|
}
|
|
474
473
|
getName() {
|
|
@@ -477,13 +476,99 @@ export class PostProcessor {
|
|
|
477
476
|
getDescription() {
|
|
478
477
|
return this.description;
|
|
479
478
|
}
|
|
480
|
-
getAsync() {
|
|
481
|
-
return this.asyncMode;
|
|
482
|
-
}
|
|
483
479
|
async execute(user, message, response, channel) {
|
|
484
480
|
return this.executeFunction(user, message, response, channel);
|
|
485
481
|
}
|
|
486
482
|
}
|
|
483
|
+
/**
|
|
484
|
+
* LuaMCPServer class.
|
|
485
|
+
* Defines an MCP (Model Context Protocol) server connection.
|
|
486
|
+
*
|
|
487
|
+
* MCP servers provide tools that can be used by your agent at runtime.
|
|
488
|
+
* You can connect to local servers (via stdio) or remote servers (via SSE/HTTP).
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* ```typescript
|
|
492
|
+
* import { LuaMCPServer } from 'lua-cli';
|
|
493
|
+
*
|
|
494
|
+
* // Local MCP server via npx
|
|
495
|
+
* const wikipediaServer = new LuaMCPServer({
|
|
496
|
+
* name: 'wikipedia',
|
|
497
|
+
* transport: 'stdio',
|
|
498
|
+
* command: 'npx',
|
|
499
|
+
* args: ['-y', 'wikipedia-mcp'],
|
|
500
|
+
* description: 'Wikipedia search and retrieval'
|
|
501
|
+
* });
|
|
502
|
+
*
|
|
503
|
+
* // Remote MCP server via SSE
|
|
504
|
+
* const weatherServer = new LuaMCPServer({
|
|
505
|
+
* name: 'weather',
|
|
506
|
+
* transport: 'sse',
|
|
507
|
+
* url: 'https://api.example.com/mcp',
|
|
508
|
+
* headers: {
|
|
509
|
+
* 'Authorization': 'Bearer ${env.WEATHER_API_KEY}'
|
|
510
|
+
* },
|
|
511
|
+
* description: 'Weather information service'
|
|
512
|
+
* });
|
|
513
|
+
* ```
|
|
514
|
+
*/
|
|
515
|
+
export class LuaMCPServer {
|
|
516
|
+
constructor(config) {
|
|
517
|
+
if (!config.name) {
|
|
518
|
+
throw new Error('MCP server name is required');
|
|
519
|
+
}
|
|
520
|
+
if (config.transport === 'stdio' && !config.command) {
|
|
521
|
+
throw new Error('Command is required for stdio transport');
|
|
522
|
+
}
|
|
523
|
+
if (config.transport === 'sse' && !config.url) {
|
|
524
|
+
throw new Error('URL is required for sse transport');
|
|
525
|
+
}
|
|
526
|
+
this.config = config;
|
|
527
|
+
}
|
|
528
|
+
getName() {
|
|
529
|
+
return this.config.name;
|
|
530
|
+
}
|
|
531
|
+
getTransport() {
|
|
532
|
+
return this.config.transport;
|
|
533
|
+
}
|
|
534
|
+
getTimeout() {
|
|
535
|
+
return this.config.timeout;
|
|
536
|
+
}
|
|
537
|
+
getConfig() {
|
|
538
|
+
return this.config;
|
|
539
|
+
}
|
|
540
|
+
/**
|
|
541
|
+
* Returns the server configuration in a format suitable for serialization.
|
|
542
|
+
* Environment variable references (${env.VAR_NAME}) are preserved for runtime resolution.
|
|
543
|
+
*/
|
|
544
|
+
toJSON() {
|
|
545
|
+
const base = {
|
|
546
|
+
name: this.config.name,
|
|
547
|
+
transport: this.config.transport,
|
|
548
|
+
};
|
|
549
|
+
if (this.config.timeout) {
|
|
550
|
+
base.timeout = this.config.timeout;
|
|
551
|
+
}
|
|
552
|
+
if (this.config.transport === 'stdio') {
|
|
553
|
+
const stdioConfig = this.config;
|
|
554
|
+
base.command = stdioConfig.command;
|
|
555
|
+
if (stdioConfig.args) {
|
|
556
|
+
base.args = stdioConfig.args;
|
|
557
|
+
}
|
|
558
|
+
if (stdioConfig.env) {
|
|
559
|
+
base.env = stdioConfig.env;
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
else {
|
|
563
|
+
const sseConfig = this.config;
|
|
564
|
+
base.url = sseConfig.url;
|
|
565
|
+
if (sseConfig.headers) {
|
|
566
|
+
base.headers = sseConfig.headers;
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
return base;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
487
572
|
/**
|
|
488
573
|
* LuaAgent class.
|
|
489
574
|
* Unified agent configuration that consolidates skills, webhooks, jobs, and processors.
|
|
@@ -524,6 +609,7 @@ export class LuaAgent {
|
|
|
524
609
|
* @param config.jobs - Optional array of jobs
|
|
525
610
|
* @param config.preProcessors - Optional array of preprocessors
|
|
526
611
|
* @param config.postProcessors - Optional array of postprocessors
|
|
612
|
+
* @param config.mcpServers - Optional array of MCP servers
|
|
527
613
|
*/
|
|
528
614
|
constructor(config) {
|
|
529
615
|
this.name = config.name;
|
|
@@ -533,6 +619,7 @@ export class LuaAgent {
|
|
|
533
619
|
this.jobs = config.jobs || [];
|
|
534
620
|
this.preProcessors = config.preProcessors || [];
|
|
535
621
|
this.postProcessors = config.postProcessors || [];
|
|
622
|
+
this.mcpServers = config.mcpServers || [];
|
|
536
623
|
}
|
|
537
624
|
getName() {
|
|
538
625
|
return this.name;
|
|
@@ -555,4 +642,7 @@ export class LuaAgent {
|
|
|
555
642
|
getPostProcessors() {
|
|
556
643
|
return this.postProcessors;
|
|
557
644
|
}
|
|
645
|
+
getMCPServers() {
|
|
646
|
+
return this.mcpServers;
|
|
647
|
+
}
|
|
558
648
|
}
|
package/dist/utils/bundling.d.ts
CHANGED
|
@@ -65,15 +65,8 @@ export declare function bundlePreProcessor(preprocessor: any, indexFile: any, di
|
|
|
65
65
|
*/
|
|
66
66
|
export declare function bundlePostProcessor(postprocessor: any, indexFile: any, distDir: string, project?: any, debugMode?: boolean): Promise<any>;
|
|
67
67
|
/**
|
|
68
|
-
* Extracts
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
* 2. Detects and bundles any Jobs.create() calls within execute
|
|
72
|
-
* 3. Extracts the execute function
|
|
73
|
-
* 4. Converts Zod schema to JSON Schema format
|
|
74
|
-
*
|
|
75
|
-
* @param tool - The tool to extract metadata from (mutated with executeCode and inputSchema)
|
|
76
|
-
* @param project - The ts-morph Project instance for AST analysis
|
|
77
|
-
* @param distDir - Distribution directory for bundling nested jobs
|
|
68
|
+
* Extracts tool code from a bundled tool.
|
|
69
|
+
* Reads the bundled code, wraps it for VM execution (execute and condition),
|
|
70
|
+
* and converts the Zod schema to JSON Schema format.
|
|
78
71
|
*/
|
|
79
|
-
export declare function
|
|
72
|
+
export declare function extractToolCode(tool: ToolInfo, project: Project): Promise<void>;
|
package/dist/utils/bundling.js
CHANGED
|
@@ -8,7 +8,7 @@ import { build } from "esbuild";
|
|
|
8
8
|
import { Project, Node } from "ts-morph";
|
|
9
9
|
import { writeProgress } from "./cli.js";
|
|
10
10
|
import { COMPILE_DIRS, COMPILE_FILES, ESBUILD_TOOL_CONFIG, ESBUILD_INDEX_CONFIG, DEFAULT_INPUT_SCHEMA, EXTERNAL_PACKAGES, } from '../config/compile.constants.js';
|
|
11
|
-
import {
|
|
11
|
+
import { wrapExecuteForVM, wrapConditionForVM, evaluateZodSchemaToJsonSchema } from './compile.js';
|
|
12
12
|
/**
|
|
13
13
|
* Helper function to remove lua-cli and api-exports imports from source code.
|
|
14
14
|
* Used when bundling via stdin or temp files where the plugin can't process them.
|
|
@@ -347,8 +347,6 @@ export async function bundleTool(tool, distDir, modifiedSource, debugMode) {
|
|
|
347
347
|
plugins: [sandboxGlobalsPlugin],
|
|
348
348
|
});
|
|
349
349
|
}
|
|
350
|
-
// Wrap the bundled code for VM execution environment
|
|
351
|
-
await wrapToolForVM(outputPath, tool);
|
|
352
350
|
// Clean up temp file if created (unless in debug mode)
|
|
353
351
|
if (tempFile && fs.existsSync(tempFile) && !debugMode) {
|
|
354
352
|
try {
|
|
@@ -819,7 +817,6 @@ export async function bundlePostProcessor(postprocessor, indexFile, distDir, pro
|
|
|
819
817
|
name: postprocessor.name,
|
|
820
818
|
version: postprocessor.version,
|
|
821
819
|
description: postprocessor.description,
|
|
822
|
-
async: postprocessor.async === true ? true : false, // Explicitly set boolean
|
|
823
820
|
executeFunction,
|
|
824
821
|
code: compressedCode
|
|
825
822
|
};
|
|
@@ -845,18 +842,11 @@ async function bundleAndCompressProcessorCode(executeFunction, processorName, ty
|
|
|
845
842
|
})`, distDir, sourceFilePath, debugMode);
|
|
846
843
|
}
|
|
847
844
|
/**
|
|
848
|
-
* Extracts
|
|
849
|
-
*
|
|
850
|
-
*
|
|
851
|
-
* 2. Detects and bundles any Jobs.create() calls within execute
|
|
852
|
-
* 3. Extracts the execute function
|
|
853
|
-
* 4. Converts Zod schema to JSON Schema format
|
|
854
|
-
*
|
|
855
|
-
* @param tool - The tool to extract metadata from (mutated with executeCode and inputSchema)
|
|
856
|
-
* @param project - The ts-morph Project instance for AST analysis
|
|
857
|
-
* @param distDir - Distribution directory for bundling nested jobs
|
|
845
|
+
* Extracts tool code from a bundled tool.
|
|
846
|
+
* Reads the bundled code, wraps it for VM execution (execute and condition),
|
|
847
|
+
* and converts the Zod schema to JSON Schema format.
|
|
858
848
|
*/
|
|
859
|
-
export async function
|
|
849
|
+
export async function extractToolCode(tool, project) {
|
|
860
850
|
try {
|
|
861
851
|
const toolSourceFile = project.getSourceFile(tool.filePath);
|
|
862
852
|
if (!toolSourceFile) {
|
|
@@ -890,28 +880,30 @@ export async function extractExecuteCode(tool, project, distDir) {
|
|
|
890
880
|
return;
|
|
891
881
|
}
|
|
892
882
|
}
|
|
893
|
-
//
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
883
|
+
// Read bundled code and wrap for VM execution
|
|
884
|
+
const rawBundledCode = readBundledToolCode(tool);
|
|
885
|
+
if (rawBundledCode) {
|
|
886
|
+
tool.executeCode = wrapExecuteForVM(rawBundledCode, tool.className);
|
|
887
|
+
// Check if tool has condition and wrap it
|
|
888
|
+
const hasCondition = classDecl.getMethod('condition') || classDecl.getProperty('condition');
|
|
889
|
+
if (hasCondition) {
|
|
890
|
+
tool.conditionCode = wrapConditionForVM(rawBundledCode, tool.className);
|
|
891
|
+
}
|
|
892
|
+
}
|
|
897
893
|
// Extract and convert input schema
|
|
898
894
|
tool.inputSchema = await extractInputSchema(classDecl, tool);
|
|
899
895
|
}
|
|
900
896
|
catch (error) {
|
|
901
|
-
console.warn(`Warning: Could not extract
|
|
897
|
+
console.warn(`Warning: Could not extract tool metadata for ${tool.className}:`, error);
|
|
902
898
|
}
|
|
903
899
|
}
|
|
904
900
|
/**
|
|
905
|
-
*
|
|
906
|
-
*
|
|
907
|
-
* @param tool - The tool whose bundled code to read
|
|
908
|
-
* @returns The execute function code or undefined if not found
|
|
901
|
+
* Reads the raw bundled tool code from the dist directory.
|
|
909
902
|
*/
|
|
910
|
-
function
|
|
903
|
+
function readBundledToolCode(tool) {
|
|
911
904
|
const bundledPath = path.join(process.cwd(), COMPILE_DIRS.DIST, COMPILE_DIRS.TOOLS, `${tool.className}.js`);
|
|
912
905
|
if (fs.existsSync(bundledPath)) {
|
|
913
|
-
|
|
914
|
-
return createExecuteFunction(bundledCode, tool);
|
|
906
|
+
return fs.readFileSync(bundledPath, 'utf8');
|
|
915
907
|
}
|
|
916
908
|
return undefined;
|
|
917
909
|
}
|
package/dist/utils/compile.d.ts
CHANGED
|
@@ -12,24 +12,25 @@ export declare function compressCode(code: string): string;
|
|
|
12
12
|
*/
|
|
13
13
|
export declare function findIndexFile(): string;
|
|
14
14
|
/**
|
|
15
|
-
* Resolves import path from module specifier with support for multiple extensions and index files
|
|
16
|
-
*
|
|
15
|
+
* Resolves import path from module specifier with support for multiple extensions and index files.
|
|
16
|
+
* Handles modern TypeScript projects that use .js extensions in imports (Node16/NodeNext resolution).
|
|
17
|
+
* @param moduleSpecifier - The import path (e.g., './tools/MyTool.js' or '../utils')
|
|
17
18
|
* @param currentFilePath - The file doing the importing
|
|
18
19
|
* @returns Resolved absolute file path
|
|
19
20
|
*/
|
|
20
21
|
export declare function resolveImportPath(moduleSpecifier: string, currentFilePath: string): string;
|
|
21
|
-
/**
|
|
22
|
-
* Creates execute function wrapper from bundled code
|
|
23
|
-
*/
|
|
24
|
-
export declare function createExecuteFunction(bundledCode: string, tool: ToolInfo): string;
|
|
25
22
|
/**
|
|
26
23
|
* Evaluates Zod schema code and converts it to JSON Schema
|
|
27
24
|
*/
|
|
28
25
|
export declare function evaluateZodSchemaToJsonSchema(zodSchemaCode: string): Promise<any>;
|
|
29
26
|
/**
|
|
30
|
-
* Wraps bundled tool code for
|
|
27
|
+
* Wraps raw bundled tool code for execute function
|
|
28
|
+
*/
|
|
29
|
+
export declare function wrapExecuteForVM(bundledCode: string, className: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Wraps raw bundled tool code for condition evaluation
|
|
31
32
|
*/
|
|
32
|
-
export declare function
|
|
33
|
+
export declare function wrapConditionForVM(bundledCode: string, className: string): string;
|
|
33
34
|
/**
|
|
34
35
|
* Extracts tool information from a new expression in the AST
|
|
35
36
|
*/
|
|
@@ -69,6 +70,7 @@ export declare function extractLuaAgentMetadata(indexFile: any): {
|
|
|
69
70
|
jobs: any[];
|
|
70
71
|
preProcessors: any[];
|
|
71
72
|
postProcessors: any[];
|
|
73
|
+
mcpServers: any[];
|
|
72
74
|
} | null;
|
|
73
75
|
/**
|
|
74
76
|
* Gets the file paths where skills are defined in a LuaAgent.
|
|
@@ -93,10 +95,17 @@ export declare function resolveLuaAgentReferences(agentMetadata: {
|
|
|
93
95
|
jobs: any[];
|
|
94
96
|
preProcessors: any[];
|
|
95
97
|
postProcessors: any[];
|
|
98
|
+
mcpServers: any[];
|
|
96
99
|
}, indexFile: any, project: Project): {
|
|
97
100
|
skills: any[];
|
|
98
101
|
webhooks: any[];
|
|
99
102
|
jobs: any[];
|
|
100
103
|
preProcessors: any[];
|
|
101
104
|
postProcessors: any[];
|
|
105
|
+
mcpServers: any[];
|
|
102
106
|
};
|
|
107
|
+
/**
|
|
108
|
+
* Extracts MCP server metadata from a source file.
|
|
109
|
+
* Looks for LuaMCPServer constructor calls.
|
|
110
|
+
*/
|
|
111
|
+
export declare function extractMCPServersMetadata(sourceFile: any): any[];
|
package/dist/utils/compile.js
CHANGED
|
@@ -29,17 +29,24 @@ export function findIndexFile() {
|
|
|
29
29
|
throw new Error("index.ts not found in current directory or src/ directory");
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
32
|
-
* Resolves import path from module specifier with support for multiple extensions and index files
|
|
33
|
-
*
|
|
32
|
+
* Resolves import path from module specifier with support for multiple extensions and index files.
|
|
33
|
+
* Handles modern TypeScript projects that use .js extensions in imports (Node16/NodeNext resolution).
|
|
34
|
+
* @param moduleSpecifier - The import path (e.g., './tools/MyTool.js' or '../utils')
|
|
34
35
|
* @param currentFilePath - The file doing the importing
|
|
35
36
|
* @returns Resolved absolute file path
|
|
36
37
|
*/
|
|
37
38
|
export function resolveImportPath(moduleSpecifier, currentFilePath) {
|
|
38
39
|
const extensions = ['.ts', '.tsx', '.js', '.jsx', '/index.ts', '/index.tsx', '/index.js'];
|
|
39
|
-
|
|
40
|
+
// Handle modern TS projects using .js extensions in imports (Node16/NodeNext module resolution)
|
|
41
|
+
// Strip the extension so we can properly resolve to the .ts source file
|
|
42
|
+
let normalizedSpecifier = moduleSpecifier;
|
|
43
|
+
if (moduleSpecifier.endsWith('.js')) {
|
|
44
|
+
normalizedSpecifier = moduleSpecifier.slice(0, -3);
|
|
45
|
+
}
|
|
46
|
+
if (normalizedSpecifier.startsWith('./') || normalizedSpecifier.startsWith('../')) {
|
|
40
47
|
// Relative import - resolve relative to current file
|
|
41
48
|
const currentDir = path.dirname(currentFilePath);
|
|
42
|
-
const basePath = path.resolve(currentDir,
|
|
49
|
+
const basePath = path.resolve(currentDir, normalizedSpecifier);
|
|
43
50
|
// Try each extension in order
|
|
44
51
|
for (const ext of extensions) {
|
|
45
52
|
const fullPath = ext.startsWith('/') ? path.join(basePath, ext) : basePath + ext;
|
|
@@ -52,7 +59,7 @@ export function resolveImportPath(moduleSpecifier, currentFilePath) {
|
|
|
52
59
|
}
|
|
53
60
|
else {
|
|
54
61
|
// Absolute import - check in src/ directory
|
|
55
|
-
const srcBase = path.resolve(process.cwd(), 'src',
|
|
62
|
+
const srcBase = path.resolve(process.cwd(), 'src', normalizedSpecifier);
|
|
56
63
|
for (const ext of extensions) {
|
|
57
64
|
const fullPath = ext.startsWith('/') ? path.join(srcBase, ext) : srcBase + ext;
|
|
58
65
|
if (fs.existsSync(fullPath)) {
|
|
@@ -60,17 +67,9 @@ export function resolveImportPath(moduleSpecifier, currentFilePath) {
|
|
|
60
67
|
}
|
|
61
68
|
}
|
|
62
69
|
// Fallback: return .ts in src/ (original behavior)
|
|
63
|
-
return path.resolve(process.cwd(), 'src',
|
|
70
|
+
return path.resolve(process.cwd(), 'src', normalizedSpecifier + '.ts');
|
|
64
71
|
}
|
|
65
72
|
}
|
|
66
|
-
/**
|
|
67
|
-
* Creates execute function wrapper from bundled code
|
|
68
|
-
*/
|
|
69
|
-
export function createExecuteFunction(bundledCode, tool) {
|
|
70
|
-
// The bundled code is already wrapped for VM execution by wrapToolForVM
|
|
71
|
-
// Just return it directly since it's already an async function
|
|
72
|
-
return bundledCode;
|
|
73
|
-
}
|
|
74
73
|
/**
|
|
75
74
|
* Evaluates Zod schema code and converts it to JSON Schema
|
|
76
75
|
*/
|
|
@@ -109,25 +108,28 @@ export async function evaluateZodSchemaToJsonSchema(zodSchemaCode) {
|
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
/**
|
|
112
|
-
* Wraps bundled tool code for
|
|
111
|
+
* Wraps raw bundled tool code for execute function
|
|
113
112
|
*/
|
|
114
|
-
export
|
|
115
|
-
|
|
116
|
-
// Create a wrapper that's compatible with the existing sandbox.ts VM system
|
|
117
|
-
// The sandbox expects: const executeFunction = ${toolCode}; module.exports = async (input) => { return await executeFunction(input); };
|
|
118
|
-
const wrappedCode = `async (input) => {
|
|
119
|
-
|
|
120
|
-
// Execute the bundled tool code
|
|
113
|
+
export function wrapExecuteForVM(bundledCode, className) {
|
|
114
|
+
return `async (input) => {
|
|
121
115
|
${bundledCode}
|
|
122
116
|
|
|
123
|
-
|
|
124
|
-
const ToolClass = module.exports.default || module.exports.${tool.className} || module.exports;
|
|
125
|
-
|
|
126
|
-
// Create and execute the tool
|
|
117
|
+
const ToolClass = module.exports.default || module.exports.${className} || module.exports;
|
|
127
118
|
const toolInstance = new ToolClass();
|
|
128
119
|
return await toolInstance.execute(input);
|
|
129
120
|
}`;
|
|
130
|
-
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Wraps raw bundled tool code for condition evaluation
|
|
124
|
+
*/
|
|
125
|
+
export function wrapConditionForVM(bundledCode, className) {
|
|
126
|
+
return `async () => {
|
|
127
|
+
${bundledCode}
|
|
128
|
+
|
|
129
|
+
const ToolClass = module.exports.default || module.exports.${className} || module.exports;
|
|
130
|
+
const toolInstance = new ToolClass();
|
|
131
|
+
return await toolInstance.condition() === true;
|
|
132
|
+
}`;
|
|
131
133
|
}
|
|
132
134
|
/**
|
|
133
135
|
* Extracts tool information from a new expression in the AST
|
|
@@ -463,7 +465,6 @@ export function extractPostProcessorsMetadata(indexFile) {
|
|
|
463
465
|
const configObj = args[0];
|
|
464
466
|
let name = '';
|
|
465
467
|
let description = '';
|
|
466
|
-
let asyncMode = false;
|
|
467
468
|
configObj.getProperties().forEach((prop) => {
|
|
468
469
|
if (Node.isPropertyAssignment(prop)) {
|
|
469
470
|
const propName = prop.getName();
|
|
@@ -474,18 +475,12 @@ export function extractPostProcessorsMetadata(indexFile) {
|
|
|
474
475
|
else if (propName === 'description' && value) {
|
|
475
476
|
description = value.getText().replace(/['"]/g, '');
|
|
476
477
|
}
|
|
477
|
-
else if (propName === 'async' && value) {
|
|
478
|
-
// Properly extract boolean value by checking node kind
|
|
479
|
-
const nodeKind = value.getKind();
|
|
480
|
-
asyncMode = nodeKind === 110; // TrueKeyword = 110, FalseKeyword = 95
|
|
481
|
-
}
|
|
482
478
|
}
|
|
483
479
|
});
|
|
484
480
|
if (name) {
|
|
485
481
|
postprocessors.push({
|
|
486
482
|
name,
|
|
487
|
-
description
|
|
488
|
-
async: asyncMode
|
|
483
|
+
description
|
|
489
484
|
});
|
|
490
485
|
}
|
|
491
486
|
}
|
|
@@ -518,6 +513,7 @@ export function extractLuaAgentMetadata(indexFile) {
|
|
|
518
513
|
const jobs = [];
|
|
519
514
|
const preProcessors = [];
|
|
520
515
|
const postProcessors = [];
|
|
516
|
+
const mcpServers = [];
|
|
521
517
|
// Extract properties from LuaAgent config
|
|
522
518
|
configObj.getProperties().forEach((prop) => {
|
|
523
519
|
if (Node.isPropertyAssignment(prop)) {
|
|
@@ -608,6 +604,22 @@ export function extractLuaAgentMetadata(indexFile) {
|
|
|
608
604
|
}
|
|
609
605
|
});
|
|
610
606
|
}
|
|
607
|
+
else if (propName === 'mcpServers' && value && Node.isArrayLiteralExpression(value)) {
|
|
608
|
+
// Extract MCP server references from the array
|
|
609
|
+
value.getElements().forEach((element) => {
|
|
610
|
+
if (Node.isIdentifier(element)) {
|
|
611
|
+
mcpServers.push({ ref: element.getText() });
|
|
612
|
+
}
|
|
613
|
+
else if (Node.isNewExpression(element)) {
|
|
614
|
+
// Extract inline MCP server metadata
|
|
615
|
+
const mcpArgs = element.getArguments();
|
|
616
|
+
if (mcpArgs.length > 0 && Node.isObjectLiteralExpression(mcpArgs[0])) {
|
|
617
|
+
const mcpConfig = extractConfigFromObjectLiteral(mcpArgs[0]);
|
|
618
|
+
mcpServers.push(mcpConfig);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
}
|
|
611
623
|
}
|
|
612
624
|
});
|
|
613
625
|
if (name && persona) {
|
|
@@ -618,7 +630,8 @@ export function extractLuaAgentMetadata(indexFile) {
|
|
|
618
630
|
webhooks,
|
|
619
631
|
jobs,
|
|
620
632
|
preProcessors,
|
|
621
|
-
postProcessors
|
|
633
|
+
postProcessors,
|
|
634
|
+
mcpServers
|
|
622
635
|
};
|
|
623
636
|
}
|
|
624
637
|
}
|
|
@@ -788,9 +801,30 @@ export function resolveLuaAgentReferences(agentMetadata, indexFile, project) {
|
|
|
788
801
|
webhooks: resolveArrayReferences(agentMetadata.webhooks, extractWebhooksMetadata),
|
|
789
802
|
jobs: resolveArrayReferences(agentMetadata.jobs, extractJobsMetadata),
|
|
790
803
|
preProcessors: resolveArrayReferences(agentMetadata.preProcessors, extractPreProcessorsMetadata),
|
|
791
|
-
postProcessors: resolveArrayReferences(agentMetadata.postProcessors, extractPostProcessorsMetadata)
|
|
804
|
+
postProcessors: resolveArrayReferences(agentMetadata.postProcessors, extractPostProcessorsMetadata),
|
|
805
|
+
mcpServers: resolveArrayReferences(agentMetadata.mcpServers, extractMCPServersMetadata)
|
|
792
806
|
};
|
|
793
807
|
}
|
|
808
|
+
/**
|
|
809
|
+
* Extracts MCP server metadata from a source file.
|
|
810
|
+
* Looks for LuaMCPServer constructor calls.
|
|
811
|
+
*/
|
|
812
|
+
export function extractMCPServersMetadata(sourceFile) {
|
|
813
|
+
const mcpServers = [];
|
|
814
|
+
sourceFile.forEachDescendant((node) => {
|
|
815
|
+
if (Node.isNewExpression(node)) {
|
|
816
|
+
const expression = node.getExpression();
|
|
817
|
+
if (expression.getText() === 'LuaMCPServer') {
|
|
818
|
+
const args = node.getArguments();
|
|
819
|
+
if (args.length > 0 && Node.isObjectLiteralExpression(args[0])) {
|
|
820
|
+
const config = extractConfigFromObjectLiteral(args[0]);
|
|
821
|
+
mcpServers.push(config);
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
});
|
|
826
|
+
return mcpServers;
|
|
827
|
+
}
|
|
794
828
|
/**
|
|
795
829
|
* Finds a variable declaration in a source file by name.
|
|
796
830
|
*/
|
package/dist/utils/deployment.js
CHANGED
|
@@ -154,12 +154,19 @@ function buildSkillsArray(skillsMetadata, skillToTools, tools) {
|
|
|
154
154
|
name: skillMeta.name,
|
|
155
155
|
description: skillMeta.description,
|
|
156
156
|
context: skillMeta.context,
|
|
157
|
-
tools: skillTools.map(tool =>
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
157
|
+
tools: skillTools.map(tool => {
|
|
158
|
+
const toolData = {
|
|
159
|
+
name: tool.name,
|
|
160
|
+
description: tool.description || '',
|
|
161
|
+
inputSchema: tool.inputSchema || DEFAULT_INPUT_SCHEMA,
|
|
162
|
+
execute: compressCode(tool.executeCode || '')
|
|
163
|
+
};
|
|
164
|
+
// Include condition if tool has one
|
|
165
|
+
if (tool.conditionCode) {
|
|
166
|
+
toolData.condition = compressCode(tool.conditionCode);
|
|
167
|
+
}
|
|
168
|
+
return toolData;
|
|
169
|
+
})
|
|
163
170
|
};
|
|
164
171
|
});
|
|
165
172
|
}
|
package/dist/utils/dev-api.js
CHANGED
|
@@ -349,8 +349,7 @@ export async function pushSinglePostProcessorToSandbox(apiKey, agentId, postproc
|
|
|
349
349
|
version: sandboxVersion,
|
|
350
350
|
description: postprocessorData.description,
|
|
351
351
|
code: postprocessorData.code,
|
|
352
|
-
executeFunction: postprocessorData.executeFunction
|
|
353
|
-
async: Boolean(postprocessorData.async ?? false)
|
|
352
|
+
executeFunction: postprocessorData.executeFunction
|
|
354
353
|
};
|
|
355
354
|
if (sandboxPostProcessorId) {
|
|
356
355
|
// Try to update existing sandbox version
|
package/dist/utils/dev-server.js
CHANGED
|
@@ -792,7 +792,7 @@ async function handleCustomDataEndpoint(req, res, apiKey, agentId) {
|
|
|
792
792
|
req.on('end', () => resolve(data));
|
|
793
793
|
});
|
|
794
794
|
const updateData = JSON.parse(body);
|
|
795
|
-
result = await customDataApi.update(collectionName, entryId, updateData);
|
|
795
|
+
result = await customDataApi.update(collectionName, entryId, updateData.data, updateData.searchText);
|
|
796
796
|
res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
|
|
797
797
|
res.end(JSON.stringify({ success: true, data: result }));
|
|
798
798
|
}
|
package/dist/utils/files.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Copies template files to target directory.
|
|
3
|
+
*
|
|
4
|
+
* @param templateDir - Source template directory
|
|
5
|
+
* @param targetDir - Target directory to copy to
|
|
6
|
+
* @param includeExamples - Whether to include the examples/ directory (default: false)
|
|
7
|
+
*/
|
|
8
|
+
export declare function copyTemplateFiles(templateDir: string, targetDir: string, includeExamples?: boolean): void;
|
|
2
9
|
export declare function createSkillYaml(agentId: string, orgId: string, skillName?: string, skillId?: string, persona?: string): void;
|
|
3
10
|
export declare function readSkillYaml(): any;
|
|
4
11
|
export declare function readSkillConfig(): any;
|
package/dist/utils/files.js
CHANGED
|
@@ -2,18 +2,29 @@ import * as fs from "fs";
|
|
|
2
2
|
import * as path from "path";
|
|
3
3
|
import pkg from 'js-yaml';
|
|
4
4
|
const { load, dump } = pkg;
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Copies template files to target directory.
|
|
7
|
+
*
|
|
8
|
+
* @param templateDir - Source template directory
|
|
9
|
+
* @param targetDir - Target directory to copy to
|
|
10
|
+
* @param includeExamples - Whether to include the examples/ directory (default: false)
|
|
11
|
+
*/
|
|
12
|
+
export function copyTemplateFiles(templateDir, targetDir, includeExamples = false) {
|
|
6
13
|
const files = fs.readdirSync(templateDir);
|
|
7
14
|
for (const file of files) {
|
|
8
15
|
// Skip node_modules and package-lock.json to avoid circular dependencies
|
|
9
16
|
if (file === 'node_modules' || file === 'package-lock.json') {
|
|
10
17
|
continue;
|
|
11
18
|
}
|
|
19
|
+
// Skip examples/ by default (user can include with --with-examples flag)
|
|
20
|
+
if (file === 'examples' && !includeExamples) {
|
|
21
|
+
continue;
|
|
22
|
+
}
|
|
12
23
|
const srcPath = path.join(templateDir, file);
|
|
13
24
|
const destPath = path.join(targetDir, file);
|
|
14
25
|
if (fs.statSync(srcPath).isDirectory()) {
|
|
15
26
|
fs.mkdirSync(destPath, { recursive: true });
|
|
16
|
-
copyTemplateFiles(srcPath, destPath);
|
|
27
|
+
copyTemplateFiles(srcPath, destPath, includeExamples);
|
|
17
28
|
}
|
|
18
29
|
else if (file === 'package.json') {
|
|
19
30
|
// Special handling for package.json to update lua-cli version
|
|
@@ -14,9 +14,11 @@ export declare function getTemplateDir(): string;
|
|
|
14
14
|
* @param agentId - Agent ID for configuration
|
|
15
15
|
* @param orgId - Organization ID for configuration
|
|
16
16
|
* @param persona - Optional persona configuration
|
|
17
|
+
* @param agentName - Optional agent name
|
|
18
|
+
* @param withExamples - Whether to include example skills, tools, jobs, etc. (default: false)
|
|
17
19
|
* @returns Current working directory
|
|
18
20
|
*/
|
|
19
|
-
export declare function initializeProject(agentId: string, orgId: string, persona?: string, agentName?: string): string;
|
|
21
|
+
export declare function initializeProject(agentId: string, orgId: string, persona?: string, agentName?: string, withExamples?: boolean): string;
|
|
20
22
|
/**
|
|
21
23
|
* Installs npm dependencies for the project.
|
|
22
24
|
*
|
|
@@ -24,17 +24,22 @@ export function getTemplateDir() {
|
|
|
24
24
|
* @param agentId - Agent ID for configuration
|
|
25
25
|
* @param orgId - Organization ID for configuration
|
|
26
26
|
* @param persona - Optional persona configuration
|
|
27
|
+
* @param agentName - Optional agent name
|
|
28
|
+
* @param withExamples - Whether to include example skills, tools, jobs, etc. (default: false)
|
|
27
29
|
* @returns Current working directory
|
|
28
30
|
*/
|
|
29
|
-
export function initializeProject(agentId, orgId, persona, agentName) {
|
|
31
|
+
export function initializeProject(agentId, orgId, persona, agentName, withExamples = false) {
|
|
30
32
|
const templateDir = getTemplateDir();
|
|
31
33
|
const currentDir = process.cwd();
|
|
32
|
-
copyTemplateFiles(templateDir, currentDir);
|
|
34
|
+
copyTemplateFiles(templateDir, currentDir, withExamples);
|
|
33
35
|
createSkillYaml(agentId, orgId, undefined, undefined, persona);
|
|
34
36
|
// Update LuaAgent in index.ts with agent configuration
|
|
35
37
|
updateLuaAgentInIndexFile(currentDir, agentName, persona);
|
|
36
38
|
writeProgress("✅ Created lua.skill.yaml");
|
|
37
39
|
writeProgress("✅ Copied template files");
|
|
40
|
+
if (withExamples) {
|
|
41
|
+
writeProgress("✅ Included example skills, tools, jobs, and webhooks");
|
|
42
|
+
}
|
|
38
43
|
writeProgress("✅ Updated LuaAgent configuration");
|
|
39
44
|
return currentDir;
|
|
40
45
|
}
|