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.
@@ -47,8 +47,8 @@ export async function chatCommand() {
47
47
  name: 'environment',
48
48
  message: 'Select environment:',
49
49
  choices: [
50
- { name: 'šŸ”§ Sandbox (with skill overrides)', value: '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...`);
@@ -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, promptFeatureConfiguration, promptBusinessConfiguration, } from "../utils/init-prompts.js";
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: 'confirm',
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
- // Configure features
239
+ // Enable all features by default (skip configuration prompt)
236
240
  const availableFeatures = Object.keys(selectedAgentType.features);
237
- const features = availableFeatures.length > 0
238
- ? await promptFeatureConfiguration(selectedAgentType)
239
- : {};
240
- linesToClear += availableFeatures.length;
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
@@ -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
- const otpSent = await requestEmailOTP(email);
62
- if (!otpSent) {
63
- throw new Error("Failed to send OTP. Please try again.");
64
- }
65
- writeProgress("āœ… OTP sent successfully!");
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 code:",
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
  }
@@ -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
- const { compressCode } = await import('./compile.js');
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
- const { compressCode } = await import('./compile.js');
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
- const { compressCode } = await import('./compile.js');
746
- const tempDir = path.join(distDir, '.temp');
747
- if (!fs.existsSync(tempDir)) {
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.
@@ -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 will be replaced by the next message
17
- * Uses carriage return to overwrite the current line
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
- * Uses console.log to ensure it stays in the output
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
- * Uses console.error for proper error output
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
- * Uses console.log for informational output
32
+ * Clears the progress line first, then writes the message with newline
33
33
  */
34
34
  export declare function writeInfo(message: string): void;