lua-cli 3.0.1 ā 3.0.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.
- package/dist/commands/chat.js +2 -2
- package/dist/commands/chatClear.js +1 -1
- package/dist/commands/features.js +1 -1
- package/dist/commands/init.js +11 -7
- package/dist/config/init.constants.d.ts +2 -2
- package/dist/config/init.constants.js +4 -2
- package/dist/utils/auth-flows.js +17 -8
- package/dist/utils/bundling.js +135 -176
- package/dist/utils/cli.d.ts +5 -5
- package/dist/utils/cli.js +14 -10
- package/dist/utils/init-prompts.js +31 -5
- package/dist/utils/prompt-handler.d.ts +1 -0
- package/dist/utils/prompt-handler.js +6 -2
- package/package.json +5 -1
- package/template/package.json +1 -1
- package/template/src/skills/tools/CreateInlineJob.ts +1 -1
- package/template/src/skills/tools/CreatePostTool.ts +1 -1
- package/template/src/skills/tools/GetWeatherTool.ts +1 -1
- package/template/src/skills/tools/UserDataTool.ts +16 -3
- package/dist/utils/dynamic-job-bundler.d.ts +0 -17
- package/dist/utils/dynamic-job-bundler.js +0 -143
- package/template/lua.skill.yaml +0 -47
- package/template/package-lock.json +0 -10505
package/dist/commands/chat.js
CHANGED
|
@@ -47,8 +47,8 @@ export async function chatCommand() {
|
|
|
47
47
|
name: 'environment',
|
|
48
48
|
message: 'Select environment:',
|
|
49
49
|
choices: [
|
|
50
|
-
{ name: 'š§ Sandbox (
|
|
51
|
-
{ name: 'š Production', value: 'production' }
|
|
50
|
+
{ name: 'š§ Sandbox (Agent will execute skills etc from your local machine)', value: 'sandbox' },
|
|
51
|
+
{ name: 'š Production (Agent will execute latest version of skills etc)', value: 'production' }
|
|
52
52
|
]
|
|
53
53
|
}
|
|
54
54
|
]);
|
|
@@ -45,7 +45,7 @@ export async function chatClearCommand() {
|
|
|
45
45
|
}
|
|
46
46
|
]);
|
|
47
47
|
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
48
|
-
console.log("\nā Operation cancelled. History not cleared.\n");
|
|
48
|
+
// console.log("\nā Operation cancelled. History not cleared.\n");
|
|
49
49
|
return;
|
|
50
50
|
}
|
|
51
51
|
// Step 4: Clear history via API
|
|
@@ -233,7 +233,7 @@ async function toggleFeature(context, feature) {
|
|
|
233
233
|
}
|
|
234
234
|
]);
|
|
235
235
|
if (!confirmAnswer || !confirmAnswer.confirm) {
|
|
236
|
-
console.log("\nā Operation cancelled.\n");
|
|
236
|
+
// console.log("\nā Operation cancelled.\n");
|
|
237
237
|
return;
|
|
238
238
|
}
|
|
239
239
|
writeProgress(`š ${newStatus ? 'Activating' : 'Deactivating'} feature...`);
|
package/dist/commands/init.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
6
|
import { loadApiKey, checkApiKey } from "../services/auth.js";
|
|
7
7
|
import { withErrorHandling, writeProgress, writeSuccess, writeInfo, writeError, } from "../utils/cli.js";
|
|
8
|
-
import { promptAgentChoice, promptOrganizationSelection, promptAgentSelection, promptMetadataCollection,
|
|
8
|
+
import { promptAgentChoice, promptOrganizationSelection, promptAgentSelection, promptMetadataCollection, promptBusinessConfiguration, } from "../utils/init-prompts.js";
|
|
9
9
|
import { fetchAgentTypes, selectBaseAgentType, createNewAgent, fetchExistingAgentDetails, } from "../utils/init-agent.js";
|
|
10
10
|
import { initializeProject, installDependencies, clearLinesIfNeeded, } from "../utils/init-helpers.js";
|
|
11
11
|
import { readSkillYaml, updateYamlAgent } from "../utils/files.js";
|
|
@@ -84,9 +84,13 @@ export async function initCommand() {
|
|
|
84
84
|
writeInfo(` Current Agent ID: ${existingAgentId}\n`);
|
|
85
85
|
const { wantSwitch } = await inquirer.prompt([
|
|
86
86
|
{
|
|
87
|
-
type: '
|
|
87
|
+
type: 'list',
|
|
88
88
|
name: 'wantSwitch',
|
|
89
89
|
message: 'Do you want to switch this project to a different agent?',
|
|
90
|
+
choices: [
|
|
91
|
+
{ name: 'No - Keep current agent', value: false },
|
|
92
|
+
{ name: 'Yes - Switch to a different agent', value: true }
|
|
93
|
+
],
|
|
90
94
|
default: false
|
|
91
95
|
}
|
|
92
96
|
]);
|
|
@@ -232,12 +236,12 @@ async function createNewAgentFlow(apiKey, userData) {
|
|
|
232
236
|
const metadata = selectedAgentType.requiredSubAgentMetadata?.length
|
|
233
237
|
? await promptMetadataCollection(selectedAgentType.requiredSubAgentMetadata)
|
|
234
238
|
: {};
|
|
235
|
-
//
|
|
239
|
+
// Enable all features by default (skip configuration prompt)
|
|
236
240
|
const availableFeatures = Object.keys(selectedAgentType.features);
|
|
237
|
-
const features = availableFeatures.
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
+
const features = availableFeatures.reduce((acc, feature) => {
|
|
242
|
+
acc[feature] = true;
|
|
243
|
+
return acc;
|
|
244
|
+
}, {});
|
|
241
245
|
// Collect business configuration
|
|
242
246
|
// If using existing org, don't ask for business name (use org name)
|
|
243
247
|
const businessConfig = await promptBusinessConfiguration(usingExistingOrg);
|
|
@@ -8,11 +8,11 @@ export declare const AGENT_READY_WAIT_TIME = 30000;
|
|
|
8
8
|
/**
|
|
9
9
|
* Business type options for agent creation
|
|
10
10
|
*/
|
|
11
|
-
export declare const BUSINESS_TYPES: readonly ["Retail & Consumer Goods (e.g. clothing store, bookstore)", "Food & Beverage (e.g. restaurant, bakery)", "Hospitality (e.g. hotel, resort)", "Personal services (e.g. hair salon, spa)", "Education (e.g. language school, online courses)", "Health (e.g. gym, yoga studio, clinic)"];
|
|
11
|
+
export declare const BUSINESS_TYPES: readonly ["Retail & Consumer Goods (e.g. clothing store, bookstore)", "Food & Beverage (e.g. restaurant, bakery)", "Hospitality (e.g. hotel, resort)", "Personal services (e.g. hair salon, spa)", "Education (e.g. language school, online courses)", "Health (e.g. gym, yoga studio, clinic)", "Other (describe your business)"];
|
|
12
12
|
/**
|
|
13
13
|
* Brand personality options for agent creation
|
|
14
14
|
*/
|
|
15
|
-
export declare const BRAND_PERSONALITIES: readonly ["Energetic & fun", "Refined & elegant", "Chatty", "Casual", "Funny", "Friendly"];
|
|
15
|
+
export declare const BRAND_PERSONALITIES: readonly ["Energetic & fun", "Refined & elegant", "Chatty", "Casual", "Funny", "Friendly", "Other (describe your brand personality)"];
|
|
16
16
|
/**
|
|
17
17
|
* Default business name
|
|
18
18
|
*/
|
|
@@ -14,7 +14,8 @@ export const BUSINESS_TYPES = [
|
|
|
14
14
|
"Hospitality (e.g. hotel, resort)",
|
|
15
15
|
"Personal services (e.g. hair salon, spa)",
|
|
16
16
|
"Education (e.g. language school, online courses)",
|
|
17
|
-
"Health (e.g. gym, yoga studio, clinic)"
|
|
17
|
+
"Health (e.g. gym, yoga studio, clinic)",
|
|
18
|
+
"Other (describe your business)"
|
|
18
19
|
];
|
|
19
20
|
/**
|
|
20
21
|
* Brand personality options for agent creation
|
|
@@ -25,7 +26,8 @@ export const BRAND_PERSONALITIES = [
|
|
|
25
26
|
"Chatty",
|
|
26
27
|
"Casual",
|
|
27
28
|
"Funny",
|
|
28
|
-
"Friendly"
|
|
29
|
+
"Friendly",
|
|
30
|
+
"Other (describe your brand personality)"
|
|
29
31
|
];
|
|
30
32
|
/**
|
|
31
33
|
* Default business name
|
package/dist/utils/auth-flows.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import inquirer from "inquirer";
|
|
6
6
|
import { saveApiKey, checkApiKey, requestEmailOTP, verifyOTPAndGetToken, generateApiKey } from "../services/auth.js";
|
|
7
|
-
import { clearPromptLines, writeProgress, writeSuccess } from "./cli.js";
|
|
7
|
+
import { clearPromptLines, writeProgress, writeSuccess, writeInfo } from "./cli.js";
|
|
8
8
|
/**
|
|
9
9
|
* Configuration for OTP verification
|
|
10
10
|
*/
|
|
@@ -57,12 +57,13 @@ export async function handleEmailAuth() {
|
|
|
57
57
|
]);
|
|
58
58
|
clearPromptLines(2);
|
|
59
59
|
// Step 2: Send OTP
|
|
60
|
-
writeProgress("š§ Sending OTP to your email...");
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
// writeProgress("š§ Sending OTP to your email...");
|
|
61
|
+
requestEmailOTP(email).catch((error) => {
|
|
62
|
+
});
|
|
63
|
+
// if (!otpSent) {
|
|
64
|
+
// throw new Error("Failed to send OTP. Please try again.");
|
|
65
|
+
// }
|
|
66
|
+
// writeProgress("ā
OTP sent successfully!");
|
|
66
67
|
// Step 3: Verify OTP with retry logic
|
|
67
68
|
const signInToken = await verifyOTPWithRetry(email);
|
|
68
69
|
// Step 4: Generate API key
|
|
@@ -74,6 +75,14 @@ export async function handleEmailAuth() {
|
|
|
74
75
|
// Step 5: Save API key
|
|
75
76
|
await saveApiKey(apiKey);
|
|
76
77
|
writeSuccess("ā
API key generated and saved securely.");
|
|
78
|
+
// Guide user to next steps
|
|
79
|
+
writeInfo("\nš You're all set! Here's what to do next:\n");
|
|
80
|
+
writeInfo(" 1ļøā£ Create a new project directory:");
|
|
81
|
+
writeInfo(" mkdir my-agent && cd my-agent\n");
|
|
82
|
+
writeInfo(" 2ļøā£ Initialize your agent:");
|
|
83
|
+
writeInfo(" lua init\n");
|
|
84
|
+
writeInfo(" 3ļøā£ Follow the prompts to create or select an agent\n");
|
|
85
|
+
writeInfo("š” Tip: Run 'lua --help' to see all available commands\n");
|
|
77
86
|
}
|
|
78
87
|
/**
|
|
79
88
|
* Verifies OTP with retry logic.
|
|
@@ -92,7 +101,7 @@ async function verifyOTPWithRetry(email) {
|
|
|
92
101
|
{
|
|
93
102
|
type: "input",
|
|
94
103
|
name: "pin",
|
|
95
|
-
message: "Enter the OTP
|
|
104
|
+
message: "Enter the OTP sent to your email:",
|
|
96
105
|
validate: (input) => {
|
|
97
106
|
return input.length === OTP_CONFIG.OTP_LENGTH || `OTP must be ${OTP_CONFIG.OTP_LENGTH} digits`;
|
|
98
107
|
}
|
package/dist/utils/bundling.js
CHANGED
|
@@ -7,7 +7,7 @@ import path from "path";
|
|
|
7
7
|
import { build } from "esbuild";
|
|
8
8
|
import { Project, Node } from "ts-morph";
|
|
9
9
|
import { writeProgress } from "./cli.js";
|
|
10
|
-
import { COMPILE_DIRS, COMPILE_FILES, ESBUILD_TOOL_CONFIG, ESBUILD_INDEX_CONFIG, DEFAULT_INPUT_SCHEMA, } from '../config/compile.constants.js';
|
|
10
|
+
import { COMPILE_DIRS, COMPILE_FILES, ESBUILD_TOOL_CONFIG, ESBUILD_INDEX_CONFIG, DEFAULT_INPUT_SCHEMA, EXTERNAL_PACKAGES, } from '../config/compile.constants.js';
|
|
11
11
|
import { wrapToolForVM, createExecuteFunction, evaluateZodSchemaToJsonSchema } from './compile.js';
|
|
12
12
|
/**
|
|
13
13
|
* Helper function to remove lua-cli and api-exports imports from source code.
|
|
@@ -30,6 +30,108 @@ function stripLuaCliImports(sourceCode) {
|
|
|
30
30
|
: '// lua-cli/skill imports removed - using sandbox globals';
|
|
31
31
|
});
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Extracts and filters relevant imports from source code.
|
|
35
|
+
* Removes lua-cli internal classes and API imports that are available in the sandbox.
|
|
36
|
+
*
|
|
37
|
+
* @param sourceFilePath - Path to the source file
|
|
38
|
+
* @returns Array of relevant import statements
|
|
39
|
+
*/
|
|
40
|
+
function extractRelevantImports(sourceFilePath) {
|
|
41
|
+
const sourceContent = fs.readFileSync(sourceFilePath, 'utf8');
|
|
42
|
+
// Extract all import statements from the source
|
|
43
|
+
const importPattern = /^import\s+.+\s+from\s+['"][^'"]+['"];?$/gm;
|
|
44
|
+
const imports = sourceContent.match(importPattern) || [];
|
|
45
|
+
// Filter to only imports that might be used (exclude lua-cli internal classes and APIs)
|
|
46
|
+
return imports.filter(imp => !imp.includes('LuaTool') &&
|
|
47
|
+
!imp.includes('LuaWebhook') &&
|
|
48
|
+
!imp.includes('LuaJob') &&
|
|
49
|
+
!imp.includes('PreProcessor') &&
|
|
50
|
+
!imp.includes('PostProcessor') &&
|
|
51
|
+
!imp.includes('LuaAgent') &&
|
|
52
|
+
!imp.includes('lua-cli') && // Exclude all lua-cli imports (they're available in sandbox)
|
|
53
|
+
!imp.includes('api-exports') && // Exclude api-exports
|
|
54
|
+
!imp.includes('../../../dist/api-exports') // Exclude direct api-exports imports
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Generic function to bundle and compress execute function code with dependencies.
|
|
59
|
+
*
|
|
60
|
+
* @param executeFunction - Raw execute function code
|
|
61
|
+
* @param componentName - Name of the component (webhook/job/processor)
|
|
62
|
+
* @param componentType - Type identifier for temp files
|
|
63
|
+
* @param vmWrapperGenerator - Function that generates the VM wrapper code
|
|
64
|
+
* @param distDir - Distribution directory
|
|
65
|
+
* @param sourceFilePath - Path to source file containing the component
|
|
66
|
+
* @returns Compressed base64-encoded bundled code
|
|
67
|
+
*/
|
|
68
|
+
async function bundleAndCompressExecuteFunction(executeFunction, componentName, componentType, vmWrapperGenerator, distDir, sourceFilePath) {
|
|
69
|
+
const { compressCode } = await import('./compile.js');
|
|
70
|
+
// Create temporary file with the execute function wrapped as a module
|
|
71
|
+
const tempDir = path.join(distDir, '.temp');
|
|
72
|
+
if (!fs.existsSync(tempDir)) {
|
|
73
|
+
fs.mkdirSync(tempDir, { recursive: true });
|
|
74
|
+
}
|
|
75
|
+
const tempFile = path.join(tempDir, `${componentName}-${componentType}.ts`);
|
|
76
|
+
const tempOutput = path.join(tempDir, `${componentName}-${componentType}.js`);
|
|
77
|
+
try {
|
|
78
|
+
// Extract relevant imports from source file
|
|
79
|
+
const relevantImports = extractRelevantImports(sourceFilePath);
|
|
80
|
+
// Write execute function as a module export with all relevant imports
|
|
81
|
+
const moduleCode = `
|
|
82
|
+
// ${componentType} execute function for ${componentName}
|
|
83
|
+
${relevantImports.join('\n')}
|
|
84
|
+
|
|
85
|
+
// The execute function with all dependencies available
|
|
86
|
+
const executeFunc = ${executeFunction};
|
|
87
|
+
|
|
88
|
+
export default executeFunc;
|
|
89
|
+
`;
|
|
90
|
+
fs.writeFileSync(tempFile, moduleCode);
|
|
91
|
+
// Bundle with esbuild using the source file's directory for import resolution
|
|
92
|
+
await build({
|
|
93
|
+
entryPoints: [tempFile],
|
|
94
|
+
bundle: true,
|
|
95
|
+
platform: 'node',
|
|
96
|
+
target: 'node16',
|
|
97
|
+
format: 'cjs',
|
|
98
|
+
minify: true,
|
|
99
|
+
outfile: tempOutput,
|
|
100
|
+
external: [...EXTERNAL_PACKAGES], // Use same external packages as tools
|
|
101
|
+
plugins: [sandboxGlobalsPlugin],
|
|
102
|
+
absWorkingDir: path.dirname(sourceFilePath), // Use source file's directory for resolution
|
|
103
|
+
});
|
|
104
|
+
// Read bundled code
|
|
105
|
+
const bundledCode = fs.readFileSync(tempOutput, 'utf8');
|
|
106
|
+
// Wrap for VM execution using provided generator
|
|
107
|
+
const wrappedCode = vmWrapperGenerator(bundledCode);
|
|
108
|
+
// Compress the wrapped code
|
|
109
|
+
const compressed = compressCode(wrappedCode);
|
|
110
|
+
// Clean up temp files
|
|
111
|
+
try {
|
|
112
|
+
fs.unlinkSync(tempFile);
|
|
113
|
+
fs.unlinkSync(tempOutput);
|
|
114
|
+
}
|
|
115
|
+
catch (cleanupError) {
|
|
116
|
+
// Ignore cleanup errors
|
|
117
|
+
}
|
|
118
|
+
return compressed;
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
console.warn(`Warning: Could not bundle ${componentType} ${componentName} code:`, error);
|
|
122
|
+
// Clean up on error
|
|
123
|
+
try {
|
|
124
|
+
if (fs.existsSync(tempFile))
|
|
125
|
+
fs.unlinkSync(tempFile);
|
|
126
|
+
if (fs.existsSync(tempOutput))
|
|
127
|
+
fs.unlinkSync(tempOutput);
|
|
128
|
+
}
|
|
129
|
+
catch (cleanupError) {
|
|
130
|
+
// Ignore cleanup errors
|
|
131
|
+
}
|
|
132
|
+
return '';
|
|
133
|
+
}
|
|
134
|
+
}
|
|
33
135
|
/**
|
|
34
136
|
* esbuild plugin to inject sandbox globals instead of requiring lua-cli
|
|
35
137
|
* This removes require("lua-cli") statements and injects the global API objects
|
|
@@ -226,6 +328,7 @@ export async function bundleWebhook(webhook, indexFile, distDir, project) {
|
|
|
226
328
|
let querySchema = undefined;
|
|
227
329
|
let headerSchema = undefined;
|
|
228
330
|
let bodySchema = undefined;
|
|
331
|
+
let sourceFilePath = indexFile.getFilePath();
|
|
229
332
|
// Helper function to search for webhook in a file
|
|
230
333
|
const searchFileForWebhook = (file) => {
|
|
231
334
|
file.forEachDescendant((node) => {
|
|
@@ -271,6 +374,8 @@ export async function bundleWebhook(webhook, indexFile, distDir, project) {
|
|
|
271
374
|
querySchema = foundQuerySchema;
|
|
272
375
|
headerSchema = foundHeaderSchema;
|
|
273
376
|
bodySchema = foundBodySchema;
|
|
377
|
+
// Update source file path to the file where webhook was found
|
|
378
|
+
sourceFilePath = file.getFilePath();
|
|
274
379
|
}
|
|
275
380
|
}
|
|
276
381
|
}
|
|
@@ -315,7 +420,7 @@ export async function bundleWebhook(webhook, indexFile, distDir, project) {
|
|
|
315
420
|
// Bundle and compress the execute function (like tools)
|
|
316
421
|
let compressedCode = '';
|
|
317
422
|
if (executeFunction) {
|
|
318
|
-
compressedCode = await bundleAndCompressWebhookCode(executeFunction, webhook.name, distDir);
|
|
423
|
+
compressedCode = await bundleAndCompressWebhookCode(executeFunction, webhook.name, distDir, sourceFilePath);
|
|
319
424
|
}
|
|
320
425
|
return {
|
|
321
426
|
...webhook,
|
|
@@ -332,44 +437,16 @@ export async function bundleWebhook(webhook, indexFile, distDir, project) {
|
|
|
332
437
|
/**
|
|
333
438
|
* Bundles and compresses webhook execute function code.
|
|
334
439
|
* Creates a temporary file, bundles with esbuild, compresses with gzip.
|
|
440
|
+
* Includes all imports from the source file to ensure dependencies are bundled.
|
|
335
441
|
*
|
|
336
442
|
* @param executeFunction - Raw execute function code
|
|
337
443
|
* @param webhookName - Name of the webhook
|
|
338
444
|
* @param distDir - Distribution directory
|
|
445
|
+
* @param sourceFilePath - Path to the source file containing the webhook
|
|
339
446
|
* @returns Compressed base64-encoded bundled code
|
|
340
447
|
*/
|
|
341
|
-
async function bundleAndCompressWebhookCode(executeFunction, webhookName, distDir) {
|
|
342
|
-
|
|
343
|
-
// Create temporary file with the execute function wrapped as a module
|
|
344
|
-
const tempDir = path.join(distDir, '.temp');
|
|
345
|
-
if (!fs.existsSync(tempDir)) {
|
|
346
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
|
347
|
-
}
|
|
348
|
-
const tempFile = path.join(tempDir, `${webhookName}-webhook.ts`);
|
|
349
|
-
const tempOutput = path.join(tempDir, `${webhookName}-webhook.js`);
|
|
350
|
-
try {
|
|
351
|
-
// Write execute function as a module export
|
|
352
|
-
const moduleCode = stripLuaCliImports(`
|
|
353
|
-
// Webhook execute function for ${webhookName}
|
|
354
|
-
export default ${executeFunction};
|
|
355
|
-
`);
|
|
356
|
-
fs.writeFileSync(tempFile, moduleCode);
|
|
357
|
-
// Bundle with esbuild
|
|
358
|
-
await build({
|
|
359
|
-
entryPoints: [tempFile],
|
|
360
|
-
bundle: true,
|
|
361
|
-
platform: 'node',
|
|
362
|
-
target: 'node16',
|
|
363
|
-
format: 'cjs',
|
|
364
|
-
minify: true,
|
|
365
|
-
outfile: tempOutput,
|
|
366
|
-
external: [], // Bundle everything
|
|
367
|
-
plugins: [sandboxGlobalsPlugin],
|
|
368
|
-
});
|
|
369
|
-
// Read bundled code
|
|
370
|
-
let bundledCode = fs.readFileSync(tempOutput, 'utf8');
|
|
371
|
-
// Wrap for webhook VM execution (similar to tools)
|
|
372
|
-
const wrappedCode = `(async (query, headers, body) => {
|
|
448
|
+
async function bundleAndCompressWebhookCode(executeFunction, webhookName, distDir, sourceFilePath) {
|
|
449
|
+
return bundleAndCompressExecuteFunction(executeFunction, webhookName, 'webhook', (bundledCode) => `(async (query, headers, body) => {
|
|
373
450
|
|
|
374
451
|
// Execute the bundled webhook code
|
|
375
452
|
${bundledCode}
|
|
@@ -379,33 +456,7 @@ export default ${executeFunction};
|
|
|
379
456
|
|
|
380
457
|
// Execute with three separate parameters (not an object)
|
|
381
458
|
return await executeFunction(query, headers, body);
|
|
382
|
-
})
|
|
383
|
-
// Compress the wrapped code
|
|
384
|
-
const compressed = compressCode(wrappedCode);
|
|
385
|
-
// Clean up temp files
|
|
386
|
-
try {
|
|
387
|
-
fs.unlinkSync(tempFile);
|
|
388
|
-
fs.unlinkSync(tempOutput);
|
|
389
|
-
}
|
|
390
|
-
catch (cleanupError) {
|
|
391
|
-
// Ignore cleanup errors
|
|
392
|
-
}
|
|
393
|
-
return compressed;
|
|
394
|
-
}
|
|
395
|
-
catch (error) {
|
|
396
|
-
console.warn(`Warning: Could not bundle webhook ${webhookName} code:`, error);
|
|
397
|
-
// Clean up on error
|
|
398
|
-
try {
|
|
399
|
-
if (fs.existsSync(tempFile))
|
|
400
|
-
fs.unlinkSync(tempFile);
|
|
401
|
-
if (fs.existsSync(tempOutput))
|
|
402
|
-
fs.unlinkSync(tempOutput);
|
|
403
|
-
}
|
|
404
|
-
catch (cleanupError) {
|
|
405
|
-
// Ignore cleanup errors
|
|
406
|
-
}
|
|
407
|
-
return '';
|
|
408
|
-
}
|
|
459
|
+
})`, distDir, sourceFilePath);
|
|
409
460
|
}
|
|
410
461
|
/**
|
|
411
462
|
* Extracts and bundles job execute function.
|
|
@@ -421,6 +472,7 @@ export async function bundleJob(job, indexFile, distDir, project) {
|
|
|
421
472
|
try {
|
|
422
473
|
// Find the LuaJob constructor in the AST
|
|
423
474
|
let executeFunction = '';
|
|
475
|
+
let sourceFilePath = indexFile.getFilePath();
|
|
424
476
|
// Helper function to search for job in a file
|
|
425
477
|
const searchFileForJob = (file) => {
|
|
426
478
|
file.forEachDescendant((node) => {
|
|
@@ -451,6 +503,8 @@ export async function bundleJob(job, indexFile, distDir, project) {
|
|
|
451
503
|
// Only set executeFunction if this is the matching job
|
|
452
504
|
if (isMatchingJob && foundExecute) {
|
|
453
505
|
executeFunction = foundExecute;
|
|
506
|
+
// Update source file path to the file where job was found
|
|
507
|
+
sourceFilePath = file.getFilePath();
|
|
454
508
|
}
|
|
455
509
|
}
|
|
456
510
|
}
|
|
@@ -484,7 +538,7 @@ export async function bundleJob(job, indexFile, distDir, project) {
|
|
|
484
538
|
// Bundle and compress the execute function (like tools)
|
|
485
539
|
let compressedCode = '';
|
|
486
540
|
if (executeFunction) {
|
|
487
|
-
compressedCode = await bundleAndCompressJobCode(executeFunction, job.name, distDir);
|
|
541
|
+
compressedCode = await bundleAndCompressJobCode(executeFunction, job.name, distDir, sourceFilePath);
|
|
488
542
|
}
|
|
489
543
|
return {
|
|
490
544
|
...job,
|
|
@@ -500,44 +554,16 @@ export async function bundleJob(job, indexFile, distDir, project) {
|
|
|
500
554
|
/**
|
|
501
555
|
* Bundles and compresses job execute function code.
|
|
502
556
|
* Creates a temporary file, bundles with esbuild, compresses with gzip.
|
|
557
|
+
* Includes all imports from the source file to ensure dependencies are bundled.
|
|
503
558
|
*
|
|
504
559
|
* @param executeFunction - Raw execute function code
|
|
505
560
|
* @param jobName - Name of the job
|
|
506
561
|
* @param distDir - Distribution directory
|
|
562
|
+
* @param sourceFilePath - Path to the source file containing the job
|
|
507
563
|
* @returns Compressed base64-encoded bundled code
|
|
508
564
|
*/
|
|
509
|
-
async function bundleAndCompressJobCode(executeFunction, jobName, distDir) {
|
|
510
|
-
|
|
511
|
-
// Create temporary file with the execute function wrapped as a module
|
|
512
|
-
const tempDir = path.join(distDir, '.temp');
|
|
513
|
-
if (!fs.existsSync(tempDir)) {
|
|
514
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
|
515
|
-
}
|
|
516
|
-
const tempFile = path.join(tempDir, `${jobName}-job.ts`);
|
|
517
|
-
const tempOutput = path.join(tempDir, `${jobName}-job.js`);
|
|
518
|
-
try {
|
|
519
|
-
// Write execute function as a module export
|
|
520
|
-
const moduleCode = stripLuaCliImports(`
|
|
521
|
-
// Job execute function for ${jobName}
|
|
522
|
-
export default ${executeFunction};
|
|
523
|
-
`);
|
|
524
|
-
fs.writeFileSync(tempFile, moduleCode);
|
|
525
|
-
// Bundle with esbuild
|
|
526
|
-
await build({
|
|
527
|
-
entryPoints: [tempFile],
|
|
528
|
-
bundle: true,
|
|
529
|
-
platform: 'node',
|
|
530
|
-
target: 'node16',
|
|
531
|
-
format: 'cjs',
|
|
532
|
-
minify: true,
|
|
533
|
-
outfile: tempOutput,
|
|
534
|
-
external: [], // Bundle everything
|
|
535
|
-
plugins: [sandboxGlobalsPlugin],
|
|
536
|
-
});
|
|
537
|
-
// Read bundled code
|
|
538
|
-
let bundledCode = fs.readFileSync(tempOutput, 'utf8');
|
|
539
|
-
// Wrap for job VM execution (similar to tools, but accepts job parameter)
|
|
540
|
-
const wrappedCode = `(async (job) => {
|
|
565
|
+
async function bundleAndCompressJobCode(executeFunction, jobName, distDir, sourceFilePath) {
|
|
566
|
+
return bundleAndCompressExecuteFunction(executeFunction, jobName, 'job', (bundledCode) => `(async (job) => {
|
|
541
567
|
// Execute the bundled job code
|
|
542
568
|
${bundledCode}
|
|
543
569
|
|
|
@@ -546,33 +572,7 @@ export default ${executeFunction};
|
|
|
546
572
|
|
|
547
573
|
// Execute job with job instance parameter
|
|
548
574
|
return await executeFunction(job);
|
|
549
|
-
})
|
|
550
|
-
// Compress the wrapped code
|
|
551
|
-
const compressed = compressCode(wrappedCode);
|
|
552
|
-
// Clean up temp files
|
|
553
|
-
try {
|
|
554
|
-
fs.unlinkSync(tempFile);
|
|
555
|
-
fs.unlinkSync(tempOutput);
|
|
556
|
-
}
|
|
557
|
-
catch (cleanupError) {
|
|
558
|
-
// Ignore cleanup errors
|
|
559
|
-
}
|
|
560
|
-
return compressed;
|
|
561
|
-
}
|
|
562
|
-
catch (error) {
|
|
563
|
-
console.warn(`Warning: Could not bundle job ${jobName} code:`, error);
|
|
564
|
-
// Clean up on error
|
|
565
|
-
try {
|
|
566
|
-
if (fs.existsSync(tempFile))
|
|
567
|
-
fs.unlinkSync(tempFile);
|
|
568
|
-
if (fs.existsSync(tempOutput))
|
|
569
|
-
fs.unlinkSync(tempOutput);
|
|
570
|
-
}
|
|
571
|
-
catch (cleanupError) {
|
|
572
|
-
// Ignore cleanup errors
|
|
573
|
-
}
|
|
574
|
-
return '';
|
|
575
|
-
}
|
|
575
|
+
})`, distDir, sourceFilePath);
|
|
576
576
|
}
|
|
577
577
|
/**
|
|
578
578
|
* Bundles and compresses preprocessor execute function code.
|
|
@@ -581,6 +581,7 @@ export async function bundlePreProcessor(preprocessor, indexFile, distDir, proje
|
|
|
581
581
|
writeProgress(`š¦ Bundling preprocessor ${preprocessor.name}...`);
|
|
582
582
|
try {
|
|
583
583
|
let executeFunction = '';
|
|
584
|
+
let sourceFilePath = indexFile.getFilePath();
|
|
584
585
|
const searchFileForPreProcessor = (file) => {
|
|
585
586
|
file.forEachDescendant((node) => {
|
|
586
587
|
if (Node.isNewExpression(node)) {
|
|
@@ -608,6 +609,8 @@ export async function bundlePreProcessor(preprocessor, indexFile, distDir, proje
|
|
|
608
609
|
});
|
|
609
610
|
if (isMatching && foundExecute) {
|
|
610
611
|
executeFunction = foundExecute;
|
|
612
|
+
// Update source file path to the file where preprocessor was found
|
|
613
|
+
sourceFilePath = file.getFilePath();
|
|
611
614
|
}
|
|
612
615
|
}
|
|
613
616
|
}
|
|
@@ -639,7 +642,7 @@ export async function bundlePreProcessor(preprocessor, indexFile, distDir, proje
|
|
|
639
642
|
}
|
|
640
643
|
let compressedCode = '';
|
|
641
644
|
if (executeFunction) {
|
|
642
|
-
compressedCode = await bundleAndCompressProcessorCode(executeFunction, preprocessor.name, 'pre', distDir);
|
|
645
|
+
compressedCode = await bundleAndCompressProcessorCode(executeFunction, preprocessor.name, 'pre', distDir, sourceFilePath);
|
|
643
646
|
}
|
|
644
647
|
return {
|
|
645
648
|
name: preprocessor.name,
|
|
@@ -663,6 +666,7 @@ export async function bundlePostProcessor(postprocessor, indexFile, distDir, pro
|
|
|
663
666
|
writeProgress(`š¦ Bundling postprocessor ${postprocessor.name}...`);
|
|
664
667
|
try {
|
|
665
668
|
let executeFunction = '';
|
|
669
|
+
let sourceFilePath = indexFile.getFilePath();
|
|
666
670
|
const searchFileForPostProcessor = (file) => {
|
|
667
671
|
file.forEachDescendant((node) => {
|
|
668
672
|
if (Node.isNewExpression(node)) {
|
|
@@ -690,6 +694,8 @@ export async function bundlePostProcessor(postprocessor, indexFile, distDir, pro
|
|
|
690
694
|
});
|
|
691
695
|
if (isMatching && foundExecute) {
|
|
692
696
|
executeFunction = foundExecute;
|
|
697
|
+
// Update source file path to the file where postprocessor was found
|
|
698
|
+
sourceFilePath = file.getFilePath();
|
|
693
699
|
}
|
|
694
700
|
}
|
|
695
701
|
}
|
|
@@ -721,7 +727,7 @@ export async function bundlePostProcessor(postprocessor, indexFile, distDir, pro
|
|
|
721
727
|
}
|
|
722
728
|
let compressedCode = '';
|
|
723
729
|
if (executeFunction) {
|
|
724
|
-
compressedCode = await bundleAndCompressProcessorCode(executeFunction, postprocessor.name, 'post', distDir);
|
|
730
|
+
compressedCode = await bundleAndCompressProcessorCode(executeFunction, postprocessor.name, 'post', distDir, sourceFilePath);
|
|
725
731
|
}
|
|
726
732
|
return {
|
|
727
733
|
name: postprocessor.name,
|
|
@@ -740,65 +746,18 @@ export async function bundlePostProcessor(postprocessor, indexFile, distDir, pro
|
|
|
740
746
|
}
|
|
741
747
|
/**
|
|
742
748
|
* Bundles and compresses processor execute function code.
|
|
749
|
+
* Includes all imports from the source file to ensure dependencies are bundled.
|
|
743
750
|
*/
|
|
744
|
-
async function bundleAndCompressProcessorCode(executeFunction, processorName, type, distDir) {
|
|
745
|
-
|
|
746
|
-
const
|
|
747
|
-
|
|
748
|
-
fs.mkdirSync(tempDir, { recursive: true });
|
|
749
|
-
}
|
|
750
|
-
const tempFile = path.join(tempDir, `${processorName}-${type}processor.ts`);
|
|
751
|
-
const tempOutput = path.join(tempDir, `${processorName}-${type}processor.js`);
|
|
752
|
-
try {
|
|
753
|
-
// Processor execute functions receive: (user, message, [response], channel)
|
|
754
|
-
const paramList = type === 'pre' ? 'user, message, channel' : 'user, message, response, channel';
|
|
755
|
-
const moduleCode = stripLuaCliImports(`
|
|
756
|
-
// ${type === 'pre' ? 'Pre' : 'Post'}Processor execute function for ${processorName}
|
|
757
|
-
export default ${executeFunction};
|
|
758
|
-
`);
|
|
759
|
-
fs.writeFileSync(tempFile, moduleCode);
|
|
760
|
-
await build({
|
|
761
|
-
entryPoints: [tempFile],
|
|
762
|
-
bundle: true,
|
|
763
|
-
platform: 'node',
|
|
764
|
-
target: 'node16',
|
|
765
|
-
format: 'cjs',
|
|
766
|
-
minify: true,
|
|
767
|
-
outfile: tempOutput,
|
|
768
|
-
external: [],
|
|
769
|
-
plugins: [sandboxGlobalsPlugin],
|
|
770
|
-
});
|
|
771
|
-
let bundledCode = fs.readFileSync(tempOutput, 'utf8');
|
|
772
|
-
const wrappedCode = `(async (${paramList}) => {
|
|
751
|
+
async function bundleAndCompressProcessorCode(executeFunction, processorName, type, distDir, sourceFilePath) {
|
|
752
|
+
// Processor execute functions receive: (user, message, [response], channel)
|
|
753
|
+
const paramList = type === 'pre' ? 'user, message, channel' : 'user, message, response, channel';
|
|
754
|
+
return bundleAndCompressExecuteFunction(executeFunction, processorName, `${type}processor`, (bundledCode) => `(async (${paramList}) => {
|
|
773
755
|
// Execute the bundled processor code
|
|
774
756
|
${bundledCode}
|
|
775
757
|
|
|
776
758
|
const executeFunction = module.exports.default || module.exports;
|
|
777
759
|
return await executeFunction(${paramList});
|
|
778
|
-
})
|
|
779
|
-
const compressed = compressCode(wrappedCode);
|
|
780
|
-
try {
|
|
781
|
-
fs.unlinkSync(tempFile);
|
|
782
|
-
fs.unlinkSync(tempOutput);
|
|
783
|
-
}
|
|
784
|
-
catch (cleanupError) {
|
|
785
|
-
// Ignore
|
|
786
|
-
}
|
|
787
|
-
return compressed;
|
|
788
|
-
}
|
|
789
|
-
catch (error) {
|
|
790
|
-
console.warn(`Warning: Could not bundle ${type}processor ${processorName} code:`, error);
|
|
791
|
-
try {
|
|
792
|
-
if (fs.existsSync(tempFile))
|
|
793
|
-
fs.unlinkSync(tempFile);
|
|
794
|
-
if (fs.existsSync(tempOutput))
|
|
795
|
-
fs.unlinkSync(tempOutput);
|
|
796
|
-
}
|
|
797
|
-
catch (cleanupError) {
|
|
798
|
-
// Ignore
|
|
799
|
-
}
|
|
800
|
-
return '';
|
|
801
|
-
}
|
|
760
|
+
})`, distDir, sourceFilePath);
|
|
802
761
|
}
|
|
803
762
|
/**
|
|
804
763
|
* Extracts execute code and input schema from a tool.
|
package/dist/utils/cli.d.ts
CHANGED
|
@@ -13,22 +13,22 @@ export declare function withErrorHandling<T>(commandFn: () => Promise<T>, comman
|
|
|
13
13
|
*/
|
|
14
14
|
export declare function clearPromptLines(count?: number): void;
|
|
15
15
|
/**
|
|
16
|
-
* Writes a progress message that
|
|
17
|
-
* Uses carriage return to
|
|
16
|
+
* Writes a progress message that overwrites the current line
|
|
17
|
+
* Uses carriage return to replace previous progress messages
|
|
18
18
|
*/
|
|
19
19
|
export declare function writeProgress(message: string): void;
|
|
20
20
|
/**
|
|
21
21
|
* Writes a final success message that will remain visible
|
|
22
|
-
*
|
|
22
|
+
* Clears the progress line first, then writes the message with newline
|
|
23
23
|
*/
|
|
24
24
|
export declare function writeSuccess(message: string): void;
|
|
25
25
|
/**
|
|
26
26
|
* Writes an error message
|
|
27
|
-
*
|
|
27
|
+
* Clears the progress line first, then writes the error with newline
|
|
28
28
|
*/
|
|
29
29
|
export declare function writeError(message: string): void;
|
|
30
30
|
/**
|
|
31
31
|
* Writes an info message
|
|
32
|
-
*
|
|
32
|
+
* Clears the progress line first, then writes the message with newline
|
|
33
33
|
*/
|
|
34
34
|
export declare function writeInfo(message: string): void;
|